source: rtems/cpukit/include/rtems/score/coresemimpl.h @ a660e9dc

Last change on this file since a660e9dc was a660e9dc, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/22 at 08:37:05

Do not use RTEMS_INLINE_ROUTINE

Directly use "static inline" which is available in C99 and later. This brings
the RTEMS implementation closer to standard C.

Close #3935.

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreSemaphore
7 *
8 * @brief This header file provides interfaces of the
9 *   @ref RTEMSScoreSemaphore which are only used by the implementation.
10 */
11
12/*
13 *  COPYRIGHT (c) 1989-2006.
14 *  On-Line Applications Research Corporation (OAR).
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef _RTEMS_SCORE_CORESEMIMPL_H
39#define _RTEMS_SCORE_CORESEMIMPL_H
40
41#include <rtems/score/coresem.h>
42#include <rtems/score/objectimpl.h>
43#include <rtems/score/threaddispatch.h>
44#include <rtems/score/threadimpl.h>
45#include <rtems/score/threadqimpl.h>
46#include <rtems/score/statesimpl.h>
47#include <rtems/score/status.h>
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
53/**
54 * @addtogroup RTEMSScoreSemaphore
55 *
56 * @{
57 */
58
59/**
60 * @brief Initializes the semaphore based on the parameters passed.
61 *
62 * This package is the implementation of the CORE Semaphore Handler.
63 * This core object utilizes standard Dijkstra counting semaphores to provide
64 * synchronization and mutual exclusion capabilities.
65 *
66 * This routine initializes the semaphore based on the parameters passed.
67 *
68 * @param[out] the_semaphore The semaphore to initialize.
69 * @param initial_value The initial count of the semaphore.
70 */
71void _CORE_semaphore_Initialize(
72  CORE_semaphore_Control *the_semaphore,
73  uint32_t                initial_value
74);
75
76/**
77 * @brief Acquires the semaphore critical.
78 *
79 * This routine acquires the semaphore.
80 *
81 * @param[in, out] the_semaphore The semaphore to acquire.
82 * @param queue_context The thread queue context.
83 */
84static inline void _CORE_semaphore_Acquire_critical(
85  CORE_semaphore_Control *the_semaphore,
86  Thread_queue_Context   *queue_context
87)
88{
89  _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, queue_context );
90}
91
92/**
93 * @brief Releases the semaphore.
94 *
95 * This routine releases the semaphore.
96 *
97 * @param[in, out] the_semaphore The semaphore to release.
98 * @param queue_context The thread queue context.
99 */
100static inline void _CORE_semaphore_Release(
101  CORE_semaphore_Control *the_semaphore,
102  Thread_queue_Context   *queue_context
103)
104{
105  _Thread_queue_Release( &the_semaphore->Wait_queue, queue_context );
106}
107
108/**
109 * @brief Destroys the semaphore.
110 *
111 * This routine destroys the semaphore.
112 *
113 * @param[out] the_semaphore The semaphore to destroy.
114 * @param operations The thread queue operations.
115 * @param queue_context The thread queue context.
116 */
117static inline void _CORE_semaphore_Destroy(
118  CORE_semaphore_Control        *the_semaphore,
119  const Thread_queue_Operations *operations,
120  Thread_queue_Context          *queue_context
121)
122{
123  _Thread_queue_Flush_critical(
124    &the_semaphore->Wait_queue.Queue,
125    operations,
126    _Thread_queue_Flush_status_object_was_deleted,
127    queue_context
128  );
129  _Thread_queue_Destroy( &the_semaphore->Wait_queue );
130}
131
132/**
133 * @brief Surrenders a unit to the semaphore.
134 *
135 * This routine frees a unit to the semaphore.  If a task was blocked waiting
136 * for a unit from this semaphore, then that task will be readied and the unit
137 * given to that task.  Otherwise, the unit will be returned to the semaphore.
138 *
139 * @param[in, out] the_semaphore is the semaphore to surrender
140 * @param operations The thread queue operations.
141 * @param maximum_count The maximum number of units in the semaphore.
142 * @param queue_context is a temporary variable used to contain the ISR
143 *       disable level cookie.
144 *
145 * @retval STATUS_SUCCESSFUL The unit was successfully freed to the semaphore.
146 * @retval STATUS_MAXIMUM_COUNT_EXCEEDED The maximum number of units was exceeded.
147 */
148static inline Status_Control _CORE_semaphore_Surrender(
149  CORE_semaphore_Control        *the_semaphore,
150  const Thread_queue_Operations *operations,
151  uint32_t                       maximum_count,
152  Thread_queue_Context          *queue_context
153)
154{
155  Status_Control      status;
156  Thread_queue_Heads *heads;
157
158  status = STATUS_SUCCESSFUL;
159
160  _CORE_semaphore_Acquire_critical( the_semaphore, queue_context );
161
162  heads = the_semaphore->Wait_queue.Queue.heads;
163
164  if ( heads != NULL ) {
165    _Thread_queue_Surrender_no_priority(
166      &the_semaphore->Wait_queue.Queue,
167      heads,
168      queue_context,
169      operations
170    );
171  } else {
172    if ( the_semaphore->count < maximum_count )
173      the_semaphore->count += 1;
174    else
175      status = STATUS_MAXIMUM_COUNT_EXCEEDED;
176
177    _CORE_semaphore_Release( the_semaphore, queue_context );
178  }
179
180  return status;
181}
182
183/**
184 * @brief Returns the current count associated with the semaphore.
185 *
186 * @param the_semaphore The semaphore to obtain the count of.
187 *
188 * @return the current count of this semaphore.
189 */
190static inline uint32_t  _CORE_semaphore_Get_count(
191  const CORE_semaphore_Control *the_semaphore
192)
193{
194  return the_semaphore->count;
195}
196
197/**
198 * @brief Seizes the semaphore
199 *
200 * This routine attempts to receive a unit from the_semaphore.
201 * If a unit is available or if the wait flag is false, then the routine
202 * returns.  Otherwise, the calling task is blocked until a unit becomes
203 * available.
204 *
205 * @param[in, out] the_semaphore The semaphore to obtain.
206 * @param operations The thread queue operations.
207 * @param executing The currently executing thread.
208 * @param wait Indicates whether the calling thread is willing to wait.
209 * @param queue_context is a temporary variable used to contain the ISR
210 *        disable level cookie.
211 *
212 * @retval STATUS_SUCCESSFUL The semaphore was successfully seized.
213 * @retval STATUS_UNSATISFIED The semaphore is currently not free and the
214 *      calling thread not willing to wait.
215 * @retval STATUS_TIMEOUT A timeout occurred.
216 */
217static inline Status_Control _CORE_semaphore_Seize(
218  CORE_semaphore_Control        *the_semaphore,
219  const Thread_queue_Operations *operations,
220  Thread_Control                *executing,
221  bool                           wait,
222  Thread_queue_Context          *queue_context
223)
224{
225  _Assert( _ISR_Get_level() != 0 );
226
227  _CORE_semaphore_Acquire_critical( the_semaphore, queue_context );
228  if ( the_semaphore->count != 0 ) {
229    the_semaphore->count -= 1;
230    _CORE_semaphore_Release( the_semaphore, queue_context );
231    return STATUS_SUCCESSFUL;
232  }
233
234  if ( !wait ) {
235    _CORE_semaphore_Release( the_semaphore, queue_context );
236    return STATUS_UNSATISFIED;
237  }
238
239  _Thread_queue_Context_set_thread_state(
240    queue_context,
241    STATES_WAITING_FOR_SEMAPHORE
242  );
243  _Thread_queue_Enqueue(
244    &the_semaphore->Wait_queue.Queue,
245    operations,
246    executing,
247    queue_context
248  );
249  return _Thread_Wait_get_status( executing );
250}
251
252/** @} */
253
254#ifdef __cplusplus
255}
256#endif
257
258#endif
259/* end of include file */
Note: See TracBrowser for help on using the repository browser.