/* * ======== ti_sdo_ipc_Ipc_procSyncFinish ======== * Each processor writes its reserve memory address in SharedRegion 0 * to let the other processors know its finished the process of * synchronization. */ Int ti_sdo_ipc_Ipc_procSyncFinish(UInt16 remoteProcId, Ptr sharedAddr) { volatile ti_sdo_ipc_Ipc_Reserved *self, *remote; SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc(); Bool cacheEnabled = SharedRegion_isCacheEnabled(0); UInt oldPri; /* don't do any synchronization if procSync is NONE */ if (ti_sdo_ipc_Ipc_procSync == ti_sdo_ipc_Ipc_ProcSync_NONE) { return (Ipc_S_SUCCESS); } /* determine self and remote pointers */ if (MultiProc_self() < remoteProcId) { self = Ipc_getSlaveAddr(remoteProcId, sharedAddr); remote = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr); } else { self = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr); remote = Ipc_getSlaveAddr(remoteProcId, sharedAddr); } /* set my processor's reserved key to finish */ self->startedKey = ti_sdo_ipc_Ipc_PROCSYNCFINISH; /* write back my processor's reserve key */ if (cacheEnabled) { Cache_wbInv((Ptr)self, reservedSize, Cache_Type_ALL, TRUE); } /* if slave processor, wait for remote to finish sync */ if (MultiProc_self() < remoteProcId) { if (BIOS_getThreadType() == BIOS_ThreadType_Task) { oldPri = Task_getPri(Task_self()); } /* wait for remote processor to finish */ while (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCFINISH && remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCDETACH) { /* Set self priority to 1 [lowest] and yield cpu */ if (BIOS_getThreadType() == BIOS_ThreadType_Task) { Task_setPri(Task_self(), 1); Task_yield(); } /* Check the remote's sync flag */ if (cacheEnabled) { Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE); } } /* Restore self priority */ if (BIOS_getThreadType() == BIOS_ThreadType_Task) { Task_setPri(Task_self(), oldPri); } } return (Ipc_S_SUCCESS); }
/********************************************************************* * @fn SensorTagBar_processCharChangeEvt * * @brief SensorTag Barometer event handling * */ void SensorTagBar_processCharChangeEvt(uint8_t paramID) { uint8_t newValue; switch (paramID) { case SENSOR_CONF: if ((SensorTag_testResult() & SENSOR_BAR_TEST_BM) == 0) { sensorConfig = ST_CFG_ERROR; } if (sensorConfig != ST_CFG_ERROR) { Barometer_getParameter(SENSOR_CONF, &newValue); if (newValue == ST_CFG_SENSOR_DISABLE) { sensorConfig = ST_CFG_SENSOR_DISABLE; initCharacteristicValue(SENSOR_DATA, 0, SENSOR_DATA_LEN); // Deactivate task Task_setPri(Task_handle(&sensorTask), -1); } else if (newValue == ST_CFG_SENSOR_ENABLE) { sensorConfig = ST_CFG_SENSOR_ENABLE; // Activate task Task_setPri(Task_handle(&sensorTask), SENSOR_TASK_PRIORITY); } } else { // Make sure the previous characteristics value is restored initCharacteristicValue(SENSOR_CONF, sensorConfig, sizeof(uint8_t)); } // Make sure sensor is disabled sensorMs5607Enable(false); break; case SENSOR_PERI: Barometer_getParameter(SENSOR_PERI, &newValue); sensorPeriod = newValue * SENSOR_PERIOD_RESOLUTION; break; default: // Should not get here break; } }
/* * ======== pthread_setschedparam ======== */ int pthread_setschedparam(pthread_t pthread, int policy, const struct sched_param *param) { pthread_Obj *thread = (pthread_Obj *)pthread; Task_Handle task = thread->task; UInt oldPri; int priority = param->sched_priority; UInt key; #if ti_sysbios_posix_Settings_supportsMutexPriority__D int maxPri; #endif if ((priority >= Task_numPriorities) || ((priority == 0)) || (priority < -1)) { /* Bad priority value */ return (EINVAL); } key = Task_disable(); oldPri = Task_getPri(task); thread->priority = priority; #if ti_sysbios_posix_Settings_supportsMutexPriority__D /* * If the thread is holding a PTHREAD_PRIO_PROTECT or * PTHREAD_PRIO_INHERIT mutex and running at its ceiling, we don't * want to set its priority to a lower value. Instead, we save the * new priority to set it to, once the mutexes of higher priority * ceilings are released. */ if (!Queue_empty(Queue_handle(&(thread->mutexList)))) { maxPri = _pthread_getMaxPrioCeiling(thread); if (priority > maxPri) { Task_setPri(task, priority); } } else { /* The thread owns no mutexes */ oldPri = Task_setPri(task, priority); } #else oldPri = Task_setPri(task, priority); #endif Task_restore(key); /* Suppress warning about oldPri not being used. */ (void)oldPri; return (0); }
/********************************************************************* * @fn PMLDotTmp_processCharChangeEvt * * @brief PMLDot IR temperature event handling * */ void PMLDotTmp_processCharChangeEvt(uint8_t paramID) { uint8_t newValue; switch (paramID) { case SENSOR_CONF: if ((sensorTestResult() & ST_IRTEMP) == 0) { sensorConfig = ST_CFG_ERROR; } if (sensorConfig != ST_CFG_ERROR) { IRTemp_getParameter(SENSOR_CONF, &newValue); if (newValue == ST_CFG_SENSOR_DISABLE) { // Reset characteristics initCharacteristicValue(SENSOR_DATA, 0, SENSOR_DATA_LEN); // Deactivate task Task_setPri(Task_handle(&sensorTask), -1); } else { Task_setPri(Task_handle(&sensorTask), SENSOR_TASK_PRIORITY); } sensorConfig = newValue; } else { // Make sure the previous characteristics value is restored initCharacteristicValue(SENSOR_CONF, sensorConfig, sizeof ( uint8_t )); } // Make sure sensor is disabled sensorTmp007Enable(false); break; case SENSOR_PERI: IRTemp_getParameter(SENSOR_PERI, &newValue); sensorPeriod = newValue * SENSOR_PERIOD_RESOLUTION; break; default: // Should not get here break; } }
/* * ======== ThreadSupport_setPriority ======== */ Bool ThreadSupport_setPriority(ThreadSupport_Handle obj, ThreadSupport_Priority newPri, Error_Block* eb) { Int bios6Pri; if (newPri == ThreadSupport_Priority_LOWEST) { bios6Pri = ThreadSupport_lowestPriority; } else if (newPri == ThreadSupport_Priority_BELOW_NORMAL) { bios6Pri = ThreadSupport_belowNormalPriority; } else if (newPri == ThreadSupport_Priority_NORMAL) { bios6Pri = ThreadSupport_normalPriority; } else if (newPri == ThreadSupport_Priority_ABOVE_NORMAL) { bios6Pri = ThreadSupport_aboveNormalPriority; } else if (newPri == ThreadSupport_Priority_HIGHEST) { bios6Pri = ThreadSupport_highestPriority; } else { Error_raise(NULL, ThreadSupport_E_priority, newPri, 0); return (FALSE); } Task_setPri(obj->task, bios6Pri); return (TRUE); }
/* * ======== ThreadSupport_setOsPriority ======== */ Bool ThreadSupport_setOsPriority(ThreadSupport_Handle obj, Int newPri, Error_Block* eb) { Task_setPri(obj->task, newPri); return (TRUE); }
VOID Task_Start(Task *pThis) { LOG_TRACE2("\ninside Task_Start name: %d, Handle:%d .",pThis->hPriority,pThis->Handle); //TSK_setpri(pThis->Handle, pThis->hPriority); Task_setPri(pThis->Handle, pThis->hPriority); LOG_TRACE0("\n After Task_setpri"); }
TIMM_OSAL_ERRORTYPE TIMM_OSAL_Task_newpri ( TIMM_OSAL_PTR pTask, TIMM_OSAL_S32 sNewPriority ) { TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_NONE; TIMM_OSAL_TASK *pHandle = (TIMM_OSAL_TASK *)pTask; if ( ( TIMM_OSAL_NULL == pHandle ) || ( 0 == sNewPriority ) || ( sNewPriority >= Task_numPriorities ) ) { bReturnStatus = TIMM_OSAL_ERR_PARAMETER; goto EXIT; } if (pHandle->isCreated != TIMM_OSAL_TRUE) { bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; goto EXIT; } if ( Task_Mode_TERMINATED == Task_getMode ( pHandle->task) ) { bReturnStatus = TIMM_OSAL_ERR_UNKNOWN; goto EXIT; } Task_setPri ( pHandle->task, (Int) sNewPriority ); EXIT: return bReturnStatus; }
/* * ======== pthread_exit ======== */ void pthread_exit(void *retval) { pthread_Obj *thread = (pthread_Obj *)pthread_self(); /* * This function terminates the calling thread and returns * a value via retval that (if the thread is joinable) is available to * another thread that calls pthread_join(). * * Any clean-up handlers that have not yet been popped, are popped * (in the reverse of the order in which they were pushed) and executed. */ thread->ret = retval; /* * Don't bother disabling the Task scheduler while the thread * is exiting. It will be up to the application to not make * such calls as pthread_cancel() or pthread_detach() while the * thread is exiting. */ /* Pop and execute the cleanup handlers */ while (thread->cleanupList != NULL) { _pthread_cleanup_pop(thread->cleanupList, 1); } /* Cleanup any pthread specific data */ _pthread_removeThreadKeys((pthread_t)thread); if (!thread->detached) { Semaphore_post(Semaphore_handle(&(thread->joinSem))); /* Set this task's priority to -1 to stop it from running. */ Task_setPri(thread->task, -1); } else { /* Free memory */ #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Semaphore_destruct(&(thread->joinSem)); Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); /* * Don't call Task_delete on the calling thread. Task_exit() * will put the task on the terminated queue, and if * Task_deleteTerminatedTasks is TRUE, the task will be cleaned * up automatically. */ Task_exit(); } }
/********************************************************************* * @fn sensorTaskFxn * * @brief The task loop of the humidity readout task * * @return none */ static void sensorTaskFxn(UArg a0, UArg a1) { // Register task with BLE stack ICall_registerApp(&sensorSelfEntity, &sensorSem); // Deactivate task (active only when measurement is enabled) Task_setPri(Task_handle(&sensorTask), -1); // Task loop while (true) { if (sensorConfig == ST_CFG_SENSOR_ENABLE) { uint8_t data[MS5607_DATA_SIZE]; sensorMs5607Read(data); // int32_t temp; // uint32_t press; // bool success; // // // Readout // SensorBmp280_enable(true); // DELAY_MS(SENSOR_FSM_PERIOD); // success = SensorBmp280_read(data); // SensorBmp280_enable(false); // // // Processing // if (success) // { // SensorBmp280_convert(data,&temp,&press); // // data[2] = (temp >> 16) & 0xFF; // data[1] = (temp >> 8) & 0xFF; // data[0] = temp & 0xFF; // // data[5] = (press >> 16) & 0xFF; // data[4] = (press >> 8) & 0xFF; // data[3] = press & 0xFF; // } // Send data Barometer_setParameter(SENSOR_DATA, SENSOR_DATA_LEN, data); DELAY_MS(sensorPeriod - SENSOR_FSM_PERIOD); } else { DELAY_MS(SENSOR_DEFAULT_PERIOD); } } }
Int32 Utils_tskSetPri(Utils_TskHndl * pHndl, UInt32 newPri) { if((Task_Mode_TERMINATED != Task_getMode(pHndl->tsk)) && (newPri != 0) && (newPri < (UInt32)Task_numPriorities)) { Task_setPri(pHndl->tsk, newPri); pHndl->tskPri = newPri; } else return FVID2_EFAIL; return FVID2_SOK; }
/* * ======== pthread_cancel ======== * The specification of this API is that it be used as a means for one thread * to termintate the execution of another thread. There is no mention of * returning an error if the argument, pthread, is the same thread as the * calling thread. */ int pthread_cancel(pthread_t pthread) { pthread_Obj *thread = (pthread_Obj *)pthread; UInt key; /* * Cancel the thread. Only asynchronous cancellation is supported, * since functions that would normally be cancellation points (eg, * printf()), are not cancellation points for BIOS. */ key = Task_disable(); /* Indicate that cancellation is requested. */ thread->cancelPending = 1; if (thread->cancelState == PTHREAD_CANCEL_ENABLE) { /* Set this task's priority to -1 to stop it from running. */ Task_setPri(thread->task, -1); Task_restore(key); /* Pop and execute the cleanup handlers */ while (thread->cleanupList != NULL) { _pthread_cleanup_pop(thread->cleanupList, 1); } /* Cleanup any pthread specific data */ _pthread_removeThreadKeys(pthread); if (thread->detached) { /* Free memory */ #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Semaphore_destruct(&(thread->joinSem)); Task_delete(&(thread->task)); Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); } else { /* pthread_join() will clean up. */ thread->ret = PTHREAD_CANCELED; Semaphore_post(Semaphore_handle(&(thread->joinSem))); } } else { Task_restore(key); } return (0); }
/* * ======== apSetup ======== */ __extern void apSetup() { Serial.begin(9600); /* set priority of this task to be lower than other tasks */ Task_setPri(Task_self(), 1); /* toggle LED when clients connect/disconnect */ pinMode(MAIN_LED_PIN, OUTPUT); digitalWrite(MAIN_LED_PIN, LOW); System_printf(" apSetup.\r\n"); Serial.print("Setting up Access Point named: "); Serial.print(ssid); Serial.print(" with password: "******" firmware version: "); Serial.println(WiFi.firmwareVersion()); Serial.println("AP active."); /* startup the command server on port PORTNUM */ Serial.print("Starting dataserver ... "); server.begin(); Serial.print("dataserver started on port "); Serial.println(PORTNUM); }
/* * ======== _pthread_runStub ======== */ static void _pthread_runStub(UArg arg0, UArg arg1) { UInt key; Ptr arg; pthread_Obj *thread = (pthread_Obj *)(xdc_uargToPtr(arg1)); arg = Task_getEnv(thread->task); thread->ret = thread->fxn(arg); /* Pop and execute the cleanup handlers */ while (thread->cleanupList != NULL) { _pthread_cleanup_pop(thread->cleanupList, 1); } /* Cleanup any pthread specific data */ _pthread_removeThreadKeys((pthread_t)thread); key = Task_disable(); if (!thread->detached) { Semaphore_post(Semaphore_handle(&(thread->joinSem))); /* * Set this task's priority to -1 to prevent it from being put * on the terminated queue (and deleted if Task.deleteTerminatedTasks * is true). pthread_join() will delete the Task object. */ Task_setPri(thread->task, -1); Task_restore(key); } else { Task_restore(key); /* Free memory */ #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Semaphore_destruct(&(thread->joinSem)); Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); /* The system will have to clean up the Task object */ } /* Task_exit() is called when returning from this function */ }
/********************************************************************* * @fn sensorTaskFxn * * @brief The task loop of the temperature readout task * * @return none */ static void sensorTaskFxn(UArg a0, UArg a1) { typedef union { struct { uint16_t tempTarget, tempLocal; } v; uint16_t a[2]; } Data_t; // Register task with BLE stack ICall_registerApp(&sensorSelfEntity, &sensorSem); // Initialize the task sensorTaskInit(); // Deactivate task (active only when measurement is enabled) Task_setPri(Task_handle(&sensorTask), -1); // Task loop while (true) { if (sensorConfig == ST_CFG_SENSOR_ENABLE) { Data_t data; // Read data sensorTmp007Enable(true); delay_ms(TEMP_MEAS_DELAY); sensorTmp007Read(&data.v.tempLocal, &data.v.tempTarget); sensorTmp007Enable(false); // Update GATT IRTemp_setParameter( SENSOR_DATA, SENSOR_DATA_LEN, data.a); // Next cycle delay_ms(sensorPeriod - TEMP_MEAS_DELAY); } else { delay_ms(SENSOR_DEFAULT_PERIOD); } } }
/********************************************************************* * @fn sensorTaskFxn * * @brief The task loop of the humidity readout task * * @param a0 - not used * * @param a1 - not used * * @return none */ static void sensorTaskFxn(UArg a0, UArg a1) { typedef union { struct { uint16_t rawTemp, rawHum; } v; uint8_t a[SENSOR_DATA_LEN]; } Data_t; // Register task with BLE stack ICall_registerApp(&sensorSelfEntity, &sensorSem); // Deactivate task (active only when measurement is enabled) Task_setPri(Task_handle(&sensorTask), -1); // Task loop while (true) { if (sensorConfig == ST_CFG_SENSOR_ENABLE) { Data_t data; // 1. Start temperature measurement SensorHdc1080_start(); DELAY_MS(HUM_DELAY_PERIOD); // 2. Read data SensorHdc1080_read(&data.v.rawTemp, &data.v.rawHum); // 3. Send data Humidity_setParameter(SENSOR_DATA, SENSOR_DATA_LEN, data.a); // 4. Wait until next cycle DELAY_MS(sensorPeriod - HUM_DELAY_PERIOD); } else { DELAY_MS(SENSOR_DEFAULT_PERIOD); } } }
/********************************************************************* * @fn sensorTaskFxn * * @brief The task loop of the humidity readout task * * @return none */ static void sensorTaskFxn(UArg a0, UArg a1) { typedef union { struct { uint16_t rawTemp, rawHum; } v; uint8_t a[2]; } Data_t; // Initialize the task sensorTaskInit(); // Deactivate task (active only when measurement is enabled) Task_setPri(Task_handle(&sensorTask), -1); // Task loop while (true) { if (sensorConfig == ST_CFG_SENSOR_ENABLE) { Data_t data; // 1. Start temperature measurement sensorHdc1000Start(); delay_ms(HUM_DELAY_PERIOD); // 2. Read data sensorHdc1000Read(&data.v.rawTemp, &data.v.rawHum); // 3. Send data Humidity_setParameter( SENSOR_DATA, SENSOR_DATA_LEN, data.a); // 4. Wait until next cycle delay_ms(sensorPeriod - HUM_DELAY_PERIOD); } else { delay_ms(SENSOR_DEFAULT_PERIOD); } } }
/* * ======== pthread_create ======== */ int pthread_create(pthread_t *newthread, const pthread_attr_t *attr, void *(*startroutine)(void *), void *arg) { Semaphore_Params semParams; Task_Params taskParams; pthread_Obj *thread = NULL; Error_Block eb; pthread_attr_t *pAttr; Error_init(&eb); Task_Params_init(&taskParams); *newthread = NULL; thread = (pthread_Obj *)Memory_alloc(Task_Object_heap(), sizeof(pthread_Obj), 0, &eb); if (thread == NULL) { return (ENOMEM); } pAttr = (attr == NULL) ? &defaultPthreadAttrs : (pthread_attr_t *)attr; taskParams.priority = pAttr->priority; taskParams.stack = pAttr->stack; taskParams.stackSize = pAttr->stacksize + pAttr->guardsize; /* Save the function in arg0 for ROV */ taskParams.arg0 = (UArg)startroutine; taskParams.arg1 = (UArg)thread; taskParams.env = arg; taskParams.priority = -1; thread->detached = (pAttr->detachstate == PTHREAD_CREATE_JOINABLE) ? 0 : 1; thread->fxn = startroutine; thread->joinThread = NULL; thread->cancelState = PTHREAD_CANCEL_ENABLE; thread->cancelPending = 0; thread->priority = pAttr->priority; thread->cleanupList = NULL; #if ti_sysbios_posix_Settings_supportsMutexPriority__D thread->blockedMutex = NULL; Queue_elemClear((Queue_Elem *)thread); Queue_construct(&(thread->mutexList), NULL); #endif Semaphore_Params_init(&semParams); semParams.mode = Semaphore_Mode_BINARY; Semaphore_construct(&(thread->joinSem), 0, &semParams); thread->task = Task_create((Task_FuncPtr)_pthread_runStub, &taskParams, &eb); if (thread->task == NULL) { Semaphore_destruct(&(thread->joinSem)); #if ti_sysbios_posix_Settings_supportsMutexPriority__D Queue_destruct(&(thread->mutexList)); #endif Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj)); return (ENOMEM); } *newthread = (pthread_t)thread; Task_setPri(thread->task, pAttr->priority); return (0); }
/***************************************************************************** ** Function name: Task_Stop ** ** Descriptions: ** Stops the Task, and move to Suspend state ** parameters: Task *pThis ** Returned value: None ** ** Dependencies/Limitations/Side Effects/Design Notes: ** ** ******************************************************************************/ VOID Task_Stop(Task *pThis) { //TSK_setpri(pThis->Handle, STE_TASK_SUSPEND); Task_setPri(pThis->Handle, STE_TASK_SUSPEND); }
/* * ======== GateMutexPri_leave ======== * Only releases the gate if key == FIRST_ENTER. */ Void GateMutexPri_leave(GateMutexPri_Object *obj, IArg key) { UInt tskKey, hwiKey; Task_Handle owner; Task_Handle newOwner; Task_PendElem *elem; Queue_Handle pendQ; pendQ = GateMutexPri_Instance_State_pendQ(obj); owner = Task_self(); /* * Prior to tasks starting, Task_self() will return NULL. * Simply return here as, by definition, there is * is only one thread running at this time. */ if (owner == NULL) { return; } /* * Gate may only be called from task context, so Task_disable is sufficient * protection. */ tskKey = Task_disable(); /* Assert that caller is gate owner. */ // ASSERT(owner == obj->owner); /* If this is not the outermost call to leave, just return. */ if (key != FIRST_ENTER) { Task_restore(tskKey); return; } /* * Restore this task's priority. The if-test is worthwhile because of the * cost of a call to setPri. */ if (obj->ownerOrigPri != Task_getPri(owner)) { Task_setPri(owner, obj->ownerOrigPri); } /* If the list of waiting tasks is not empty... */ if (!Queue_empty(pendQ)) { /* * Get the next owner from the front of the queue (the task with the * highest priority of those waiting on the queue). */ elem = (Task_PendElem *)Queue_dequeue(pendQ); newOwner = elem->task; /* Setup the gate. */ obj->owner = newOwner; obj->ownerOrigPri = Task_getPri(newOwner); /* Task_unblockI must be called with interrupts disabled. */ hwiKey = Hwi_disable(); Task_unblockI(newOwner, hwiKey); Hwi_restore(hwiKey); } /* If the gate is to be posted... */ else { obj->mutexCnt = 1; } Task_restore(tskKey); }
/***************************************************************************** ** Function name: Task_SetPri ** ** Descriptions: ** Provision to Revise the priority of the mentioned task. ** parameters: Task *pThis, Priority ** Returned value: None ** ** Dependencies/Limitations/Side Effects/Design Notes: ** ** ******************************************************************************/ VOID Task_SetPri(Task *pThis, TaskPri ePriority) { pThis->hPriority = ePriority; //TSK_setpri(pThis->Handle, ePriority); Task_setPri(pThis->Handle, ePriority); }
/* * ======== GateMutexPri_Gate ======== * Returns FIRST_ENTER when it gets the gate, returns NESTED_ENTER * on nested calls. */ IArg GateMutexPri_enter(GateMutexPri_Object *obj) { Task_Handle tsk; UInt tskKey; Int tskPri; Task_PendElem elem; Queue_Handle pendQ; /* make sure we're not calling from Hwi or Swi context */ Assert_isTrue(((BIOS_getThreadType() == BIOS_ThreadType_Task) || (BIOS_getThreadType() == BIOS_ThreadType_Main)), GateMutexPri_A_badContext); pendQ = GateMutexPri_Instance_State_pendQ(obj); tsk = Task_self(); /* * Prior to tasks starting, Task_self() will return NULL. * Simply return NESTED_ENTER here as, by definition, there is * is only one thread running at this time. */ if (tsk == NULL) { return (NESTED_ENTER); } tskPri = Task_getPri(tsk); /* * Gate may only be called from task context, so Task_disable is sufficient * protection. */ tskKey = Task_disable(); /* If the gate is free, take it. */ if (obj->mutexCnt == 1) { obj->mutexCnt = 0; obj->owner = tsk; obj->ownerOrigPri = tskPri; Task_restore(tskKey); return (FIRST_ENTER); } /* At this point, the gate is already held by someone. */ /* If this is a nested call to gate... */ if (obj->owner == tsk) { Task_restore(tskKey); return (NESTED_ENTER); } /* * Donate priority if necessary. The owner is guaranteed to have the * highest priority of anyone waiting on the gate, so just compare this * task's priority against the owner's. */ if (tskPri > Task_getPri(obj->owner)) { Task_setPri(obj->owner, tskPri); } /* Remove tsk from ready list. */ Task_block(tsk); elem.task = tsk; elem.clock = NULL; /* leave a pointer for Task_delete() */ tsk->pendElem = &elem; /* Insert tsk in wait queue in order by priority (high pri at head) */ GateMutexPri_insertPri(pendQ, (Queue_Elem *)&elem, tskPri); /* Task_restore will call the scheduler and this task will block. */ Task_restore(tskKey); tsk->pendElem = NULL; /* * At this point, tsk has the gate. Initialization of the gate is handled * by the previous owner's call to leave. */ return (FIRST_ENTER); }