Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Program C Ansi Programming Embedded Systems in C and C++ phần 7 docx
Nội dung xem thử
Mô tả chi tiết
}
else
{
//
// The mutex is taken. Add the calling task to the waiting list.
//
pCallingTask = os.pRunningTask;
pCallingTask->state = Waiting;
os.readyList.remove(pCallingTask);
waitingList.insert(pCallingTask);
os.schedule(); // Scheduling Point
// When the mutex is released, the caller begins executing here.
}
exitCS(); ////// Critical Section End
} /* take() */
The neatest thing about the take method is that if the mutex is currently held by another task (that is, the binary flag
is already set), the calling task will be suspended until the mutex is released by that other task. This is kind of like
telling your spouse that you are going to take a nap and asking him or her to wake you up when dinner is ready. It is
even possible for multiple tasks to be waiting for the same mutex. In fact, the waiting list associated with each
mutex is ordered by priority, so the highest-priority waiting task will always be awakened first.
The method that comes next is used to release a mutex. Although this method could be called by any task, it is
expected that only a task that previously called take would invoke it. Unlike take, this routine will never block.
However, one possible result of releasing the mutex could be to wake a task of higher priority. In that case, the
releasing task would immediately be forced (by the scheduler) to give up control of the processor, in favor of the
higher-priority task.
/**********************************************************************
*
* Method: release()
*
* Description: Release a mutex that is held by the calling task.
*
* Notes:
*
* Returns: None defined.
*
**********************************************************************/
void
Mutex::release(void)
{
Task * pWaitingTask;
enterCS(); ////// Critical Section Begins
if (state == Held)
{
pWaitingTask = waitingList.pTop;
if (pWaitingTask != NULL)
{
//
// Wake the first task on the waiting list.
//
waitingList.pTop = pWaitingTask->pNext;
pWaitingTask->state = Ready;
os.readyList.insert(pWaitingTask);