📄 semmlib.html
字号:
<html><head><!-- /vobs/wpwr/docs/vxworks/ref/semMLib.html - generated by refgen from semMLib.c --> <title> semMLib </title></head><body bgcolor="#FFFFFF"> <hr><a name="top"></a><p align=right><a href="libIndex.htm"><i>VxWorks API Reference : OS Libraries</i></a></p></blockquote><h1>semMLib</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong>semMLib</strong> - mutual-exclusion semaphore library </p></blockquote><h4>ROUTINES</h4><blockquote><p><p><b><a href="./semMLib.html#semMCreate">semMCreate</a>( )</b> - create and initialize a mutual-exclusion semaphore<br><b><a href="./semMLib.html#semMGiveForce">semMGiveForce</a>( )</b> - give a mutual-exclusion semaphore without restrictions<br><p></blockquote><h4>DESCRIPTION</h4><blockquote><p>This library provides the interface to VxWorks mutual-exclusionsemaphores. Mutual-exclusion semaphores offer convenient optionssuited for situations requiring mutually exclusive access to resources.Typical applications include sharing devices and protecting datastructures. Mutual-exclusion semaphores are used by many higher-levelVxWorks facilities.<p>The mutual-exclusion semaphore is a specialized version of the binarysemaphore, designed to address issues inherent in mutual exclusion, suchas recursive access to resources, priority inversion, and deletion safety.The fundamental behavior of the mutual-exclusion semaphore is identicalto the binary semaphore (see the manual entry for <b><a href="./semBLib.html#top">semBLib</a></b>), except forthe following restrictions:<p> - It can only be used for mutual exclusion.<br> - It can only be given by the task that took it.<br> - It may not be taken or given from interrupt level.<br> - The <b><a href="./semLib.html#semFlush">semFlush</a>( )</b> operation is illegal.<p>These last two operations have no meaning in mutual-exclusion situations.<p></blockquote><h4>RECURSIVE RESOURCE ACCESS</h4><blockquote><p>A special feature of the mutual-exclusion semaphore is that it may betaken "recursively," i.e., it can be taken more than once by the task thatowns it before finally being released. Recursion is useful for a set ofroutines that need mutually exclusive access to a resource, but may needto call each other.<p>Recursion is possible because the system keeps track of which taskcurrently owns a mutual-exclusion semaphore. Before being released, amutual-exclusion semaphore taken recursively must be given the same numberof times it has been taken; this is tracked by means of a count which isincremented with each <b><a href="./semLib.html#semTake">semTake</a>( )</b> and decremented with each <b><a href="./semLib.html#semGive">semGive</a>( )</b>.<p>The example below illustrates recursive use of a mutual-exclusion semaphore.Function A requires access to a resource which it acquires by taking <b>semM</b>;function A may also need to call function B, which also requires <b>semM</b>:<pre> SEM_ID semM; semM = semMCreate (...); funcA () { semTake (semM, WAIT_FOREVER); ... funcB (); ... semGive (semM); } funcB () { semTake (semM, WAIT_FOREVER); ... semGive (semM); }</pre></blockquote><h4>PRIORITY-INVERSION SAFETY</h4><blockquote><p>If the option <b>SEM_INVERSION_SAFE</b> is selected, the library adopts apriority-inheritance protocol to resolve potential occurrences of"priority inversion," a problem stemming from the use semaphores formutual exclusion. Priority inversion arises when a higher-priority taskis forced to wait an indefinite period of time for the completion of alower-priority task.<p>Consider the following scenario: T1, T2, and T3 are tasks of high,medium, and low priority, respectively. T3 has acquired some resource bytaking its associated semaphore. When T1 preempts T3 and contends for theresource by taking the same semaphore, it becomes blocked. If we could beassured that T1 would be blocked no longer than the time it normally takesT3 to finish with the resource, the situation would not be problematic.However, the low-priority task is vulnerable to preemption by medium-prioritytasks; a preempting task, T2, could inhibit T3 from relinquishing the resource.This condition could persist, blocking T1 for an indefinite period of time.<p>The priority-inheritance protocol solves the problem of priority inversionby elevating the priority of T3 to the priority of T1 during the time T1 isblocked on T3. This protects T3, and indirectly T1, from preemption by T2.Stated more generally, the priority-inheritance protocol assures thata task which owns a resource will execute at the priority of the highestpriority task blocked on that resource. Once the task priority has beenelevated, it remains at the higher level until all mutual-exclusion semaphoresthat the task owns are released; then the task returns to its normal, or standard, priority. Hence, the "inheriting" task is protected from preemption by any intermediate-priority tasks.<p>The priority-inheritance protocol also takes into consideration a task'sownership of more than one mutual-exclusion semaphore at a time. Such atask will execute at the priority of the highest priority task blocked onany of its owned resources. The task will return to its normal priorityonly after relinquishing all of its mutual-exclusion semaphores that havethe inversion-safety option enabled.<p></blockquote><h4>SEMAPHORE DELETION</h4><blockquote><p>The <b><a href="./semLib.html#semDelete">semDelete</a>( )</b> call terminates a semaphore and deallocates anyassociated memory. The deletion of a semaphore unblocks tasks pendedon that semaphore; the routines which were pended return ERROR. Takespecial care when deleting mutual-exclusion semaphores to avoiddeleting a semaphore out from under a task that already owns (hastaken) that semaphore. Applications should adopt the protocol of onlydeleting semaphores that the deleting task owns.<p></blockquote><h4>TASK-DELETION SAFETY</h4><blockquote><p>If the option <b>SEM_DELETE_SAFE</b> is selected, the task owning the semaphorewill be protected from deletion as long as it owns the semaphore. Thissolves another problem endemic to mutual exclusion. Deleting a taskexecuting in a critical region can be catastrophic. The resource could beleft in a corrupted state and the semaphore guarding the resource would beunavailable, effectively shutting off all access to the resource.<p>As discussed in <b><a href="./taskLib.html#top">taskLib</a></b>, the primitives <b><a href="./taskLib.html#taskSafe">taskSafe</a>( )</b> and <b><a href="./taskLib.html#taskUnsafe">taskUnsafe</a>( )</b>offer one solution, but as this type of protection goes hand in hand withmutual exclusion, the mutual-exclusion semaphore provides the option<b>SEM_DELETE_SAFE</b>, which enables an implicit <b><a href="./taskLib.html#taskSafe">taskSafe</a>( )</b> with each <b><a href="./semLib.html#semTake">semTake</a>( )</b>,and a <b><a href="./taskLib.html#taskUnsafe">taskUnsafe</a>( )</b> with each <b><a href="./semLib.html#semGive">semGive</a>( )</b>. This convenience is also moreefficient, as the resulting code requires fewer entrances to the kernel.<p></blockquote><h4>CAVEATS</h4><blockquote><p>There is no mechanism to give back or reclaim semaphores automatically whentasks are suspended or deleted. Such a mechanism, though desirable, is notcurrently feasible. Without explicit knowledge of the state of the guardedresource or region, reckless automatic reclamation of a semaphore couldleave the resource in a partial state. Thus if a task ceases executionunexpectedly, as with a bus error, currently owned semaphores will not begiven back, effectively leaving a resource permanently unavailable. The<b>SEM_DELETE_SAFE</b> option partially protects an application, to the extentthat unexpected deletions will be deferred until the resource is released.<p>Because the priority of a task which has been elevated by the taking of amutual-exclusion semaphore remains at the higher priority until allmutexes held by that task are released, unbounded priority inversion situationscan result when nested mutexes are involved. If nested mutexes are required,consider the following alternatives:<p><table></tr><tr valign=top><td>1.<td>Avoid overlapping critical regions.</tr><tr valign=top><td>2.<td>Adjust priorities of tasks so that there are no tasks at intermediatepriority levels.</tr><tr valign=top><td>3.<td>Adjust priorities of tasks so that priority inheritance protocol is notneeded.</tr><tr valign=top><td>4.<td>Manually implement a static priority ceiling protocol using a non-inversion-save mutex. This involves setting all blockers on a mutex to the ceiling priority, then taking the mutex. After semGive, set the priorities back to the base priority. Note that this implementation reduces the queue to a fifo queue.</table><p></blockquote><h4>INCLUDE FILES</h4><blockquote><p><b>semLib.h</b><p></blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./semLib.html#top">semLib</a></b>, <b><a href="./semBLib.html#top">semBLib</a></b>, <b><a href="./semCLib.html#top">semCLib</a></b>,<i>VxWorks Programmer's Guide: Basic OS </i><hr><a name="semMCreate"></a><p align=right><a href="rtnIndex.htm"><i>OS Libraries : Routines</i></a></p></blockquote><h1>semMCreate( )</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong>semMCreate( )</strong> - create and initialize a mutual-exclusion semaphore</p></blockquote><h4>SYNOPSIS</h4><blockquote><p><pre>SEM_ID semMCreate ( int options /* mutex semaphore options */ )</pre></blockquote><h4>DESCRIPTION</h4><blockquote><p>This routine allocates and initializes a mutual-exclusion semaphore. Thesemaphore state is initialized to full.<p>Semaphore options include the following:<dl><dt><b>SEM_Q_PRIORITY</b> (0x1)<dd>Queue pended tasks on the basis of their priority.<dt><b>SEM_Q_FIFO</b> (0x0)<dd>Queue pended tasks on a first-in-first-out basis.<dt><b>SEM_DELETE_SAFE</b> (0x4)<dd>Protect a task that owns the semaphore from unexpected deletion. Thisoption enables an implicit <b><a href="./taskLib.html#taskSafe">taskSafe</a>( )</b> for each <b><a href="./semLib.html#semTake">semTake</a>( )</b>, and an implicit<b><a href="./taskLib.html#taskUnsafe">taskUnsafe</a>( )</b> for each <b><a href="./semLib.html#semGive">semGive</a>( )</b>.<dt><b>SEM_INVERSION_SAFE</b> (0x8)<dd>Protect the system from priority inversion. With this option, the taskowning the semaphore will execute at the highest priority of the taskspended on the semaphore, if it is higher than its current priority. Thisoption must be accompanied by the <b>SEM_Q_PRIORITY</b> queuing mode.<dt><b>SEM_EVENTSEND_ERR_NOTIFY</b> (0x10)<dd>When the semaphore is given, if a task is registered for events and theactual sending of events fails, a value of ERROR is returned and the errnois set accordingly. This option is off by default.</dl><p></blockquote><h4>RETURNS</h4><blockquote><p>The semaphore ID, or NULL if the semaphore cannot be created.<p></blockquote><h4>ERRNO</h4><blockquote><p><dl><dt><b>S_semLib_INVALID_OPTION</b><dd>Invalid option was passed to semMCreate.<dt><b>S_memLib_NOT_ENOUGH_MEMORY</b><dd>Not enough memory available to create the semaphore.</dl><p></blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./semMLib.html#top">semMLib</a></b>, <b><a href="./semLib.html#top">semLib</a></b>, <b><a href="./semBLib.html#top">semBLib</a></b>, <b><a href="./taskLib.html#taskSafe">taskSafe</a>( )</b>, <b><a href="./taskLib.html#taskUnsafe">taskUnsafe</a>( )</b><hr><a name="semMGiveForce"></a><p align=right><a href="rtnIndex.htm"><i>OS Libraries : Routines</i></a></p></blockquote><h1>semMGiveForce( )</h1> <blockquote></a></blockquote><h4>NAME</h4><blockquote> <p><strong>semMGiveForce( )</strong> - give a mutual-exclusion semaphore without restrictions</p></blockquote><h4>SYNOPSIS</h4><blockquote><p><pre>STATUS semMGiveForce ( SEM_ID semId /* semaphore ID to give */ )</pre></blockquote><h4>DESCRIPTION</h4><blockquote><p>This routine gives a mutual-exclusion semaphore, regardless of semaphoreownership. It is intended as a debugging aid only.<p>The routine is particularly useful when a task dies while holding somemutual-exclusion semaphore, because the semaphore can be resurrected. Theroutine will give the semaphore to the next task in the pend queue or makethe semaphore full if no tasks are pending. In effect, execution willcontinue as if the task owning the semaphore had actually given thesemaphore.<p></blockquote><h4>CAVEATS</h4><blockquote><p>This routine should be used only as a debugging aid, when the condition ofthe semaphore is known.<p></blockquote><h4>RETURNS</h4><blockquote><p>OK, or ERROR if the semaphore ID is invalid.<p></blockquote><h4>SEE ALSO</h4><blockquote><p><b><a href="./semMLib.html#top">semMLib</a></b>, <b><a href="./semLib.html#semGive">semGive</a>( )</b></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -