[ae68ff0] | 1 | @c |
---|
[4ffbc49] | 2 | @c COPYRIGHT (c) 1988-2007. |
---|
[ae68ff0] | 3 | @c On-Line Applications Research Corporation (OAR). |
---|
| 4 | @c All rights reserved. |
---|
| 5 | |
---|
| 6 | @chapter Semaphore Manager |
---|
[20515fc] | 7 | |
---|
[169502e] | 8 | @cindex semaphores |
---|
| 9 | @cindex binary semaphores |
---|
| 10 | @cindex counting semaphores |
---|
| 11 | @cindex mutual exclusion |
---|
| 12 | |
---|
[ae68ff0] | 13 | @section Introduction |
---|
| 14 | |
---|
| 15 | The semaphore manager utilizes standard Dijkstra |
---|
| 16 | counting semaphores to provide synchronization and mutual |
---|
| 17 | exclusion capabilities. The directives provided by the |
---|
| 18 | semaphore manager are: |
---|
| 19 | |
---|
| 20 | @itemize @bullet |
---|
[880e2f37] | 21 | @item @code{@value{DIRPREFIX}semaphore_create} - Create a semaphore |
---|
[f331481c] | 22 | @item @code{@value{DIRPREFIX}semaphore_ident} - Get ID of a semaphore |
---|
| 23 | @item @code{@value{DIRPREFIX}semaphore_delete} - Delete a semaphore |
---|
| 24 | @item @code{@value{DIRPREFIX}semaphore_obtain} - Acquire a semaphore |
---|
| 25 | @item @code{@value{DIRPREFIX}semaphore_release} - Release a semaphore |
---|
[5a69fe3] | 26 | @item @code{@value{DIRPREFIX}semaphore_flush} - Unblock all tasks waiting on a semaphore |
---|
[8fcafdd5] | 27 | @item @code{@value{DIRPREFIX}semaphore_set_priority} - Set priority by |
---|
| 28 | scheduler for a semaphore |
---|
[ae68ff0] | 29 | @end itemize |
---|
| 30 | |
---|
| 31 | @section Background |
---|
| 32 | |
---|
| 33 | A semaphore can be viewed as a protected variable |
---|
[75e22db] | 34 | whose value can be modified only with the |
---|
| 35 | @code{@value{DIRPREFIX}semaphore_create}, |
---|
| 36 | @code{@value{DIRPREFIX}semaphore_obtain}, and |
---|
| 37 | @code{@value{DIRPREFIX}semaphore_release} directives. RTEMS |
---|
[ae68ff0] | 38 | supports both binary and counting semaphores. A binary semaphore |
---|
| 39 | is restricted to values of zero or one, while a counting |
---|
| 40 | semaphore can assume any non-negative integer value. |
---|
| 41 | |
---|
| 42 | A binary semaphore can be used to control access to a |
---|
| 43 | single resource. In particular, it can be used to enforce |
---|
| 44 | mutual exclusion for a critical section in user code. In this |
---|
| 45 | instance, the semaphore would be created with an initial count |
---|
| 46 | of one to indicate that no task is executing the critical |
---|
| 47 | section of code. Upon entry to the critical section, a task |
---|
[75e22db] | 48 | must issue the @code{@value{DIRPREFIX}semaphore_obtain} |
---|
| 49 | directive to prevent other tasks from entering the critical section. |
---|
| 50 | Upon exit from the critical section, the task must issue the |
---|
| 51 | @code{@value{DIRPREFIX}semaphore_release} directive to |
---|
[ae68ff0] | 52 | allow another task to execute the critical section. |
---|
| 53 | |
---|
| 54 | A counting semaphore can be used to control access to |
---|
| 55 | a pool of two or more resources. For example, access to three |
---|
| 56 | printers could be administered by a semaphore created with an |
---|
| 57 | initial count of three. When a task requires access to one of |
---|
[75e22db] | 58 | the printers, it issues the @code{@value{DIRPREFIX}semaphore_obtain} |
---|
| 59 | directive to obtain access to a printer. If a printer is not currently |
---|
| 60 | available, the task can wait for a printer to become available or return |
---|
[ae68ff0] | 61 | immediately. When the task has completed printing, it should |
---|
[75e22db] | 62 | issue the @code{@value{DIRPREFIX}semaphore_release} |
---|
| 63 | directive to allow other tasks access to the printer. |
---|
[ae68ff0] | 64 | |
---|
| 65 | Task synchronization may be achieved by creating a |
---|
| 66 | semaphore with an initial count of zero. One task waits for the |
---|
[75e22db] | 67 | arrival of another task by issuing a @code{@value{DIRPREFIX}semaphore_obtain} |
---|
| 68 | directive when it reaches a synchronization point. The other task |
---|
| 69 | performs a corresponding @code{@value{DIRPREFIX}semaphore_release} |
---|
| 70 | operation when it reaches its synchronization point, thus unblocking |
---|
| 71 | the pending task. |
---|
[ae68ff0] | 72 | |
---|
| 73 | @subsection Nested Resource Access |
---|
| 74 | |
---|
| 75 | Deadlock occurs when a task owning a binary semaphore |
---|
| 76 | attempts to acquire that same semaphore and blocks as result. |
---|
| 77 | Since the semaphore is allocated to a task, it cannot be |
---|
| 78 | deleted. Therefore, the task that currently holds the semaphore |
---|
| 79 | and is also blocked waiting for that semaphore will never |
---|
| 80 | execute again. |
---|
| 81 | |
---|
| 82 | RTEMS addresses this problem by allowing the task |
---|
| 83 | holding the binary semaphore to obtain the same binary semaphore |
---|
[75e22db] | 84 | multiple times in a nested manner. Each |
---|
| 85 | @code{@value{DIRPREFIX}semaphore_obtain} must be accompanied with a |
---|
| 86 | @code{@value{DIRPREFIX}semaphore_release}. The semaphore will |
---|
[ae68ff0] | 87 | only be made available for acquisition by other tasks when the |
---|
[75e22db] | 88 | outermost @code{@value{DIRPREFIX}semaphore_obtain} is matched with |
---|
| 89 | a @code{@value{DIRPREFIX}semaphore_release}. |
---|
[ae68ff0] | 90 | |
---|
[edc1347e] | 91 | Simple binary semaphores do not allow nested access and so can be used for task synchronization. |
---|
| 92 | |
---|
[ae68ff0] | 93 | |
---|
| 94 | @subsection Priority Inversion |
---|
| 95 | |
---|
| 96 | Priority inversion is a form of indefinite |
---|
| 97 | postponement which is common in multitasking, preemptive |
---|
| 98 | executives with shared resources. Priority inversion occurs |
---|
| 99 | when a high priority tasks requests access to shared resource |
---|
| 100 | which is currently allocated to low priority task. The high |
---|
| 101 | priority task must block until the low priority task releases |
---|
| 102 | the resource. This problem is exacerbated when the low priority |
---|
| 103 | task is prevented from executing by one or more medium priority |
---|
| 104 | tasks. Because the low priority task is not executing, it |
---|
| 105 | cannot complete its interaction with the resource and release |
---|
| 106 | that resource. The high priority task is effectively prevented |
---|
| 107 | from executing by lower priority tasks. |
---|
| 108 | |
---|
| 109 | @subsection Priority Inheritance |
---|
| 110 | |
---|
| 111 | Priority inheritance is an algorithm that calls for |
---|
| 112 | the lower priority task holding a resource to have its priority |
---|
| 113 | increased to that of the highest priority task blocked waiting |
---|
| 114 | for that resource. Each time a task blocks attempting to obtain |
---|
| 115 | the resource, the task holding the resource may have its |
---|
| 116 | priority increased. |
---|
| 117 | |
---|
[dafa5d88] | 118 | On SMP configurations, in case the task holding the resource and the task that |
---|
| 119 | blocks attempting to obtain the resource are in different scheduler instances, |
---|
| 120 | the priority of the holder is raised to the pseudo-interrupt priority (priority |
---|
| 121 | boosting). The pseudo-interrupt priority is the highest priority. |
---|
| 122 | |
---|
[ae68ff0] | 123 | RTEMS supports priority inheritance for local, binary |
---|
| 124 | semaphores that use the priority task wait queue blocking |
---|
| 125 | discipline. When a task of higher priority than the task |
---|
| 126 | holding the semaphore blocks, the priority of the task holding |
---|
| 127 | the semaphore is increased to that of the blocking task. When |
---|
| 128 | the task holding the task completely releases the binary |
---|
| 129 | semaphore (i.e. not for a nested release), the holder's priority |
---|
| 130 | is restored to the value it had before any higher priority was |
---|
| 131 | inherited. |
---|
| 132 | |
---|
| 133 | The RTEMS implementation of the priority inheritance |
---|
| 134 | algorithm takes into account the scenario in which a task holds |
---|
| 135 | more than one binary semaphore. The holding task will execute |
---|
| 136 | at the priority of the higher of the highest ceiling priority or |
---|
| 137 | at the priority of the highest priority task blocked waiting for |
---|
| 138 | any of the semaphores the task holds. Only when the task |
---|
| 139 | releases ALL of the binary semaphores it holds will its priority |
---|
| 140 | be restored to the normal value. |
---|
| 141 | |
---|
| 142 | @subsection Priority Ceiling |
---|
| 143 | |
---|
| 144 | Priority ceiling is an algorithm that calls for the |
---|
| 145 | lower priority task holding a resource to have its priority |
---|
| 146 | increased to that of the highest priority task which will EVER |
---|
| 147 | block waiting for that resource. This algorithm addresses the |
---|
| 148 | problem of priority inversion although it avoids the possibility |
---|
| 149 | of changing the priority of the task holding the resource |
---|
| 150 | multiple times. The priority ceiling algorithm will only change |
---|
| 151 | the priority of the task holding the resource a maximum of one |
---|
| 152 | time. The ceiling priority is set at creation time and must be |
---|
| 153 | the priority of the highest priority task which will ever |
---|
| 154 | attempt to acquire that semaphore. |
---|
| 155 | |
---|
| 156 | RTEMS supports priority ceiling for local, binary |
---|
| 157 | semaphores that use the priority task wait queue blocking |
---|
| 158 | discipline. When a task of lower priority than the ceiling |
---|
| 159 | priority successfully obtains the semaphore, its priority is |
---|
| 160 | raised to the ceiling priority. When the task holding the task |
---|
| 161 | completely releases the binary semaphore (i.e. not for a nested |
---|
| 162 | release), the holder's priority is restored to the value it had |
---|
| 163 | before any higher priority was put into effect. |
---|
| 164 | |
---|
| 165 | The need to identify the highest priority task which |
---|
| 166 | will attempt to obtain a particular semaphore can be a difficult |
---|
| 167 | task in a large, complicated system. Although the priority |
---|
| 168 | ceiling algorithm is more efficient than the priority |
---|
| 169 | inheritance algorithm with respect to the maximum number of task |
---|
| 170 | priority changes which may occur while a task holds a particular |
---|
| 171 | semaphore, the priority inheritance algorithm is more forgiving |
---|
| 172 | in that it does not require this apriori information. |
---|
| 173 | |
---|
| 174 | The RTEMS implementation of the priority ceiling |
---|
| 175 | algorithm takes into account the scenario in which a task holds |
---|
| 176 | more than one binary semaphore. The holding task will execute |
---|
| 177 | at the priority of the higher of the highest ceiling priority or |
---|
| 178 | at the priority of the highest priority task blocked waiting for |
---|
| 179 | any of the semaphores the task holds. Only when the task |
---|
| 180 | releases ALL of the binary semaphores it holds will its priority |
---|
| 181 | be restored to the normal value. |
---|
| 182 | |
---|
[8fcafdd5] | 183 | @subsection Multiprocessor Resource Sharing Protocol |
---|
| 184 | |
---|
| 185 | The Multiprocessor Resource Sharing Protocol (MrsP) is defined in @cite{A. |
---|
| 186 | Burns and A.J. Wellings, A Schedulability Compatible Multiprocessor Resource |
---|
| 187 | Sharing Protocol - MrsP, Proceedings of the 25th Euromicro Conference on |
---|
| 188 | Real-Time Systems (ECRTS 2013), July 2013}. It is a generalization of the |
---|
| 189 | Priority Ceiling Protocol to SMP systems. Each MrsP semaphore uses a ceiling |
---|
| 190 | priority per scheduler instance. These ceiling priorities can be specified |
---|
| 191 | with @code{rtems_semaphore_set_priority()}. A task obtaining or owning a MrsP |
---|
| 192 | semaphore will execute with the ceiling priority for its scheduler instance as |
---|
| 193 | specified by the MrsP semaphore object. Tasks waiting to get ownership of a |
---|
| 194 | MrsP semaphore will not relinquish the processor voluntarily. In case the |
---|
| 195 | owner of a MrsP semaphore gets preempted it can ask all tasks waiting for this |
---|
| 196 | semaphore to help out and temporarily borrow the right to execute on one of |
---|
| 197 | their assigned processors. |
---|
| 198 | |
---|
[ed11cadf] | 199 | @subsection Building a Semaphore Attribute Set |
---|
[ae68ff0] | 200 | |
---|
| 201 | In general, an attribute set is built by a bitwise OR |
---|
| 202 | of the desired attribute components. The following table lists |
---|
| 203 | the set of valid semaphore attributes: |
---|
| 204 | |
---|
| 205 | @itemize @bullet |
---|
[75e22db] | 206 | @item @code{@value{RPREFIX}FIFO} - tasks wait by FIFO (default) |
---|
| 207 | |
---|
| 208 | @item @code{@value{RPREFIX}PRIORITY} - tasks wait by priority |
---|
| 209 | |
---|
| 210 | @item @code{@value{RPREFIX}BINARY_SEMAPHORE} - restrict values to |
---|
[3d4d5ee] | 211 | 0 and 1 |
---|
[75e22db] | 212 | |
---|
| 213 | @item @code{@value{RPREFIX}COUNTING_SEMAPHORE} - no restriction on values |
---|
[3d4d5ee] | 214 | (default) |
---|
[75e22db] | 215 | |
---|
[edc1347e] | 216 | @item @code{@value{RPREFIX}SIMPLE_BINARY_SEMAPHORE} - restrict values to |
---|
[bb4b574] | 217 | 0 and 1, do not allow nested access, allow deletion of locked semaphore. |
---|
[edc1347e] | 218 | |
---|
[75e22db] | 219 | @item @code{@value{RPREFIX}NO_INHERIT_PRIORITY} - do not use priority |
---|
| 220 | inheritance (default) |
---|
| 221 | |
---|
| 222 | @item @code{@value{RPREFIX}INHERIT_PRIORITY} - use priority inheritance |
---|
| 223 | |
---|
| 224 | @item @code{@value{RPREFIX}NO_PRIORITY_CEILING} - do not use priority |
---|
| 225 | ceiling (default) |
---|
| 226 | |
---|
[8fcafdd5] | 227 | @item @code{@value{RPREFIX}PRIORITY_CEILING} - use priority ceiling |
---|
| 228 | |
---|
| 229 | @item @code{@value{RPREFIX}NO_MULTIPROCESSOR_RESOURCE_SHARING} - do not use |
---|
| 230 | Multiprocessor Resource Sharing Protocol (default) |
---|
| 231 | |
---|
| 232 | @item @code{@value{RPREFIX}MULTIPROCESSOR_RESOURCE_SHARING} - use |
---|
| 233 | Multiprocessor Resource Sharing Protocol |
---|
| 234 | |
---|
[593fb9e] | 235 | @item @code{@value{RPREFIX}LOCAL} - local semaphore (default) |
---|
[75e22db] | 236 | |
---|
[593fb9e] | 237 | @item @code{@value{RPREFIX}GLOBAL} - global semaphore |
---|
[ae68ff0] | 238 | @end itemize |
---|
| 239 | |
---|
| 240 | Attribute values are specifically designed to be |
---|
| 241 | mutually exclusive, therefore bitwise OR and addition operations |
---|
| 242 | are equivalent as long as each attribute appears exactly once in |
---|
| 243 | the component list. An attribute listed as a default is not |
---|
| 244 | required to appear in the attribute list, although it is a good |
---|
| 245 | programming practice to specify default attributes. If all |
---|
[75e22db] | 246 | defaults are desired, the attribute |
---|
| 247 | @code{@value{RPREFIX}DEFAULT_ATTRIBUTES} should be |
---|
[ae68ff0] | 248 | specified on this call. |
---|
| 249 | |
---|
[169502e] | 250 | This example demonstrates the attribute_set parameter needed to create a |
---|
| 251 | local semaphore with the task priority waiting queue discipline. The |
---|
| 252 | attribute_set parameter passed to the |
---|
| 253 | @code{@value{DIRPREFIX}semaphore_create} directive could be either |
---|
| 254 | @code{@value{RPREFIX}PRIORITY} or @code{@value{RPREFIX}LOCAL @value{OR} |
---|
| 255 | @value{RPREFIX}PRIORITY}. The attribute_set parameter can be set to |
---|
| 256 | @code{@value{RPREFIX}PRIORITY} because @code{@value{RPREFIX}LOCAL} is the |
---|
| 257 | default for all created tasks. If a similar semaphore were to be known |
---|
| 258 | globally, then the attribute_set parameter would be |
---|
[a3a7527] | 259 | @code{@value{RPREFIX}GLOBAL @value{OR} @value{RPREFIX}PRIORITY}. |
---|
[ae68ff0] | 260 | |
---|
[bd861cc6] | 261 | Some combinatinos of these attributes are invalid. For example, priority |
---|
| 262 | ordered blocking discipline must be applied to a binary semaphore in order |
---|
| 263 | to use either the priority inheritance or priority ceiling functionality. |
---|
| 264 | The following tree figure illustrates the valid combinations. |
---|
| 265 | |
---|
| 266 | @float Figure,fig:semaphore-attributes |
---|
| 267 | @caption{Valid Semaphore Attributes Combinations} |
---|
| 268 | |
---|
| 269 | @ifset use-ascii |
---|
| 270 | @example |
---|
| 271 | @group |
---|
| 272 | Not available in ASCII representation |
---|
| 273 | @end group |
---|
| 274 | @end example |
---|
| 275 | @end ifset |
---|
| 276 | |
---|
| 277 | @ifset use-tex |
---|
| 278 | @example |
---|
| 279 | @image{semaphore_attributes,5in,3.5in} |
---|
| 280 | @end example |
---|
| 281 | @end ifset |
---|
| 282 | |
---|
| 283 | @ifset use-html |
---|
| 284 | @html |
---|
| 285 | <IMG SRC="semaphore_attributes.png" WIDTH=550 HEIGHT=400 ALT="Valid Semaphore Attribute Combinations"> |
---|
| 286 | @end html |
---|
| 287 | @end ifset |
---|
| 288 | @end float |
---|
| 289 | |
---|
[ae68ff0] | 290 | @subsection Building a SEMAPHORE_OBTAIN Option Set |
---|
| 291 | |
---|
| 292 | In general, an option is built by a bitwise OR of the |
---|
| 293 | desired option components. The set of valid options for the |
---|
[75e22db] | 294 | @code{@value{DIRPREFIX}semaphore_obtain} directive are listed |
---|
| 295 | in the following table: |
---|
[ae68ff0] | 296 | |
---|
| 297 | @itemize @bullet |
---|
[f331481c] | 298 | @item @code{@value{RPREFIX}WAIT} - task will wait for semaphore (default) |
---|
| 299 | @item @code{@value{RPREFIX}NO_WAIT} - task should not wait |
---|
[ae68ff0] | 300 | @end itemize |
---|
| 301 | |
---|
[169502e] | 302 | Option values are specifically designed to be mutually exclusive, |
---|
| 303 | therefore bitwise OR and addition operations are equivalent as long as |
---|
| 304 | each attribute appears exactly once in the component list. An option |
---|
| 305 | listed as a default is not required to appear in the list, although it is |
---|
| 306 | a good programming practice to specify default options. If all defaults |
---|
| 307 | are desired, the option @code{@value{RPREFIX}DEFAULT_OPTIONS} should be |
---|
[ae68ff0] | 308 | specified on this call. |
---|
| 309 | |
---|
| 310 | This example demonstrates the option parameter needed |
---|
| 311 | to poll for a semaphore. The option parameter passed to the |
---|
[75e22db] | 312 | @code{@value{DIRPREFIX}semaphore_obtain} |
---|
| 313 | directive should be @code{@value{RPREFIX}NO_WAIT}. |
---|
[ae68ff0] | 314 | |
---|
| 315 | @section Operations |
---|
[20515fc] | 316 | |
---|
[ae68ff0] | 317 | @subsection Creating a Semaphore |
---|
| 318 | |
---|
[75e22db] | 319 | The @code{@value{DIRPREFIX}semaphore_create} directive creates a binary or |
---|
[ae68ff0] | 320 | counting semaphore with a user-specified name as well as an |
---|
| 321 | initial count. If a binary semaphore is created with a count of |
---|
| 322 | zero (0) to indicate that it has been allocated, then the task |
---|
| 323 | creating the semaphore is considered the current holder of the |
---|
| 324 | semaphore. At create time the method for ordering waiting tasks |
---|
| 325 | in the semaphore's task wait queue (by FIFO or task priority) is |
---|
| 326 | specified. Additionally, the priority inheritance or priority |
---|
| 327 | ceiling algorithm may be selected for local, binary semaphores |
---|
| 328 | that use the priority task wait queue blocking discipline. If |
---|
| 329 | the priority ceiling algorithm is selected, then the highest |
---|
| 330 | priority of any task which will attempt to obtain this semaphore |
---|
| 331 | must be specified. RTEMS allocates a Semaphore Control Block |
---|
| 332 | (SMCB) from the SMCB free list. This data structure is used by |
---|
| 333 | RTEMS to manage the newly created semaphore. Also, a unique |
---|
| 334 | semaphore ID is generated and returned to the calling task. |
---|
| 335 | |
---|
| 336 | @subsection Obtaining Semaphore IDs |
---|
| 337 | |
---|
| 338 | When a semaphore is created, RTEMS generates a unique |
---|
| 339 | semaphore ID and assigns it to the created semaphore until it is |
---|
| 340 | deleted. The semaphore ID may be obtained by either of two |
---|
| 341 | methods. First, as the result of an invocation of the |
---|
[75e22db] | 342 | @code{@value{DIRPREFIX}semaphore_create} directive, the |
---|
| 343 | semaphore ID is stored in a user provided location. Second, |
---|
| 344 | the semaphore ID may be obtained later using the |
---|
| 345 | @code{@value{DIRPREFIX}semaphore_ident} directive. The semaphore ID is |
---|
[ae68ff0] | 346 | used by other semaphore manager directives to access this |
---|
| 347 | semaphore. |
---|
| 348 | |
---|
| 349 | @subsection Acquiring a Semaphore |
---|
| 350 | |
---|
[75e22db] | 351 | The @code{@value{DIRPREFIX}semaphore_obtain} directive is used to acquire the |
---|
[ae68ff0] | 352 | specified semaphore. A simplified version of the |
---|
[75e22db] | 353 | @code{@value{DIRPREFIX}semaphore_obtain} directive can be described as follows: |
---|
[ae68ff0] | 354 | |
---|
| 355 | @example |
---|
| 356 | if semaphore's count is greater than zero |
---|
| 357 | then decrement semaphore's count |
---|
| 358 | else wait for release of semaphore |
---|
| 359 | |
---|
| 360 | return SUCCESSFUL |
---|
| 361 | @end example |
---|
| 362 | |
---|
| 363 | When the semaphore cannot be immediately acquired, |
---|
| 364 | one of the following situations applies: |
---|
| 365 | |
---|
| 366 | @itemize @bullet |
---|
| 367 | @item By default, the calling task will wait forever to |
---|
| 368 | acquire the semaphore. |
---|
| 369 | |
---|
[169502e] | 370 | @item Specifying @code{@value{RPREFIX}NO_WAIT} forces an immediate return |
---|
| 371 | with an error status code. |
---|
[ae68ff0] | 372 | |
---|
| 373 | @item Specifying a timeout limits the interval the task will |
---|
| 374 | wait before returning with an error status code. |
---|
| 375 | @end itemize |
---|
| 376 | |
---|
| 377 | If the task waits to acquire the semaphore, then it |
---|
| 378 | is placed in the semaphore's task wait queue in either FIFO or |
---|
| 379 | task priority order. If the task blocked waiting for a binary |
---|
| 380 | semaphore using priority inheritance and the task's priority is |
---|
| 381 | greater than that of the task currently holding the semaphore, |
---|
| 382 | then the holding task will inherit the priority of the blocking |
---|
| 383 | task. All tasks waiting on a semaphore are returned an error |
---|
| 384 | code when the semaphore is deleted. |
---|
| 385 | |
---|
| 386 | When a task successfully obtains a semaphore using |
---|
| 387 | priority ceiling and the priority ceiling for this semaphore is |
---|
| 388 | greater than that of the holder, then the holder's priority will |
---|
| 389 | be elevated. |
---|
| 390 | |
---|
| 391 | @subsection Releasing a Semaphore |
---|
| 392 | |
---|
[75e22db] | 393 | The @code{@value{DIRPREFIX}semaphore_release} directive is used to release |
---|
[ae68ff0] | 394 | the specified semaphore. A simplified version of the |
---|
[169502e] | 395 | @code{@value{DIRPREFIX}semaphore_release} directive can be described as |
---|
| 396 | follows: |
---|
[ae68ff0] | 397 | |
---|
| 398 | @example |
---|
| 399 | if no tasks are waiting on this semaphore |
---|
| 400 | then increment semaphore's count |
---|
| 401 | else assign semaphore to a waiting task |
---|
| 402 | |
---|
| 403 | return SUCCESSFUL |
---|
| 404 | @end example |
---|
| 405 | |
---|
| 406 | If this is the outermost release of a binary |
---|
| 407 | semaphore that uses priority inheritance or priority ceiling and |
---|
| 408 | the task does not currently hold any other binary semaphores, |
---|
[75e22db] | 409 | then the task performing the @code{@value{DIRPREFIX}semaphore_release} |
---|
| 410 | will have its priority restored to its normal value. |
---|
[ae68ff0] | 411 | |
---|
| 412 | @subsection Deleting a Semaphore |
---|
| 413 | |
---|
[75e22db] | 414 | The @code{@value{DIRPREFIX}semaphore_delete} directive removes a semaphore |
---|
[ae68ff0] | 415 | from the system and frees its control block. A semaphore can be |
---|
| 416 | deleted by any local task that knows the semaphore's ID. As a |
---|
| 417 | result of this directive, all tasks blocked waiting to acquire |
---|
| 418 | the semaphore will be readied and returned a status code which |
---|
| 419 | indicates that the semaphore was deleted. Any subsequent |
---|
| 420 | references to the semaphore's name and ID are invalid. |
---|
| 421 | |
---|
| 422 | @section Directives |
---|
| 423 | |
---|
| 424 | This section details the semaphore manager's |
---|
| 425 | directives. A subsection is dedicated to each of this manager's |
---|
| 426 | directives and describes the calling sequence, related |
---|
| 427 | constants, usage, and status codes. |
---|
| 428 | |
---|
[169502e] | 429 | @c |
---|
| 430 | @c |
---|
| 431 | @c |
---|
[ae68ff0] | 432 | @page |
---|
| 433 | @subsection SEMAPHORE_CREATE - Create a semaphore |
---|
| 434 | |
---|
[169502e] | 435 | @cindex create a semaphore |
---|
| 436 | |
---|
[ae68ff0] | 437 | @subheading CALLING SEQUENCE: |
---|
| 438 | |
---|
[61389eac] | 439 | @ifset is-C |
---|
[169502e] | 440 | @findex rtems_semaphore_create |
---|
[ae68ff0] | 441 | @example |
---|
| 442 | rtems_status_code rtems_semaphore_create( |
---|
| 443 | rtems_name name, |
---|
[ae10dbd] | 444 | uint32_t count, |
---|
[ae68ff0] | 445 | rtems_attribute attribute_set, |
---|
| 446 | rtems_task_priority priority_ceiling, |
---|
| 447 | rtems_id *id |
---|
| 448 | ); |
---|
| 449 | @end example |
---|
[61389eac] | 450 | @end ifset |
---|
| 451 | |
---|
| 452 | @ifset is-Ada |
---|
| 453 | @example |
---|
| 454 | procedure Semaphore_Create ( |
---|
[4ffbc49] | 455 | Name : in RTEMS.Name; |
---|
| 456 | Count : in RTEMS.Unsigned32; |
---|
| 457 | Attribute_Set : in RTEMS.Attribute; |
---|
| 458 | Priority_Ceiling : in RTEMS.Task_Priority; |
---|
| 459 | ID : out RTEMS.ID; |
---|
| 460 | Result : out RTEMS.Status_Codes |
---|
[61389eac] | 461 | ); |
---|
| 462 | @end example |
---|
| 463 | @end ifset |
---|
[ae68ff0] | 464 | |
---|
| 465 | @subheading DIRECTIVE STATUS CODES: |
---|
[f331481c] | 466 | @code{@value{RPREFIX}SUCCESSFUL} - semaphore created successfully@* |
---|
[4dc6a46] | 467 | @code{@value{RPREFIX}INVALID_NAME} - invalid semaphore name@* |
---|
[f8892c9] | 468 | @code{@value{RPREFIX}INVALID_ADDRESS} - @code{id} is NULL@* |
---|
[f331481c] | 469 | @code{@value{RPREFIX}TOO_MANY} - too many semaphores created@* |
---|
| 470 | @code{@value{RPREFIX}NOT_DEFINED} - invalid attribute set@* |
---|
| 471 | @code{@value{RPREFIX}INVALID_NUMBER} - invalid starting count for binary semaphore@* |
---|
| 472 | @code{@value{RPREFIX}MP_NOT_CONFIGURED} - multiprocessing not configured@* |
---|
| 473 | @code{@value{RPREFIX}TOO_MANY} - too many global objects |
---|
[ae68ff0] | 474 | |
---|
| 475 | @subheading DESCRIPTION: |
---|
| 476 | |
---|
| 477 | This directive creates a semaphore which resides on |
---|
| 478 | the local node. The created semaphore has the user-defined name |
---|
| 479 | specified in name and the initial count specified in count. For |
---|
| 480 | control and maintenance of the semaphore, RTEMS allocates and |
---|
| 481 | initializes a SMCB. The RTEMS-assigned semaphore id is returned |
---|
| 482 | in id. This semaphore id is used with other semaphore related |
---|
| 483 | directives to access the semaphore. |
---|
| 484 | |
---|
| 485 | Specifying PRIORITY in attribute_set causes tasks |
---|
| 486 | waiting for a semaphore to be serviced according to task |
---|
| 487 | priority. When FIFO is selected, tasks are serviced in First |
---|
| 488 | In-First Out order. |
---|
| 489 | |
---|
| 490 | @subheading NOTES: |
---|
| 491 | |
---|
| 492 | This directive will not cause the calling task to be |
---|
| 493 | preempted. |
---|
| 494 | |
---|
| 495 | The priority inheritance and priority ceiling |
---|
| 496 | algorithms are only supported for local, binary semaphores that |
---|
| 497 | use the priority task wait queue blocking discipline. |
---|
| 498 | |
---|
| 499 | The following semaphore attribute constants are |
---|
| 500 | defined by RTEMS: |
---|
| 501 | |
---|
| 502 | @itemize @bullet |
---|
[75e22db] | 503 | @item @code{@value{RPREFIX}FIFO} - tasks wait by FIFO (default) |
---|
| 504 | |
---|
| 505 | @item @code{@value{RPREFIX}PRIORITY} - tasks wait by priority |
---|
| 506 | |
---|
| 507 | @item @code{@value{RPREFIX}BINARY_SEMAPHORE} - restrict values to |
---|
[3d4d5ee] | 508 | 0 and 1 |
---|
[75e22db] | 509 | |
---|
| 510 | @item @code{@value{RPREFIX}COUNTING_SEMAPHORE} - no restriction on values |
---|
[3d4d5ee] | 511 | (default) |
---|
[75e22db] | 512 | |
---|
[edc1347e] | 513 | @item @code{@value{RPREFIX}SIMPLE_BINARY_SEMAPHORE} - restrict values to |
---|
[bb4b574] | 514 | 0 and 1, block on nested access, allow deletion of locked semaphore. |
---|
[edc1347e] | 515 | |
---|
[75e22db] | 516 | @item @code{@value{RPREFIX}NO_INHERIT_PRIORITY} - do not use priority |
---|
| 517 | inheritance (default) |
---|
| 518 | |
---|
| 519 | @item @code{@value{RPREFIX}INHERIT_PRIORITY} - use priority inheritance |
---|
| 520 | |
---|
| 521 | @item @code{@value{RPREFIX}NO_PRIORITY_CEILING} - do not use priority |
---|
| 522 | ceiling (default) |
---|
| 523 | |
---|
[8fcafdd5] | 524 | @item @code{@value{RPREFIX}PRIORITY_CEILING} - use priority ceiling |
---|
| 525 | |
---|
| 526 | @item @code{@value{RPREFIX}NO_MULTIPROCESSOR_RESOURCE_SHARING} - do not use |
---|
| 527 | Multiprocessor Resource Sharing Protocol (default) |
---|
| 528 | |
---|
| 529 | @item @code{@value{RPREFIX}MULTIPROCESSOR_RESOURCE_SHARING} - use |
---|
| 530 | Multiprocessor Resource Sharing Protocol |
---|
| 531 | |
---|
[bd861cc6] | 532 | @item @code{@value{RPREFIX}LOCAL} - local semaphore (default) |
---|
[75e22db] | 533 | |
---|
[bd861cc6] | 534 | @item @code{@value{RPREFIX}GLOBAL} - global semaphore |
---|
[ae68ff0] | 535 | @end itemize |
---|
| 536 | |
---|
| 537 | Semaphores should not be made global unless remote |
---|
| 538 | tasks must interact with the created semaphore. This is to |
---|
| 539 | avoid the system overhead incurred by the creation of a global |
---|
| 540 | semaphore. When a global semaphore is created, the semaphore's |
---|
| 541 | name and id must be transmitted to every node in the system for |
---|
| 542 | insertion in the local copy of the global object table. |
---|
| 543 | |
---|
[bd861cc6] | 544 | Note that some combinations of attributes are not valid. See the |
---|
| 545 | earlier discussion on this. |
---|
| 546 | |
---|
| 547 | The total number of global objects, including semaphores, is limited by |
---|
| 548 | the maximum_global_objects field in the Configuration Table. |
---|
[ae68ff0] | 549 | |
---|
[8fcafdd5] | 550 | It is not allowed to create an initially locked MrsP semaphore and the |
---|
| 551 | @code{@value{RPREFIX}INVALID_NUMBER} status code will be returned on SMP |
---|
| 552 | configurations in this case. This prevents lock order reversal problems with |
---|
| 553 | the allocator mutex. |
---|
| 554 | |
---|
[169502e] | 555 | @c |
---|
| 556 | @c |
---|
| 557 | @c |
---|
[ae68ff0] | 558 | @page |
---|
| 559 | @subsection SEMAPHORE_IDENT - Get ID of a semaphore |
---|
| 560 | |
---|
[169502e] | 561 | @cindex get ID of a semaphore |
---|
| 562 | @cindex obtain ID of a semaphore |
---|
| 563 | |
---|
[ae68ff0] | 564 | @subheading CALLING SEQUENCE: |
---|
| 565 | |
---|
[61389eac] | 566 | @ifset is-C |
---|
[169502e] | 567 | @findex rtems_semaphore_ident |
---|
[ae68ff0] | 568 | @example |
---|
| 569 | rtems_status_code rtems_semaphore_ident( |
---|
[ae10dbd] | 570 | rtems_name name, |
---|
| 571 | uint32_t node, |
---|
| 572 | rtems_id *id |
---|
[ae68ff0] | 573 | ); |
---|
| 574 | @end example |
---|
[61389eac] | 575 | @end ifset |
---|
| 576 | |
---|
| 577 | @ifset is-Ada |
---|
| 578 | @example |
---|
| 579 | procedure Semaphore_Ident ( |
---|
| 580 | Name : in RTEMS.Name; |
---|
| 581 | Node : in RTEMS.Unsigned32; |
---|
| 582 | ID : out RTEMS.ID; |
---|
| 583 | Result : out RTEMS.Status_Codes |
---|
| 584 | ); |
---|
| 585 | @end example |
---|
| 586 | @end ifset |
---|
[ae68ff0] | 587 | |
---|
| 588 | @subheading DIRECTIVE STATUS CODES: |
---|
[f331481c] | 589 | @code{@value{RPREFIX}SUCCESSFUL} - semaphore identified successfully@* |
---|
| 590 | @code{@value{RPREFIX}INVALID_NAME} - semaphore name not found@* |
---|
| 591 | @code{@value{RPREFIX}INVALID_NODE} - invalid node id |
---|
[ae68ff0] | 592 | |
---|
| 593 | @subheading DESCRIPTION: |
---|
| 594 | |
---|
| 595 | This directive obtains the semaphore id associated |
---|
| 596 | with the semaphore name. If the semaphore name is not unique, |
---|
| 597 | then the semaphore id will match one of the semaphores with that |
---|
| 598 | name. However, this semaphore id is not guaranteed to |
---|
| 599 | correspond to the desired semaphore. The semaphore id is used |
---|
| 600 | by other semaphore related directives to access the semaphore. |
---|
| 601 | |
---|
| 602 | @subheading NOTES: |
---|
| 603 | |
---|
| 604 | This directive will not cause the running task to be |
---|
| 605 | preempted. |
---|
| 606 | |
---|
[f331481c] | 607 | If node is @code{@value{RPREFIX}SEARCH_ALL_NODES}, all nodes are searched |
---|
[ae68ff0] | 608 | with the local node being searched first. All other nodes are |
---|
| 609 | searched with the lowest numbered node searched first. |
---|
| 610 | |
---|
| 611 | If node is a valid node number which does not |
---|
| 612 | represent the local node, then only the semaphores exported by |
---|
| 613 | the designated node are searched. |
---|
| 614 | |
---|
| 615 | This directive does not generate activity on remote |
---|
| 616 | nodes. It accesses only the local copy of the global object |
---|
| 617 | table. |
---|
| 618 | |
---|
[169502e] | 619 | @c |
---|
| 620 | @c |
---|
| 621 | @c |
---|
[ae68ff0] | 622 | @page |
---|
| 623 | @subsection SEMAPHORE_DELETE - Delete a semaphore |
---|
| 624 | |
---|
[169502e] | 625 | @cindex delete a semaphore |
---|
| 626 | |
---|
[ae68ff0] | 627 | @subheading CALLING SEQUENCE: |
---|
| 628 | |
---|
[61389eac] | 629 | @ifset is-C |
---|
[169502e] | 630 | @findex rtems_semaphore_delete |
---|
[ae68ff0] | 631 | @example |
---|
| 632 | rtems_status_code rtems_semaphore_delete( |
---|
| 633 | rtems_id id |
---|
| 634 | ); |
---|
| 635 | @end example |
---|
[61389eac] | 636 | @end ifset |
---|
| 637 | |
---|
| 638 | @ifset is-Ada |
---|
| 639 | @example |
---|
| 640 | procedure Semaphore_Delete ( |
---|
| 641 | ID : in RTEMS.ID; |
---|
| 642 | Result : out RTEMS.Status_Codes |
---|
| 643 | ); |
---|
| 644 | @end example |
---|
| 645 | @end ifset |
---|
[ae68ff0] | 646 | |
---|
| 647 | @subheading DIRECTIVE STATUS CODES: |
---|
[880e2f37] | 648 | @code{@value{RPREFIX}SUCCESSFUL} - semaphore deleted successfully@* |
---|
[f331481c] | 649 | @code{@value{RPREFIX}INVALID_ID} - invalid semaphore id@* |
---|
[880e2f37] | 650 | @code{@value{RPREFIX}RESOURCE_IN_USE} - binary semaphore is in use@* |
---|
| 651 | @code{@value{RPREFIX}ILLEGAL_ON_REMOTE_OBJECT} - cannot delete remote semaphore |
---|
[ae68ff0] | 652 | |
---|
| 653 | @subheading DESCRIPTION: |
---|
| 654 | |
---|
[c85b8f2f] | 655 | This directive deletes the semaphore specified by @code{id}. |
---|
[ae68ff0] | 656 | All tasks blocked waiting to acquire the semaphore will be |
---|
| 657 | readied and returned a status code which indicates that the |
---|
| 658 | semaphore was deleted. The SMCB for this semaphore is reclaimed |
---|
| 659 | by RTEMS. |
---|
| 660 | |
---|
| 661 | @subheading NOTES: |
---|
| 662 | |
---|
| 663 | The calling task will be preempted if it is enabled |
---|
| 664 | by the task's execution mode and a higher priority local task is |
---|
| 665 | waiting on the deleted semaphore. The calling task will NOT be |
---|
| 666 | preempted if all of the tasks that are waiting on the semaphore |
---|
| 667 | are remote tasks. |
---|
| 668 | |
---|
| 669 | The calling task does not have to be the task that |
---|
| 670 | created the semaphore. Any local task that knows the semaphore |
---|
| 671 | id can delete the semaphore. |
---|
| 672 | |
---|
| 673 | When a global semaphore is deleted, the semaphore id |
---|
| 674 | must be transmitted to every node in the system for deletion |
---|
| 675 | from the local copy of the global object table. |
---|
| 676 | |
---|
| 677 | The semaphore must reside on the local node, even if |
---|
[75e22db] | 678 | the semaphore was created with the @code{@value{RPREFIX}GLOBAL} option. |
---|
[ae68ff0] | 679 | |
---|
| 680 | Proxies, used to represent remote tasks, are |
---|
| 681 | reclaimed when the semaphore is deleted. |
---|
| 682 | |
---|
[169502e] | 683 | @c |
---|
| 684 | @c |
---|
| 685 | @c |
---|
[ae68ff0] | 686 | @page |
---|
| 687 | @subsection SEMAPHORE_OBTAIN - Acquire a semaphore |
---|
| 688 | |
---|
[169502e] | 689 | @cindex obtain a semaphore |
---|
| 690 | @cindex lock a semaphore |
---|
| 691 | |
---|
[ae68ff0] | 692 | @subheading CALLING SEQUENCE: |
---|
| 693 | |
---|
[61389eac] | 694 | @ifset is-C |
---|
[169502e] | 695 | @findex rtems_semaphore_obtain |
---|
[ae68ff0] | 696 | @example |
---|
| 697 | rtems_status_code rtems_semaphore_obtain( |
---|
[ae10dbd] | 698 | rtems_id id, |
---|
[8ad2468c] | 699 | rtems_option option_set, |
---|
[ae10dbd] | 700 | rtems_interval timeout |
---|
[ae68ff0] | 701 | ); |
---|
| 702 | @end example |
---|
[61389eac] | 703 | @end ifset |
---|
| 704 | |
---|
| 705 | @ifset is-Ada |
---|
| 706 | @example |
---|
| 707 | procedure Semaphore_Obtain ( |
---|
| 708 | ID : in RTEMS.ID; |
---|
| 709 | Option_Set : in RTEMS.Option; |
---|
| 710 | Timeout : in RTEMS.Interval; |
---|
| 711 | Result : out RTEMS.Status_Codes |
---|
| 712 | ); |
---|
| 713 | @end example |
---|
| 714 | @end ifset |
---|
[ae68ff0] | 715 | |
---|
| 716 | @subheading DIRECTIVE STATUS CODES: |
---|
[f331481c] | 717 | @code{@value{RPREFIX}SUCCESSFUL} - semaphore obtained successfully@* |
---|
| 718 | @code{@value{RPREFIX}UNSATISFIED} - semaphore not available@* |
---|
| 719 | @code{@value{RPREFIX}TIMEOUT} - timed out waiting for semaphore@* |
---|
| 720 | @code{@value{RPREFIX}OBJECT_WAS_DELETED} - semaphore deleted while waiting@* |
---|
| 721 | @code{@value{RPREFIX}INVALID_ID} - invalid semaphore id |
---|
[ae68ff0] | 722 | |
---|
| 723 | @subheading DESCRIPTION: |
---|
| 724 | |
---|
| 725 | This directive acquires the semaphore specified by |
---|
[f331481c] | 726 | id. The @code{@value{RPREFIX}WAIT} and @code{@value{RPREFIX}NO_WAIT} components of the options parameter |
---|
[ae68ff0] | 727 | indicate whether the calling task wants to wait for the |
---|
| 728 | semaphore to become available or return immediately if the |
---|
[f331481c] | 729 | semaphore is not currently available. With either @code{@value{RPREFIX}WAIT} or |
---|
| 730 | @code{@value{RPREFIX}NO_WAIT}, if the current semaphore count is positive, then it is |
---|
[ae68ff0] | 731 | decremented by one and the semaphore is successfully acquired by |
---|
| 732 | returning immediately with a successful return code. |
---|
| 733 | |
---|
[169502e] | 734 | If the calling task chooses to return immediately and the current |
---|
| 735 | semaphore count is zero or negative, then a status code is returned |
---|
| 736 | indicating that the semaphore is not available. If the calling task |
---|
| 737 | chooses to wait for a semaphore and the current semaphore count is zero or |
---|
| 738 | negative, then it is decremented by one and the calling task is placed on |
---|
| 739 | the semaphore's wait queue and blocked. If the semaphore was created with |
---|
| 740 | the @code{@value{RPREFIX}PRIORITY} attribute, then the calling task is |
---|
| 741 | inserted into the queue according to its priority. However, if the |
---|
| 742 | semaphore was created with the @code{@value{RPREFIX}FIFO} attribute, then |
---|
| 743 | the calling task is placed at the rear of the wait queue. If the binary |
---|
| 744 | semaphore was created with the @code{@value{RPREFIX}INHERIT_PRIORITY} |
---|
| 745 | attribute, then the priority of the task currently holding the binary |
---|
| 746 | semaphore is guaranteed to be greater than or equal to that of the |
---|
| 747 | blocking task. If the binary semaphore was created with the |
---|
| 748 | @code{@value{RPREFIX}PRIORITY_CEILING} attribute, a task successfully |
---|
| 749 | obtains the semaphore, and the priority of that task is greater than the |
---|
| 750 | ceiling priority for this semaphore, then the priority of the task |
---|
| 751 | obtaining the semaphore is elevated to that of the ceiling. |
---|
| 752 | |
---|
| 753 | The timeout parameter specifies the maximum interval the calling task is |
---|
| 754 | willing to be blocked waiting for the semaphore. If it is set to |
---|
| 755 | @code{@value{RPREFIX}NO_TIMEOUT}, then the calling task will wait forever. |
---|
| 756 | If the semaphore is available or the @code{@value{RPREFIX}NO_WAIT} option |
---|
| 757 | component is set, then timeout is ignored. |
---|
[ae68ff0] | 758 | |
---|
[9553e7a6] | 759 | Deadlock situations are detected for MrsP semaphores and the |
---|
| 760 | @code{@value{RPREFIX}UNSATISFIED} status code will be returned on SMP |
---|
| 761 | configurations in this case. |
---|
| 762 | |
---|
[ae68ff0] | 763 | @subheading NOTES: |
---|
| 764 | The following semaphore acquisition option constants |
---|
| 765 | are defined by RTEMS: |
---|
| 766 | |
---|
| 767 | @itemize @bullet |
---|
[f331481c] | 768 | @item @code{@value{RPREFIX}WAIT} - task will wait for semaphore (default) |
---|
| 769 | @item @code{@value{RPREFIX}NO_WAIT} - task should not wait |
---|
[ae68ff0] | 770 | @end itemize |
---|
| 771 | |
---|
[169502e] | 772 | Attempting to obtain a global semaphore which does not reside on the local |
---|
| 773 | node will generate a request to the remote node to access the semaphore. |
---|
| 774 | If the semaphore is not available and @code{@value{RPREFIX}NO_WAIT} was |
---|
| 775 | not specified, then the task must be blocked until the semaphore is |
---|
| 776 | released. A proxy is allocated on the remote node to represent the task |
---|
| 777 | until the semaphore is released. |
---|
[ae68ff0] | 778 | |
---|
[1ca951ce] | 779 | A clock tick is required to support the timeout functionality of |
---|
| 780 | this directive. |
---|
| 781 | |
---|
[8fcafdd5] | 782 | It is not allowed to obtain a MrsP semaphore more than once by one task at a |
---|
| 783 | time (nested access) and the @code{@value{RPREFIX}UNSATISFIED} status code will |
---|
| 784 | be returned on SMP configurations in this case. |
---|
| 785 | |
---|
[169502e] | 786 | @c |
---|
| 787 | @c |
---|
| 788 | @c |
---|
[ae68ff0] | 789 | @page |
---|
| 790 | @subsection SEMAPHORE_RELEASE - Release a semaphore |
---|
| 791 | |
---|
[169502e] | 792 | @cindex release a semaphore |
---|
| 793 | @cindex unlock a semaphore |
---|
| 794 | |
---|
[ae68ff0] | 795 | @subheading CALLING SEQUENCE: |
---|
| 796 | |
---|
[61389eac] | 797 | @ifset is-C |
---|
[169502e] | 798 | @findex rtems_semaphore_release |
---|
[ae68ff0] | 799 | @example |
---|
| 800 | rtems_status_code rtems_semaphore_release( |
---|
| 801 | rtems_id id |
---|
| 802 | ); |
---|
| 803 | @end example |
---|
[61389eac] | 804 | @end ifset |
---|
| 805 | |
---|
| 806 | @ifset is-Ada |
---|
| 807 | @example |
---|
| 808 | procedure Semaphore_Release ( |
---|
| 809 | ID : in RTEMS.ID; |
---|
| 810 | Result : out RTEMS.Status_Codes |
---|
| 811 | ); |
---|
| 812 | @end example |
---|
| 813 | @end ifset |
---|
[ae68ff0] | 814 | |
---|
| 815 | @subheading DIRECTIVE STATUS CODES: |
---|
[f331481c] | 816 | @code{@value{RPREFIX}SUCCESSFUL} - semaphore released successfully@* |
---|
| 817 | @code{@value{RPREFIX}INVALID_ID} - invalid semaphore id@* |
---|
[9553e7a6] | 818 | @code{@value{RPREFIX}NOT_OWNER_OF_RESOURCE} - calling task does not own semaphore@* |
---|
| 819 | @code{@value{RPREFIX}INCORRECT_STATE} - invalid unlock order |
---|
[ae68ff0] | 820 | |
---|
| 821 | @subheading DESCRIPTION: |
---|
| 822 | |
---|
| 823 | This directive releases the semaphore specified by |
---|
| 824 | id. The semaphore count is incremented by one. If the count is |
---|
| 825 | zero or negative, then the first task on this semaphore's wait |
---|
| 826 | queue is removed and unblocked. The unblocked task may preempt |
---|
| 827 | the running task if the running task's preemption mode is |
---|
| 828 | enabled and the unblocked task has a higher priority than the |
---|
| 829 | running task. |
---|
| 830 | |
---|
| 831 | @subheading NOTES: |
---|
| 832 | |
---|
| 833 | The calling task may be preempted if it causes a |
---|
| 834 | higher priority task to be made ready for execution. |
---|
| 835 | |
---|
| 836 | Releasing a global semaphore which does not reside on |
---|
| 837 | the local node will generate a request telling the remote node |
---|
| 838 | to release the semaphore. |
---|
| 839 | |
---|
| 840 | If the task to be unblocked resides on a different |
---|
| 841 | node from the semaphore, then the semaphore allocation is |
---|
| 842 | forwarded to the appropriate node, the waiting task is |
---|
| 843 | unblocked, and the proxy used to represent the task is reclaimed. |
---|
| 844 | |
---|
| 845 | The outermost release of a local, binary, priority |
---|
| 846 | inheritance or priority ceiling semaphore may result in the |
---|
| 847 | calling task having its priority lowered. This will occur if |
---|
| 848 | the calling task holds no other binary semaphores and it has |
---|
| 849 | inherited a higher priority. |
---|
| 850 | |
---|
[9553e7a6] | 851 | The MrsP semaphores must be released in the reversed obtain order, otherwise |
---|
| 852 | the @code{@value{RPREFIX}INCORRECT_STATE} status code will be returned on SMP |
---|
| 853 | configurations in this case. |
---|
| 854 | |
---|
[5a69fe3] | 855 | @c |
---|
| 856 | @c |
---|
| 857 | @c |
---|
| 858 | @page |
---|
| 859 | @subsection SEMAPHORE_FLUSH - Unblock all tasks waiting on a semaphore |
---|
| 860 | |
---|
| 861 | @cindex flush a semaphore |
---|
[6449498] | 862 | @cindex unblock all tasks waiting on a semaphore |
---|
[5a69fe3] | 863 | |
---|
| 864 | @subheading CALLING SEQUENCE: |
---|
| 865 | |
---|
| 866 | @ifset is-C |
---|
| 867 | @findex rtems_semaphore_flush |
---|
| 868 | @example |
---|
| 869 | rtems_status_code rtems_semaphore_flush( |
---|
| 870 | rtems_id id |
---|
| 871 | ); |
---|
| 872 | @end example |
---|
| 873 | @end ifset |
---|
| 874 | |
---|
| 875 | @ifset is-Ada |
---|
| 876 | @example |
---|
| 877 | procedure Semaphore_Flush ( |
---|
| 878 | ID : in RTEMS.ID; |
---|
| 879 | Result : out RTEMS.Status_Codes |
---|
| 880 | ); |
---|
| 881 | @end example |
---|
| 882 | @end ifset |
---|
| 883 | |
---|
| 884 | @subheading DIRECTIVE STATUS CODES: |
---|
| 885 | @code{@value{RPREFIX}SUCCESSFUL} - semaphore released successfully@* |
---|
| 886 | @code{@value{RPREFIX}INVALID_ID} - invalid semaphore id@* |
---|
[8fcafdd5] | 887 | @code{@value{RPREFIX}NOT_DEFINED} - operation not defined for the protocol of |
---|
| 888 | the semaphore@* |
---|
[5a69fe3] | 889 | @code{@value{RPREFIX}ILLEGAL_ON_REMOTE_OBJECT} - not supported for remote semaphores |
---|
| 890 | |
---|
| 891 | @subheading DESCRIPTION: |
---|
| 892 | |
---|
| 893 | This directive unblocks all tasks waiting on the semaphore specified by |
---|
| 894 | id. Since there are tasks blocked on the semaphore, the semaphore's |
---|
| 895 | count is not changed by this directive and thus is zero before and |
---|
| 896 | after this directive is executed. Tasks which are unblocked as the |
---|
| 897 | result of this directive will return from the |
---|
[8ad2468c] | 898 | @code{@value{DIRPREFIX}semaphore_obtain} directive with a |
---|
[5a69fe3] | 899 | status code of @code{@value{RPREFIX}UNSATISFIED} to indicate |
---|
| 900 | that the semaphore was not obtained. |
---|
| 901 | |
---|
| 902 | This directive may unblock any number of tasks. Any of the unblocked |
---|
| 903 | tasks may preempt the running task if the running task's preemption mode is |
---|
| 904 | enabled and an unblocked task has a higher priority than the |
---|
| 905 | running task. |
---|
| 906 | |
---|
| 907 | @subheading NOTES: |
---|
| 908 | |
---|
| 909 | The calling task may be preempted if it causes a |
---|
| 910 | higher priority task to be made ready for execution. |
---|
| 911 | |
---|
| 912 | If the task to be unblocked resides on a different |
---|
| 913 | node from the semaphore, then the waiting task is |
---|
| 914 | unblocked, and the proxy used to represent the task is reclaimed. |
---|
| 915 | |
---|
[8fcafdd5] | 916 | It is not allowed to flush a MrsP semaphore and the |
---|
| 917 | @code{@value{RPREFIX}NOT_DEFINED} status code will be returned on SMP |
---|
| 918 | configurations in this case. |
---|
| 919 | |
---|
| 920 | @c |
---|
| 921 | @c |
---|
| 922 | @c |
---|
| 923 | @page |
---|
| 924 | @subsection SEMAPHORE_SET_PRIORITY - Set priority by scheduler for a semaphore |
---|
| 925 | |
---|
| 926 | @cindex set priority by scheduler for a semaphore |
---|
| 927 | |
---|
| 928 | @subheading CALLING SEQUENCE: |
---|
| 929 | |
---|
| 930 | @ifset is-C |
---|
| 931 | @findex rtems_semaphore_set_priority |
---|
| 932 | @example |
---|
| 933 | rtems_status_code rtems_semaphore_set_priority( |
---|
| 934 | rtems_id semaphore_id, |
---|
| 935 | rtems_id scheduler_id, |
---|
| 936 | rtems_task_priority new_priority, |
---|
| 937 | rtems_task_priority *old_priority |
---|
| 938 | ); |
---|
| 939 | @end example |
---|
| 940 | @end ifset |
---|
| 941 | |
---|
| 942 | @subheading DIRECTIVE STATUS CODES: |
---|
| 943 | @code{@value{RPREFIX}SUCCESSFUL} - successful operation@* |
---|
| 944 | @code{@value{RPREFIX}INVALID_ID} - invalid semaphore or scheduler id@* |
---|
| 945 | @code{@value{RPREFIX}INVALID_ADDRESS} - @code{old_priority} is NULL@* |
---|
| 946 | @code{@value{RPREFIX}INVALID_PRIORITY} - invalid new priority value@* |
---|
| 947 | @code{@value{RPREFIX}NOT_DEFINED} - operation not defined for the protocol of |
---|
| 948 | the semaphore@* |
---|
| 949 | @code{@value{RPREFIX}ILLEGAL_ON_REMOTE_OBJECT} - not supported for remote semaphores |
---|
| 950 | |
---|
| 951 | @subheading DESCRIPTION: |
---|
| 952 | |
---|
| 953 | This directive sets the priority value with respect to the specified scheduler |
---|
| 954 | of a semaphore. |
---|
| 955 | |
---|
| 956 | The special priority value @code{RTEMS_CURRENT_PRIORITY} can be used to get the |
---|
| 957 | current priority value without changing it. |
---|
| 958 | |
---|
| 959 | The interpretation of the priority value depends on the protocol of the |
---|
| 960 | semaphore object. |
---|
| 961 | |
---|
| 962 | @itemize @bullet |
---|
| 963 | @item The Multiprocessor Resource Sharing Protocol needs a ceiling priority per |
---|
| 964 | scheduler instance. This operation can be used to specify these priority |
---|
| 965 | values. |
---|
| 966 | @item For the Priority Ceiling Protocol the ceiling priority is used with this |
---|
| 967 | operation. |
---|
| 968 | @item For other protocols this operation is not defined. |
---|
| 969 | @end itemize |
---|
| 970 | |
---|
| 971 | @subheading EXAMPLE: |
---|
| 972 | |
---|
| 973 | @example |
---|
| 974 | @group |
---|
| 975 | #include <assert.h> |
---|
| 976 | #include <stdlib.h> |
---|
| 977 | |
---|
| 978 | #include <rtems.h> |
---|
| 979 | |
---|
| 980 | #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A') |
---|
| 981 | |
---|
| 982 | #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B') |
---|
| 983 | |
---|
| 984 | static void Init(rtems_task_argument arg) |
---|
| 985 | @{ |
---|
| 986 | rtems_status_code sc; |
---|
| 987 | rtems_id semaphore_id; |
---|
| 988 | rtems_id scheduler_a_id; |
---|
| 989 | rtems_id scheduler_b_id; |
---|
| 990 | rtems_task_priority prio; |
---|
| 991 | |
---|
| 992 | /* Get the scheduler identifiers */ |
---|
| 993 | |
---|
| 994 | sc = rtems_scheduler_ident(SCHED_A, &scheduler_a_id); |
---|
| 995 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 996 | |
---|
| 997 | sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id); |
---|
| 998 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 999 | |
---|
| 1000 | /* Create a MrsP semaphore object */ |
---|
| 1001 | |
---|
| 1002 | sc = rtems_semaphore_create( |
---|
| 1003 | rtems_build_name('M', 'R', 'S', 'P'), |
---|
| 1004 | 1, |
---|
| 1005 | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING |
---|
| 1006 | | RTEMS_BINARY_SEMAPHORE, |
---|
| 1007 | 1, |
---|
| 1008 | &semaphore_id |
---|
| 1009 | ); |
---|
| 1010 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 1011 | |
---|
| 1012 | /* |
---|
| 1013 | * The ceiling priority values per scheduler are equal to the value specified |
---|
| 1014 | * for object creation. |
---|
| 1015 | */ |
---|
| 1016 | |
---|
| 1017 | prio = RTEMS_CURRENT_PRIORITY; |
---|
| 1018 | sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio); |
---|
| 1019 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 1020 | assert(prio == 1); |
---|
| 1021 | |
---|
| 1022 | /* Check the old value and set a new ceiling priority for scheduler B */ |
---|
| 1023 | |
---|
| 1024 | prio = 2; |
---|
| 1025 | sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio); |
---|
| 1026 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 1027 | assert(prio == 1); |
---|
[5a69fe3] | 1028 | |
---|
[8fcafdd5] | 1029 | /* Check the ceiling priority values */ |
---|
| 1030 | |
---|
| 1031 | prio = RTEMS_CURRENT_PRIORITY; |
---|
| 1032 | sc = rtems_semaphore_set_priority(semaphore_id, scheduler_a_id, prio, &prio); |
---|
| 1033 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 1034 | assert(prio == 1); |
---|
| 1035 | |
---|
| 1036 | prio = RTEMS_CURRENT_PRIORITY; |
---|
| 1037 | sc = rtems_semaphore_set_priority(semaphore_id, scheduler_b_id, prio, &prio); |
---|
| 1038 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 1039 | assert(prio == 2); |
---|
| 1040 | |
---|
| 1041 | sc = rtems_semaphore_delete(semaphore_id); |
---|
| 1042 | assert(sc == RTEMS_SUCCESSFUL); |
---|
| 1043 | |
---|
| 1044 | exit(0); |
---|
| 1045 | @} |
---|
| 1046 | |
---|
| 1047 | #define CONFIGURE_SMP_APPLICATION |
---|
| 1048 | |
---|
| 1049 | #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER |
---|
| 1050 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER |
---|
| 1051 | |
---|
| 1052 | #define CONFIGURE_MAXIMUM_TASKS 1 |
---|
| 1053 | #define CONFIGURE_MAXIMUM_SEMAPHORES 1 |
---|
| 1054 | #define CONFIGURE_MAXIMUM_MRSP_SEMAPHORES 1 |
---|
| 1055 | |
---|
| 1056 | #define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2 |
---|
| 1057 | |
---|
| 1058 | #define CONFIGURE_SCHEDULER_SIMPLE_SMP |
---|
| 1059 | |
---|
| 1060 | #include <rtems/scheduler.h> |
---|
| 1061 | |
---|
| 1062 | RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(a); |
---|
| 1063 | |
---|
| 1064 | RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(b); |
---|
| 1065 | |
---|
| 1066 | #define CONFIGURE_SCHEDULER_CONTROLS \ |
---|
| 1067 | RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(a, SCHED_A), \ |
---|
| 1068 | RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(b, SCHED_B) |
---|
| 1069 | |
---|
| 1070 | #define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \ |
---|
| 1071 | RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \ |
---|
| 1072 | RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY) |
---|
| 1073 | |
---|
| 1074 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE |
---|
| 1075 | |
---|
| 1076 | #define CONFIGURE_INIT |
---|
| 1077 | |
---|
| 1078 | #include <rtems/confdefs.h> |
---|
| 1079 | @end group |
---|
| 1080 | @end example |
---|