/* |------------------+------------------------------------------------------------| */ EXPORT StatusType WaitEvent ( EventMaskType Mask ) { StatusType ercd = E_OK; uint8 flgid; OS_EXT_VALIDATE((0 == knl_taskindp),E_OS_CALLEVEL); OS_EXT_VALIDATE((INVALID_RESOURCE == knl_tcb_resque[knl_curtsk]),E_OS_RESOURCE); flgid = knl_tcb_flgid[knl_curtsk]; OS_EXT_VALIDATE((flgid != INVALID_FLAG),E_OS_ACCESS); BEGIN_CRITICAL_SECTION(); if((knl_fcb_set[flgid] & Mask) == NO_EVENT) { knl_fcb_wait[flgid] = Mask; knl_tcb_state[knl_curtsk] = WAITING; //release internal resource or for Non-Preemtable Task ReleaseInternalResource(); knl_search_schedtsk(); } END_CRITICAL_SECTION(); //re-get internal resource or for Non-Preemtable task GetInternalResource(); OS_VALIDATE_ERROR_EXIT() OsErrorProcess1(WaitEvent,mask,Mask); return ercd; }
/* |------------------+-------------------------------------------------------------| */ StatusType Schedule ( void ) { StatusType ercd = E_OK; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); OS_CHECK_EXT(isQueEmpty(&knl_ctxtsk->resque),E_OS_RESOURCE); BEGIN_CRITICAL_SECTION; //if task has internal resource or task is non-premtable if(knl_ready_queue.top_priority < knl_ctxtsk->itskpri) { //release internal resource or for Non-Preemtable Task ReleaseInternalResource(); knl_reschedule(); } END_CRITICAL_SECTION; //re-get internal resource or for Non-Preemtable task GetInternalResource(); Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_Schedule; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }
//when task start to run EXPORT void portActivateR(void) { /* This is the most easiest Way to get Internal Resourse and * to make a task non-preemtable I think */ GetInternalResource(); ENABLE_INTERRUPT(); knl_tcb_pc[knl_curtsk](); }
LOCAL void* portWaitForStart(void* taskid) { if ( 0 == pthread_mutex_lock( &portSingleThreadMutex ) ) { portSuspendThread( pthread_self() ); } GetInternalResource(); knl_tcb_pc[(TaskType)(TaskRefType)taskid](); return NULL; }
//when task start to run EXPORT void knl_activate_r(void) { #if(cfgOS_PRE_TASK_HOOK == STD_ON) PreTaskHook(); #endif /* This is the most easiest Way to get Internal Resourse and * to make a task non-preemtable I think */ GetInternalResource(); __asm CLI; // enable interrupt knl_ctxtsk->task(); }
/* |------------------+------------------------------------------------------------| */ StatusType WaitEvent( EventMaskType Mask ) { StatusType ercd = E_OK; ID flgid; FLGCB *flgcb; OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL); OS_CHECK_EXT(isQueEmpty(&knl_ctxtsk->resque),E_OS_RESOURCE); flgid = knl_ctxtsk - knl_tcb_table; flgid = knl_gtsk_table[flgid].flgid; OS_CHECK_EXT((flgid != INVALID_EVENT),E_OS_ACCESS); flgcb = &knl_flgcb_table[flgid]; BEGIN_CRITICAL_SECTION; if((flgcb->flgptn & Mask) == NO_EVENT) { flgcb->waipth = Mask; knl_ctxtsk->state = TS_WAIT; //release internal resource or for Non-Preemtable Task ReleaseInternalResource(); knl_search_schedtsk(); } END_CRITICAL_SECTION; //re-get internal resource or for Non-Preemtable task GetInternalResource(); Error_Exit: #if(cfgOS_ERROR_HOOK == STD_ON) if(E_OK != ercd) { BEGIN_CRITICAL_SECTION; _errorhook_svcid = OSServiceId_WaitEvent; _errorhook_par1.mask = Mask; CallErrorHook(ercd); END_CRITICAL_SECTION; } #endif /* cfgOS_ERROR_HOOK */ return ercd; }