source: rtems/cpukit/score/include/rtems/score/coresemimpl.h @ 97bbf02

5
Last change on this file since 97bbf02 was 97bbf02, checked in by Sebastian Huber <sebastian.huber@…>, on 03/22/16 at 07:52:50

score: Use constant for maximum count of CORE sema

  • Property mode set to 100644
File size: 8.1 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 *  The following type defines the callout which the API provides
72 *  to support global/multiprocessor operations on semaphores.
73 */
74typedef void ( *CORE_semaphore_API_mp_support_callout )(
75                 Thread_Control *,
76                 Objects_Id
77             );
78
79/**
80 *  @brief Initialize the semaphore based on the parameters passed.
81 *
82 *  This package is the implementation of the CORE Semaphore Handler.
83 *  This core object utilizes standard Dijkstra counting semaphores to provide
84 *  synchronization and mutual exclusion capabilities.
85 *
86 *  This routine initializes the semaphore based on the parameters passed.
87 *
88 *  @param[in] the_semaphore is the semaphore to initialize
89 *  @param[in] discipline the blocking discipline
90 *  @param[in] initial_value is the initial count of the semaphore
91 */
92void _CORE_semaphore_Initialize(
93  CORE_semaphore_Control     *the_semaphore,
94  CORE_semaphore_Disciplines  discipline,
95  uint32_t                    initial_value
96);
97
98RTEMS_INLINE_ROUTINE void _CORE_semaphore_Destroy(
99  CORE_semaphore_Control *the_semaphore
100)
101{
102  _Thread_queue_Destroy( &the_semaphore->Wait_queue );
103}
104
105/**
106 *  @brief Surrender a unit to a semaphore.
107 *
108 *  This routine frees a unit to the semaphore.  If a task was blocked waiting
109 *  for a unit from this semaphore, then that task will be readied and the unit
110 *  given to that task.  Otherwise, the unit will be returned to the semaphore.
111 *
112 *  @param[in] the_semaphore is the semaphore to surrender
113 *  @param[in] id is the Id of the API level Semaphore object associated
114 *         with this instance of a SuperCore Semaphore
115 *  @param[in] api_semaphore_mp_support is the routine to invoke if the
116 *         thread unblocked is remote
117 *  @param[in] lock_context is a temporary variable used to contain the ISR
118 *        disable level cookie
119 *
120 *  @retval an indication of whether the routine succeeded or failed
121 */
122RTEMS_INLINE_ROUTINE CORE_semaphore_Status _CORE_semaphore_Surrender(
123  CORE_semaphore_Control                *the_semaphore,
124  Objects_Id                             id,
125  CORE_semaphore_API_mp_support_callout  api_semaphore_mp_support,
126  ISR_lock_Context                      *lock_context
127)
128{
129  Thread_Control *the_thread;
130  CORE_semaphore_Status status;
131
132  status = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
133
134  _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context );
135
136  the_thread = _Thread_queue_First_locked(
137    &the_semaphore->Wait_queue,
138    the_semaphore->operations
139  );
140  if ( the_thread != NULL ) {
141#if defined(RTEMS_MULTIPROCESSING)
142    _Thread_Dispatch_disable();
143#endif
144
145    _Thread_queue_Extract_critical(
146      &the_semaphore->Wait_queue.Queue,
147      the_semaphore->operations,
148      the_thread,
149      lock_context
150    );
151
152#if defined(RTEMS_MULTIPROCESSING)
153    if ( !_Objects_Is_local_id( the_thread->Object.id ) )
154      (*api_semaphore_mp_support) ( the_thread, id );
155
156    _Thread_Dispatch_enable( _Per_CPU_Get() );
157#endif
158  } else {
159    if ( the_semaphore->count < UINT32_MAX )
160      the_semaphore->count += 1;
161    else
162      status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED;
163
164    _Thread_queue_Release( &the_semaphore->Wait_queue, lock_context );
165  }
166
167  return status;
168}
169
170/**
171 *  @brief Core semaphore flush.
172 *
173 *  This package is the implementation of the CORE Semaphore Handler.
174 *  This core object utilizes standard Dijkstra counting semaphores to provide
175 *  synchronization and mutual exclusion capabilities.
176 *
177 *  This routine assists in the deletion of a semaphore by flushing the
178 *  associated wait queue.
179 *
180 *  @param[in] the_semaphore is the semaphore to flush
181 *  @param[in] remote_extract_callout is the routine to invoke if the
182 *         thread unblocked is remote
183 *  @param[in] status is the status to be returned to the unblocked thread
184 */
185RTEMS_INLINE_ROUTINE void _CORE_semaphore_Flush(
186  CORE_semaphore_Control         *the_semaphore,
187  Thread_queue_Flush_callout      remote_extract_callout,
188  uint32_t                        status
189)
190{
191  _Thread_queue_Flush(
192    &the_semaphore->Wait_queue,
193    the_semaphore->operations,
194    remote_extract_callout,
195    status
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] id is the Id of the owning API level Semaphore object
222 * @param[in] wait is true if the thread is willing to wait
223 * @param[in] timeout is the maximum number of ticks to block
224 * @param[in] lock_context is a temporary variable used to contain the ISR
225 *        disable level cookie
226 *
227 * @note There is currently no MACRO version of this routine.
228 */
229RTEMS_INLINE_ROUTINE void _CORE_semaphore_Seize(
230  CORE_semaphore_Control  *the_semaphore,
231  Thread_Control          *executing,
232  Objects_Id               id,
233  bool                     wait,
234  Watchdog_Interval        timeout,
235  ISR_lock_Context        *lock_context
236)
237{
238  /* disabled when you get here */
239
240  executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
241  _Thread_queue_Acquire_critical( &the_semaphore->Wait_queue, lock_context );
242  if ( the_semaphore->count != 0 ) {
243    the_semaphore->count -= 1;
244    _Thread_queue_Release( &the_semaphore->Wait_queue, lock_context );
245    return;
246  }
247
248  if ( !wait ) {
249    _Thread_queue_Release( &the_semaphore->Wait_queue, lock_context );
250    executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
251    return;
252  }
253
254  executing->Wait.id = id;
255  _Thread_queue_Enqueue_critical(
256    &the_semaphore->Wait_queue.Queue,
257    the_semaphore->operations,
258    executing,
259    STATES_WAITING_FOR_SEMAPHORE,
260    timeout,
261    CORE_SEMAPHORE_TIMEOUT,
262    lock_context
263  );
264}
265
266/** @} */
267
268#ifdef __cplusplus
269}
270#endif
271
272#endif
273/* end of include file */
Note: See TracBrowser for help on using the repository browser.