source: rtems/cpukit/rtems/src/sem.c @ 3a4ae6c

4.104.114.84.95
Last change on this file since 3a4ae6c was 3a4ae6c, checked in by Joel Sherrill <joel.sherrill@…>, on 09/11/95 at 19:35:39

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: 15.1 KB
Line 
1/*
2 *  Semaphore Manager
3 *
4 *  DESCRIPTION:
5 *
6 *  This package is the implementation of the Semaphore Manager.
7 *  This manager utilizes standard Dijkstra counting semaphores to provide
8 *  synchronization and mutual exclusion capabilities.
9 *
10 *  Directives provided are:
11 *
12 *     + create a semaphore
13 *     + get an ID of a semaphore
14 *     + delete a semaphore
15 *     + acquire a semaphore
16 *     + release a semaphore
17 *
18 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
19 *  On-Line Applications Research Corporation (OAR).
20 *  All rights assigned to U.S. Government, 1994.
21 *
22 *  This material may be reproduced by or for the U.S. Government pursuant
23 *  to the copyright license under the clause at DFARS 252.227-7013.  This
24 *  notice must appear in all copies of this file and its derivatives.
25 *
26 *  $Id$
27 */
28
29#include <rtems/system.h>
30#include <rtems/rtems/status.h>
31#include <rtems/rtems/support.h>
32#include <rtems/rtems/attr.h>
33#include <rtems/core/isr.h>
34#include <rtems/core/object.h>
35#include <rtems/rtems/options.h>
36#include <rtems/rtems/sem.h>
37#include <rtems/core/coremutex.h>
38#include <rtems/core/coresem.h>
39#include <rtems/core/states.h>
40#include <rtems/core/thread.h>
41#include <rtems/core/threadq.h>
42#include <rtems/core/mpci.h>
43#include <rtems/sysstate.h>
44
45#include <rtems/core/interr.h>
46
47/*PAGE
48 *
49 *  _Semaphore_Manager_initialization
50 *
51 *  This routine initializes all semaphore manager related data structures.
52 *
53 *  Input parameters:
54 *    maximum_semaphores - maximum configured semaphores
55 *
56 *  Output parameters:  NONE
57 */
58
59void _Semaphore_Manager_initialization(
60  unsigned32 maximum_semaphores
61)
62{
63  _Objects_Initialize_information(
64    &_Semaphore_Information,
65    OBJECTS_RTEMS_SEMAPHORES,
66    TRUE,
67    maximum_semaphores,
68    sizeof( Semaphore_Control ),
69    FALSE,
70    RTEMS_MAXIMUM_NAME_LENGTH,
71    FALSE
72  );
73 
74  /*
75   *  Register the MP Process Packet routine.
76   */
77 
78  _MPCI_Register_packet_processor(
79    MP_PACKET_SEMAPHORE,
80    _Semaphore_MP_Process_packet
81  );
82
83}
84
85/*PAGE
86 *
87 *  rtems_semaphore_create
88 *
89 *  This directive creates a semaphore and sets the initial value based
90 *  on the given count.  A semaphore id is returned.
91 *
92 *  Input parameters:
93 *    name             - user defined semaphore name
94 *    count            - initial count of semaphore
95 *    attribute_set    - semaphore attributes
96 *    priority_ceiling - semaphore's ceiling priority
97 *    id               - pointer to semaphore id
98 *
99 *  Output parameters:
100 *    id       - semaphore id
101 *    RTEMS_SUCCESSFUL - if successful
102 *    error code - if unsuccessful
103 */
104
105rtems_status_code rtems_semaphore_create(
106  rtems_name           name,
107  unsigned32           count,
108  rtems_attribute      attribute_set,
109  rtems_task_priority  priority_ceiling,
110  Objects_Id          *id
111)
112{
113  register Semaphore_Control *the_semaphore;
114  CORE_mutex_Attributes       the_mutex_attributes;
115  CORE_semaphore_Attributes   the_semaphore_attributes;
116  unsigned32                  lock;
117
118  if ( !rtems_is_name_valid( name ) )
119    return ( RTEMS_INVALID_NAME );
120
121  if ( _Attributes_Is_global( attribute_set ) ) {
122
123    if ( !_System_state_Is_multiprocessing )
124      return( RTEMS_MP_NOT_CONFIGURED );
125
126    if ( _Attributes_Is_inherit_priority( attribute_set ) )
127      return( RTEMS_NOT_DEFINED );
128
129  } else if ( _Attributes_Is_inherit_priority( attribute_set ) ) {
130
131    if ( ! ( _Attributes_Is_binary_semaphore( attribute_set ) &&
132             _Attributes_Is_priority( attribute_set ) ) )
133      return( RTEMS_NOT_DEFINED );
134
135  }
136
137  if ( _Attributes_Is_binary_semaphore( attribute_set ) && ( count > 1 ) )
138    return( RTEMS_INVALID_NUMBER );
139
140  _Thread_Disable_dispatch();             /* prevents deletion */
141
142  the_semaphore = _Semaphore_Allocate();
143
144  if ( !the_semaphore ) {
145    _Thread_Enable_dispatch();
146    return( RTEMS_TOO_MANY );
147  }
148
149  if ( _Attributes_Is_global( attribute_set ) &&
150       ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
151                            the_semaphore->Object.id, FALSE ) ) ) {
152    _Semaphore_Free( the_semaphore );
153    _Thread_Enable_dispatch();
154    return( RTEMS_TOO_MANY );
155  }
156
157  the_semaphore->attribute_set = attribute_set;
158
159  if ( _Attributes_Is_binary_semaphore( attribute_set ) ) {
160    if ( _Attributes_Is_inherit_priority( attribute_set ) )
161      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
162    else if (_Attributes_Is_priority_ceiling( attribute_set ) )
163      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
164    else if (_Attributes_Is_priority( attribute_set ) )
165      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_PRIORITY;
166    else
167      the_mutex_attributes.discipline = CORE_MUTEX_DISCIPLINES_FIFO;
168
169    the_mutex_attributes.allow_nesting = TRUE;
170
171    /* Add priority ceiling code here ????? */
172
173    if ( count == 1 )
174      lock = CORE_MUTEX_UNLOCKED;
175    else
176      lock = CORE_MUTEX_LOCKED;
177
178    _CORE_mutex_Initialize(
179      &the_semaphore->Core_control.mutex,
180      OBJECTS_RTEMS_SEMAPHORES,
181      &the_mutex_attributes,
182      lock,
183      _Semaphore_MP_Send_extract_proxy
184    );
185  }
186  else {
187    if ( _Attributes_Is_priority( attribute_set ) )
188      the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_PRIORITY;
189    else
190      the_semaphore_attributes.discipline = CORE_SEMAPHORE_DISCIPLINES_FIFO;
191
192    _CORE_semaphore_Initialize(
193      &the_semaphore->Core_control.semaphore,
194      OBJECTS_RTEMS_SEMAPHORES,
195      &the_semaphore_attributes,
196      count,
197      _Semaphore_MP_Send_extract_proxy
198    );
199  }
200
201  _Objects_Open( &_Semaphore_Information, &the_semaphore->Object, &name );
202
203  *id = the_semaphore->Object.id;
204
205  if ( _Attributes_Is_global( attribute_set ) )
206    _Semaphore_MP_Send_process_packet(
207      SEMAPHORE_MP_ANNOUNCE_CREATE,
208      the_semaphore->Object.id,
209      name,
210      0                          /* Not used */
211    );
212  _Thread_Enable_dispatch();
213  return( RTEMS_SUCCESSFUL );
214}
215
216/*PAGE
217 *
218 *  rtems_semaphore_ident
219 *
220 *  This directive returns the system ID associated with
221 *  the semaphore name.
222 *
223 *  Input parameters:
224 *    name - user defined semaphore name
225 *    node - node(s) to be searched
226 *    id   - pointer to semaphore id
227 *
228 *  Output parameters:
229 *    *id      - semaphore id
230 *    RTEMS_SUCCESSFUL - if successful
231 *    error code - if unsuccessful
232 */
233
234rtems_status_code rtems_semaphore_ident(
235  rtems_name  name,
236  unsigned32  node,
237  Objects_Id *id
238)
239{
240  Objects_Name_to_id_errors  status;
241 
242  status = _Objects_Name_to_id( &_Semaphore_Information, &name, node, id );
243 
244  return _Status_Object_name_errors_to_status[ status ];
245}
246
247/*PAGE
248 *
249 *  rtems_semaphore_delete
250 *
251 *  This directive allows a thread to delete a semaphore specified by
252 *  the semaphore id.  The semaphore is freed back to the inactive
253 *  semaphore chain.
254 *
255 *  Input parameters:
256 *    id - semaphore id
257 *
258 *  Output parameters:
259 *    RTEMS_SUCCESSFUL - if successful
260 *    error code        - if unsuccessful
261 */
262
263rtems_status_code rtems_semaphore_delete(
264  Objects_Id id
265)
266{
267  register Semaphore_Control *the_semaphore;
268  Objects_Locations           location;
269
270  the_semaphore = _Semaphore_Get( id, &location );
271  switch ( location ) {
272    case OBJECTS_ERROR:
273      return( RTEMS_INVALID_ID );
274    case OBJECTS_REMOTE:
275      _Thread_Dispatch();
276      return( RTEMS_ILLEGAL_ON_REMOTE_OBJECT );
277    case OBJECTS_LOCAL:
278      if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set) ) {
279        if ( _CORE_mutex_Is_locked( &the_semaphore->Core_control.mutex ) ) {
280          _Thread_Enable_dispatch();
281          return( RTEMS_RESOURCE_IN_USE );
282        }
283        else
284          _CORE_mutex_Flush(
285            &the_semaphore->Core_control.mutex,
286            _Semaphore_MP_Send_object_was_deleted,
287            CORE_MUTEX_WAS_DELETED
288          );
289      }
290      else
291        _CORE_semaphore_Flush(
292          &the_semaphore->Core_control.semaphore,
293          _Semaphore_MP_Send_object_was_deleted,
294          CORE_SEMAPHORE_WAS_DELETED
295        );
296
297      _Objects_Close( &_Semaphore_Information, &the_semaphore->Object );
298
299      _Semaphore_Free( the_semaphore );
300
301      if ( _Attributes_Is_global( the_semaphore->attribute_set ) ) {
302
303        _Objects_MP_Close( &_Semaphore_Information, the_semaphore->Object.id );
304
305        _Semaphore_MP_Send_process_packet(
306          SEMAPHORE_MP_ANNOUNCE_DELETE,
307          the_semaphore->Object.id,
308          0,                         /* Not used */
309          0                          /* Not used */
310        );
311      }
312      _Thread_Enable_dispatch();
313      return( RTEMS_SUCCESSFUL );
314  }
315
316  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
317}
318
319/*PAGE
320 *
321 *  rtems_semaphore_obtain
322 *
323 *  This directive allows a thread to acquire a semaphore.
324 *
325 *  Input parameters:
326 *    id         - semaphore id
327 *    option_set - wait option
328 *    timeout    - number of ticks to wait (0 means wait forever)
329 *
330 *  Output parameters:
331 *    RTEMS_SUCCESSFUL - if successful
332 *    error code        - if unsuccessful
333 */
334
335rtems_status_code rtems_semaphore_obtain(
336  Objects_Id      id,
337  unsigned32      option_set,
338  rtems_interval  timeout
339)
340{
341  register Semaphore_Control *the_semaphore;
342  Objects_Locations           location;
343  boolean                     wait;
344
345  the_semaphore = _Semaphore_Get( id, &location );
346  switch ( location ) {
347    case OBJECTS_ERROR:
348      return( RTEMS_INVALID_ID );
349    case OBJECTS_REMOTE:
350      return _Semaphore_MP_Send_request_packet(
351          SEMAPHORE_MP_OBTAIN_REQUEST,
352          id,
353          option_set,
354          timeout
355      );
356    case OBJECTS_LOCAL:
357      if ( _Options_Is_no_wait( option_set ) )
358        wait = FALSE;
359      else
360        wait = TRUE;
361
362      if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
363        _CORE_mutex_Seize(
364          &the_semaphore->Core_control.mutex,
365          id,
366          wait,
367          timeout
368        );
369        _Thread_Enable_dispatch();
370        return( _Semaphore_Translate_core_mutex_return_code(
371                  _Thread_Executing->Wait.return_code ) );
372      } else {
373        _CORE_semaphore_Seize(
374          &the_semaphore->Core_control.semaphore,
375          id,
376          wait,
377          timeout
378        );
379        _Thread_Enable_dispatch();
380        return( _Semaphore_Translate_core_semaphore_return_code(
381                  _Thread_Executing->Wait.return_code ) );
382      }
383  }
384
385  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
386}
387
388/*PAGE
389 *
390 *  rtems_semaphore_release
391 *
392 *  This directive allows a thread to release a semaphore.
393 *
394 *  Input parameters:
395 *    id - semaphore id
396 *
397 *  Output parameters:
398 *    RTEMS_SUCCESSFUL - if successful
399 *    error code        - if unsuccessful
400 */
401
402rtems_status_code rtems_semaphore_release(
403  Objects_Id id
404)
405{
406  register Semaphore_Control *the_semaphore;
407  Objects_Locations           location;
408  CORE_mutex_Status           mutex_status;
409  CORE_semaphore_Status       semaphore_status;
410
411  the_semaphore = _Semaphore_Get( id, &location );
412  switch ( location ) {
413    case OBJECTS_ERROR:
414      return( RTEMS_INVALID_ID );
415    case OBJECTS_REMOTE:
416      return(
417        _Semaphore_MP_Send_request_packet(
418          SEMAPHORE_MP_RELEASE_REQUEST,
419          id,
420          0,                               /* Not used */
421          MPCI_DEFAULT_TIMEOUT
422        )
423      );
424    case OBJECTS_LOCAL:
425      if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
426        mutex_status = _CORE_mutex_Surrender(
427                         &the_semaphore->Core_control.mutex,
428                         id,
429                         _Semaphore_Core_mutex_mp_support
430                       );
431        _Thread_Enable_dispatch();
432        return( _Semaphore_Translate_core_mutex_return_code( mutex_status ) );
433      }
434      else
435        semaphore_status = _CORE_semaphore_Surrender(
436                             &the_semaphore->Core_control.semaphore,
437                             id,
438                             _Semaphore_Core_semaphore_mp_support
439                           );
440        _Thread_Enable_dispatch();
441        return(
442          _Semaphore_Translate_core_semaphore_return_code( semaphore_status ) );
443  }
444
445  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
446}
447
448/*PAGE
449 *
450 *  _Semaphore_Translate_core_mutex_return_code
451 *
452 *  Input parameters:
453 *    the_mutex_status - mutex status code to translate
454 *
455 *  Output parameters:
456 *    rtems status code - translated RTEMS status code
457 *
458 */
459 
460rtems_status_code _Semaphore_Translate_core_mutex_return_code (
461  unsigned32 the_mutex_status
462)
463{
464  switch ( the_mutex_status ) {
465    case  CORE_MUTEX_STATUS_SUCCESSFUL:
466      return( RTEMS_SUCCESSFUL );
467    case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
468      return( RTEMS_UNSATISFIED );
469    case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
470      return( RTEMS_INTERNAL_ERROR );
471    case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
472      return( RTEMS_NOT_OWNER_OF_RESOURCE );
473    case CORE_MUTEX_WAS_DELETED:
474      return( RTEMS_OBJECT_WAS_DELETED );
475    case CORE_MUTEX_TIMEOUT:
476      return( RTEMS_TIMEOUT );
477    case THREAD_STATUS_PROXY_BLOCKING:
478      return( THREAD_STATUS_PROXY_BLOCKING );
479  }
480  _Internal_error_Occurred(
481    INTERNAL_ERROR_RTEMS_API,
482    TRUE,
483    the_mutex_status
484  );
485  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
486}
487
488/*PAGE
489 *
490 *  _Semaphore_Translate_core_semaphore_return_code
491 *
492 *  Input parameters:
493 *    the_semaphore_status - semaphore status code to translate
494 *
495 *  Output parameters:
496 *    rtems status code - translated RTEMS status code
497 *
498 */
499 
500rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
501  unsigned32 the_semaphore_status
502)
503{
504  switch ( the_semaphore_status ) {
505    case  CORE_SEMAPHORE_STATUS_SUCCESSFUL:
506      return( RTEMS_SUCCESSFUL );
507    case CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT:
508      return( RTEMS_UNSATISFIED );
509    case CORE_SEMAPHORE_WAS_DELETED:
510      return( RTEMS_OBJECT_WAS_DELETED );
511    case CORE_SEMAPHORE_TIMEOUT:
512      return( RTEMS_TIMEOUT );
513    case THREAD_STATUS_PROXY_BLOCKING:
514      return( THREAD_STATUS_PROXY_BLOCKING );
515  }
516  _Internal_error_Occurred(
517    INTERNAL_ERROR_RTEMS_API,
518    TRUE,
519    the_semaphore_status
520  );
521  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
522  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
523}
524
525/*PAGE
526 *
527 *  _Semaphore_Core_mutex_mp_support
528 *
529 *  Input parameters:
530 *    the_thread - the remote thread the semaphore was surrendered to
531 *    id         - id of the surrendered semaphore
532 *
533 *  Output parameters: NONE
534 */
535 
536void  _Semaphore_Core_mutex_mp_support (
537  Thread_Control *the_thread,
538  Objects_Id      id
539)
540{
541  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
542 
543  _Semaphore_MP_Send_response_packet(
544     SEMAPHORE_MP_OBTAIN_RESPONSE,
545     id,
546     the_thread
547   );
548}
549
550
551/*PAGE
552 *
553 *  _Semaphore_Core_semaphore_mp_support
554 *
555 *  Input parameters:
556 *    the_thread - the remote thread the semaphore was surrendered to
557 *    id         - id of the surrendered semaphore
558 *
559 *  Output parameters: NONE
560 */
561 
562void  _Semaphore_Core_semaphore_mp_support (
563  Thread_Control *the_thread,
564  Objects_Id      id
565)
566{
567  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
568 
569  _Semaphore_MP_Send_response_packet(
570     SEMAPHORE_MP_OBTAIN_RESPONSE,
571     id,
572     the_thread
573   );
574}
Note: See TracBrowser for help on using the repository browser.