source: rtems/cpukit/score/include/rtems/score/coresemimpl.h @ 39bcf741

5
Last change on this file since 39bcf741 was 39bcf741, checked in by Sebastian Huber <sebastian.huber@…>, on 05/25/16 at 12:23:48

Fix semaphore post overflow status

Close #2720.

  • Property mode set to 100644
File size: 7.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Inlined Routines Associated with the SuperCore Semaphore
5 *
6 * This include file contains all of the inlined routines associated
7 * with the SuperCore semaphore.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2006.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_CORESEMIMPL_H
20#define _RTEMS_SCORE_CORESEMIMPL_H
21
22#include <rtems/score/coresem.h>
23#include <rtems/score/objectimpl.h>
24#include <rtems/score/threaddispatch.h>
25#include <rtems/score/threadqimpl.h>
26#include <rtems/score/statesimpl.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32/**
33 * @addtogroup ScoreSemaphore
34 */
35/**@{**/
36
37/**
38 *  Core Semaphore handler return statuses.
39 */
40typedef enum {
41  /** This status indicates that the operation completed successfully. */
42  CORE_SEMAPHORE_STATUS_SUCCESSFUL,
43  /** This status indicates that the calling task did not want to block
44   *  and the operation was unable to complete immediately because the
45   *  resource was unavailable.
46   */
47  CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT,
48  /** This status indicates that the thread was blocked waiting for an
49   *  operation to complete and the semaphore was deleted.
50   */
51  CORE_SEMAPHORE_WAS_DELETED,
52  /** This status indicates that the calling task was willing to block
53   *  but the operation was unable to complete within the time allotted
54   *  because the resource never became available.
55   */
56  CORE_SEMAPHORE_TIMEOUT,
57  /** This status indicates that an attempt was made to unlock the semaphore
58   *  and this would have made its count greater than that allowed.
59   */
60  CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED
61}   CORE_semaphore_Status;
62
63/**
64 *  @brief Core semaphore last status value.
65 *
66 *  This is the last status value.
67 */
68#define CORE_SEMAPHORE_STATUS_LAST CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED
69
70/**
71 *  @brief Initialize the semaphore based on the parameters passed.
72 *
73 *  This package is the implementation of the CORE Semaphore Handler.
74 *  This core object utilizes standard Dijkstra counting semaphores to provide
75 *  synchronization and mutual exclusion capabilities.
76 *
77 *  This routine initializes the semaphore based on the parameters passed.
78 *
79 *  @param[in] the_semaphore is the semaphore to initialize
80 *  @param[in] discipline the blocking discipline
81 *  @param[in] initial_value is the initial count of the semaphore
82 */
83void _CORE_semaphore_Initialize(
84  CORE_semaphore_Control     *the_semaphore,
85  CORE_semaphore_Disciplines  discipline,
86  uint32_t                    initial_value
87);
88
89RTEMS_INLINE_ROUTINE void _CORE_semaphore_Acquire_critical(
90  CORE_semaphore_Control *the_semaphore,
91  Thread_queue_Context   *queue_context
92)
93{
94  _Thread_queue_Acquire_critical(
95    &the_semaphore->Wait_queue,
96    &queue_context->Lock_context
97  );
98}
99
100RTEMS_INLINE_ROUTINE void _CORE_semaphore_Release(
101  CORE_semaphore_Control *the_semaphore,
102  Thread_queue_Context   *queue_context
103)
104{
105  _Thread_queue_Release(
106    &the_semaphore->Wait_queue,
107    &queue_context->Lock_context
108  );
109}
110
111Thread_Control *_CORE_semaphore_Was_deleted(
112  Thread_Control       *the_thread,
113  Thread_queue_Queue   *queue,
114  Thread_queue_Context *queue_context
115);
116
117Thread_Control *_CORE_semaphore_Unsatisfied_nowait(
118  Thread_Control       *the_thread,
119  Thread_queue_Queue   *queue,
120  Thread_queue_Context *queue_context
121);
122
123RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
124  CORE_semaphore_Control *the_semaphore,
125  Thread_queue_Context   *queue_context
126)
127{
128  _Thread_queue_Flush_critical(
129    &the_semaphore->Wait_queue.Queue,
130    the_semaphore->operations,
131    _CORE_semaphore_Was_deleted,
132    queue_context
133  );
134  _Thread_queue_Destroy( &the_semaphore->Wait_queue );
135}
136
137/**
138 *  @brief Surrender a unit to a semaphore.
139 *
140 *  This routine frees a unit to the semaphore.  If a task was blocked waiting
141 *  for a unit from this semaphore, then that task will be readied and the unit
142 *  given to that task.  Otherwise, the unit will be returned to the semaphore.
143 *
144 *  @param[in] the_semaphore is the semaphore to surrender
145 *  @param[in] queue_context is a temporary variable used to contain the ISR
146 *        disable level cookie
147 *
148 *  @retval an indication of whether the routine succeeded or failed
149 */
150RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
151  CORE_semaphore_Control  *the_semaphore,
152  uint32_t                 maximum_count,
153  Thread_queue_Context    *queue_context
154)
155{
156  Thread_Control *the_thread;
157  CORE_semaphore_Status status;
158
159  status = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
160
161  _CORE_semaphore_Acquire_critical( the_semaphore, queue_context );
162
163  the_thread = _Thread_queue_First_locked(
164    &the_semaphore->Wait_queue,
165    the_semaphore->operations
166  );
167  if ( the_thread != NULL ) {
168    _Thread_queue_Extract_critical(
169      &the_semaphore->Wait_queue.Queue,
170      the_semaphore->operations,
171      the_thread,
172      queue_context
173    );
174  } else {
175    if ( the_semaphore->count < maximum_count )
176      the_semaphore->count += 1;
177    else
178      status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED;
179
180    _CORE_semaphore_Release( the_semaphore, queue_context );
181  }
182
183  return status;
184}
185
186RTEMS_INLINE_ROUTINE void _CORE_semaphore_Flush(
187  CORE_semaphore_Control *the_semaphore,
188  Thread_queue_Context   *queue_context
189)
190{
191  _Thread_queue_Flush_critical(
192    &the_semaphore->Wait_queue.Queue,
193    the_semaphore->operations,
194    _CORE_semaphore_Unsatisfied_nowait,
195    queue_context
196  );
197}
198
199/**
200 * This routine returns the current count associated with the semaphore.
201 *
202 * @param[in] the_semaphore is the semaphore to obtain the count of
203 *
204 * @return the current count of this semaphore
205 */
206RTEMS_INLINE_ROUTINE uint32_t  _CORE_semaphore_Get_count(
207  CORE_semaphore_Control  *the_semaphore
208)
209{
210  return the_semaphore->count;
211}
212
213/**
214 * This routine attempts to receive a unit from the_semaphore.
215 * If a unit is available or if the wait flag is false, then the routine
216 * returns.  Otherwise, the calling task is blocked until a unit becomes
217 * available.
218 *
219 * @param[in] the_semaphore is the semaphore to obtain
220 * @param[in,out] executing The currently executing thread.
221 * @param[in] wait is true if the thread is willing to wait
222 * @param[in] timeout is the maximum number of ticks to block
223 * @param[in] queue_context is a temporary variable used to contain the ISR
224 *        disable level cookie
225 *
226 * @note There is currently no MACRO version of this routine.
227 */
228RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize(
229  CORE_semaphore_Control *the_semaphore,
230  Thread_Control         *executing,
231  bool                    wait,
232  Watchdog_Interval       timeout,
233  Thread_queue_Context   *queue_context
234)
235{
236  /* disabled when you get here */
237
238  executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
239  _CORE_semaphore_Acquire_critical( the_semaphore, queue_context );
240  if ( the_semaphore->count != 0 ) {
241    the_semaphore->count -= 1;
242    _CORE_semaphore_Release( the_semaphore, queue_context );
243    return;
244  }
245
246  if ( !wait ) {
247    _CORE_semaphore_Release( the_semaphore, queue_context );
248    executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
249    return;
250  }
251
252  _Thread_queue_Enqueue_critical(
253    &the_semaphore->Wait_queue.Queue,
254    the_semaphore->operations,
255    executing,
256    STATES_WAITING_FOR_SEMAPHORE,
257    timeout,
258    CORE_SEMAPHORE_TIMEOUT,
259    &queue_context->Lock_context
260  );
261}
262
263/** @} */
264
265#ifdef __cplusplus
266}
267#endif
268
269#endif
270/* end of include file */
Note: See TracBrowser for help on using the repository browser.