source: rtems/cpukit/score/src/coremutex.c @ 3652ad35

4.104.114.84.95
Last change on this file since 3652ad35 was 3a4ae6c, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 11, 1995 at 7:35:39 PM

The word "RTEMS" almost completely removed from the core.

Configuration Table Template file added and all tests
modified to use this. All gvar.h and conftbl.h files
removed from test directories.

Configuration parameter maximum_devices added.

Core semaphore and mutex handlers added and RTEMS API Semaphore
Manager updated to reflect this.

Initialization sequence changed to invoke API specific initialization
routines. Initialization tasks table now owned by RTEMS Tasks Manager.

Added user extension for post-switch.

Utilized user extensions to implement API specific functionality
like signal dispatching.

Added extensions to the System Initialization Thread so that an
API can register a function to be invoked while the system
is being initialized. These are largely equivalent to the
pre-driver and post-driver hooks.

Added the Modules file oar-go32_p5, modified oar-go32, and modified
the file make/custom/go32.cfg to look at an environment varable which
determines what CPU model is being used.

All BSPs updated to reflect named devices and clock driver's IOCTL
used by the Shared Memory Driver. Also merged clock isr into
main file and removed ckisr.c where possible.

Updated spsize to reflect new and moved variables.

Makefiles for the executive source and include files updated to show
break down of files into Core, RTEMS API, and Neither.

Header and inline files installed into subdirectory based on whether
logically in the Core or a part of the RTEMS API.

  • Property mode set to 100644
