Move flush channel to ovni model only
This commit is contained in:
parent
9041583207
commit
e3880d178e
@ -35,6 +35,7 @@ add_library(emu STATIC
|
|||||||
thread.c
|
thread.c
|
||||||
extend.c
|
extend.c
|
||||||
ovni/probe.c
|
ovni/probe.c
|
||||||
|
ovni/create.c
|
||||||
ovni/event.c
|
ovni/event.c
|
||||||
nanos6/probe.c
|
nanos6/probe.c
|
||||||
nanos6/connect.c
|
nanos6/connect.c
|
||||||
|
@ -13,4 +13,6 @@ struct extend {
|
|||||||
void extend_set(struct extend *ext, int id, void *ctx);
|
void extend_set(struct extend *ext, int id, void *ctx);
|
||||||
void *extend_get(struct extend *ext, int id);
|
void *extend_get(struct extend *ext, int id);
|
||||||
|
|
||||||
|
#define EXT(st, m) extend_get(&(st)->ext, (m))
|
||||||
|
|
||||||
#endif /* EXTEND_H */
|
#endif /* EXTEND_H */
|
||||||
|
@ -31,10 +31,14 @@ model_probe(struct model *model, struct emu *emu)
|
|||||||
if (spec->probe == NULL)
|
if (spec->probe == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (spec->probe(emu) != 0) {
|
int ret = spec->probe(emu);
|
||||||
|
if (ret < 0) {
|
||||||
err("probe failed for model '%c'", (char) i);
|
err("probe failed for model '%c'", (char) i);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
model->enabled[i] = 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -43,7 +47,7 @@ int
|
|||||||
model_create(struct model *model, struct emu *emu)
|
model_create(struct model *model, struct emu *emu)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_MODELS; i++) {
|
for (int i = 0; i < MAX_MODELS; i++) {
|
||||||
if (!model->registered[i])
|
if (!model->enabled[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct model_spec *spec = model->spec[i];
|
struct model_spec *spec = model->spec[i];
|
||||||
@ -62,7 +66,7 @@ int
|
|||||||
model_connect(struct model *model, struct emu *emu)
|
model_connect(struct model *model, struct emu *emu)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_MODELS; i++) {
|
for (int i = 0; i < MAX_MODELS; i++) {
|
||||||
if (!model->registered[i])
|
if (!model->enabled[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct model_spec *spec = model->spec[i];
|
struct model_spec *spec = model->spec[i];
|
||||||
@ -81,7 +85,12 @@ int
|
|||||||
model_event(struct model *model, struct emu *emu, int index)
|
model_event(struct model *model, struct emu *emu, int index)
|
||||||
{
|
{
|
||||||
if (!model->registered[index]) {
|
if (!model->registered[index]) {
|
||||||
err("no model registered for '%c'", (char) index);
|
err("model not registered for '%c'", (char) index);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!model->enabled[index]) {
|
||||||
|
err("model not enabled for '%c'", (char) index);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ struct model_spec {
|
|||||||
struct model {
|
struct model {
|
||||||
struct model_spec *spec[MAX_MODELS];
|
struct model_spec *spec[MAX_MODELS];
|
||||||
int registered[MAX_MODELS];
|
int registered[MAX_MODELS];
|
||||||
|
int enabled[MAX_MODELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
void model_init(struct model *model);
|
void model_init(struct model *model);
|
||||||
|
@ -13,7 +13,7 @@ int
|
|||||||
nanos6_probe(struct emu *emu)
|
nanos6_probe(struct emu *emu)
|
||||||
{
|
{
|
||||||
if (emu->system.nthreads == 0)
|
if (emu->system.nthreads == 0)
|
||||||
return -1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
181
src/emu/ovni/connect.c
Normal file
181
src/emu/ovni/connect.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
#include "ovni_priv.h"
|
||||||
|
|
||||||
|
static const int th_type[] = {
|
||||||
|
[CH_FLUSH] = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int *cpu_type = th_type;
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_thread_mux(struct emu *emu, struct thread *thread)
|
||||||
|
{
|
||||||
|
struct ovni_thread *th = extend_get(&thread->ext, 'O');
|
||||||
|
for (int i = 0; i < CH_MAX; i++) {
|
||||||
|
struct chan *inp = &th->ch[i];
|
||||||
|
struct chan *sel = &thread->chan[TH_CHAN_STATE];
|
||||||
|
struct mux *mux_run = &th->mux_run[i];
|
||||||
|
mux_select_func_t selrun = thread_select_running;
|
||||||
|
if (mux_init(mux_run, &emu->bay, sel, &th->ch_run[i], selrun) != 0) {
|
||||||
|
err("mux_init failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mux_add_input(mux_run, value_int64(0), inp) != 0) {
|
||||||
|
err("mux_add_input failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv)
|
||||||
|
{
|
||||||
|
struct ovni_thread *th = extend_get(&thread->ext, 'O');
|
||||||
|
for (int i = 0; i < CH_MAX; i++) {
|
||||||
|
struct chan *out = th->ch_out[i];
|
||||||
|
long type = th_type[i];
|
||||||
|
long row = thread->gindex;
|
||||||
|
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {
|
||||||
|
err("prv_register failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i)
|
||||||
|
{
|
||||||
|
for (struct thread *t = emu->system.threads; t; t = t->gnext) {
|
||||||
|
struct ovni_thread *th = extend_get(&t->ext, 'O');
|
||||||
|
struct chan *inp = &th->ch_run[i];
|
||||||
|
if (mux_add_input(mux, value_int64(t->gindex), inp) != 0) {
|
||||||
|
err("mux_add_input failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_cpu_mux(struct emu *emu, struct cpu *scpu)
|
||||||
|
{
|
||||||
|
struct ovni_cpu *cpu = extend_get(&scpu->ext, 'O');
|
||||||
|
for (int i = 0; i < CH_MAX; i++) {
|
||||||
|
struct mux *mux = &cpu->mux[i];
|
||||||
|
struct chan *out = &cpu->ch[i];
|
||||||
|
struct chan *sel = &scpu->chan[CPU_CHAN_THRUN];
|
||||||
|
|
||||||
|
if (mux_init(mux, &emu->bay, sel, out, NULL) != 0) {
|
||||||
|
err("mux_init failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_inputs_cpu_mux(emu, mux, i) != 0) {
|
||||||
|
err("add_inputs_cpu_mux failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_threads(struct emu *emu)
|
||||||
|
{
|
||||||
|
struct system *sys = &emu->system;
|
||||||
|
|
||||||
|
/* threads */
|
||||||
|
for (struct thread *t = sys->threads; t; t = t->gnext) {
|
||||||
|
if (connect_thread_mux(emu, t) != 0) {
|
||||||
|
err("connect_thread_mux failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get thread PRV */
|
||||||
|
struct pvt *pvt = recorder_find_pvt(&emu->recorder, "thread");
|
||||||
|
if (pvt == NULL) {
|
||||||
|
err("cannot find thread pvt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct prv *prv = pvt_get_prv(pvt);
|
||||||
|
|
||||||
|
for (struct thread *t = sys->threads; t; t = t->gnext) {
|
||||||
|
if (connect_thread_prv(emu, t, prv) != 0) {
|
||||||
|
err("connect_thread_prv failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv)
|
||||||
|
{
|
||||||
|
struct ovni_cpu *cpu = extend_get(&scpu->ext, 'O');
|
||||||
|
for (int i = 0; i < CH_MAX; i++) {
|
||||||
|
struct chan *out = &cpu->ch[i];
|
||||||
|
long type = cpu_type[i];
|
||||||
|
long row = scpu->gindex;
|
||||||
|
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {
|
||||||
|
err("prv_register failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
connect_cpus(struct emu *emu)
|
||||||
|
{
|
||||||
|
struct system *sys = &emu->system;
|
||||||
|
|
||||||
|
/* cpus */
|
||||||
|
for (struct cpu *c = sys->cpus; c; c = c->next) {
|
||||||
|
if (connect_cpu_mux(emu, c) != 0) {
|
||||||
|
err("connect_cpu_mux failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get cpu PRV */
|
||||||
|
struct pvt *pvt = recorder_find_pvt(&emu->recorder, "cpu");
|
||||||
|
if (pvt == NULL) {
|
||||||
|
err("cannot find cpu pvt");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
struct prv *prv = pvt_get_prv(pvt);
|
||||||
|
|
||||||
|
for (struct cpu *c = sys->cpus; c; c = c->next) {
|
||||||
|
if (connect_cpu_prv(emu, c, prv) != 0) {
|
||||||
|
err("connect_cpu_prv failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ovni_connect(struct emu *emu)
|
||||||
|
{
|
||||||
|
if (connect_threads(emu) != 0) {
|
||||||
|
err("connect_threads failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect_cpus(emu) != 0) {
|
||||||
|
err("connect_cpus failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
90
src/emu/ovni/create.c
Normal file
90
src/emu/ovni/create.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "ovni_priv.h"
|
||||||
|
|
||||||
|
static const char chan_fmt_cpu[] = "ovni.cpu%ld.%s";
|
||||||
|
static const char chan_fmt_th_raw[] = "ovni.thread%ld.%s.raw";
|
||||||
|
static const char chan_fmt_th_run[] = "ovni.thread%ld.%s.run";
|
||||||
|
|
||||||
|
static const char *chan_name[] = {
|
||||||
|
[CH_FLUSH] = "flush",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
init_chans(struct bay *bay, struct chan *chans, const char *fmt, int64_t gindex)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < CH_MAX; i++) {
|
||||||
|
struct chan *c = &chans[i];
|
||||||
|
chan_init(c, CHAN_SINGLE, fmt, gindex, chan_name[i]);
|
||||||
|
|
||||||
|
if (bay_register(bay, c) != 0) {
|
||||||
|
err("bay_register failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
init_cpu(struct bay *bay, struct cpu *syscpu)
|
||||||
|
{
|
||||||
|
struct ovni_cpu *cpu = calloc(1, sizeof(struct ovni_cpu));
|
||||||
|
if (cpu == NULL) {
|
||||||
|
err("calloc failed:");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_chans(bay, cpu->ch, chan_fmt_cpu, syscpu->gindex) != 0) {
|
||||||
|
err("init_chans failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extend_set(&syscpu->ext, 'O', cpu);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
init_thread(struct bay *bay, struct thread *systh)
|
||||||
|
{
|
||||||
|
struct ovni_thread *th = calloc(1, sizeof(struct ovni_thread));
|
||||||
|
if (th == NULL) {
|
||||||
|
err("calloc failed:");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_chans(bay, th->ch, chan_fmt_th_raw, systh->gindex) != 0) {
|
||||||
|
err("init_chans failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_chans(bay, th->ch_run, chan_fmt_th_run, systh->gindex) != 0) {
|
||||||
|
err("init_chans failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extend_set(&systh->ext, 'O', th);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ovni_create(struct emu *emu)
|
||||||
|
{
|
||||||
|
struct system *sys = &emu->system;
|
||||||
|
struct bay *bay = &emu->bay;
|
||||||
|
|
||||||
|
for (struct cpu *c = sys->cpus; c; c = c->next) {
|
||||||
|
if (init_cpu(bay, c) != 0) {
|
||||||
|
err("init_cpu failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (struct thread *t = sys->threads; t; t = t->gnext) {
|
||||||
|
if (init_thread(bay, t) != 0) {
|
||||||
|
err("init_thread failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -301,80 +301,83 @@ pre_affinity(struct emu *emu)
|
|||||||
default:
|
default:
|
||||||
err("unknown affinity event value %c\n",
|
err("unknown affinity event value %c\n",
|
||||||
emu->ev->v);
|
emu->ev->v);
|
||||||
// return -1
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static int
|
static int
|
||||||
//compare_int64(const void *a, const void *b)
|
compare_int64(const void *a, const void *b)
|
||||||
//{
|
{
|
||||||
// int64_t aa = *(const int64_t *) a;
|
int64_t aa = *(const int64_t *) a;
|
||||||
// int64_t bb = *(const int64_t *) b;
|
int64_t bb = *(const int64_t *) b;
|
||||||
//
|
|
||||||
// if (aa < bb)
|
|
||||||
// return -1;
|
|
||||||
// else if (aa > bb)
|
|
||||||
// return +1;
|
|
||||||
// else
|
|
||||||
// return 0;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//static int
|
if (aa < bb)
|
||||||
//pre_burst(struct emu *emu)
|
return -1;
|
||||||
//{
|
else if (aa > bb)
|
||||||
// struct thread *th = emu->thread;
|
return +1;
|
||||||
//
|
else
|
||||||
// if (th->nbursts >= MAX_BURSTS) {
|
return 0;
|
||||||
// err("too many bursts");
|
}
|
||||||
// return -1;
|
|
||||||
// }
|
static int
|
||||||
//
|
pre_burst(struct emu *emu)
|
||||||
// th->burst_time[th->nbursts++] = emu->delta_time;
|
{
|
||||||
// if (th->nbursts == MAX_BURSTS) {
|
struct ovni_thread *th = EXT(emu->thread, 'O');
|
||||||
// int n = MAX_BURSTS - 1;
|
|
||||||
// int64_t deltas[MAX_BURSTS - 1];
|
if (th->nbursts >= MAX_BURSTS) {
|
||||||
// for (int i = 0; i < n; i++) {
|
err("too many bursts");
|
||||||
// deltas[i] = th->burst_time[i + 1] - th->burst_time[i];
|
return -1;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// qsort(deltas, n, sizeof(int64_t), compare_int64);
|
th->burst_time[th->nbursts++] = emu->ev->dclock;
|
||||||
//
|
|
||||||
// double avg = 0.0;
|
if (th->nbursts != MAX_BURSTS)
|
||||||
// double maxdelta = 0;
|
return 0;
|
||||||
// for (int i = 0; i < n; i++) {
|
|
||||||
// if (deltas[i] > maxdelta)
|
int n = MAX_BURSTS - 1;
|
||||||
// maxdelta = deltas[i];
|
int64_t deltas[MAX_BURSTS - 1];
|
||||||
// avg += deltas[i];
|
for (int i = 0; i < n; i++)
|
||||||
// }
|
deltas[i] = th->burst_time[i + 1] - th->burst_time[i];
|
||||||
//
|
|
||||||
// avg /= (double) n;
|
qsort(deltas, n, sizeof(int64_t), compare_int64);
|
||||||
// double median = deltas[n / 2];
|
|
||||||
//
|
double avg = 0.0;
|
||||||
// err("%s burst stats: median %.0f ns, avg %.1f ns, max %.0f ns\n",
|
double maxdelta = 0;
|
||||||
// emu->cur_loom->dname, median, avg, maxdelta);
|
for (int i = 0; i < n; i++) {
|
||||||
//
|
if (deltas[i] > maxdelta)
|
||||||
// th->nbursts = 0;
|
maxdelta = deltas[i];
|
||||||
// }
|
avg += deltas[i];
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
avg /= (double) n;
|
||||||
|
double median = deltas[n / 2];
|
||||||
|
|
||||||
|
err("%s burst stats: median %.0f ns, avg %.1f ns, max %.0f ns\n",
|
||||||
|
emu->loom->id, median, avg, maxdelta);
|
||||||
|
|
||||||
|
th->nbursts = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pre_flush(struct emu *emu)
|
pre_flush(struct emu *emu)
|
||||||
{
|
{
|
||||||
struct thread *th = emu->thread;
|
struct ovni_thread *th = extend_get(&emu->thread->ext, 'O');
|
||||||
struct chan *flush = &th->chan[TH_CHAN_FLUSH];
|
struct chan *flush = &th->ch[CH_FLUSH];
|
||||||
|
|
||||||
switch (emu->ev->v) {
|
switch (emu->ev->v) {
|
||||||
case '[':
|
case '[':
|
||||||
if (chan_push(flush, value_int64(1)) != 0) {
|
if (chan_set(flush, value_int64(1)) != 0) {
|
||||||
err("chan_push failed");
|
err("chan_set failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ']':
|
case ']':
|
||||||
if (chan_pop(flush, value_int64(1)) != 0) {
|
if (chan_set(flush, value_null()) != 0) {
|
||||||
err("chan_pop failed");
|
err("chan_set failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -398,15 +401,15 @@ process_ev(struct emu *emu)
|
|||||||
return pre_thread(emu);
|
return pre_thread(emu);
|
||||||
case 'A':
|
case 'A':
|
||||||
return pre_affinity(emu);
|
return pre_affinity(emu);
|
||||||
// case 'B':
|
case 'B':
|
||||||
// pre_burst(emu);
|
pre_burst(emu);
|
||||||
// break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
return pre_flush(emu);
|
return pre_flush(emu);
|
||||||
default:
|
default:
|
||||||
err("unknown ovni event category %c\n",
|
err("unknown ovni event category %c\n",
|
||||||
emu->ev->c);
|
emu->ev->c);
|
||||||
// return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6,23 +6,37 @@
|
|||||||
|
|
||||||
/* The user-space thread "ovni" execution model tracks the state of processes and
|
/* The user-space thread "ovni" execution model tracks the state of processes and
|
||||||
* threads running in the CPUs by instrumenting the threads before and after
|
* threads running in the CPUs by instrumenting the threads before and after
|
||||||
* they are going to sleep. It jovni provides an approximate view of the real
|
* they are going to sleep. It just provides an approximate view of the real
|
||||||
* execution by the kernel. */
|
* execution by the kernel. */
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "chan.h"
|
#include "chan.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
enum ovni_chan_type {
|
enum ovni_chan_type {
|
||||||
UST_CHAN_FLUSH = 0,
|
CH_FLUSH = 0,
|
||||||
UST_CHAN_BURST,
|
CH_MAX,
|
||||||
UST_CHAN_MAX,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_BURSTS 100
|
||||||
|
|
||||||
struct ovni_thread {
|
struct ovni_thread {
|
||||||
struct chan chan[UST_CHAN_MAX];
|
struct chan ch[CH_MAX];
|
||||||
|
struct chan ch_run[CH_MAX];
|
||||||
|
struct chan mux_run[CH_MAX];
|
||||||
|
|
||||||
|
/* Burst times */
|
||||||
|
int nbursts;
|
||||||
|
int64_t burst_time[MAX_BURSTS];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ovni_cpu {
|
||||||
|
struct chan ch[CH_MAX];
|
||||||
|
struct mux mux[CH_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
int ovni_probe(struct emu *emu);
|
int ovni_probe(struct emu *emu);
|
||||||
|
int ovni_create(struct emu *emu);
|
||||||
int ovni_event(struct emu *emu);
|
int ovni_event(struct emu *emu);
|
||||||
|
|
||||||
#endif /* OVNI_PRIV_H */
|
#endif /* OVNI_PRIV_H */
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
struct model_spec model_ovni = {
|
struct model_spec model_ovni = {
|
||||||
.name = "ovni",
|
.name = "ovni",
|
||||||
.model = 'O',
|
.model = 'O',
|
||||||
.create = NULL,
|
.create = ovni_create,
|
||||||
.connect = NULL,
|
.connect = NULL,
|
||||||
.event = ovni_event,
|
.event = ovni_event,
|
||||||
.probe = ovni_probe,
|
.probe = ovni_probe,
|
||||||
@ -16,7 +16,7 @@ int
|
|||||||
ovni_probe(struct emu *emu)
|
ovni_probe(struct emu *emu)
|
||||||
{
|
{
|
||||||
if (emu->system.nthreads == 0)
|
if (emu->system.nthreads == 0)
|
||||||
return -1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -11,18 +11,12 @@ static const char *chan_name[] = {
|
|||||||
[TH_CHAN_CPU] = "cpu_gindex",
|
[TH_CHAN_CPU] = "cpu_gindex",
|
||||||
[TH_CHAN_TID] = "tid_active",
|
[TH_CHAN_TID] = "tid_active",
|
||||||
[TH_CHAN_STATE] = "state",
|
[TH_CHAN_STATE] = "state",
|
||||||
[TH_CHAN_FLUSH] = "flush",
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int chan_stack[] = {
|
|
||||||
[TH_CHAN_FLUSH] = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int chan_type[] = {
|
static const int chan_type[] = {
|
||||||
[TH_CHAN_TID] = 2,
|
[TH_CHAN_TID] = 2,
|
||||||
[TH_CHAN_STATE] = 4,
|
[TH_CHAN_STATE] = 4,
|
||||||
[TH_CHAN_CPU] = 6,
|
[TH_CHAN_CPU] = 6,
|
||||||
[TH_CHAN_FLUSH] = 7,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -103,12 +97,7 @@ thread_init_end(struct thread *th)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < TH_CHAN_MAX; i++) {
|
for (int i = 0; i < TH_CHAN_MAX; i++) {
|
||||||
enum chan_type type = CHAN_SINGLE;
|
chan_init(&th->chan[i], CHAN_SINGLE,
|
||||||
|
|
||||||
if (chan_stack[i])
|
|
||||||
type = CHAN_STACK;
|
|
||||||
|
|
||||||
chan_init(&th->chan[i], type,
|
|
||||||
chan_fmt, th->gindex, chan_name[i]);
|
chan_fmt, th->gindex, chan_name[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ enum thread_chan {
|
|||||||
TH_CHAN_CPU = 0,
|
TH_CHAN_CPU = 0,
|
||||||
TH_CHAN_TID,
|
TH_CHAN_TID,
|
||||||
TH_CHAN_STATE,
|
TH_CHAN_STATE,
|
||||||
TH_CHAN_FLUSH,
|
|
||||||
TH_CHAN_MAX,
|
TH_CHAN_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user