STATUS semBTake(SEM_ID semId, int timeout) { int level; int status; /* TODO ISR no be allowed */ again: level = intLock(); if(!IS_CLASS(semId, semClassId)) { intUnlock(level); return (ERROR); } if(NULL == semId->semOwner) { semId->semOwner = (RAIN_TCB*)taskIdCurrent; intUnlock(level); return (OK); } /* semId have been take by other task */ kernelState = TRUE; intUnlock(level); if(OK != kernelPendQPut(&semId->qHead, timeout)) { kernelExit(); return (ERROR); } /* test for interrupt in kernelState=TRUE of semGive */ /*{ int j = 1000000; while(j >= 0) { j--; } }*/ if(RESTART == (status = kernelExit())) { goto again; } return (status); }
STATUS semBGive(SEM_ID semId) { /* RAIN_TCB* pOwner; */ int level = intLock(); if(!IS_CLASS(semId, semClassId)) { intUnlock(level); return (ERROR); } /*pOwner = semId->semOwner;*/ if(NULL == (semId->semOwner = (RAIN_TCB*)Q_FIRST(&semId->qHead))) { intUnlock(level); } else { kernelState = TRUE; intUnlock(level); kernelPendQGet(&semId->qHead); kernelExit(); } return (OK); }
STATUS semDestroy(SEM_ID semId, BOOL dealloc) { int level; level = intLock(); if(!IS_CLASS(semId, semClassId)) { return (ERROR); } objCoreTerminate(&semId->objCore); kernelState = TRUE; intUnlock(level); kernelSemDelete(semId); TASK_SAFE(); kernelExit(); if(dealloc) { objFree(semClassId, (char*)semId); } TASK_UNSAFE(); return (OK); }
static STATUS msgQDestroy(MSG_Q_ID msgQId, BOOL dealloc) { Q_JOB_NODE* pNode; FAST int timeout; FAST int nMsgs; /* TODO isr not allowed */ TASK_SAFE(); TASK_LOCK(); if(!IS_CLASS(msgQId, msgQClassId)) { TASK_UNLOCK(); TASK_UNSAFE(); return (ERROR); } objCoreTerminate(&msgQId->objCore); TASK_UNLOCK(); timeout = NO_WAIT; nMsgs = 0; while(nMsgs < msgQId->maxMsgs) { while(((pNode = qJobGet(msgQId, &msgQId->freeQ, timeout)) != NULL) && (pNode != (Q_JOB_NODE*)NONE)) { nMsgs++; } while(((pNode = qJobGet(msgQId, &msgQId->msgQ, timeout)) != NULL) && (pNode != (Q_JOB_NODE*)NONE)) { nMsgs++; } timeout = 1; } kernelState = TRUE; qJobTerminate(&msgQId->msgQ); qJobTerminate(&msgQId->freeQ); kernelExit(); if(dealloc) { objFree(msgQClassId, (char*)msgQId); } TASK_UNSAFE(); return (OK); }
STATUS semQFlush(SEM_ID semId) { int level = intLock(); if(!IS_CLASS(semId, semClassId)) { intUnlock(level); } if(NULL == Q_FIRST(&semId->qHead)) { intUnlock(level); } else { kernelState = TRUE; intUnlock(level); kernelPendQFlush(&semId->qHead); kernelExit(); } return (OK); }
int main() { /* Initialize hardware */ // Turn off interrupt asm("msr CPSR_c, #0xd3"); // Tune up the system enableCache(); // speedUpCpu(); // Setup UART2 setUARTLineControl(UART2_BASE, 3, FALSE, FALSE, FALSE, FALSE, FALSE, 115200); setUARTControl(UART2_BASE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE); // Setup UART1 setUARTLineControl(UART1_BASE, 3, FALSE, TRUE, FALSE, FALSE, FALSE, 2400); setUARTControl(UART1_BASE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE); // Setup timer setTimerLoadValue(TIMER1_BASE, TIMER_TICK_SIZE); setTimerControl(TIMER1_BASE, TRUE, TRUE, TRUE); setTimerControl(TIMER3_BASE, TRUE, FALSE, FALSE); // Enable interrupt enableVicInterrupt(VIC1_BASE, VIC_TIMER1_MASK); enableVicInterrupt(VIC2_BASE, VIC_UART2_MASK); enableVicInterrupt(VIC2_BASE, VIC_UART1_MASK); /* Initialize ReadyQueue and Task related data structures */ KernelGlobal global; ReadyQueue ready_queue; Heap task_heap; HeapNode *task_heap_data[TASK_PRIORITY_MAX]; HeapNode task_heap_nodes[TASK_PRIORITY_MAX]; FreeList free_list; Task task_array[TASK_MAX]; TaskList task_list[TASK_PRIORITY_MAX]; BlockedList receive_blocked_lists[TASK_MAX]; BlockedList event_blocked_lists[EVENT_MAX]; MsgBuffer msg_array[TASK_MAX]; char stacks[TASK_MAX * TASK_STACK_SIZE]; taskArrayInitial(task_array, stacks); freeListInitial(&free_list, task_array); heapInitial(&task_heap, task_heap_data, TASK_PRIORITY_MAX); readyQueueInitial(&ready_queue, &task_heap, task_heap_nodes, task_list); blockedListsInitial(receive_blocked_lists, TASK_MAX); blockedListsInitial(event_blocked_lists, EVENT_MAX); msgArrayInitial(msg_array); /* Setup global kernel entry */ int *swi_entry = (int *) SWI_ENTRY_POINT; *swi_entry = (int) (TEXT_REG_BASE + swiEntry); int *irq_entry = (int *) IRQ_ENTRY_POINT; *irq_entry = (int) (TEXT_REG_BASE + irqEntry); /* Setup kernel global variable structure */ global.ready_queue = &ready_queue; global.free_list = &free_list; global.receive_blocked_lists = receive_blocked_lists; global.event_blocked_lists = event_blocked_lists; global.msg_array = msg_array; global.task_array = task_array; kernelGlobalInitial(&global); /* Create first task with highest priority */ Task *first_task = createTask(&free_list, 0, umain); insertTask(&ready_queue, first_task); /* Main syscall handling loop */ while(1){ // If no more task to run, break if(!scheduleNextTask(&ready_queue)) break; UserTrapframe* user_sp = (UserTrapframe *)ready_queue.curtask->current_sp; DEBUG(DB_TASK, "| TASK:\tEXITING SP: 0x%x SPSR: 0x%x ResumePoint: 0x%x\n", user_sp, user_sp->spsr, user_sp->resume_point); STAT_TASK_BEGIN(&global); // Exit kernel to let user program to execute kernelExit(ready_queue.curtask->current_sp); asm("mov r1, %0" : :"r"(&global) :"r0", "r2", "r3" ); asm("bl handlerRedirection(PLT)"); } // printStat(&global); /* Turm off timer */ setTimerControl(TIMER1_BASE, FALSE, FALSE, FALSE); setTimerControl(TIMER3_BASE, FALSE, FALSE, FALSE); return 0; }