int exec(Memory entry_p) { Instruction insn; unsigned long clk = 0; uint32_t cmod; if(signal(SIGINT, signal_on_sigint) == SIG_ERR) { err(EXIT_FAILURE, "signal SIGINT"); } step_by_step = false; exec_finish = false; /* initialize internal variable */ memory_is_fault = 0; memory_io_writeback = 0; instruction_prefetch_flush(); /* setup system registers */ PSR = 0; cmod = (PSR & PSR_CMOD_MASK); PCR = entry_p; next_PCR = 0xffffffff; KSPR = (Memory)STACK_DEFAULT; #if !NO_DEBUG /* internal debug variable */ traceback_next = 0; FLAGR.flags = 0x80000000; prev_FLAGR.flags = 0x80000000; for(unsigned int i = 0; i < breakp_next; i++) { NOTICE("Break point[%d]: 0x%08x\n", i, breakp[i]); } #endif NOTICE("Execution Start: entry = 0x%08x\n", PCR); do { /* choose stack */ if(cmod != (PSR & PSR_CMOD_MASK)) { SPR = !cmod ? USPR : KSPR; } cmod = (PSR & PSR_CMOD_MASK); #if !NO_DEBUG /* break point check */ for(unsigned int i = 0; i < breakp_next; i++) { if(PCR == breakp[i]) { step_by_step = true; break; } } #endif /* instruction fetch */ insn.value = instruction_fetch(PCR); if(memory_is_fault) { /* fault fetch */ DEBUGINT("[FAULT] Instruction fetch: %08x\n", PCR); goto fault; } #if !NO_DEBUG if(DEBUG || step_by_step) { puts("---"); print_instruction(insn); } #endif /* execution */ insn_dispatch(insn); fault: if(memory_is_fault) { /* faulting memory access */ interrupt_dispatch_nonmask(memory_is_fault); next_PCR = PCR; memory_io_writeback = 0; memory_is_fault = 0; } else if(memory_io_writeback) { /* sync io */ io_store(memory_io_writeback); memory_io_writeback = 0; } /* writeback SP */ if(cmod) { USPR = SPR; } else { KSPR = SPR; } #if !NO_DEBUG if(step_by_step) { step_by_step_pause(); } else { if(DEBUG && DEBUG_REG) { print_registers(); } if(DEBUG_TRACE) { print_traceback(); } if(DEBUG_STACK) { print_stack(SPR); } if(DEBUG_DPS) { dps_info(); } } #endif if(!(clk & MONITOR_RECV_INTERVAL_MASK)) { if((PSR & PSR_IM_ENABLE) && IDT_ISENABLE(IDT_DPS_LS_NUM)) { dps_sci_recv(); } if(MONITOR) { monitor_method_recv(); monitor_send_queue(); } } /* next */ if(next_PCR != 0xffffffff) { #if !NO_DEBUG /* alignment check */ if(next_PCR & 0x3) { abort_sim(); errx(EXIT_FAILURE, "invalid branch addres. %08x", next_PCR); } #endif PCR = next_PCR; next_PCR = 0xffffffff; } else { PCR += 4; } /* interrupt check */ interrupt_dispatcher(); #if !NO_DEBUG /* for invalid flags checking */ prev_FLAGR.flags = FLAGR.flags; FLAGR._invalid |= 1; #endif /* next cycle */ clk++; } while(!(PCR == 0 && GR[31] == 0 && DEBUG_EXIT_B0) && !exec_finish); /* DEBUG_EXIT_B0: exit if b rret && rret == 0 */ NOTICE("---- Program Terminated ----\n"); print_instruction(insn); print_registers(); return 0; }
int TenshiRunQuanta(TenshiRuntimeState s) { // Do timeouts ActorProcessTimeouts(s); // Run the sensor actor // Dup the function first, as it disappears when we exit // TODO(rqou): Will we have a problem with the hardcoded op limit? lua_pushvalue(s->sensor_actor->L, -1); int ret = threading_run_ops(s->sensor_actor->L, 1000, NULL); if (ret != THREADING_EXITED) { printf("There was an error running the sensor actor!\n"); print_traceback(s->sensor_actor->L); return ret; } // Run the main code int ops_left = QUANTA_OPCODES; while (ops_left > 0) { TenshiActorState a; ret = ActorDequeueHead(s, &a); if (ret != LUA_OK) return ret; if (!a) { break; } ret = threading_run_ops(a->L, ops_left, &ops_left); if (ret == THREADING_ERROR) { printf("THERE WAS AN ERROR!\n"); print_traceback(a->L); return LUA_ERRRUN; } if (ret == THREADING_EXITED) { printf("Thread exited!\n"); ActorDestroy(a); } else if (ret == THREADING_YIELD) { printf("Thread yielded (blocked)!\n"); ret = ActorSetBlocked(a); if (ret != LUA_OK) return ret; } else if (ret == THREADING_PREEMPT) { // Requeue it ret = ActorSetRunnable(a, 0); if (ret != LUA_OK) return ret; } } // Run the actuator actor // Dup the function first, as it disappears when we exit lua_pushvalue(s->actuator_actor->L, -1); ret = threading_run_ops(s->actuator_actor->L, 1000, NULL); if (ret != THREADING_EXITED) { printf("There was an error running the actuator actor!\n"); print_traceback(s->actuator_actor->L); return ret; } lua_gc(s->L, LUA_GCCOLLECT, 0); return LUA_OK; }