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