static void X86ContextDoCreate(X86Context *self, X86Emu *emu) { int num_nodes; int i; /* Initialize */ self->emu = emu; self->pid = emu->current_pid++; self->sched_policy = SCHED_RR; self->sched_priority = 1; /* Lowest priority */ /* Update state so that the context is inserted in the * corresponding lists. The x86_ctx_running parameter has no * effect, since it will be updated later. */ X86ContextSetState(self, X86ContextRunning); DOUBLE_LINKED_LIST_INSERT_HEAD(emu, context, self); /* Structures */ self->regs = x86_regs_create(); self->backup_regs = x86_regs_create(); self->signal_mask_table = x86_signal_mask_table_create(); /* Thread affinity mask, used only for timing simulation. It is * initialized to all 1's. */ num_nodes = x86_cpu_num_cores * x86_cpu_num_threads; self->affinity = bit_map_create(num_nodes); for (i = 0; i < num_nodes; i++) bit_map_set(self->affinity, i, 1, 1); /* Initialize statically allocate instruction */ new_static(&self->inst, X86Inst, emu->as); /* Virtual functions */ asObject(self)->Dump = X86ContextDump; }
void MIPSEmuListInsertHead(MIPSEmu *self, enum mips_emu_list_kind_t list, struct mips_ctx_t *ctx) { assert(!MIPSEmuListMember(self, list, ctx)); switch (list) { case mips_emu_list_context: DOUBLE_LINKED_LIST_INSERT_HEAD(self, context, ctx); break; case mips_emu_list_running: DOUBLE_LINKED_LIST_INSERT_HEAD(self, running, ctx); break; case mips_emu_list_finished: DOUBLE_LINKED_LIST_INSERT_HEAD(self, finished, ctx); break; case mips_emu_list_zombie: DOUBLE_LINKED_LIST_INSERT_HEAD(self, zombie, ctx); break; case mips_emu_list_suspended: DOUBLE_LINKED_LIST_INSERT_HEAD(self, suspended, ctx); break; case mips_emu_list_alloc: DOUBLE_LINKED_LIST_INSERT_HEAD(self, alloc, ctx); break; } }
void x86_emu_list_insert_head(enum x86_emu_list_kind_t list, struct x86_ctx_t *ctx) { assert(!x86_emu_list_member(list, ctx)); switch (list) { case x86_emu_list_context: DOUBLE_LINKED_LIST_INSERT_HEAD(x86_emu, context, ctx); break; case x86_emu_list_running: DOUBLE_LINKED_LIST_INSERT_HEAD(x86_emu, running, ctx); break; case x86_emu_list_finished: DOUBLE_LINKED_LIST_INSERT_HEAD(x86_emu, finished, ctx); break; case x86_emu_list_zombie: DOUBLE_LINKED_LIST_INSERT_HEAD(x86_emu, zombie, ctx); break; case x86_emu_list_suspended: DOUBLE_LINKED_LIST_INSERT_HEAD(x86_emu, suspended, ctx); break; case x86_emu_list_alloc: DOUBLE_LINKED_LIST_INSERT_HEAD(x86_emu, alloc, ctx); break; } }
static void X86ContextUpdateState(X86Context *self, X86ContextState state) { X86Emu *emu = self->emu; X86ContextState status_diff; char state_str[MAX_STRING_SIZE]; /* Remove contexts from the following lists: * running, suspended, zombie */ if (DOUBLE_LINKED_LIST_MEMBER(emu, running, self)) DOUBLE_LINKED_LIST_REMOVE(emu, running, self); if (DOUBLE_LINKED_LIST_MEMBER(emu, suspended, self)) DOUBLE_LINKED_LIST_REMOVE(emu, suspended, self); if (DOUBLE_LINKED_LIST_MEMBER(emu, zombie, self)) DOUBLE_LINKED_LIST_REMOVE(emu, zombie, self); if (DOUBLE_LINKED_LIST_MEMBER(emu, finished, self)) DOUBLE_LINKED_LIST_REMOVE(emu, finished, self); /* If the difference between the old and new state lies in other * states other than 'x86_ctx_specmode', a reschedule is marked. */ status_diff = self->state ^ state; if (status_diff & ~X86ContextSpecMode) emu->schedule_signal = 1; /* Update state */ self->state = state; if (self->state & X86ContextFinished) self->state = X86ContextFinished | (state & X86ContextAlloc) | (state & X86ContextMapped); if (self->state & X86ContextZombie) self->state = X86ContextZombie | (state & X86ContextAlloc) | (state & X86ContextMapped); if (!(self->state & X86ContextSuspended) && !(self->state & X86ContextFinished) && !(self->state & X86ContextZombie) && !(self->state & X86ContextLocked)) self->state |= X86ContextRunning; else self->state &= ~X86ContextRunning; /* Insert context into the corresponding lists. */ if (self->state & X86ContextRunning) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, running, self); if (self->state & X86ContextZombie) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, zombie, self); if (self->state & X86ContextFinished) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, finished, self); if (self->state & X86ContextSuspended) DOUBLE_LINKED_LIST_INSERT_HEAD(emu, suspended, self); /* Dump new state (ignore 'x86_ctx_specmode' state, it's too frequent) */ if (debug_status(x86_context_debug_category) && (status_diff & ~X86ContextSpecMode)) { str_map_flags(&x86_context_state_map, self->state, state_str, sizeof state_str); X86ContextDebug("inst %lld: ctx %d changed state to %s\n", asEmu(emu)->instructions, self->pid, state_str); } /* Start/stop x86 timer depending on whether there are any contexts * currently running. */ if (emu->running_list_count) m2s_timer_start(asEmu(emu)->timer); else m2s_timer_stop(asEmu(emu)->timer); }