diff --git a/emu.c b/emu.c index 4c7aad6..3660adc 100644 --- a/emu.c +++ b/emu.c @@ -92,6 +92,9 @@ emit_channels(struct ovni_emu *emu) cpu = emu->global_cpu[j]; chan_cpu = &cpu->chan[i]; + /* Not implemented */ + assert(chan_cpu->track != CHAN_TRACK_TH_UNPAUSED); + if(chan_cpu->track != CHAN_TRACK_TH_RUNNING) { //dbg("cpu chan %d not tracking threads\n", i); @@ -120,19 +123,25 @@ emit_channels(struct ovni_emu *emu) //dbg("cpu chan %d bad: multiple threads\n", i); if(!chan_is_enabled(chan_cpu)) chan_enable(chan_cpu, 1); - chan_set(chan_cpu, -1); + chan_set(chan_cpu, ST_BAD); } else { + th = last_th; chan_th = &th->chan[i]; //dbg("cpu chan %d good: one thread\n", i); if(!chan_is_enabled(chan_cpu)) chan_enable(chan_cpu, 1); + if(chan_is_enabled(chan_th)) - chan_set(chan_cpu, chan_get_st(&last_th->chan[i])); + st = chan_get_st(&last_th->chan[i]); else - chan_set(chan_cpu, ST_BAD); + st = ST_BAD; + + /* Only update the CPU chan if needed */ + if(chan_get_st(chan_cpu) != st) + chan_set(chan_cpu, st); } } } @@ -667,7 +676,6 @@ write_row_cpu(struct ovni_emu *emu) FILE *f; int i, j; char path[PATH_MAX]; - struct ovni_loom *loom; struct ovni_cpu *cpu; sprintf(path, "%s/%s", emu->tracedir, "cpu.row"); @@ -686,19 +694,12 @@ write_row_cpu(struct ovni_emu *emu) fprintf(f, "LEVEL THREAD SIZE %d\n", emu->total_ncpus); - /* TODO: Use a cpu name per CPU */ - for(i=0; itrace.nlooms; i++) + for(i=0; itotal_ncpus; i++) { - loom = &emu->trace.loom[i]; - for(j=0; jncpus; j++) - { - cpu = &loom->cpu[j]; - fprintf(f, "CPU %d.%d\n", i, cpu->i); - } + cpu = emu->global_cpu[i]; + fprintf(f, "%s\n", cpu->name); } - fprintf(f, "UNSET\n"); - fclose(f); } @@ -861,9 +862,20 @@ init_cpus(struct ovni_emu *emu) { cpu = &loom->cpu[j]; emu->global_cpu[cpu->gindex] = cpu; + + if(snprintf(cpu->name, MAX_CPU_NAME, "CPU %d.%d", + i, j) >= MAX_CPU_NAME) + { + abort(); + } } emu->global_cpu[loom->vcpu.gindex] = &loom->vcpu; + if(snprintf(loom->vcpu.name, MAX_CPU_NAME, "CPU %d.*", + i) >= MAX_CPU_NAME) + { + abort(); + } } } @@ -904,8 +916,8 @@ static void emu_post(struct ovni_emu *emu) { /* Write the PCF files */ - pcf_write(emu->pcf_thread); - pcf_write(emu->pcf_cpu); + pcf_write(emu->pcf_thread, emu); + pcf_write(emu->pcf_cpu, emu); write_row_cpu(emu); write_row_thread(emu); diff --git a/emu.h b/emu.h index 21b0ea8..ab6f2f7 100644 --- a/emu.h +++ b/emu.h @@ -22,6 +22,8 @@ enum ethread_state { TH_ST_RUNNING, TH_ST_PAUSED, TH_ST_DEAD, + TH_ST_COOLING, + TH_ST_WARMING, }; enum nosv_task_state { @@ -33,11 +35,13 @@ enum nosv_task_state { enum nosv_thread_ss_state { ST_NULL = 0, - ST_BAD = 3, ST_SCHED_HUNGRY = 6, ST_SCHED_SERVING = 7, ST_SCHED_SUBMITTING = 8, ST_MEM_ALLOCATING = 9, + ST_TASK_RUNNING = 10, + ST_NOSV_CODE = 11, + ST_BAD = 666, }; enum nosv_thread_ss_event { @@ -69,6 +73,7 @@ struct nosv_task_type { enum chan_track { CHAN_TRACK_NONE = 0, CHAN_TRACK_TH_RUNNING, + CHAN_TRACK_TH_UNPAUSED, }; struct ovni_chan { @@ -125,7 +130,7 @@ enum chan { }; /* Same order as `enum chan` */ -static int chan_to_prvtype[CHAN_MAX][3] = { +const static int chan_to_prvtype[CHAN_MAX][3] = { /* Channel TH CPU */ { CHAN_OVNI_PID, 10, 60 }, { CHAN_OVNI_TID, 11, 61 }, @@ -230,6 +235,8 @@ enum ovni_cpu_state { CPU_ST_READY, }; +#define MAX_CPU_NAME 32 + struct ovni_cpu { /* Logical index: 0 to ncpus - 1 */ int i; @@ -253,6 +260,9 @@ struct ovni_cpu { /* The threads the cpu is currently running */ size_t nthreads; struct ovni_ethread *thread[OVNI_MAX_THR]; + + /* Cpu name as shown in paraver row */ + char name[MAX_CPU_NAME]; }; /* ----------------------- trace ------------------------ */ @@ -315,6 +325,8 @@ struct ovni_stream { int64_t clock_offset; }; +#define MAX_BURSTS 100 + struct ovni_emu { struct ovni_trace trace; @@ -347,6 +359,10 @@ struct ovni_emu { int total_nthreads; int total_proc; int total_ncpus; + + /* Burst times */ + int nbursts; + int64_t burst_time[MAX_BURSTS]; }; /* Emulator function declaration */ diff --git a/emu_nosv.c b/emu_nosv.c index c72ab4e..415b0d7 100644 --- a/emu_nosv.c +++ b/emu_nosv.c @@ -37,7 +37,12 @@ hook_init_nosv(struct ovni_emu *emu) chan_th_init(th, CHAN_NOSV_TYPEID, CHAN_TRACK_TH_RUNNING, row, prv_th, clock); chan_th_init(th, CHAN_NOSV_APPID, CHAN_TRACK_TH_RUNNING, row, prv_th, clock); - chan_th_init(th, CHAN_NOSV_SUBSYSTEM, CHAN_TRACK_TH_RUNNING, row, prv_th, clock); + + /* We allow threads to emit subsystem events in cooling and + * warming states as well, as they may be allocating memory. + * However, these information won't be presented in the CPU + * channel, as it only shows the thread in the running state */ + chan_th_init(th, CHAN_NOSV_SUBSYSTEM, CHAN_TRACK_TH_UNPAUSED, row, prv_th, clock); } /* Init the nosv channels in all cpus */ @@ -200,6 +205,8 @@ pre_task_running(struct ovni_emu *emu, struct nosv_task *task) chan_set(&th->chan[CHAN_NOSV_TASKID], task->id + 1); chan_set(&th->chan[CHAN_NOSV_TYPEID], task->type_id + 1); chan_set(&th->chan[CHAN_NOSV_APPID], proc->appid + 1); + + chan_push(&th->chan[CHAN_NOSV_SUBSYSTEM], ST_TASK_RUNNING); } static void @@ -212,6 +219,8 @@ pre_task_not_running(struct ovni_emu *emu, struct nosv_task *task) chan_set(&th->chan[CHAN_NOSV_TASKID], 0); chan_set(&th->chan[CHAN_NOSV_TYPEID], 0); chan_set(&th->chan[CHAN_NOSV_APPID], 0); + + chan_pop(&th->chan[CHAN_NOSV_SUBSYSTEM], ST_TASK_RUNNING); } static void @@ -386,6 +395,28 @@ pre_memory(struct ovni_emu *emu) } } +static void +pre_code(struct ovni_emu *emu) +{ + struct ovni_ethread *th; + struct ovni_chan *chan_th; + + th = emu->cur_thread; + chan_th = &th->chan[CHAN_NOSV_SUBSYSTEM]; + + switch(emu->cur_ev->header.value) + { + case '[': + chan_push(chan_th, ST_NOSV_CODE); + break; + case ']': + chan_pop(chan_th, ST_NOSV_CODE); + break; + default: + break; + } +} + void hook_pre_nosv(struct ovni_emu *emu) { @@ -398,6 +429,7 @@ hook_pre_nosv(struct ovni_emu *emu) case 'S': pre_sched(emu); break; case 'U': pre_submit(emu); break; case 'M': pre_memory(emu); break; + case 'C': pre_code(emu); break; default: break; } diff --git a/emu_ovni.c b/emu_ovni.c index ecd1fef..3e07b1e 100644 --- a/emu_ovni.c +++ b/emu_ovni.c @@ -43,6 +43,10 @@ hook_init_ovni(struct ovni_emu *emu) chan_enable(&th->chan[CHAN_OVNI_PID], 1); chan_set(&th->chan[CHAN_OVNI_PID], th->proc->pid); chan_enable(&th->chan[CHAN_OVNI_PID], 0); + + /* All threads begin in unknown state */ + chan_enable(&th->chan[CHAN_OVNI_STATE], 1); + chan_set(&th->chan[CHAN_OVNI_STATE], TH_ST_UNKNOWN); } /* Init the ovni channels in all cpus */ @@ -72,23 +76,40 @@ hook_init_ovni(struct ovni_emu *emu) /* --------------------------- pre ------------------------------- */ static void -thread_set_channel_enabled(struct ovni_ethread *th, int enabled) +thread_update_channels(struct ovni_ethread *th) { struct ovni_chan *chan; - int i; + int i, st, enabled, is_running, is_unpaused; + + st = th->state; + is_running = (st == TH_ST_RUNNING); + is_unpaused = (st == TH_ST_RUNNING + || st == TH_ST_COOLING + || st == TH_ST_WARMING); for(i=0; ichan[i]; - if(chan->track == CHAN_TRACK_TH_RUNNING) + switch (chan->track) { - chan_enable(chan, enabled); - dbg("thread %d: %s chan %d\n", - th->tid, - enabled ? "enable" : "disable", - i); + case CHAN_TRACK_TH_RUNNING: + enabled = is_running ? 1 : 0; + break; + case CHAN_TRACK_TH_UNPAUSED: + enabled = is_unpaused ? 1 : 0; + break; + default: + continue; } + + /* The channel is already in the proper state */ + if(chan_is_enabled(chan) == enabled) + continue; + + dbg("thread %d changes state to %d: chan %d enabled=%d\n", + th->tid, th->state, i, enabled); + chan_enable(chan, enabled); } } @@ -99,36 +120,48 @@ thread_set_state(struct ovni_ethread *th, int state) th->state = state; - enabled = (state == TH_ST_RUNNING ? 1 : 0); - - thread_set_channel_enabled(th, enabled); + chan_set(&th->chan[CHAN_OVNI_STATE], th->state); + + /* Enable or disable the thread channels that track the thread state */ + thread_update_channels(th); } void update_cpu(struct ovni_emu *emu, struct ovni_cpu *cpu) { - int i, tid, pid, enabled; + int i, tid, pid, enabled, nrunning; struct ovni_loom *loom; - struct ovni_ethread *th; + struct ovni_ethread *th, *last_th; struct ovni_chan *chan; loom = emu->cur_loom; - chan_set(&cpu->chan[CHAN_OVNI_NTHREADS], cpu->nthreads); + /* Count running threads */ + for(i=0, nrunning=0; inthreads; i++) + { + th = cpu->thread[i]; + if(th->state == TH_ST_RUNNING) + { + last_th = th; + nrunning++; + } + } + + chan_set(&cpu->chan[CHAN_OVNI_NTHREADS], nrunning); th = NULL; - if(cpu->nthreads == 0) + if(nrunning == 0) { /* No thread running */ tid = pid = 0; } - else if(cpu->nthreads == 1) + else if(nrunning == 1) { - /* Take the info from the unique thread */ - tid = cpu->thread[0]->tid; - pid = cpu->thread[0]->proc->pid; - th = cpu->thread[0]; + /* Take the info from the running thread */ + tid = last_th->tid; + pid = last_th->proc->pid; + th = last_th; } else { @@ -186,8 +219,8 @@ emu_cpu_find_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) return i; } -void -emu_cpu_add_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_ethread *thread) +static void +cpu_add_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_ethread *thread) { /* Found, abort */ if(emu_cpu_find_thread(cpu, thread) >= 0) @@ -200,8 +233,8 @@ emu_cpu_add_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_ethre update_cpu(emu, cpu); } -void -emu_cpu_remove_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_ethread *thread) +static void +cpu_remove_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_ethread *thread) { int i, j; @@ -219,6 +252,52 @@ emu_cpu_remove_thread(struct ovni_emu *emu, struct ovni_cpu *cpu, struct ovni_et update_cpu(emu, cpu); } +void +cpu_migrate_thread(struct ovni_emu *emu, + struct ovni_cpu *cpu, + struct ovni_ethread *thread, + struct ovni_cpu *newcpu) +{ + + cpu_remove_thread(emu, cpu, thread); + cpu_add_thread(emu, newcpu, thread); +} + +/* Sets the thread assigned CPU to the given one. + * Precondition: the thread CPU must be null */ +void +thread_set_cpu(struct ovni_ethread *th, struct ovni_cpu *cpu) +{ + assert(th->cpu == NULL); + th->cpu = cpu; + + chan_enable(&th->chan[CHAN_OVNI_CPU], 1); + chan_set(&th->chan[CHAN_OVNI_CPU], cpu->gindex + 1); +} + +/* Unsets the thread assigned CPU. + * Precondition: the thread CPU must be not null */ +void +thread_unset_cpu(struct ovni_ethread *th) +{ + assert(th->cpu != NULL); + th->cpu = NULL; + + chan_enable(&th->chan[CHAN_OVNI_CPU], 0); +} + +/* Migrates the thread assigned CPU to the given one. + * Precondition: the thread CPU must be not null */ +void +thread_migrate_cpu(struct ovni_ethread *th, struct ovni_cpu *cpu) +{ + assert(th->cpu != NULL); + th->cpu = cpu; + + assert(chan_is_enabled(&th->chan[CHAN_OVNI_CPU])); + chan_set(&th->chan[CHAN_OVNI_CPU], cpu->gindex + 1); +} + static void print_threads_state(struct ovni_loom *loom) { @@ -246,14 +325,11 @@ print_threads_state(struct ovni_loom *loom) } static void -pre_thread_execute(struct ovni_emu *emu) +pre_thread_execute(struct ovni_emu *emu, struct ovni_ethread *th) { struct ovni_cpu *cpu; - struct ovni_ethread *th; int cpuid; - th = emu->cur_thread; - /* The thread cannot be already running */ assert(th->state != TH_ST_RUNNING); @@ -263,70 +339,65 @@ pre_thread_execute(struct ovni_emu *emu) cpu = emu_get_cpu(emu->cur_loom, cpuid); thread_set_state(th, TH_ST_RUNNING); - th->cpu = cpu; + thread_set_cpu(th, cpu); - emu_cpu_add_thread(emu, cpu, th); - - /* Enable the cpu channel of the thread */ - chan_enable(&th->chan[CHAN_OVNI_CPU], 1); - chan_set(&th->chan[CHAN_OVNI_CPU], cpu->gindex + 1); + cpu_add_thread(emu, cpu, th); /* Enable thread TID and PID */ chan_enable(&th->chan[CHAN_OVNI_TID], 1); chan_enable(&th->chan[CHAN_OVNI_PID], 1); - - /* Enable and set the thread state */ - chan_enable(&th->chan[CHAN_OVNI_STATE], 1); - chan_set(&th->chan[CHAN_OVNI_STATE], th->state); } static void -pre_thread_end(struct ovni_emu *emu) +pre_thread_end(struct ovni_emu *emu, struct ovni_ethread *th) { - struct ovni_ethread *th; - - th = emu->cur_thread; assert(th->state == TH_ST_RUNNING); assert(th->cpu); - emu_cpu_remove_thread(emu, th->cpu, th); + cpu_remove_thread(emu, th->cpu, th); thread_set_state(th, TH_ST_DEAD); - th->cpu = NULL; - - /* Disable the cpu channel of the thread */ - chan_enable(&th->chan[CHAN_OVNI_CPU], 0); + thread_unset_cpu(th); /* Disable thread TID and PID */ chan_enable(&th->chan[CHAN_OVNI_TID], 0); chan_enable(&th->chan[CHAN_OVNI_PID], 0); - - /* Disable thread state */ - chan_enable(&th->chan[CHAN_OVNI_STATE], 0); } static void -pre_thread_pause(struct ovni_emu *emu) +pre_thread_pause(struct ovni_emu *emu, struct ovni_ethread *th) { - assert(emu->cur_thread->state == TH_ST_RUNNING); - assert(emu->cur_thread->cpu); + assert(th->state == TH_ST_RUNNING || th->state == TH_ST_COOLING); + assert(th->cpu); - emu_cpu_remove_thread(emu, emu->cur_thread->cpu, emu->cur_thread); - - thread_set_state(emu->cur_thread, TH_ST_PAUSED); - chan_set(&emu->cur_thread->chan[CHAN_OVNI_STATE], emu->cur_thread->state); + thread_set_state(th, TH_ST_PAUSED); } static void -pre_thread_resume(struct ovni_emu *emu) +pre_thread_resume(struct ovni_emu *emu, struct ovni_ethread *th) { - assert(emu->cur_thread->state == TH_ST_PAUSED); - assert(emu->cur_thread->cpu); + assert(th->state == TH_ST_PAUSED || th->state == TH_ST_WARMING); + assert(th->cpu); - emu_cpu_add_thread(emu, emu->cur_thread->cpu, emu->cur_thread); + thread_set_state(th, TH_ST_RUNNING); +} - thread_set_state(emu->cur_thread, TH_ST_RUNNING); - chan_set(&emu->cur_thread->chan[CHAN_OVNI_STATE], emu->cur_thread->state); +static void +pre_thread_cool(struct ovni_emu *emu, struct ovni_ethread *th) +{ + assert(th->state == TH_ST_RUNNING); + assert(th->cpu); + + thread_set_state(th, TH_ST_COOLING); +} + +static void +pre_thread_warm(struct ovni_emu *emu, struct ovni_ethread *th) +{ + assert(th->state == TH_ST_PAUSED); + assert(th->cpu); + + thread_set_state(th, TH_ST_WARMING); } static void @@ -334,29 +405,31 @@ pre_thread(struct ovni_emu *emu) { struct ovni_ev *ev; struct ovni_cpu *cpu; - struct ovni_ethread *thread, *remote_thread; + struct ovni_ethread *th, *remote_thread; int i; //emu_emit(emu); - thread = emu->cur_thread; - cpu = thread->cpu; + th = emu->cur_thread; + cpu = th->cpu; ev = emu->cur_ev; switch(ev->header.value) { - case 'c': /* create */ + case 'C': /* create */ dbg("thread %d creates a new thread at cpu=%d with args=%x %x\n", - thread->tid, + th->tid, ev->payload.u32[0], ev->payload.u32[1], ev->payload.u32[2]); break; - case 'x': pre_thread_execute(emu); break; - case 'e': pre_thread_end(emu); break; - case 'p': pre_thread_pause(emu); break; - case 'r': pre_thread_resume(emu); break; + case 'x': pre_thread_execute(emu, th); break; + case 'e': pre_thread_end(emu, th); break; + case 'p': pre_thread_pause(emu, th); break; + case 'r': pre_thread_resume(emu, th); break; + case 'c': pre_thread_cool(emu, th); break; + case 'w': pre_thread_warm(emu, th); break; default: err("unknown thread event value %c\n", ev->header.value); @@ -369,32 +442,31 @@ pre_affinity_set(struct ovni_emu *emu) { int cpuid; struct ovni_cpu *newcpu; + struct ovni_ethread *th; + th = emu->cur_thread; cpuid = emu->cur_ev->payload.i32[0]; - assert(emu->cur_thread->state == TH_ST_RUNNING); - assert(emu->cur_thread->cpu); + assert(th->cpu); + assert(th->state == TH_ST_RUNNING + || th->state == TH_ST_COOLING + || th->state == TH_ST_WARMING); /* Migrate current cpu to the one at cpuid */ newcpu = emu_get_cpu(emu->cur_loom, cpuid); - if(emu->cur_thread->cpu == newcpu) + if(th->cpu == newcpu) { err("warning: thread %d affinity already set to cpu %d\n", - emu->cur_thread->tid, - emu->cur_thread->cpu->gindex); + th->tid, + th->cpu->gindex); return; } - emu_cpu_remove_thread(emu, emu->cur_thread->cpu, emu->cur_thread); - emu_cpu_add_thread(emu, newcpu, emu->cur_thread); + cpu_migrate_thread(emu, th->cpu, th, newcpu); + thread_migrate_cpu(th, newcpu); - emu->cur_thread->cpu = newcpu; - - chan_set(&emu->cur_thread->chan[CHAN_OVNI_CPU], - newcpu->gindex + 1); - - //dbg("cpu %d now runs %d\n", cpuid, emu->cur_thread->tid); + //dbg("cpu %d now runs %d\n", cpuid, th->tid); } static void @@ -402,45 +474,29 @@ pre_affinity_remote(struct ovni_emu *emu) { int cpuid, tid; struct ovni_cpu *newcpu; - struct ovni_ethread *thread; + struct ovni_ethread *remote_th; cpuid = emu->cur_ev->payload.i32[0]; tid = emu->cur_ev->payload.i32[1]; - thread = emu_get_thread(emu->cur_proc, tid); + remote_th = emu_get_thread(emu->cur_proc, tid); - assert(thread); + assert(remote_th); - /* The thread may still be running */ - assert(thread->state == TH_ST_RUNNING || - thread->state == TH_ST_PAUSED); + /* The remote_th cannot be in states dead or unknown */ + assert(remote_th->state != TH_ST_DEAD + && remote_th->state != TH_ST_UNKNOWN); /* It must have an assigned CPU */ - assert(thread->cpu); + assert(remote_th->cpu); /* Migrate current cpu to the one at cpuid */ newcpu = emu_get_cpu(emu->cur_loom, cpuid); - /* If running, update the CPU thread lists */ - if(thread->state == TH_ST_RUNNING) - { - emu_cpu_remove_thread(emu, thread->cpu, thread); - emu_cpu_add_thread(emu, newcpu, thread); - } - else - { - /* Otherwise, ensure that it is not in any CPU list */ - assert(emu_cpu_find_thread(thread->cpu, thread) == -1); - assert(emu_cpu_find_thread(newcpu, thread) == -1); - } + cpu_migrate_thread(emu, remote_th->cpu, remote_th, newcpu); + thread_migrate_cpu(remote_th, newcpu); - /* Always set the assigned CPU in the thread */ - thread->cpu = newcpu; - - chan_set(&thread->chan[CHAN_OVNI_CPU], - newcpu->gindex + 1); - - //dbg("thread %d switches to cpu %d by remote petition\n", tid, + //dbg("remote_th %d switches to cpu %d by remote petition\n", tid, // cpuid); } @@ -459,6 +515,27 @@ pre_affinity(struct ovni_emu *emu) } } +void +pre_burst(struct ovni_emu *emu) +{ + int64_t dt; + if(emu->nbursts >= MAX_BURSTS) + { + err("too many bursts\n"); + abort(); + } + + emu->burst_time[emu->nbursts] = emu->delta_time; + if(emu->nbursts > 0) + { + dt = emu->burst_time[emu->nbursts] - + emu->burst_time[emu->nbursts - 1]; + + err("burst delta time %ld ns\n", dt); + } + emu->nbursts++; +} + void hook_pre_ovni(struct ovni_emu *emu) { @@ -471,9 +548,7 @@ hook_pre_ovni(struct ovni_emu *emu) { case 'H': pre_thread(emu); break; case 'A': pre_affinity(emu); break; - case 'B': - //dbg("burst %c\n", emu->cur_ev->header.value); - break; + case 'B': pre_burst(emu); break; default: dbg("unknown ovni event class %c\n", emu->cur_ev->header.class); diff --git a/pcf.c b/pcf.c index 85d57be..a4335df 100644 --- a/pcf.c +++ b/pcf.c @@ -95,6 +95,8 @@ struct event_value thread_state_values[] = { { TH_ST_RUNNING, "Running" }, { TH_ST_PAUSED, "Paused" }, { TH_ST_DEAD, "Dead" }, + { TH_ST_COOLING, "Cooling" }, + { TH_ST_WARMING, "Warming" }, { -1, NULL }, }; @@ -121,6 +123,8 @@ struct event_value ss_values[] = { { ST_SCHED_HUNGRY, "Scheduler: Hungry" }, { ST_SCHED_SERVING, "Scheduler: Serving" }, { ST_SCHED_SUBMITTING, "Scheduler: Submitting" }, + { ST_TASK_RUNNING, "Task: Running" }, + { ST_NOSV_CODE, "nOS-V code" }, { EV_SCHED_SEND, "EV Scheduler: Send task" }, { EV_SCHED_RECV, "EV Scheduler: Recv task" }, { EV_SCHED_SELF, "EV Scheduler: Self-assign task" }, @@ -138,6 +142,11 @@ struct event_type cpu_ss = { ss_values }; +struct event_type thread_cpu_affinity = { + 0, chan_to_prvtype[CHAN_OVNI_CPU][1], "Thread: current CPU affinity", + /* Ignored */ NULL +}; + static void decompose_rgb(uint32_t col, uint8_t *r, uint8_t *g, uint8_t *b) { @@ -196,20 +205,37 @@ write_event_type(FILE *f, struct event_type *ev) } static void -write_events(FILE *f) +write_cpu_type(FILE *f, struct event_type *ev, struct ovni_emu *emu) +{ + int i; + + write_event_type_header(f, ev->index, ev->type, ev->label); + + fprintf(f, "VALUES\n"); + + for(i=0; itotal_ncpus; i++) + { + fprintf(f, "%-4d %s\n", i+1, emu->global_cpu[i]->name); + } +} + +static void +write_events(FILE *f, struct ovni_emu *emu) { write_event_type(f, &thread_state); write_event_type(f, &thread_tid); write_event_type(f, &thread_ss); write_event_type(f, &cpu_ss); + + write_cpu_type(f, &thread_cpu_affinity, emu); } int -pcf_write(FILE *f) +pcf_write(FILE *f, struct ovni_emu *emu) { write_header(f); write_colors(f, pcf_palette, pcf_palette_len); - write_events(f); + write_events(f, emu); return 0; } diff --git a/pcf.h b/pcf.h index a66ffb5..20e2e2a 100644 --- a/pcf.h +++ b/pcf.h @@ -2,8 +2,9 @@ #define OVNI_PCF_H #include +#include "emu.h" int -pcf_write(FILE *f); +pcf_write(FILE *f, struct ovni_emu *emu); #endif /* OVNI_PCF_H */