Add virtual events
This commit is contained in:
parent
af22678b07
commit
abdbd8d64c
93
emu.c
93
emu.c
@ -82,10 +82,13 @@ hook_pre(struct ovni_emu *emu)
|
||||
|
||||
switch(emu->cur_ev->header.model)
|
||||
{
|
||||
case 'O': hook_pre_ovni(emu); break;
|
||||
case 'V': hook_pre_nosv(emu); break;
|
||||
case 'O': hook_pre_ovni(emu);
|
||||
break;
|
||||
case 'V': hook_pre_nosv(emu);
|
||||
break;
|
||||
case '*': hook_pre_nosv(emu);
|
||||
break;
|
||||
default:
|
||||
//dbg("unknown model %c\n", emu->cur_ev->model);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -97,8 +100,12 @@ hook_emit(struct ovni_emu *emu)
|
||||
|
||||
switch(emu->cur_ev->header.model)
|
||||
{
|
||||
case 'O': hook_emit_ovni(emu); break;
|
||||
case 'V': hook_emit_nosv(emu); break;
|
||||
case 'O': hook_emit_ovni(emu);
|
||||
break;
|
||||
case 'V': hook_emit_nosv(emu);
|
||||
break;
|
||||
case '*': hook_emit_nosv(emu);
|
||||
break;
|
||||
default:
|
||||
//dbg("unknown model %c\n", emu->cur_ev->model);
|
||||
break;
|
||||
@ -112,8 +119,12 @@ hook_post(struct ovni_emu *emu)
|
||||
|
||||
switch(emu->cur_ev->header.model)
|
||||
{
|
||||
case 'O': hook_post_ovni(emu); break;
|
||||
case 'V': hook_post_nosv(emu); break;
|
||||
case 'O': hook_post_ovni(emu);
|
||||
break;
|
||||
case 'V': hook_post_nosv(emu);
|
||||
break;
|
||||
case '*': hook_post_nosv(emu);
|
||||
break;
|
||||
default:
|
||||
//dbg("unknown model %c\n", emu->cur_ev->model);
|
||||
break;
|
||||
@ -143,6 +154,21 @@ next_event(struct ovni_emu *emu)
|
||||
|
||||
trace = &emu->trace;
|
||||
|
||||
/* Look for virtual events first */
|
||||
|
||||
if(trace->ivirtual < trace->nvirtual)
|
||||
{
|
||||
emu->cur_ev = &trace->virtual_events[trace->ivirtual];
|
||||
trace->ivirtual++;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset virtual events to 0 */
|
||||
trace->ivirtual = 0;
|
||||
trace->nvirtual = 0;
|
||||
}
|
||||
|
||||
f = -1;
|
||||
minclock = 0;
|
||||
|
||||
@ -218,7 +244,8 @@ emulate(struct ovni_emu *emu)
|
||||
hook_emit(emu);
|
||||
hook_post(emu);
|
||||
|
||||
/* Read the next event */
|
||||
/* Read the next event if no virtual events exist */
|
||||
if(emu->trace.ivirtual == emu->trace.nvirtual)
|
||||
ovni_load_next_event(emu->cur_stream);
|
||||
}
|
||||
}
|
||||
@ -587,6 +614,53 @@ write_row_cpu(struct ovni_emu *emu)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static int
|
||||
emu_virtual_init(struct ovni_emu *emu)
|
||||
{
|
||||
struct ovni_trace *trace;
|
||||
|
||||
trace = &emu->trace;
|
||||
|
||||
trace->ivirtual = 0;
|
||||
trace->nvirtual = 0;
|
||||
|
||||
trace->virtual_events = calloc(MAX_VIRTUAL_EVENTS,
|
||||
sizeof(struct ovni_ev));
|
||||
|
||||
if(trace->virtual_events == NULL)
|
||||
{
|
||||
perror("calloc");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
emu_virtual_ev(struct ovni_emu *emu, char *mcv)
|
||||
{
|
||||
struct ovni_trace *trace;
|
||||
struct ovni_ev *ev;
|
||||
|
||||
trace = &emu->trace;
|
||||
|
||||
if(trace->nvirtual >= MAX_VIRTUAL_EVENTS)
|
||||
{
|
||||
err("too many virtual events\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ev = &trace->virtual_events[trace->nvirtual];
|
||||
|
||||
ev->header.flags = 0;
|
||||
ev->header.model = mcv[0];
|
||||
ev->header.class = mcv[1];
|
||||
ev->header.value = mcv[2];
|
||||
ev->header.clock = emu->cur_ev->header.clock;
|
||||
|
||||
trace->nvirtual++;
|
||||
}
|
||||
|
||||
static void
|
||||
emu_init(struct ovni_emu *emu, int argc, char *argv[])
|
||||
{
|
||||
@ -597,6 +671,9 @@ emu_init(struct ovni_emu *emu, int argc, char *argv[])
|
||||
if(ovni_load_trace(&emu->trace, emu->tracedir))
|
||||
abort();
|
||||
|
||||
if(emu_virtual_init(emu))
|
||||
abort();
|
||||
|
||||
if(ovni_load_streams(&emu->trace))
|
||||
abort();
|
||||
|
||||
|
18
emu.h
18
emu.h
@ -100,6 +100,9 @@ struct ovni_ethread {
|
||||
|
||||
/* nosv task */
|
||||
struct nosv_task *task;
|
||||
|
||||
/* Should we print the subsystem? */
|
||||
int show_ss;
|
||||
};
|
||||
|
||||
/* State of each emulated process */
|
||||
@ -179,9 +182,21 @@ struct ovni_loom {
|
||||
struct ovni_eproc proc[OVNI_MAX_PROC];
|
||||
};
|
||||
|
||||
#define MAX_VIRTUAL_EVENTS 16
|
||||
|
||||
struct ovni_trace {
|
||||
int nlooms;
|
||||
struct ovni_loom loom[OVNI_MAX_LOOM];
|
||||
|
||||
/* Index of next virtual event */
|
||||
int ivirtual;
|
||||
|
||||
/* Number of virtual events stored */
|
||||
int nvirtual;
|
||||
|
||||
/* The virtual events are generated by the emulator */
|
||||
struct ovni_ev *virtual_events;
|
||||
|
||||
int nstreams;
|
||||
struct ovni_stream *stream;
|
||||
};
|
||||
@ -254,4 +269,7 @@ struct ovni_ethread *emu_get_thread(struct ovni_eproc *proc, int tid);
|
||||
|
||||
void emu_emit_prv(struct ovni_emu *emu, int type, int val);
|
||||
|
||||
void
|
||||
emu_virtual_ev(struct ovni_emu *emu, char *mcv);
|
||||
|
||||
#endif /* OVNI_EMU_H */
|
||||
|
10
emu_nosv.c
10
emu_nosv.c
@ -146,7 +146,6 @@ pre_task_end(struct ovni_emu *emu)
|
||||
dbg("task id=%d ends\n", task->id);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pre_task(struct ovni_emu *emu)
|
||||
{
|
||||
@ -221,10 +220,13 @@ pre_type(struct ovni_emu *emu)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hook_pre_nosv(struct ovni_emu *emu)
|
||||
{
|
||||
switch(emu->cur_ev->header.model)
|
||||
{
|
||||
/* Only listen for nosv events */
|
||||
case 'V':
|
||||
switch(emu->cur_ev->header.class)
|
||||
{
|
||||
case 'T': pre_task(emu); break;
|
||||
@ -232,6 +234,10 @@ hook_pre_nosv(struct ovni_emu *emu)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hook_pre_nosv_ss(emu);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ static void
|
||||
ss_init(struct ovni_ethread *t)
|
||||
{
|
||||
t->nss = 0;
|
||||
t->show_ss = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -134,9 +135,47 @@ pre_memory(struct ovni_emu *emu)
|
||||
}
|
||||
}
|
||||
|
||||
/* Hook for the virtual "thread changed" event */
|
||||
static void
|
||||
pre_thread_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_thread(struct ovni_emu *emu)
|
||||
{
|
||||
switch(emu->cur_ev->header.value)
|
||||
{
|
||||
case 'c': pre_thread_change(emu); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hook_pre_nosv_ss(struct ovni_emu *emu)
|
||||
{
|
||||
switch(emu->cur_ev->header.model)
|
||||
{
|
||||
/* Listen for virtual events as well */
|
||||
case '*':
|
||||
switch(emu->cur_ev->header.class)
|
||||
{
|
||||
case 'H': pre_thread(emu); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
switch(emu->cur_ev->header.class)
|
||||
{
|
||||
case 'S': pre_sched(emu); break;
|
||||
@ -145,6 +184,10 @@ hook_pre_nosv_ss(struct ovni_emu *emu)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------- emit ------------------------------- */
|
||||
@ -187,6 +230,12 @@ hook_emit_nosv_ss(struct ovni_emu *emu)
|
||||
|
||||
th = emu->cur_thread;
|
||||
|
||||
if(th->show_ss == 0)
|
||||
{
|
||||
emit_thread_state(emu, th, PTT_SUBSYSTEM, ST_NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only emit a state if needed */
|
||||
if(th->ss_event != EV_NULL)
|
||||
{
|
||||
|
@ -174,8 +174,14 @@ ev_thread(struct ovni_emu *emu)
|
||||
case 'p': ev_thread_pause(emu); break;
|
||||
case 'r': ev_thread_resume(emu); break;
|
||||
default:
|
||||
break;
|
||||
err("unknown thread event value %c\n",
|
||||
ev->header.value);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* All events change the thread state: inject a virtual event to
|
||||
* notify other modules */
|
||||
emu_virtual_ev(emu, "*Hc");
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user