Add virtual events

This commit is contained in:
Rodrigo Arias 2021-09-27 17:42:14 +02:00
parent af22678b07
commit abdbd8d64c
5 changed files with 178 additions and 22 deletions

97
emu.c
View File

@ -82,11 +82,14 @@ 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;
default:
//dbg("unknown model %c\n", emu->cur_ev->model);
case 'O': hook_pre_ovni(emu);
break;
case 'V': hook_pre_nosv(emu);
break;
case '*': hook_pre_nosv(emu);
break;
default:
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,8 +244,9 @@ emulate(struct ovni_emu *emu)
hook_emit(emu);
hook_post(emu);
/* Read the next event */
ovni_load_next_event(emu->cur_stream);
/* 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
View File

@ -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 */

View File

@ -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,16 +220,23 @@ pre_type(struct ovni_emu *emu)
}
}
void
hook_pre_nosv(struct ovni_emu *emu)
{
switch(emu->cur_ev->header.class)
switch(emu->cur_ev->header.model)
{
case 'T': pre_task(emu); break;
case 'Y': pre_type(emu); break;
/* Only listen for nosv events */
case 'V':
switch(emu->cur_ev->header.class)
{
case 'T': pre_task(emu); break;
case 'Y': pre_type(emu); break;
default:
break;
}
break;
default:
break;
break;
}
hook_pre_nosv_ss(emu);

View File

@ -19,6 +19,7 @@ static void
ss_init(struct ovni_ethread *t)
{
t->nss = 0;
t->show_ss = 0;
}
static void
@ -134,16 +135,58 @@ 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.class)
switch(emu->cur_ev->header.model)
{
case 'S': pre_sched(emu); break;
case 'U': pre_submit(emu); break;
case 'M': pre_memory(emu); break;
/* 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;
case 'U': pre_submit(emu); break;
case 'M': pre_memory(emu); break;
default:
break;
}
break;
default:
break;
break;
}
}
@ -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)
{

View File

@ -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