Add preliminar nosv CPU subsystem support
This commit is contained in:
parent
e8f4060370
commit
28fa152169
6
emu.c
6
emu.c
@ -39,7 +39,7 @@ emit_ev(struct ovni_stream *stream, struct ovni_ev *ev)
|
|||||||
|
|
||||||
delta = clock - stream->lastclock;
|
delta = clock - stream->lastclock;
|
||||||
|
|
||||||
dbg("%d.%d.%d %c %c %c % 20lu % 15ld ",
|
dbg("%d.%d.%d %c %c %c % 20ld % 15ld ",
|
||||||
stream->loom, stream->proc, stream->tid,
|
stream->loom, stream->proc, stream->tid,
|
||||||
ev->header.model, ev->header.class, ev->header.value, clock, delta);
|
ev->header.model, ev->header.class, ev->header.value, clock, delta);
|
||||||
|
|
||||||
@ -87,6 +87,7 @@ hook_pre(struct ovni_emu *emu)
|
|||||||
case 'V': hook_pre_nosv(emu);
|
case 'V': hook_pre_nosv(emu);
|
||||||
break;
|
break;
|
||||||
case '*': hook_pre_nosv(emu);
|
case '*': hook_pre_nosv(emu);
|
||||||
|
hook_pre_ovni(emu);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -105,6 +106,7 @@ hook_emit(struct ovni_emu *emu)
|
|||||||
case 'V': hook_emit_nosv(emu);
|
case 'V': hook_emit_nosv(emu);
|
||||||
break;
|
break;
|
||||||
case '*': hook_emit_nosv(emu);
|
case '*': hook_emit_nosv(emu);
|
||||||
|
hook_emit_ovni(emu);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//dbg("unknown model %c\n", emu->cur_ev->model);
|
//dbg("unknown model %c\n", emu->cur_ev->model);
|
||||||
@ -124,6 +126,7 @@ hook_post(struct ovni_emu *emu)
|
|||||||
case 'V': hook_post_nosv(emu);
|
case 'V': hook_post_nosv(emu);
|
||||||
break;
|
break;
|
||||||
case '*': hook_post_nosv(emu);
|
case '*': hook_post_nosv(emu);
|
||||||
|
hook_post_ovni(emu);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
//dbg("unknown model %c\n", emu->cur_ev->model);
|
//dbg("unknown model %c\n", emu->cur_ev->model);
|
||||||
@ -240,6 +243,7 @@ emulate(struct ovni_emu *emu)
|
|||||||
while(next_event(emu) == 0)
|
while(next_event(emu) == 0)
|
||||||
{
|
{
|
||||||
//fprintf(stdout, "step %i\n", i);
|
//fprintf(stdout, "step %i\n", i);
|
||||||
|
emu_emit(emu);
|
||||||
hook_pre(emu);
|
hook_pre(emu);
|
||||||
hook_emit(emu);
|
hook_emit(emu);
|
||||||
hook_post(emu);
|
hook_post(emu);
|
||||||
|
14
emu.h
14
emu.h
@ -14,7 +14,7 @@
|
|||||||
# define dbg(...)
|
# define dbg(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define err(...) fprintf(stderr, "error: " __VA_ARGS__);
|
#define err(...) fprintf(stderr, __VA_ARGS__);
|
||||||
|
|
||||||
/* Emulated thread runtime status */
|
/* Emulated thread runtime status */
|
||||||
enum ethread_state {
|
enum ethread_state {
|
||||||
@ -33,6 +33,7 @@ enum nosv_task_state {
|
|||||||
|
|
||||||
enum nosv_thread_ss_state {
|
enum nosv_thread_ss_state {
|
||||||
ST_NULL = 0,
|
ST_NULL = 0,
|
||||||
|
ST_BAD = 3,
|
||||||
ST_SCHED_HUNGRY = 6,
|
ST_SCHED_HUNGRY = 6,
|
||||||
ST_SCHED_SERVING = 7,
|
ST_SCHED_SERVING = 7,
|
||||||
ST_SCHED_SUBMITTING = 8,
|
ST_SCHED_SUBMITTING = 8,
|
||||||
@ -156,9 +157,16 @@ struct ovni_cpu {
|
|||||||
|
|
||||||
size_t last_nthreads;
|
size_t last_nthreads;
|
||||||
|
|
||||||
|
/* 1 if the cpu has updated is threads, 0 if not */
|
||||||
|
int updated;
|
||||||
|
|
||||||
/* The threads the cpu is currently running */
|
/* The threads the cpu is currently running */
|
||||||
size_t nthreads;
|
size_t nthreads;
|
||||||
struct ovni_ethread *thread[OVNI_MAX_THR];
|
struct ovni_ethread *thread[OVNI_MAX_THR];
|
||||||
|
|
||||||
|
///* Each channel emits events in the PRV file */
|
||||||
|
//int nchannels;
|
||||||
|
//struct ovni_channel *channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------------- trace ------------------------ */
|
/* ----------------------- trace ------------------------ */
|
||||||
@ -180,6 +188,10 @@ struct ovni_loom {
|
|||||||
struct ovni_cpu vcpu;
|
struct ovni_cpu vcpu;
|
||||||
|
|
||||||
struct ovni_eproc proc[OVNI_MAX_PROC];
|
struct ovni_eproc proc[OVNI_MAX_PROC];
|
||||||
|
|
||||||
|
/* Keep a list of updated cpus */
|
||||||
|
int nupdated_cpus;
|
||||||
|
struct ovni_cpu *updated_cpu[OVNI_MAX_CPU];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_VIRTUAL_EVENTS 16
|
#define MAX_VIRTUAL_EVENTS 16
|
||||||
|
140
emu_nosv_ss.c
140
emu_nosv_ss.c
@ -161,6 +161,32 @@ pre_thread(struct ovni_emu *emu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hook for the virtual "cpu changed" event */
|
||||||
|
static void
|
||||||
|
pre_cpu_change(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
struct ovni_ethread *th;
|
||||||
|
|
||||||
|
th = emu->cur_thread;
|
||||||
|
|
||||||
|
/* Only print the subsystem if the thread is running */
|
||||||
|
if(th->state == TH_ST_RUNNING)
|
||||||
|
th->show_ss = 1;
|
||||||
|
else
|
||||||
|
th->show_ss = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pre_cpu(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
switch(emu->cur_ev->header.value)
|
||||||
|
{
|
||||||
|
case 'c': pre_thread_change(emu); break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hook_pre_nosv_ss(struct ovni_emu *emu)
|
hook_pre_nosv_ss(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
@ -171,6 +197,7 @@ hook_pre_nosv_ss(struct ovni_emu *emu)
|
|||||||
switch(emu->cur_ev->header.class)
|
switch(emu->cur_ev->header.class)
|
||||||
{
|
{
|
||||||
case 'H': pre_thread(emu); break;
|
case 'H': pre_thread(emu); break;
|
||||||
|
case 'C': pre_cpu(emu); break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -203,6 +230,17 @@ emit_thread_state(struct ovni_emu *emu, struct ovni_ethread *th,
|
|||||||
prv_ev_thread(emu, row, type, st);
|
prv_ev_thread(emu, row, type, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_cpu_state(struct ovni_emu *emu, struct ovni_ethread *th,
|
||||||
|
int type, int st)
|
||||||
|
{
|
||||||
|
/* Detect multiple threads */
|
||||||
|
if(th->cpu && th->cpu->nthreads > 1)
|
||||||
|
st = ST_BAD;
|
||||||
|
|
||||||
|
prv_ev_autocpu(emu, type, st);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_thread_event(struct ovni_emu *emu, struct ovni_ethread *th,
|
emit_thread_event(struct ovni_emu *emu, struct ovni_ethread *th,
|
||||||
int type, int st)
|
int type, int st)
|
||||||
@ -223,9 +261,108 @@ emit_thread_event(struct ovni_emu *emu, struct ovni_ethread *th,
|
|||||||
prv_ev_thread_raw(emu, row, t1, type, prev_st);
|
prv_ev_thread_raw(emu, row, t1, type, prev_st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_cpu_event(struct ovni_emu *emu, struct ovni_ethread *th,
|
||||||
|
int type, int st)
|
||||||
|
{
|
||||||
|
int64_t t0, t1;
|
||||||
|
int row;
|
||||||
|
int prev_st;
|
||||||
|
|
||||||
|
row = th->gindex + 1;
|
||||||
|
|
||||||
|
t0 = emu->delta_time - 1;
|
||||||
|
t1 = emu->delta_time;
|
||||||
|
|
||||||
|
prev_st = ss_last_st(th);
|
||||||
|
|
||||||
|
/* Detect multiple threads */
|
||||||
|
if(th->cpu && th->cpu->nthreads > 1)
|
||||||
|
{
|
||||||
|
st = ST_BAD;
|
||||||
|
prev_st = ST_BAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fake event using 1 nanosecond in the past */
|
||||||
|
prv_ev_autocpu_raw(emu, t0, type, st);
|
||||||
|
prv_ev_autocpu_raw(emu, t1, type, prev_st);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_thread_changed(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
dbg("emit_thread_changed\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_cpu_changed(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
dbg("emit_cpu_changed\n")
|
||||||
|
//int i;
|
||||||
|
//struct ovni_loom *loom;
|
||||||
|
//struct ovni_cpu *cpu;
|
||||||
|
|
||||||
|
///* Detect multiple threads */
|
||||||
|
//loom = emu->cur_loom;
|
||||||
|
|
||||||
|
//assert(loom->nupdated_cpus > 0);
|
||||||
|
|
||||||
|
//for(i=0; i<loom->nupdated_cpus; i++)
|
||||||
|
//{
|
||||||
|
// cpu = loom->updated_cpu[i];
|
||||||
|
|
||||||
|
// if(cpu->nthreads > 1)
|
||||||
|
// {
|
||||||
|
// prv_stream_disable(cpu->ss_stream);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hook_emit_nosv_ss(struct ovni_emu *emu)
|
hook_emit_nosv_ss(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
|
/* We need to emit events when a thread notifies us that the subsystem
|
||||||
|
* has changed, but also when the thread is paused, or scheduled to
|
||||||
|
* another CPU, as the CPU view must be updated as well. */
|
||||||
|
|
||||||
|
switch(emu->cur_ev->header.model)
|
||||||
|
{
|
||||||
|
/* Listen for virtual events as well */
|
||||||
|
case '*':
|
||||||
|
switch(emu->cur_ev->header.class)
|
||||||
|
{
|
||||||
|
case 'H':
|
||||||
|
switch(emu->cur_ev->header.value)
|
||||||
|
{
|
||||||
|
case 'c': emit_thread_changed(emu); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
switch(emu->cur_ev->header.value)
|
||||||
|
{
|
||||||
|
case 'c': emit_cpu_changed(emu); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
switch(emu->cur_ev->header.class)
|
||||||
|
{
|
||||||
|
case 'S': pre_sched(emu); break;
|
||||||
|
case 'U': pre_submit(emu); break;
|
||||||
|
case 'M': pre_memory(emu); break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ovni_ethread *th;
|
struct ovni_ethread *th;
|
||||||
|
|
||||||
th = emu->cur_thread;
|
th = emu->cur_thread;
|
||||||
@ -241,11 +378,14 @@ hook_emit_nosv_ss(struct ovni_emu *emu)
|
|||||||
{
|
{
|
||||||
emit_thread_event(emu, th, PTT_SUBSYSTEM,
|
emit_thread_event(emu, th, PTT_SUBSYSTEM,
|
||||||
th->ss_event);
|
th->ss_event);
|
||||||
|
emit_cpu_event(emu, th, PTC_SUBSYSTEM,
|
||||||
|
th->ss_event);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_thread_state(emu, th, PTT_SUBSYSTEM, ss_last_st(th));
|
emit_thread_state(emu, th, PTT_SUBSYSTEM, ss_last_st(th));
|
||||||
|
emit_cpu_state(emu, th, PTC_SUBSYSTEM, ss_last_st(th));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------- post ------------------------------- */
|
/* --------------------------- post ------------------------------- */
|
||||||
|
126
emu_ovni.c
126
emu_ovni.c
@ -4,6 +4,26 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* The emulator ovni module provides the execution model by tracking the thread
|
||||||
|
* state and which threads run in each CPU */
|
||||||
|
|
||||||
|
void
|
||||||
|
update_cpu(struct ovni_emu *emu, struct ovni_cpu *cpu)
|
||||||
|
{
|
||||||
|
struct ovni_loom *loom;
|
||||||
|
|
||||||
|
loom = emu->cur_loom;
|
||||||
|
|
||||||
|
if(loom->nupdated_cpus >= OVNI_MAX_CPU)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
if(cpu->updated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cpu->updated = 1;
|
||||||
|
loom->updated_cpu[loom->nupdated_cpus++] = cpu;
|
||||||
|
}
|
||||||
|
|
||||||
struct ovni_cpu *
|
struct ovni_cpu *
|
||||||
emu_get_cpu(struct ovni_loom *loom, int cpuid)
|
emu_get_cpu(struct ovni_loom *loom, int cpuid)
|
||||||
{
|
{
|
||||||
@ -34,7 +54,7 @@ emu_cpu_find_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
emu_cpu_add_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread)
|
emu_cpu_add_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_ethread *thread)
|
||||||
{
|
{
|
||||||
/* Found, abort */
|
/* Found, abort */
|
||||||
if(emu_cpu_find_thread(cpu, thread) >= 0)
|
if(emu_cpu_find_thread(cpu, thread) >= 0)
|
||||||
@ -43,10 +63,12 @@ emu_cpu_add_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread)
|
|||||||
assert(cpu->nthreads < OVNI_MAX_THR);
|
assert(cpu->nthreads < OVNI_MAX_THR);
|
||||||
|
|
||||||
cpu->thread[cpu->nthreads++] = thread;
|
cpu->thread[cpu->nthreads++] = thread;
|
||||||
|
|
||||||
|
update_cpu(emu, cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
emu_cpu_remove_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread)
|
emu_cpu_remove_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_ethread *thread)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -62,6 +84,8 @@ emu_cpu_remove_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpu->nthreads--;
|
cpu->nthreads--;
|
||||||
|
|
||||||
|
update_cpu(emu, cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -75,7 +99,7 @@ print_threads_state(struct ovni_loom *loom)
|
|||||||
{
|
{
|
||||||
cpu = &loom->cpu[i];
|
cpu = &loom->cpu[i];
|
||||||
|
|
||||||
dbg("-- cpu %d runs %d threads:", i, cpu->nthreads);
|
dbg("-- cpu %d runs %lu threads:", i, cpu->nthreads);
|
||||||
for(j=0; j<cpu->nthreads; j++)
|
for(j=0; j<cpu->nthreads; j++)
|
||||||
{
|
{
|
||||||
dbg(" %d", cpu->thread[j]->tid);
|
dbg(" %d", cpu->thread[j]->tid);
|
||||||
@ -83,7 +107,7 @@ print_threads_state(struct ovni_loom *loom)
|
|||||||
dbg("\n");
|
dbg("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg("-- vcpu runs %d threads:", loom->vcpu.nthreads);
|
dbg("-- vcpu runs %lu threads:", loom->vcpu.nthreads);
|
||||||
for(j=0; j<loom->vcpu.nthreads; j++)
|
for(j=0; j<loom->vcpu.nthreads; j++)
|
||||||
{
|
{
|
||||||
dbg(" %d", loom->vcpu.thread[j]->tid);
|
dbg(" %d", loom->vcpu.thread[j]->tid);
|
||||||
@ -108,7 +132,7 @@ ev_thread_execute(struct ovni_emu *emu)
|
|||||||
emu->cur_thread->state = TH_ST_RUNNING;
|
emu->cur_thread->state = TH_ST_RUNNING;
|
||||||
emu->cur_thread->cpu = cpu;
|
emu->cur_thread->cpu = cpu;
|
||||||
|
|
||||||
emu_cpu_add_thread(cpu, emu->cur_thread);
|
emu_cpu_add_thread(emu, cpu, emu->cur_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -117,7 +141,7 @@ ev_thread_end(struct ovni_emu *emu)
|
|||||||
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
||||||
assert(emu->cur_thread->cpu);
|
assert(emu->cur_thread->cpu);
|
||||||
|
|
||||||
emu_cpu_remove_thread(emu->cur_thread->cpu, emu->cur_thread);
|
emu_cpu_remove_thread(emu, emu->cur_thread->cpu, emu->cur_thread);
|
||||||
|
|
||||||
emu->cur_thread->state = TH_ST_DEAD;
|
emu->cur_thread->state = TH_ST_DEAD;
|
||||||
emu->cur_thread->cpu = NULL;
|
emu->cur_thread->cpu = NULL;
|
||||||
@ -129,7 +153,7 @@ ev_thread_pause(struct ovni_emu *emu)
|
|||||||
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
assert(emu->cur_thread->state == TH_ST_RUNNING);
|
||||||
assert(emu->cur_thread->cpu);
|
assert(emu->cur_thread->cpu);
|
||||||
|
|
||||||
emu_cpu_remove_thread(emu->cur_thread->cpu, emu->cur_thread);
|
emu_cpu_remove_thread(emu, emu->cur_thread->cpu, emu->cur_thread);
|
||||||
|
|
||||||
emu->cur_thread->state = TH_ST_PAUSED;
|
emu->cur_thread->state = TH_ST_PAUSED;
|
||||||
}
|
}
|
||||||
@ -140,7 +164,7 @@ ev_thread_resume(struct ovni_emu *emu)
|
|||||||
assert(emu->cur_thread->state == TH_ST_PAUSED);
|
assert(emu->cur_thread->state == TH_ST_PAUSED);
|
||||||
assert(emu->cur_thread->cpu);
|
assert(emu->cur_thread->cpu);
|
||||||
|
|
||||||
emu_cpu_add_thread(emu->cur_thread->cpu, emu->cur_thread);
|
emu_cpu_add_thread(emu, emu->cur_thread->cpu, emu->cur_thread);
|
||||||
|
|
||||||
emu->cur_thread->state = TH_ST_RUNNING;
|
emu->cur_thread->state = TH_ST_RUNNING;
|
||||||
}
|
}
|
||||||
@ -179,9 +203,13 @@ ev_thread(struct ovni_emu *emu)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All events change the thread state: inject a virtual event to
|
/* All but create events change the thread and CPU state: inject two
|
||||||
* notify other modules */
|
* virtual events to notify other modules. The order is important. */
|
||||||
emu_virtual_ev(emu, "*Hc");
|
if(ev->header.value != 'c')
|
||||||
|
{
|
||||||
|
emu_virtual_ev(emu, "*Hc");
|
||||||
|
emu_virtual_ev(emu, "*Cc");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -198,8 +226,8 @@ ev_affinity_set(struct ovni_emu *emu)
|
|||||||
/* Migrate current cpu to the one at cpuid */
|
/* Migrate current cpu to the one at cpuid */
|
||||||
newcpu = emu_get_cpu(emu->cur_loom, cpuid);
|
newcpu = emu_get_cpu(emu->cur_loom, cpuid);
|
||||||
|
|
||||||
emu_cpu_remove_thread(emu->cur_thread->cpu, emu->cur_thread);
|
emu_cpu_remove_thread(emu, emu->cur_thread->cpu, emu->cur_thread);
|
||||||
emu_cpu_add_thread(newcpu, emu->cur_thread);
|
emu_cpu_add_thread(emu, newcpu, emu->cur_thread);
|
||||||
|
|
||||||
emu->cur_thread->cpu = newcpu;
|
emu->cur_thread->cpu = newcpu;
|
||||||
|
|
||||||
@ -233,8 +261,8 @@ ev_affinity_remote(struct ovni_emu *emu)
|
|||||||
/* If running, update the CPU thread lists */
|
/* If running, update the CPU thread lists */
|
||||||
if(thread->state == TH_ST_RUNNING)
|
if(thread->state == TH_ST_RUNNING)
|
||||||
{
|
{
|
||||||
emu_cpu_remove_thread(thread->cpu, thread);
|
emu_cpu_remove_thread(emu, thread->cpu, thread);
|
||||||
emu_cpu_add_thread(newcpu, thread);
|
emu_cpu_add_thread(emu, newcpu, thread);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -270,6 +298,9 @@ hook_pre_ovni(struct ovni_emu *emu)
|
|||||||
{
|
{
|
||||||
//emu_emit(emu);
|
//emu_emit(emu);
|
||||||
|
|
||||||
|
if(emu->cur_ev->header.model != 'O')
|
||||||
|
return;
|
||||||
|
|
||||||
switch(emu->cur_ev->header.class)
|
switch(emu->cur_ev->header.class)
|
||||||
{
|
{
|
||||||
case 'H': ev_thread(emu); break;
|
case 'H': ev_thread(emu); break;
|
||||||
@ -359,6 +390,9 @@ emit_current_pid(struct ovni_emu *emu)
|
|||||||
void
|
void
|
||||||
hook_emit_ovni(struct ovni_emu *emu)
|
hook_emit_ovni(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
|
if(emu->cur_ev->header.model != 'O')
|
||||||
|
return;
|
||||||
|
|
||||||
switch(emu->cur_ev->header.class)
|
switch(emu->cur_ev->header.class)
|
||||||
{
|
{
|
||||||
case 'H':
|
case 'H':
|
||||||
@ -373,18 +407,74 @@ hook_emit_ovni(struct ovni_emu *emu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/* Reset thread state */
|
||||||
hook_post_ovni(struct ovni_emu *emu)
|
static void
|
||||||
|
post_virtual_thread(struct ovni_emu *emu)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct ovni_loom *loom;
|
struct ovni_loom *loom;
|
||||||
|
|
||||||
loom = emu->cur_loom;
|
loom = emu->cur_loom;
|
||||||
|
|
||||||
/* Update last_nthreads in the CPUs */
|
/* Should be executed *before* we reset the CPUs updated flags */
|
||||||
|
assert(loom->nupdated_cpus > 0);
|
||||||
|
|
||||||
|
/* Update last_nthreads in the CPUs */
|
||||||
for(i=0; i<loom->ncpus; i++)
|
for(i=0; i<loom->ncpus; i++)
|
||||||
loom->cpu[i].last_nthreads = loom->cpu[i].nthreads;
|
loom->cpu[i].last_nthreads = loom->cpu[i].nthreads;
|
||||||
|
|
||||||
|
/* Fix the virtual CPU as well */
|
||||||
loom->vcpu.last_nthreads = loom->vcpu.nthreads;
|
loom->vcpu.last_nthreads = loom->vcpu.nthreads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset CPU state */
|
||||||
|
static void
|
||||||
|
post_virtual_cpu(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct ovni_loom *loom;
|
||||||
|
|
||||||
|
loom = emu->cur_loom;
|
||||||
|
|
||||||
|
for(i=0; i<loom->nupdated_cpus; i++)
|
||||||
|
{
|
||||||
|
/* Remove the update flags */
|
||||||
|
assert(loom->updated_cpu[i]->updated == 1);
|
||||||
|
loom->updated_cpu[i]->updated = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix the virtual CPU as well */
|
||||||
|
loom->vcpu.last_nthreads = loom->vcpu.nthreads;
|
||||||
|
|
||||||
|
/* Restore 0 updated CPUs */
|
||||||
|
loom->nupdated_cpus = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_virtual(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
switch(emu->cur_ev->header.class)
|
||||||
|
{
|
||||||
|
case 'H':
|
||||||
|
post_virtual_thread(emu);
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
post_virtual_cpu(emu);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hook_post_ovni(struct ovni_emu *emu)
|
||||||
|
{
|
||||||
|
switch(emu->cur_ev->header.model)
|
||||||
|
{
|
||||||
|
case '*':
|
||||||
|
post_virtual(emu);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
11
pcf.c
11
pcf.c
@ -114,8 +114,9 @@ struct event_type thread_tid = {
|
|||||||
thread_tid_values
|
thread_tid_values
|
||||||
};
|
};
|
||||||
|
|
||||||
struct event_value thread_ss_values[] = {
|
struct event_value ss_values[] = {
|
||||||
{ ST_NULL, "NULL" },
|
{ ST_NULL, "NULL" },
|
||||||
|
{ ST_BAD, "Unknown subsystem: multiple threads" },
|
||||||
{ ST_SCHED_HUNGRY, "Scheduler: Hungry" },
|
{ ST_SCHED_HUNGRY, "Scheduler: Hungry" },
|
||||||
{ ST_SCHED_SERVING, "Scheduler: Serving" },
|
{ ST_SCHED_SERVING, "Scheduler: Serving" },
|
||||||
{ ST_SCHED_SUBMITTING, "Scheduler: Submitting" },
|
{ ST_SCHED_SUBMITTING, "Scheduler: Submitting" },
|
||||||
@ -128,7 +129,12 @@ struct event_value thread_ss_values[] = {
|
|||||||
|
|
||||||
struct event_type thread_ss = {
|
struct event_type thread_ss = {
|
||||||
0, PTT_SUBSYSTEM, "Thread: Subsystem",
|
0, PTT_SUBSYSTEM, "Thread: Subsystem",
|
||||||
thread_ss_values
|
ss_values
|
||||||
|
};
|
||||||
|
|
||||||
|
struct event_type cpu_ss = {
|
||||||
|
0, PTC_SUBSYSTEM, "CPU: Current thread subsystem",
|
||||||
|
ss_values
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -194,6 +200,7 @@ write_events(FILE *f)
|
|||||||
write_event_type(f, &thread_state);
|
write_event_type(f, &thread_state);
|
||||||
write_event_type(f, &thread_tid);
|
write_event_type(f, &thread_tid);
|
||||||
write_event_type(f, &thread_ss);
|
write_event_type(f, &thread_ss);
|
||||||
|
write_event_type(f, &cpu_ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user