source: rtems/cpukit/rtems/src/sem.c @ 3652ad35

4.104.114.84.95
Last change on this file since 3652ad35 was 3652ad35, checked in by Joel Sherrill <joel.sherrill@…>, on 09/19/95 at 14:53:29

Minor bug fixes to get all targets compilable and running. The
single biggest changes were the expansion of the workspace size
macro to include other types of objects and the increase in the
minimum stack size for most CPUs.

  • Property mode set to 100644
File size: 14.7 KB
RevLine 
[ac7d5ef0]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>
[3a4ae6c]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>
[ac7d5ef0]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,
[3235ad9]65    OBJECTS_RTEMS_SEMAPHORES,
[ac7d5ef0]66    TRUE,
67    maximum_semaphores,
[3235ad9]68    sizeof( Semaphore_Control ),
69    FALSE,
[5250ff39]70    RTEMS_MAXIMUM_NAME_LENGTH,
71    FALSE
[ac7d5ef0]72  );
[3a4ae6c]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
[ac7d5ef0]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:
[3a4ae6c]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
[ac7d5ef0]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(
[3a4ae6c]106  rtems_name           name,
107  unsigned32           count,
108  rtems_attribute      attribute_set,
109  rtems_task_priority  priority_ceiling,
110  Objects_Id          *id
[ac7d5ef0]111)
112{
113  register Semaphore_Control *the_semaphore;
[3a4ae6c]114  CORE_mutex_Attributes       the_mutex_attributes;
115  CORE_semaphore_Attributes   the_semaphore_attributes;
116  unsigned32                  lock;
[ac7d5ef0]117
[3235ad9]118  if ( !rtems_is_name_valid( name ) )
[3652ad35]119    return RTEMS_INVALID_NAME;
[ac7d5ef0]120
121  if ( _Attributes_Is_global( attribute_set ) ) {
122
[3a4ae6c]123    if ( !_System_state_Is_multiprocessing )
[3652ad35]124      return RTEMS_MP_NOT_CONFIGURED;
[ac7d5ef0]125
126    if ( _Attributes_Is_inherit_priority( attribute_set ) )
[3652ad35]127      return RTEMS_NOT_DEFINED;
[ac7d5ef0]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 ) ) )
[3652ad35]133      return RTEMS_NOT_DEFINED;
[ac7d5ef0]134
135  }
136
137  if ( _Attributes_Is_binary_semaphore( attribute_set ) && ( count > 1 ) )
[3652ad35]138    return RTEMS_INVALID_NUMBER;
[ac7d5ef0]139
140  _Thread_Disable_dispatch();             /* prevents deletion */
141
142  the_semaphore = _Semaphore_Allocate();
143
144  if ( !the_semaphore ) {
145    _Thread_Enable_dispatch();
[3652ad35]146    return RTEMS_TOO_MANY;
[ac7d5ef0]147  }
148
149  if ( _Attributes_Is_global( attribute_set ) &&
[3a4ae6c]150       ! ( _Objects_MP_Allocate_and_open( &_Semaphore_Information, name,
[ac7d5ef0]151                            the_semaphore->Object.id, FALSE ) ) ) {
152    _Semaphore_Free( the_semaphore );
153    _Thread_Enable_dispatch();
[3652ad35]154    return RTEMS_TOO_MANY;
[ac7d5ef0]155  }
156
157  the_semaphore->attribute_set = attribute_set;
158
[3a4ae6c]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  }
[ac7d5ef0]200
[3235ad9]201  _Objects_Open( &_Semaphore_Information, &the_semaphore->Object, &name );
[ac7d5ef0]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();
[3652ad35]213  return RTEMS_SUCCESSFUL;
[ac7d5ef0]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(
[3a4ae6c]235  rtems_name  name,
236  unsigned32  node,
237  Objects_Id *id
[ac7d5ef0]238)
239{
[3a4ae6c]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 ];
[ac7d5ef0]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:
[3652ad35]273      return RTEMS_INVALID_ID;
[ac7d5ef0]274    case OBJECTS_REMOTE:
275      _Thread_Dispatch();
[3652ad35]276      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
[ac7d5ef0]277    case OBJECTS_LOCAL:
[3a4ae6c]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();
[3652ad35]281          return RTEMS_RESOURCE_IN_USE;
[3a4ae6c]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          );
[ac7d5ef0]289      }
[3a4ae6c]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        );
[ac7d5ef0]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();
[3652ad35]313      return RTEMS_SUCCESSFUL;
[ac7d5ef0]314  }
315
[3652ad35]316  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
[ac7d5ef0]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(
[3a4ae6c]336  Objects_Id      id,
337  unsigned32      option_set,
338  rtems_interval  timeout
[ac7d5ef0]339)
340{
341  register Semaphore_Control *the_semaphore;
342  Objects_Locations           location;
[3a4ae6c]343  boolean                     wait;
[ac7d5ef0]344
345  the_semaphore = _Semaphore_Get( id, &location );
346  switch ( location ) {
347    case OBJECTS_ERROR:
[3652ad35]348      return RTEMS_INVALID_ID;
[ac7d5ef0]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:
[3a4ae6c]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();
[3652ad35]370        return _Semaphore_Translate_core_mutex_return_code(
371                  _Thread_Executing->Wait.return_code );
[3a4ae6c]372      } else {
373        _CORE_semaphore_Seize(
374          &the_semaphore->Core_control.semaphore,
375          id,
376          wait,
377          timeout
378        );
379        _Thread_Enable_dispatch();
[3652ad35]380        return _Semaphore_Translate_core_semaphore_return_code(
381                  _Thread_Executing->Wait.return_code );
[ac7d5ef0]382      }
383  }
384
[3652ad35]385  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
[ac7d5ef0]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;
[3a4ae6c]408  CORE_mutex_Status           mutex_status;
409  CORE_semaphore_Status       semaphore_status;
[ac7d5ef0]410
411  the_semaphore = _Semaphore_Get( id, &location );
412  switch ( location ) {
413    case OBJECTS_ERROR:
[3652ad35]414      return RTEMS_INVALID_ID;
[ac7d5ef0]415    case OBJECTS_REMOTE:
[3652ad35]416      return _Semaphore_MP_Send_request_packet(
417        SEMAPHORE_MP_RELEASE_REQUEST,
418        id,
419        0,                               /* Not used */
420        MPCI_DEFAULT_TIMEOUT
[ac7d5ef0]421      );
422    case OBJECTS_LOCAL:
[3a4ae6c]423      if ( _Attributes_Is_binary_semaphore( the_semaphore->attribute_set ) ) {
424        mutex_status = _CORE_mutex_Surrender(
425                         &the_semaphore->Core_control.mutex,
426                         id,
427                         _Semaphore_Core_mutex_mp_support
428                       );
429        _Thread_Enable_dispatch();
[3652ad35]430        return _Semaphore_Translate_core_mutex_return_code( mutex_status );
[ac7d5ef0]431      }
[3a4ae6c]432      else
433        semaphore_status = _CORE_semaphore_Surrender(
434                             &the_semaphore->Core_control.semaphore,
435                             id,
436                             _Semaphore_Core_semaphore_mp_support
437                           );
438        _Thread_Enable_dispatch();
[3652ad35]439        return
440          _Semaphore_Translate_core_semaphore_return_code( semaphore_status );
[3a4ae6c]441  }
[ac7d5ef0]442
[3652ad35]443  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
[3a4ae6c]444}
[ac7d5ef0]445
[3a4ae6c]446/*PAGE
447 *
448 *  _Semaphore_Translate_core_mutex_return_code
449 *
450 *  Input parameters:
451 *    the_mutex_status - mutex status code to translate
452 *
453 *  Output parameters:
454 *    rtems status code - translated RTEMS status code
455 *
456 */
457 
458rtems_status_code _Semaphore_Translate_core_mutex_return_code (
459  unsigned32 the_mutex_status
460)
461{
462  switch ( the_mutex_status ) {
463    case  CORE_MUTEX_STATUS_SUCCESSFUL:
[3652ad35]464      return RTEMS_SUCCESSFUL;
[3a4ae6c]465    case CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT:
[3652ad35]466      return RTEMS_UNSATISFIED;
[3a4ae6c]467    case CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED:
[3652ad35]468      return RTEMS_INTERNAL_ERROR;
[3a4ae6c]469    case CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE:
[3652ad35]470      return RTEMS_NOT_OWNER_OF_RESOURCE;
[3a4ae6c]471    case CORE_MUTEX_WAS_DELETED:
[3652ad35]472      return RTEMS_OBJECT_WAS_DELETED;
[3a4ae6c]473    case CORE_MUTEX_TIMEOUT:
[3652ad35]474      return RTEMS_TIMEOUT;
[3a4ae6c]475    case THREAD_STATUS_PROXY_BLOCKING:
[3652ad35]476      return THREAD_STATUS_PROXY_BLOCKING;
[ac7d5ef0]477  }
[3652ad35]478  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
[ac7d5ef0]479}
480
481/*PAGE
482 *
[3a4ae6c]483 *  _Semaphore_Translate_core_semaphore_return_code
[ac7d5ef0]484 *
485 *  Input parameters:
[3a4ae6c]486 *    the_semaphore_status - semaphore status code to translate
[ac7d5ef0]487 *
488 *  Output parameters:
[3a4ae6c]489 *    rtems status code - translated RTEMS status code
[ac7d5ef0]490 *
491 */
[3a4ae6c]492 
493rtems_status_code _Semaphore_Translate_core_semaphore_return_code (
494  unsigned32 the_semaphore_status
[ac7d5ef0]495)
496{
[3a4ae6c]497  switch ( the_semaphore_status ) {
498    case  CORE_SEMAPHORE_STATUS_SUCCESSFUL:
[3652ad35]499      return RTEMS_SUCCESSFUL;
[3a4ae6c]500    case CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT:
[3652ad35]501      return RTEMS_UNSATISFIED;
[3a4ae6c]502    case CORE_SEMAPHORE_WAS_DELETED:
[3652ad35]503      return RTEMS_OBJECT_WAS_DELETED;
[3a4ae6c]504    case CORE_SEMAPHORE_TIMEOUT:
[3652ad35]505      return RTEMS_TIMEOUT;
[3a4ae6c]506    case THREAD_STATUS_PROXY_BLOCKING:
[3652ad35]507      return THREAD_STATUS_PROXY_BLOCKING;
[ac7d5ef0]508  }
[3652ad35]509  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
[3a4ae6c]510}
[ac7d5ef0]511
[3a4ae6c]512/*PAGE
513 *
514 *  _Semaphore_Core_mutex_mp_support
515 *
516 *  Input parameters:
517 *    the_thread - the remote thread the semaphore was surrendered to
518 *    id         - id of the surrendered semaphore
519 *
520 *  Output parameters: NONE
521 */
522 
523void  _Semaphore_Core_mutex_mp_support (
524  Thread_Control *the_thread,
525  Objects_Id      id
526)
527{
528  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
529 
530  _Semaphore_MP_Send_response_packet(
531     SEMAPHORE_MP_OBTAIN_RESPONSE,
532     id,
533     the_thread
534   );
535}
[ac7d5ef0]536
537
[3a4ae6c]538/*PAGE
539 *
540 *  _Semaphore_Core_semaphore_mp_support
541 *
542 *  Input parameters:
543 *    the_thread - the remote thread the semaphore was surrendered to
544 *    id         - id of the surrendered semaphore
545 *
546 *  Output parameters: NONE
547 */
548 
549void  _Semaphore_Core_semaphore_mp_support (
550  Thread_Control *the_thread,
551  Objects_Id      id
552)
553{
554  the_thread->receive_packet->return_code = RTEMS_SUCCESSFUL;
555 
556  _Semaphore_MP_Send_response_packet(
557     SEMAPHORE_MP_OBTAIN_RESPONSE,
558     id,
559     the_thread
560   );
[ac7d5ef0]561}
Note: See TracBrowser for help on using the repository browser.