Beispiel #1
0
/* sample an actual, honest to god thread! */
static void
pet_sample_thread( thread_t thread )
{
	struct kperf_context ctx;
	task_t task;
	unsigned skip_callstack;

	/* work out the context */
	ctx.cur_thread = thread;
	ctx.cur_pid = 0;

	task = chudxnu_task_for_thread(thread);
	if(task)
		ctx.cur_pid = chudxnu_pid_for_task(task);

	skip_callstack = (chudxnu_thread_get_dirty(thread) == TRUE) || ((thread->kperf_pet_cnt % (uint64_t)pet_idle_rate) == 0) ? 0 : SAMPLE_FLAG_EMPTY_CALLSTACK;

	/* do the actual sample */
	kperf_sample( &pet_sample_buf, &ctx, pet_actionid,
	              SAMPLE_FLAG_IDLE_THREADS | skip_callstack );

	if (!skip_callstack)
		chudxnu_thread_set_dirty(thread, FALSE);

	thread->kperf_pet_cnt++;
}
Beispiel #2
0
void
kperf_ipi_handler(void *param)
{
	struct kperf_context ctx;
	struct kperf_timer *timer = param;

	assert(timer != NULL);

	/* Always cut a tracepoint to show a sample event occurred */
	BUF_DATA(PERF_TM_HNDLR | DBG_FUNC_START, 0);

	int ncpu = cpu_number();

	struct kperf_sample *intbuf = kperf_intr_sample_buffer();

	/* On a timer, we can see the "real" current thread */
	ctx.cur_thread = current_thread();
	ctx.cur_pid = task_pid(get_threadtask(ctx.cur_thread));

	/* who fired */
	ctx.trigger_type = TRIGGER_TYPE_TIMER;
	ctx.trigger_id = (unsigned int)(timer - kperf_timerv);

	if (ctx.trigger_id == pet_timer_id && ncpu < machine_info.logical_cpu_max) {
		kperf_thread_on_cpus[ncpu] = ctx.cur_thread;
	}

	/* make sure sampling is on */
	unsigned int status = kperf_sampling_status();
	if (status == KPERF_SAMPLING_OFF) {
		BUF_INFO(PERF_TM_HNDLR | DBG_FUNC_END, SAMPLE_OFF);
		return;
	} else if (status == KPERF_SAMPLING_SHUTDOWN) {
		BUF_INFO(PERF_TM_HNDLR | DBG_FUNC_END, SAMPLE_SHUTDOWN);
		return;
	}

	/* call the action -- kernel-only from interrupt, pend user */
	int r = kperf_sample(intbuf, &ctx, timer->actionid, SAMPLE_FLAG_PEND_USER);

	/* end tracepoint is informational */
	BUF_INFO(PERF_TM_HNDLR | DBG_FUNC_END, r);

#if defined(__x86_64__)
	(void)atomic_bit_clear(&(timer->pending_cpus), ncpu, __ATOMIC_RELAXED);
#endif /* defined(__x86_64__) */
}
Beispiel #3
0
static void
kperf_ipi_handler( void *param )
{
	int r;
	int ncpu;
	struct kperf_sample *intbuf = NULL;
	struct kperf_context ctx;
	struct time_trigger *trigger = param;
	task_t task = NULL;

	/* Always cut a tracepoint to show a sample event occurred */
	BUF_DATA1(PERF_TM_HNDLR | DBG_FUNC_START, 0);

	/* In an interrupt, get the interrupt buffer for this CPU */
	intbuf = kperf_intr_sample_buffer();

	/* On a timer, we can see the "real" current thread */
	ctx.cur_pid = 0; /* remove this? */
	ctx.cur_thread = current_thread();

	task = chudxnu_task_for_thread(ctx.cur_thread);
	if (task)
		ctx.cur_pid = chudxnu_pid_for_task(task);

	/* who fired */
	ctx.trigger_type = TRIGGER_TYPE_TIMER;
	ctx.trigger_id = (unsigned)(trigger-timerv); /* computer timer number */

	ncpu = chudxnu_cpu_number();
	if (ctx.trigger_id == pet_timer && ncpu < machine_info.logical_cpu_max)
		kperf_thread_on_cpus[ncpu] = ctx.cur_thread;

	/* check samppling is on */
	if( kperf_sampling_status() == KPERF_SAMPLING_OFF ) {
		BUF_INFO1(PERF_TM_HNDLR | DBG_FUNC_END, SAMPLE_OFF);
		return;
	} else if( kperf_sampling_status() == KPERF_SAMPLING_SHUTDOWN ) {
		BUF_INFO1(PERF_TM_HNDLR | DBG_FUNC_END, SAMPLE_SHUTDOWN);
		return;
	}

	/* call the action -- kernel-only from interrupt, pend user */
	r = kperf_sample( intbuf, &ctx, trigger->actionid, SAMPLE_FLAG_PEND_USER );

	/* end tracepoint is informational */
	BUF_INFO1(PERF_TM_HNDLR | DBG_FUNC_END, r);
}
Beispiel #4
0
/* sample an actual, honest to god thread! */
static void
pet_sample_thread( thread_t thread )
{
	struct kperf_context ctx;
	task_t task;

	/* work out the context */
	ctx.cur_thread = thread;
	ctx.cur_pid = -1;

	task = chudxnu_task_for_thread(thread);
	if(task)
		ctx.cur_pid = chudxnu_pid_for_task(task);

	/* do the actual sample */
	kperf_sample( &pet_sample_buf, &ctx, pet_actionid, false );
}
Beispiel #5
0
void
kpc_sample_kperf(uint32_t actionid)
{
	struct kperf_sample sbuf;
	struct kperf_context ctx;
	task_t task = NULL;
	int r;

	BUF_DATA1(PERF_KPC_HNDLR | DBG_FUNC_START, 0);

	ctx.cur_pid = 0;
	ctx.cur_thread = current_thread();

	task = chudxnu_task_for_thread(ctx.cur_thread);
	if (task)
		ctx.cur_pid = chudxnu_pid_for_task(task);

	ctx.trigger_type = TRIGGER_TYPE_PMI;
	ctx.trigger_id = 0;

	r = kperf_sample(&sbuf, &ctx, actionid, SAMPLE_FLAG_PEND_USER);

	BUF_INFO1(PERF_KPC_HNDLR | DBG_FUNC_END, r);
}