mono_handle_new_interior (gpointer rawptr, const char *owner) #endif { MonoThreadInfo *info = mono_thread_info_current (); HandleStack *handles = (HandleStack *)info->handle_stack; HandleChunk *top = handles->interior; #ifdef MONO_HANDLE_TRACK_SP mono_handle_chunk_leak_check (handles); #endif g_assert (top); /* * Don't extend the chunk now, interior handles are * only used for icall arguments, they shouldn't * overflow. */ g_assert (top->size < OBJECTS_PER_HANDLES_CHUNK); int idx = top->size; gpointer *objslot = &top->elems [idx].o; *objslot = NULL; mono_memory_write_barrier (); top->size++; mono_memory_write_barrier (); *objslot = rawptr; SET_OWNER (top,idx); SET_SP (handles, top, idx); return objslot; }
void RestoreSleptTaskContext(StackType Stack) { /* context is restored from Stack starting at Stack.StackPointer */ /* the stack decrease in direction of Stack.StackBottom but never below */ SET_SP(ActiveTask.StackDesc.StackPointer); POP_CONTEXT_FROM_STACK(); }
/* struct CPU_t{ uint8_t a; // 0x7F00 uint8_t pce; uint8_t pch; uint8_t pcl; uint8_t xh; uint8_t xl; uint8_t yh; uint8_t yl; uint8_t sph; uint8_t spl; Flag ccr; // 0x7F0A }; */ void test_cpuInit_given_write_something_to_CPU_should_save_in_cpuBlock_data_because_is_pointed(void) { cpuInit(CPU_START_ADDR, CPU_SIZE); uint8_t *dataArr = cpuBlock->data; A = 0xAA; SET_PC(0x112233); SET_X(0xCCDD); SET_Y(0xEEFF); SET_SP(0x77BB); CC = 0x99; TEST_ASSERT_EQUAL_INT8(0xAA, *dataArr++); TEST_ASSERT_EQUAL_INT8(0x11, *dataArr++); TEST_ASSERT_EQUAL_INT8(0x22, *dataArr++); TEST_ASSERT_EQUAL_INT8(0x33, *dataArr++); TEST_ASSERT_EQUAL_INT8(0xCC, *dataArr++); TEST_ASSERT_EQUAL_INT8(0xDD, *dataArr++); TEST_ASSERT_EQUAL_INT8(0xEE, *dataArr++); TEST_ASSERT_EQUAL_INT8(0xFF, *dataArr++); TEST_ASSERT_EQUAL_INT8(0x77, *dataArr++); TEST_ASSERT_EQUAL_INT8(0xBB, *dataArr++); TEST_ASSERT_EQUAL_INT8(0x99, *dataArr++); TEST_ASSERT_EQUAL_INT8(0, *dataArr++); TEST_ASSERT_EQUAL_INT8(0, *dataArr++); TEST_ASSERT_EQUAL_INT8(0, *dataArr++); }
void RestoreInterruptedTaskContext(StackType Stack) { /* context is restored from Stack.StackPointer */ /* IRET insstruction is used in order to take advantage of the context stored at interruption point*/ SET_SP(ActiveTask.StackDesc.StackPointer); RESTORE_REGISTERS_LAST_POINT(); }
void test_sub_sp_byte(void) { SET_SP(0x1100); uint8_t instr[] = {0XAB, 0X02}; TEST_ASSERT_EQUAL(2, sub_sp_byte(instr)); TEST_ASSERT_EQUAL_INT16(0x10FE, SP); }
//Assembly : A | (shortoff,SP) and A,($10,SP) void test_and_a_shortoff_sp(void){ SET_SP(0X2B11); uint8_t instr[] = {0XFB, 0X11}; MEM_WRITE_BYTE(0X2B22 , src); //0x2B11 + 0X11 = 0X2B22 TEST_ASSERT_EQUAL_INT8(2, and_a_shortoff_sp(instr)); TEST_ASSERT_EQUAL_INT8(0x8C, A); }
void test_ldw_x_shortoff_sp(void){ SET_SP(0X2B11); uint8_t instr[] = {0XFB, 0X11}; MEM_WRITE_WORD(0X2B22 , 0xAE11); //0x2B11 + 0X11 = 0X2B22 TEST_ASSERT_EQUAL_INT8(2, ldw_x_shortoff_sp(instr)); TEST_ASSERT_EQUAL_INT16(0xAE11, X); }
//Assembly : A | (shortoff,SP) ld A,($10,SP) void test_ld_a_to_shortoff_sp(void){ SET_SP(0X2B11); uint8_t instr[] = {0XFB, 0X11}; //0x2B11 + 0X11 = 0X2B22 TEST_ASSERT_EQUAL_INT8(2, ld_a_to_shortoff_sp(instr)); TEST_ASSERT_EQUAL_INT8(0xAE, MEM_READ_BYTE(0X2B22)); }
void test_cpw_x_shortoff_sp(void) { SET_X(0x0122); SET_SP(0x2B11); uint8_t instr[] = {0XFB, 0X11}; MEM_WRITE_BYTE( 0X2B22 , 0x05); //0x2B11 + 0X11 = 0X2B22 TEST_ASSERT_EQUAL(2, cpw_x_shortoff_sp(instr)); }
void setUp(void) { instantiateCPU(); // Set the ramMemory occupy the memoryTable from 0000 to FFFF, for testing purpose (FFFF / 100 = FF) ramBlock = createMemoryBlock(RAM_START_ADDR, 0xFFFF); setMemoryTable( ramMemory , 0 , 0xFFFF); inputSP = 0x1122; inputSP_DEC = inputSP - 1; SET_SP(inputSP); }
mono_handle_new (MonoObject *obj, MonoThreadInfo *info, const char *owner) #endif { info = info ? info : mono_thread_info_current (); HandleStack *handles = info->handle_stack; HandleChunk *top = handles->top; #ifdef MONO_HANDLE_TRACK_SP mono_handle_chunk_leak_check (handles); #endif retry: if (G_LIKELY (top->size < OBJECTS_PER_HANDLES_CHUNK)) { int idx = top->size; gpointer* objslot = &top->elems [idx].o; /* can be interrupted anywhere here, so: * 1. make sure the new slot is null * 2. make the new slot scannable (increment size) * 3. put a valid object in there * * (have to do 1 then 3 so that if we're interrupted * between 1 and 2, the object is still live) */ *objslot = NULL; SET_OWNER (top,idx); SET_SP (handles, top, idx); mono_memory_write_barrier (); top->size++; mono_memory_write_barrier (); *objslot = obj; return objslot; } if (G_LIKELY (top->next)) { top->next->size = 0; /* make sure size == 0 is visible to a GC thread before it sees the new top */ mono_memory_write_barrier (); top = top->next; handles->top = top; goto retry; } HandleChunk *new_chunk = new_handle_chunk (); new_chunk->size = 0; new_chunk->prev = top; new_chunk->next = NULL; /* make sure size == 0 before new chunk is visible */ mono_memory_write_barrier (); top->next = new_chunk; handles->top = new_chunk; goto retry; }
void setUp(void) { instantiateCPU(); // Set the ramMemory occupy the memoryTable from 0000 to FFFF, for testing purpose ramBlock = createMemoryBlock(0x0000 , 0xFFFF); setMemoryTable( ramMemory , 0 , 0xFFFF); inputSP = 0x1122; sp_minus1 = inputSP - 1; sp_minus2 = inputSP - 2; SET_SP(inputSP); pcToLoad = malloc(sizeof(uint32_t)); *pcToLoad = 0; }
void setUp(void) { instantiateCPU(); // Set the ramMemory occupy the memoryTable from 0000 to FFFF, for testing purpose (FFFF / 100 = FF) ramBlock = createMemoryBlock(0, 0xFFFF); setMemoryTable( ramMemory , 0 , 0xFFFF); A = 0x01; C = 0; // default carry is 0 SET_X(0X0040); SET_Y(0x1170); SET_SP(0x2290); MEM_WRITE_BYTE( X , 0x07); MEM_WRITE_BYTE( Y , 0x08); MEM_WRITE_BYTE( SP , 0x09); }
static VALUE vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_num_t flag) { const rb_block_t *block = GET_BLOCK_PTR(); rb_iseq_t *iseq; int argc = (int)num; VALUE type = GET_ISEQ()->local_iseq->type; if ((type != ISEQ_TYPE_METHOD && type != ISEQ_TYPE_CLASS) || block == 0) { rb_vm_localjump_error("no block given (yield)", Qnil, 0); } iseq = block->iseq; argc = caller_setup_args(th, GET_CFP(), flag, argc, 0, 0); if (BUILTIN_TYPE(iseq) != T_NODE) { int opt_pc; const int arg_size = iseq->arg_size; VALUE * const rsp = GET_SP() - argc; SET_SP(rsp); CHECK_STACK_OVERFLOW(GET_CFP(), iseq->stack_max); opt_pc = vm_yield_setup_args(th, iseq, argc, rsp, 0, block_proc_is_lambda(block->proc)); vm_push_frame(th, iseq, VM_FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp, iseq->iseq_encoded + opt_pc, rsp + arg_size, block->lfp, iseq->local_size - arg_size); return Qundef; } else { VALUE val = vm_yield_with_cfunc(th, block, block->self, argc, STACK_ADDR_FROM_TOP(argc), 0); POPN(argc); /* TODO: should put before C/yield? */ return val; } }
void OS_SCHEDULER(void) { DINT; DRTM; /* Restore context of scheduler */ //Nos movemos a la pila global asm(" MOV DP,#_PtrStack_Global"); asm(" MOVL ACC,@_PtrStack_Global"); asm(" MOV SP,ACC"); unsigned int i; unsigned int j; unsigned long int WaitTime; unsigned int GroupSize; TaskType NextTask; /* sort Ready tasks by WaitTime */ (void)Sort(ReadyTasks, NO_TASKS, WAIT_TIME); /* Check integrity of task stacks */ CheckTaskOverflow(); /* find and sort by Priority group of tasks of same WaitTime */ for(i=0; i<NO_TASKS; ) { GroupSize = 1; WaitTime = ReadyTasks[i].WaitTime; /* search for tasks with same WaitTime */ for(j=i+1; j<NO_TASKS; j++) { if(ReadyTasks[j].WaitTime>WaitTime) { /* another group starts at j-th task, break the search */ break; } else { /* j-th task is from the same group as task i */ GroupSize++; } } if(GroupSize>1) { /* sort group of tasks by Priority */ (void)Sort(&ReadyTasks[i], GroupSize, PRIORITY); } /* find next group of tasks */ i = j; } /* the first task in the list is the shortest wait time and higher priority */ if(ReadyTasks[0].WaitTime == 0) { /* it's time to activate task */ NextTask.State = TSK_INVALID; /* find the next higher priority task (0 is the highest priority) */ for(i=1; i<NO_TASKS; i++) { if(ReadyTasks[i].Priority < ReadyTasks[0].Priority) { /* the scheduler shall be executed again in ReadyTasks[i].WaitTime */ NextTask = ReadyTasks[i]; break; } } if(NextTask.State == TSK_INVALID) { /* there is no task with higher priority than the task about to be activated */ /* the scheduler will be called whenever the coming task finishes */ } else { /* the scheduler shall be called again in NextTask.WaitTime */ SetAlarm(NextTask.WaitTime); } ActiveTask = ReadyTasks[0]; /* Remove task to be activated from the ReadyTasks list */ for(i=1; i<NO_TASKS; i++) { ReadyTasks[i-1] = ReadyTasks[i]; } ReadyTasks[i-1].Id = 0; ReadyTasks[i-1].Priority = 0; ReadyTasks[i-1].State = TSK_INVALID; ReadyTasks[i-1].WaitTime = 0; ReadyTasks[i-1].StackDesc.StackBottom = 0; ReadyTasks[i-1].StackDesc.StackTop = 0; ReadyTasks[i-1].StackDesc.StackPointer = 0; /* Restore context of task to be executed */ switch( ActiveTask.State ) { /* Scheduler was called from OS_SLEEP function */ case TSK_SLEPT : ActiveTask.State = TSK_ACTIVE; RestoreSleptTaskContext(ActiveTask.StackDesc); break; /* Scheduler was called from interrupt routine */ case TSK_INTERRUPTED : ActiveTask.State = TSK_ACTIVE; RestoreInterruptedTaskContext(ActiveTask.StackDesc); break; /* Task is ready to run */ case TSK_READY : ActiveTask.State = TSK_ACTIVE; SET_SP(ActiveTask.StackDesc.StackPointer); RESTORE_REGISTERS_BEGINNING(ActiveTask.StackDesc.StackBottom[0]); break; /* Invalid caller */ default : break; } } else { /* set a timer to delay activation of the task */ SetAlarm(ReadyTasks[0].WaitTime); } for(;;); } // fin void SCHEDULER(void)