void nOS_SignalProcess (void) { nOS_StatusReg sr; nOS_Signal *signal = NULL; nOS_SignalCallback callback = NULL; void *arg = NULL; nOS_EnterCritical(sr); if (nOS_SemTake (&_signalSem, #if (NOS_CONFIG_SIGNAL_THREAD_ENABLE > 0) NOS_WAIT_INFINITE #else NOS_NO_WAIT #endif ) == NOS_OK) { signal = (nOS_Signal *)nOS_GetHeadOfList(&_signalList); if (signal != NULL) { if (signal->state & NOS_SIGNAL_RAISED) { signal->state = (nOS_SignalState)(signal->state &~ NOS_SIGNAL_RAISED); nOS_RemoveFromList(&_signalList, &signal->node); callback = signal->callback; arg = signal->arg; } } } nOS_LeaveCritical(sr); if (callback != NULL) { callback(signal, arg); } }
nOS_Error nOS_SignalDelete (nOS_Signal *signal) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (signal == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (signal->state == NOS_SIGNAL_DELETED) { err = NOS_E_INV_OBJ; } else #endif { if (signal->state & NOS_SIGNAL_RAISED) { nOS_RemoveFromList(&_signalList, &signal->node); } signal->state = NOS_SIGNAL_DELETED; signal->callback = NULL; signal->node.payload = NULL; err = NOS_OK; } nOS_LeaveCritical(sr); } return err; }
void nOS_WakeUpThread (nOS_Thread *thread, nOS_Error err) { if (thread->event != NULL) { nOS_RemoveFromList(&thread->event->waitList, &thread->readyWait); } thread->error = err; thread->state = (nOS_ThreadState)(thread->state &~ NOS_THREAD_WAITING_MASK); #if (NOS_CONFIG_WAITING_TIMEOUT_ENABLE > 0) || (NOS_CONFIG_SLEEP_ENABLE > 0) || (NOS_CONFIG_SLEEP_UNTIL_ENABLE > 0) if (thread->state & NOS_THREAD_WAIT_TIMEOUT) { thread->state = (nOS_ThreadState)(thread->state &~ NOS_THREAD_WAIT_TIMEOUT); nOS_RemoveFromList(&nOS_timeoutThreadsList, &thread->tout); } #endif if (thread->state == NOS_THREAD_READY) { nOS_AppendThreadToReadyList(thread); } }
nOS_Error nOS_TimerDelete (nOS_Timer *timer) { nOS_Error err; #if (NOS_CONFIG_SAFE > 0) if (timer == NULL) { err = NOS_E_INV_OBJ; } else if (timer->state == NOS_TIMER_DELETED) { err = NOS_E_DELETED; } else #endif { nOS_EnterCritical(); timer->state = NOS_TIMER_DELETED; nOS_RemoveFromList(&_timerList, &timer->node); nOS_LeaveCritical(); err = NOS_OK; } return err; }
nOS_Error nOS_SignalSend (nOS_Signal *signal, void *arg) { nOS_Error err; nOS_StatusReg sr; #if (NOS_CONFIG_SAFE > 0) if (signal == NULL) { err = NOS_E_INV_OBJ; } else #endif { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (signal->state == NOS_SIGNAL_DELETED) { err = NOS_E_INV_OBJ; } else #endif { if (signal->state & NOS_SIGNAL_RAISED) { err = NOS_E_OVERFLOW; } else { signal->state = (nOS_SignalState)(signal->state | NOS_SIGNAL_RAISED); signal->arg = arg; nOS_AppendToList(&_signalList, &signal->node); err = nOS_SemGive(&_signalSem); if (err != NOS_OK) { signal->state = (nOS_SignalState)(signal->state &~ NOS_SIGNAL_RAISED); nOS_RemoveFromList(&_signalList, &signal->node); } } } nOS_LeaveCritical(sr); } return err; }
nOS_Error nOS_ThreadDelete (nOS_Thread *thread) { nOS_Error err; nOS_StatusReg sr; if (thread == NULL) { thread = nOS_runningThread; } #if (NOS_CONFIG_SAFE > 0) /* Main thread can't be deleted */ if (thread == &nOS_idleHandle) { err = NOS_E_INV_OBJ; } else if (thread == nOS_runningThread) { #if (NOS_CONFIG_SCHED_LOCK_ENABLE > 0) /* Can't switch context if scheduler is locked */ if (nOS_lockNestingCounter > 0) { err = NOS_E_LOCKED; } else #endif { err = NOS_OK; } } else #endif { err = NOS_OK; } if (err == NOS_OK) { nOS_EnterCritical(sr); #if (NOS_CONFIG_SAFE > 0) if (thread->state == NOS_THREAD_STOPPED) { err = NOS_E_INV_OBJ; } else #endif { #if (NOS_CONFIG_THREAD_SUSPEND_ALL_ENABLE > 0) nOS_RemoveFromList(&nOS_allThreadsList, &thread->node); #endif if (thread->state == NOS_THREAD_READY) { nOS_RemoveThreadFromReadyList(thread); } else if (thread->state & NOS_THREAD_WAITING_MASK) { if (thread->event != NULL) { nOS_RemoveFromList(&thread->event->waitList, &thread->readyWait); } #if (NOS_CONFIG_WAITING_TIMEOUT_ENABLE > 0) || (NOS_CONFIG_SLEEP_ENABLE > 0) || (NOS_CONFIG_SLEEP_UNTIL_ENABLE > 0) if (thread->state & NOS_THREAD_WAIT_TIMEOUT) { nOS_RemoveFromList(&nOS_timeoutThreadsList, &thread->tout); } #endif } thread->state = NOS_THREAD_STOPPED; thread->event = NULL; thread->ext = NULL; #if (NOS_CONFIG_WAITING_TIMEOUT_ENABLE > 0) || (NOS_CONFIG_SLEEP_ENABLE > 0) || (NOS_CONFIG_SLEEP_UNTIL_ENABLE > 0) thread->timeout = 0; #endif thread->error = NOS_OK; if (thread == nOS_runningThread) { /* Will never return */ nOS_Schedule(); } } nOS_LeaveCritical(sr); } return err; }