【正文】
嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Priority Inheritance Priority inheritance algorithm solves priority inversion problem. Task owning a mutex semaphore is elevated to priority of highest priority task waiting for that semaphore. Enabled on mutex semaphore by specifying the SEM_INVERSION_SAFE option during semMCreat( ). Must also specify SEM_Q_PRIORITY (SEM_Q_FIFO is inpatible with SEM_INVERSION_SAFE). 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Priority Inversion Safety High Priority Medium Priority Low Priority Pended tHigh unblocks tMediumunblocks semTake( ) Pended Pend Ready semTake( ) Critical Region Ready time semGive( ) 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Avoiding Mistakes It is easy to miuse mutex semaphores, since you must protect all accesses to the resource. To prevent such a mistake Write a library of routines to access the resource. Initialization routine creates the semaphore. Routines in this library obtain exclusive access by calling semGIve( ) and semTake( ). All uses of the resource are through this library. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Caveat Deadlocks A deadlock is a race condition associated with the taking of multiple mutex semaphores. Very difficult to detect during testing. INT 6 INT 3 tExcTask tLogTask tEvtTask tWdbTask tNetTask tTaskHi tTaskLow tPortmapd tWvSvc u0 idle semTake(semId1,1) semTake(semId1,1) semTake(semId2,1) semTake(semId2,1) 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Other Caveats Mutual exclusion semaphores can not be used at interrupt time. This issue will be discussed later in the chapter. Keep the critical region (code between semTake( ) and semGive( )) short. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Common Routines Additional semaphore routines : semDelete( ) Destroy the ( ) calls for all tasks pended on the semaphore return ERROR. show( ) Display semaphoreinformation. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Semaphore Br。當(dāng)執(zhí)行完成,任務(wù)釋放該資源并返回到它正常的或標(biāo)準(zhǔn)的優(yōu)先級(jí)。這防止了 T3,間接地防止 T1,被 T2搶占。 ? 互斥信號(hào)量有一個(gè)選項(xiàng)允許實(shí)現(xiàn)優(yōu)先級(jí)繼承的算法。這種情況可能會(huì)持續(xù)阻塞 T1等待一段不可確定的時(shí)間。畢竟資源是不可被搶占的。當(dāng) T1搶占 T3,為競(jìng)爭(zhēng)使用該資源而請(qǐng)求相同的信號(hào)量的時(shí)候,它被阻塞。 ? T1, T2和 T3分別是高、中、低優(yōu)先級(jí)的任務(wù)。當(dāng)被保護(hù)的任務(wù)完成臨界區(qū)操作以后,它將取消刪除保護(hù)以使自己可以被刪除,從而解阻塞刪除任務(wù)。而且,假想任務(wù)沒(méi)有機(jī)會(huì)釋放該資源,那麼現(xiàn)在其他任何任務(wù)現(xiàn)在就不能獲得該資源,資源被凍結(jié)了。 ? 我們?cè)O(shè)想下面的情況:一個(gè)任務(wù)獲得一些數(shù)據(jù)結(jié)構(gòu)的互斥訪問(wèn)權(quán),當(dāng)它正在臨界區(qū)內(nèi)執(zhí)行時(shí)被另一個(gè)任務(wù)刪除。 21 } 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Deletion Safety Deleting a task which owns a semaphore can be catastrophic. data structures left inconsistent. semaphore left permanently unavailable. The deletion safety option prevents a task from being deleted while it owns the semaphore. Enabled for mutex semaphores by specifying the SEM_DELETE_SAFE option during semMCreate( ). 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 安全刪除 ? wind內(nèi)核提供防止任務(wù)被意外刪除的機(jī)制。 19 myBuf[myBufIndex] = ch。 13 } 14 15 void myBufPut (char ch) 16 { 17 semTake(mySemId, WAIT_OREVER)。 /* Index of last data */ 6 LOCAL SEM_ID mySemId。 call semGive() when done. semTake() will block until the semaphore (and hence the resource) bees available. semGive() releases the semaphore (and hence access to the resource). 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Creating Mutual Exclusion Semaphores SEM_ID semMCreate (options) options can be : queue specification SEM_Q_FIFO or SEM_Q_PRIORITY deletion safety SEM_DELETE_SAFE priority inheritance SEM_INVERSION_SAFE Initial state of semaphore is available. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Mutex Ownership A task which takes a mutex semaphore “owns” it, so that no other task can give this semaphore. Mutex semaphores can be taken recursively. The task which owns the semaphore may take it more than once. Must be given same number of times as taken before it will be released. Mutual exclusion semaphores cannot be used in an interrupt service routine. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Taking a Mutex Semaphore owner of Semaphore? task pends until sem is given or timeout another task task continues semTake() returns OK Task bees owner no one task continues semTake() returns OK task ownership count incremented this task 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Giving a Mutex Semaphore ownership count? semaphore made available one semGive() returns ERROR not owner greater than one tasks pended? no decrement ownership count task at head of queue is made ready, bees owner yes 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Code Example Solution 1 include ”” 2 include ” ” 3 4 LOCAL char myBuf[BUF_SIZE]。 7 myBuf [myBufIndex] = ch。 /* store data here */ 2 int myBufIndex = 1。 3. repeat (3, semGive, semId)。 } What would happen in the scenarios below ? 1. repeat (1, semGive, semId)。 } Task may need to wait for an event to occur. Busy waiting (., polling) is inefficient. Pending until the event occurs is better. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 The Synchronization Solution Create a binary semaphore for the event. Full (event has occurred). Binary semaphores exist in one of two states: Empty (event has not occurred). Task waiting for the event calls semTake(), and blocks until semaphore is given. Task or interrupt service routine detecting the event calls semGive(), which unblocks the waiting task. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Binary Semaphores SEM_ID semBCreate (options, intialState) options Sepcify queue type (SEM_Q_PRIORITY or SEM_Q_FIFO) for tasks pended on this semaphore. initialState Initialize semaphore to be available (SEM_FULL) or unavailable (SEM_EMPTY). Semaphores used for synchronization are typically initialized to SEM_EMPTY (event has not occurred). Returns a SEM_ID, or NULL on error. 嵌入式培訓(xùn)專題 微迪軟件培訓(xùn)中心 Taking a Semaphore STATUS semTake (semId, timeout) semId The SEM_ID returned from semBCreate(). timeout Maximum time to wait for semaphore. Value can be clock ticks, WAIT_FOREVER, or NO_WAIT. Can pend the task until either Semaphore left unavaiable.