void OS_ThreadExit(void) { int tid = current->tid; DEBUG ("(); tid=%d", tid); KTRACE (KTRACE_EXIT, current->tid, 0); /* Init the thread status */ task_table[tid].status = 0; /* Traps off, set S, PS and FP unit */ //task_table[tid].context.psr = 0x000010c0; /* Free the thread stack */ OS_Free(task_table[tid].stack.addr); /* Add the TCB into the free TCB queue */ OS_ListAppend(&tcb_list, &task_table[tid].node); }
/* * Function: void OS_TCBInit(void) * * This function initializes all the Thread Control Blocks to the init state */ void OS_TCBInit(void) { int i; OS_ListReset(&tcb_list); /* Assure that the priority of the task 0 is 0. This is important if ERCOS * is linked to C++ stuff; constructors (called from OS_CPPInit) may do * system calls and the task 0 will store the context of OS_Start function * before the first official dispatch (at the end of the function). Until * now, priority was 0 because task_table is allocated in the bss which is * zeroed at startup time (!!) */ task_table[0].priority = 0; for (i = MAIN_THREAD_TID; i < CONFIG_ERCOS_MAX_THREADS; ++i) { /* Init the thread status */ task_table[i].status = 0; /* Traps off, set S, PS and FP unit */ //task_table[i].context.psr = 0x000010c0; /* Init the thread identifier */ task_table[i].tid = i; /* Reset all the nodes associated with each thread */ OS_ListNodeReset(&task_table[i].node); OS_ListNodeReset(&task_table[i].time_node); OS_ListNodeReset(&task_table[i].resource_node); /* Add the TCB into the free TCBs queue */ OS_ListAppend(&tcb_list, &task_table[i].node); } /* create the idle task, with the minimum priority */ OS_TaskCreate (NULL, 0x600, OS_IdleTask, NULL, SCHED_MIN_PRIORITY); /* create the main task, with the maximum priority */ OS_TaskCreate (NULL, CONFIG_ERCOS_MAIN_STACK_SIZE, (void *) main, NULL, SCHED_MAX_PRIORITY); }
/* * === FUNCTION ====================================================================== * Name: OS_SemWait * Description: This function tries to catch a binary semaphore. The calling * task may get blocked in the semaphore queue whether the semaphore is already * taken from another task. If the semaphore was not taken, it is signaled as * taken and the calling task continues the execution. * ===================================================================================== */ int OS_SemWait(OS_SemID_t _sem) { OS_SemID_t id_sem = _sem; if(SEM(id_sem)->sem_value == 0) { current->status |= TS_SEM_BLOCKED; /* Block the caller thread */ /** Trace the event in case of need */ KTRACE_EVENT_SEM(KEVENT_LOCK_BLOCKED, SEM(id_sem)->sem_id); /* * The sem_wait field stores the semaphore identifier for which the * thread is waitting. */ current->wait_sem = _sem; OS_ListAppend(&(SEM(id_sem)->list), &(current->resource_node)); return -1; } else { /** Trace the event in case of need */ KTRACE_EVENT_SEM(KEVENT_LOCK_CATCHED, SEM(id_sem)->sem_id); /* Lock the semaphore */ SEM(id_sem)->sem_value = 0; /* Store what is the blocked thread in the semaphore structure */ SEM(id_sem)->tid_in = current->tid; /* The thread must be added to the ready queue */ return 0; } }
void TestList(void) { OS_List os_test_list; OS_ListItem* item_l_p; OS_ListItem* item_next_p; // Init list. srand(rand()); OS_ListInit(&os_test_list); TEST_ASSERT_TRUE(OS_LIST_IS_INITIALISED(&os_test_list)); // Add items to the list. for (SIZE i = 0; i < 0x10; ++i) { item_l_p = OS_ListItemCreate(); if (OS_NULL == item_l_p) { OS_TRACE(D_CRITICAL, "No memory!\n", OS_NULL); } OS_LIST_ITEM_VALUE_SET(item_l_p, (OS_Value)(rand() % U8_MAX)); OS_ListAppend(&os_test_list, item_l_p); } OS_LOG(D_DEBUG, "Initial list:"); TestListLog(&os_test_list); // Sort the list. TestListSort(&os_test_list, SORT_ASCENDING); OS_LOG(D_DEBUG, "List sorted by ascending:"); TestListLog(&os_test_list); TestListSort(&os_test_list, SORT_DESCENDING); OS_LOG(D_DEBUG, "List sorted by descending:"); TestListLog(&os_test_list); OS_TRACE(D_DEBUG, "\n", OS_NULL); // Clean up. item_l_p = OS_LIST_ITEM_NEXT_GET((OS_ListItem*)&OS_LIST_ITEM_LAST_GET(&os_test_list)); while (OS_TRUE != OS_LIST_IS_EMPTY(&os_test_list)) { item_next_p = OS_LIST_ITEM_NEXT_GET(item_l_p); OS_ListItemDelete(item_l_p); item_l_p = item_next_p; } }