#include <mach/mach_types.h>
#include <kern/thread.h>
#include <kern/debug.h>
#include <chud/chud_xnu.h>
#include <kperf/kperf.h>
#include <kperf/buffer.h>
#include <kperf/context.h>
#include <kperf/threadinfo.h>
#include <kperf/ast.h>
#define TH_IDLE_N (TH_IDLE << 16)
static uint64_t
make_runmode(thread_t thread)
{
const int mode = chudxnu_thread_get_scheduler_state(thread);
#if !TARGET_OS_EMBEDDED
if( 0 == mode)
{
return (chudxnu_thread_get_idle(thread) ? TH_IDLE : TH_IDLE_N);
}
else
#endif
{
return ((mode & 0xffff) | ((~mode & 0xffff) << 16));
}
}
void
kperf_threadinfo_sample(struct threadinfo *ti, struct kperf_context *context)
{
thread_t cur_thread = context->cur_thread;
BUF_INFO1( PERF_TI_SAMPLE, (uintptr_t)cur_thread );
ti->pid = context->cur_pid;
ti->tid = thread_tid(cur_thread);
ti->dq_addr = thread_dispatchqaddr(cur_thread);
ti->runmode = make_runmode(cur_thread);
}
void
kperf_threadinfo_log(struct threadinfo *ti)
{
BUF_DATA( PERF_TI_DATA, ti->pid, ti->tid, ti->dq_addr, ti->runmode );
}
void
kperf_threadinfo_extra_sample(struct tinfo_ex *tex, struct kperf_context *context)
{
thread_t cur_thread = context->cur_thread;
uint32_t t_chud;
t_chud = kperf_get_thread_bits(cur_thread);
if( t_chud & T_AST_NAME )
{
BUF_INFO1( PERF_TI_XSAMPLE, (uintptr_t)cur_thread );
#ifdef FIXME
proc_name( context->cur_pid,
&tex->p_comm[0], CHUD_MAXPCOMM );
#endif
t_chud &= ~T_AST_NAME;
t_chud |= T_NAME_DONE;
kperf_set_thread_bits(cur_thread, t_chud);
}
else
tex->p_comm[0] = '\0';
}
void
kperf_threadinfo_extra_log(struct tinfo_ex *tex)
{
if( tex->p_comm[0] == '\0' )
return;
BUF_DATA1( PERF_TI_XDATA, (uintptr_t)*(uintptr_t*)&tex->p_comm[0] );
}
int
kperf_threadinfo_extra_pend(struct kperf_context *context)
{
return kperf_ast_pend( context->cur_thread, T_NAME_DONE | T_AST_NAME,
T_AST_NAME );
}
#if 0
APTIAKernelEntry_t *threadInfo = (APTIAKernelEntry_t*)(threadInfos + account->offset);
context->timeStamp = mach_absolute_time();
context->cpuNum = chudxnu_cpu_number();
context->pid = chudxnu_current_pid();
threadInfo->pid = context->generic->pid;
context->threadID = chudxnu_current_thread();
threadInfo->tid = thread_tid(context->generic->threadID);
threadInfo->dispatch_queue_addr = thread_dispatchqaddr(context->generic->threadID);
threadInfo->runMode = AppleProfileGetRunModeOfThread(context->generic->threadID);
typedef enum {
kAppleProfileTriggerClientThreadModeNone = 0x0,
kAppleProfileTriggerClientThreadModeRunning = 0x1, kAppleProfileTriggerClientThreadModeRunnable = 0x2, kAppleProfileTriggerClientThreadModeBlocked = 0x4, kAppleProfileTriggerClientThreadModeUninterruptible = 0x8, kAppleProfileTriggerClientThreadModeSuspended = 0x10, kAppleProfileTriggerClientThreadModeTerminating = 0x20, kAppleProfileTriggerClientThreadModeIdle = 0x40,
kAppleProfileTriggerClientThreadModeNotRunning = kAppleProfileTriggerClientThreadModeRunning << 16, kAppleProfileTriggerClientThreadModeNotRunnable = kAppleProfileTriggerClientThreadModeRunnable << 16, kAppleProfileTriggerClientThreadModeNotBlocked = kAppleProfileTriggerClientThreadModeBlocked << 16, kAppleProfileTriggerClientThreadModeNotUninterruptible = kAppleProfileTriggerClientThreadModeUninterruptible << 16, kAppleProfileTriggerClientThreadModeNotSuspended = kAppleProfileTriggerClientThreadModeSuspended << 16, kAppleProfileTriggerClientThreadModeNotTerminating = kAppleProfileTriggerClientThreadModeTerminating << 16, kAppleProfileTriggerClientThreadModeNotIdle = kAppleProfileTriggerClientThreadModeIdle << 16,
kAppleProfileTriggerClientThreadModeAny = ( kAppleProfileTriggerClientThreadModeRunning
| kAppleProfileTriggerClientThreadModeNotRunning),
} AppleProfileTriggerClientThreadRunMode;
extern "C" AppleProfileTriggerClientThreadRunMode AppleProfileGetRunModeOfThread(thread_t thread) {
const int mode = chudxnu_thread_get_scheduler_state(thread);
#if !TARGET_OS_EMBEDDED
if (0 == mode) {
return (chudxnu_thread_get_idle(thread) ? kAppleProfileTriggerClientThreadModeIdle : kAppleProfileTriggerClientThreadModeNotIdle);
} else
#endif
return (AppleProfileTriggerClientThreadRunMode)((mode & 0xffff) | ((~mode & 0xffff) << 16)); }
#endif