OS_RESULT os_mut_wait (OS_ID mutex, U16 timeout) { /* Wait for a mutex, continue when mutex is free. */ P_MUCB p_MCB = mutex; tsk_lock(); if (p_MCB->level == 0) { p_MCB->owner = os_runtask; p_MCB->prio = os_runtask->prio; goto inc; } if (p_MCB->owner == os_runtask) { /* OK, running task is the owner of this mutex. */ inc:p_MCB->level++; tsk_unlock(); return (OS_R_OK); } /* Mutex owned by another task, wait until released. */ if (timeout == 0) { goto rto; } /* Raise the owner task priority if lower than current priority. */ /* This priority inversion is called priority inheritance. */ if (p_MCB->prio < os_runtask->prio) { p_MCB->owner->prio = os_runtask->prio; os_resort_prio (p_MCB->owner); } if (p_MCB->p_lnk != NULL) { os_put_prio ((P_XCB)p_MCB, os_runtask); } else { p_MCB->p_lnk = os_runtask; os_runtask->p_lnk = NULL; os_runtask->p_rlnk = (P_TCB)p_MCB; } if (os_block(timeout, WAIT_MUT) == OS_R_TMO) { rto:tsk_unlock(); return (OS_R_TMO); } /* A mutex has been released. */ tsk_unlock(); return (OS_R_MUT); }
OS_RESULT os_tsk_prio (OS_TID task_id, U8 new_prio) { /* Change execution priority of a task to "new_prio". */ P_TCB p_task; tsk_lock(); if (task_id == 0) { /* Change execution priority of calling task. */ os_runtask->prio = new_prio; os_runtask->prio_base = new_prio; run:if (os_rdy_prio() > new_prio) { os_put_prio (&os_rdy, os_runtask); os_runtask->state = READY; os_dispatch (NULL); } tsk_unlock(); return (OS_R_OK); } /* Find the task in the "os_active_TCB" array. */ if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { /* Task with "task_id" not found or not started. */ tsk_unlock (); return (OS_R_NOK); } p_task = os_active_TCB[task_id-1]; p_task->prio = new_prio; p_task->prio_base = new_prio; if (p_task == os_runtask) { goto run; } os_resort_prio (p_task); if (p_task->state == READY) { /* Task enqueued in a ready list. */ p_task = os_get_first (&os_rdy); os_dispatch (p_task); } tsk_unlock (); return (OS_R_OK); }