File size: 7.4 KB
Line 
1/*
2 *  Mutex Handler
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the Mutex Handler.
7 *  This handler provides synchronization and mutual exclusion capabilities.
8 *
9 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
10 *  On-Line Applications Research Corporation (OAR).
11 *  All rights assigned to U.S. Government, 1994.
12 *
13 *  This material may be reproduced by or for the U.S. Government pursuant
14 *  to the copyright license under the clause at DFARS 252.227-7013.  This
15 *  notice must appear in all copies of this file and its derivatives.
16 *
17 *  $Id$
18 */
19
20#include <rtems/system.h>
21#include <rtems/core/isr.h>
22#include <rtems/core/coremutex.h>
23#include <rtems/core/states.h>
24#include <rtems/core/thread.h>
25#include <rtems/core/threadq.h>
26
27/*PAGE
28 *
29 *  _CORE_mutex_Initialize
30 *
31 *  This routine initializes a mutex at create time and set the control
32 *  structure according to the values passed.
33 *
34 *  Input parameters:
35 *    the_mutex             - the mutex control block to initialize
36 *    the_class             - the API class of the object
37 *    the_mutex_attributes  - the mutex attributes specified at create time
38 *    initial_lock          - mutex initial lock or unlocked status
39 *    proxy_extract_callout - MP specific extract callout
40 *
41 *  Output parameters:  NONE
42 */
43 
44void _CORE_mutex_Initialize(
45  CORE_mutex_Control           *the_mutex,
46  Objects_Classes               the_class,
47  CORE_mutex_Attributes        *the_mutex_attributes,
48  unsigned32                    initial_lock,
49  Thread_queue_Extract_callout  proxy_extract_callout
50)
51{
52
53/* Add this to the RTEMS environment later ?????????
54  rtems_assert( initial_lock == CORE_MUTEX_LOCKED ||
55                initial_lock == CORE_MUTEX_UNLOCKED );
56 */
57
58  the_mutex->Attributes = *the_mutex_attributes;
59  the_mutex->lock          = initial_lock;
60 
61  if ( initial_lock == CORE_MUTEX_LOCKED ) {
62    the_mutex->nest_count = 1;
63    the_mutex->holder     = _Thread_Executing;
64    the_mutex->holder_id  = _Thread_Executing->Object.id;
65    _Thread_Executing->resource_count++;
66  } else {
67    the_mutex->nest_count = 0;
68    the_mutex->holder     = NULL;
69    the_mutex->holder_id  = 0;
70  }
71
72  _Thread_queue_Initialize(
73    &the_mutex->Wait_queue,
74    the_class,
75    _CORE_mutex_Is_priority( the_mutex_attributes ) ?
76      THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
77    STATES_WAITING_FOR_MUTEX,
78    proxy_extract_callout,
79    CORE_MUTEX_TIMEOUT
80  );
81}
82
83/*PAGE
84 *
85 *  _CORE_mutex_Seize
86 *
87 *  This routine attempts to allocate a mutex to the calling thread.
88 *
89 *  Input parameters:
90 *    the_mutex - pointer to mutex control block
91 *    id        - id of object to wait on
92 *    wait      - TRUE if wait is allowed, FALSE otherwise
93 *    timeout   - number of ticks to wait (0 means forever)
94 *
95 *  Output parameters:  NONE
96 *
97 *  INTERRUPT LATENCY:
98 *    available
99 *    wait
100 */
101
102void _CORE_mutex_Seize(
103  CORE_mutex_Control  *the_mutex,
104  Objects_Id           id,
105  boolean              wait,
106  Watchdog_Interval    timeout
107)
108{
109  Thread_Control *executing;
110  ISR_Level       level;
111
112  executing = _Thread_Executing;
113  executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
114  _ISR_Disable( level );
115  if ( ! _CORE_mutex_Is_locked( the_mutex ) ) {
116    the_mutex->lock       = CORE_MUTEX_LOCKED;
117    the_mutex->holder     = executing;
118    the_mutex->holder_id  = executing->Object.id;
119    the_mutex->nest_count = 1;
120    executing->resource_count++;
121    _ISR_Enable( level );
122    return;
123  }
124
125  if ( !wait ) {
126    _ISR_Enable( level );
127    executing->Wait.return_code = CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT;
128    return;
129  }
130
131  if ( _Objects_Are_ids_equal(
132              _Thread_Executing->Object.id, the_mutex->holder_id ) ) {
133    if ( _CORE_mutex_Is_nesting_allowed( &the_mutex->Attributes ) )
134      the_mutex->nest_count++;
135    else 
136      executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
137
138    _ISR_Enable( level );
139    return;
140  }
141
142  the_mutex->Wait_queue.sync = TRUE;
143  executing->Wait.queue      = &the_mutex->Wait_queue;
144  executing->Wait.id         = id;
145  _ISR_Enable( level );
146
147  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) &&
148    the_mutex->holder->current_priority >
149                                      _Thread_Executing->current_priority ) {
150    _Thread_Change_priority(
151    the_mutex->holder, _Thread_Executing->current_priority );
152  }
153
154  _Thread_queue_Enqueue( &the_mutex->Wait_queue, timeout );
155}
156
157/*
158 *  _CORE_mutex_Surrender
159 *
160 *  DESCRIPTION:
161 *
162 *  This routine frees a unit to the mutex.  If a task was blocked waiting for
163 *  a unit from this mutex, then that task will be readied and the unit
164 *  given to that task.  Otherwise, the unit will be returned to the mutex.
165 *
166 *  Input parameters:
167 *    the_mutex            - the mutex to be flushed
168 *    id                   - id of parent mutex
169 *    api_mutex_mp_support - api dependent MP support actions
170 *
171 *  Output parameters:
172 *    CORE_MUTEX_STATUS_SUCCESSFUL - if successful
173 *    core error code              - if unsuccessful
174 */
175 
176CORE_mutex_Status _CORE_mutex_Surrender(
177  CORE_mutex_Control                *the_mutex,
178  Objects_Id                         id,
179  CORE_mutex_API_mp_support_callout  api_mutex_mp_support
180)
181{
182  Thread_Control *the_thread;
183
184  if ( !_Objects_Are_ids_equal(
185           _Thread_Executing->Object.id, the_mutex->holder_id ) )
186    return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
187 
188  the_mutex->nest_count--;
189 
190  if ( the_mutex->nest_count != 0 )
191    return( CORE_MUTEX_STATUS_SUCCESSFUL );
192 
193  _Thread_Executing->resource_count--;
194  the_mutex->holder    = NULL;
195  the_mutex->holder_id = 0;
196 
197  /*
198   *  Whether or not someone is waiting for the mutex, an
199   *  inherited priority must be lowered if this is the last
200   *  mutex (i.e. resource) this task has.
201   */
202 
203  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) &&
204          _Thread_Executing->resource_count == 0 &&
205          _Thread_Executing->real_priority !=
206          _Thread_Executing->current_priority ) {
207     _Thread_Change_priority(
208       _Thread_Executing,
209       _Thread_Executing->real_priority
210     );
211  }
212
213  if ( ( the_thread = _Thread_queue_Dequeue( &the_mutex->Wait_queue ) ) ) {
214 
215    if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
216     
217      the_mutex->holder     = NULL;
218      the_mutex->holder_id  = the_thread->Object.id;
219      the_mutex->nest_count = 1;
220 
221      ( *api_mutex_mp_support)( the_thread, id );
222
223    } else {
224 
225      the_mutex->holder     = the_thread;
226      the_mutex->holder_id  = the_thread->Object.id;
227      the_thread->resource_count++;
228      the_mutex->nest_count = 1;
229 
230     /*
231      *  No special action for priority inheritance because the_thread
232      *  is guaranteed to be the highest priority thread waiting for
233      *  the mutex.
234      */
235    }
236  } else
237    the_mutex->lock = CORE_MUTEX_UNLOCKED;
238 
239  return( CORE_MUTEX_STATUS_SUCCESSFUL );
240}
241
242/*PAGE
243 *
244 *  _CORE_mutex_Flush
245 *
246 *  This function a flushes the mutex's task wait queue.
247 *
248 *  Input parameters:
249 *    the_mutex              - the mutex to be flushed
250 *    remote_extract_callout - function to invoke remotely
251 *    status                 - status to pass to thread
252 *
253 *  Output parameters:  NONE
254 */
255 
256void _CORE_mutex_Flush(
257  CORE_mutex_Control         *the_mutex,
258  Thread_queue_Flush_callout  remote_extract_callout,
259  unsigned32                  status
260)
261{
262 
263  _Thread_queue_Flush(
264    &the_mutex->Wait_queue,
265    remote_extract_callout,
266    status
267  );
268 
269}
Note: See TracBrowser for help on using the repository browser.