source: rtems/cpukit/posix/src/mutexinit.c @ e7bd66a7

4.104.114.84.95
Last change on this file since e7bd66a7 was 3c465878, checked in by Joel Sherrill <joel.sherrill@…>, on 07/01/02 at 22:33:47

2002-07-01 Joel Sherrill <joel@…>

  • Mega patch merge to change the format of the object IDs to loosen the dependency between the SCORE and the various APIs. There was considerable work to simplify the object name management and it appears that the name_table field is no longer needed. This patch also includes the addition of the internal mutex which is currently only used to protect some types of allocation and deallocation. This significantly can reduce context switch latency under certain circumstances. In particular, some heap/region operations were O(n) and had dispatching disabled. This should help enormously. With this merge, the patch is not as clean as it should be. In particular, the documentation has not been modified to reflect the new object ID layout, the IDs in the test screens are not updated, and _Objects_Get_information needs to be a real routine not inlined. As part of this patch a lot of MP code for thread/proxy blocking was made conditional and cleaned up.
  • include/rtems/posix/key.h, src/cond.c, src/condinit.c, src/intr.c, src/key.c, src/keycreate.c, src/keydelete.c, src/killinfo.c, src/mqueue.c, src/mqueuecreatesupp.c, src/mutex.c, src/mutexinit.c, src/psignal.c, src/pthread.c, src/semaphore.c, src/semaphorecreatesupp.c: Modified as part of above.
  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 *  $Id$
3 */
4
5#if HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9#include <assert.h>
10#include <errno.h>
11#include <pthread.h>
12
13#include <rtems/system.h>
14#include <rtems/score/coremutex.h>
15#include <rtems/score/watchdog.h>
16#if defined(RTEMS_MULTIPROCESSING)
17#include <rtems/score/mpci.h>
18#endif
19#include <rtems/posix/mutex.h>
20#include <rtems/posix/priority.h>
21#include <rtems/posix/time.h>
22
23/*PAGE
24 *
25 *  11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
26 *
27 *  NOTE:  XXX Could be optimized so all the attribute error checking
28 *             is not performed when attr is NULL.
29 */
30
31int pthread_mutex_init(
32  pthread_mutex_t           *mutex,
33  const pthread_mutexattr_t *attr
34)
35{
36  POSIX_Mutex_Control          *the_mutex;
37  CORE_mutex_Attributes        *the_mutex_attr;
38  const pthread_mutexattr_t    *the_attr;
39  CORE_mutex_Disciplines        the_discipline;
40#if 0
41  register POSIX_Mutex_Control *mutex_in_use;
42  Objects_Locations             location;
43#endif
44
45  if ( attr ) the_attr = attr;
46  else        the_attr = &_POSIX_Mutex_Default_attributes;
47
48  /* Check for NULL mutex */
49
50  if ( !mutex )
51    return EINVAL;
52
53  /*
54   *  This code should eventually be removed. 
55   *
56   *  Although the POSIX specification says:
57   *
58   *  "Attempting to initialize an already initialized mutex results
59   *  in undefined behavior."
60   *
61   *  Trying to keep the caller from doing the create when *mutex
62   *  is actually a valid ID causes grief.  All it takes is the wrong
63   *  value in an uninitialized variable to make this fail.  As best
64   *  I can tell, RTEMS was the only pthread implementation to choose
65   *  this option for "undefined behavior" and doing so has created
66   *  portability problems.  In particular, Rosimildo DaSilva
67   *  <rdasilva@connecttel.com> saw seemingly random failures in the
68   *  RTEMS port of omniORB2 when this code was enabled.
69   *
70   *  Joel Sherrill <joel@OARcorp.com>     14 May 1999
71   */
72
73 
74#if 0
75  /* avoid infinite recursion on call to this routine in _POSIX_Mutex_Get */
76
77  if ( *mutex != PTHREAD_MUTEX_INITIALIZER ) {
78
79    /* EBUSY if *mutex is a valid id */
80
81    mutex_in_use = _POSIX_Mutex_Get( mutex, &location );
82    switch ( location ) {
83      case OBJECTS_REMOTE:
84      case OBJECTS_ERROR:
85        break;
86      case OBJECTS_LOCAL:
87        _Thread_Enable_dispatch();
88        return EBUSY;
89    }
90  }
91#endif
92 
93  if ( !the_attr->is_initialized )
94    return EINVAL;
95
96  /*
97   *  XXX: Be careful about attributes when global!!!
98   */
99
100  assert( the_attr->process_shared == PTHREAD_PROCESS_PRIVATE );
101
102#if defined(RTEMS_MULTIPROCESSING)
103  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
104    return POSIX_MP_NOT_IMPLEMENTED();
105#endif
106 
107  /*
108   *  Determine the discipline of the mutex
109   */
110 
111  switch ( the_attr->protocol ) {
112    case PTHREAD_PRIO_NONE:
113      the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
114      break;
115    case PTHREAD_PRIO_INHERIT:
116      the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
117      break;
118    case PTHREAD_PRIO_PROTECT:
119      the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
120      break;
121    default:
122      return EINVAL;
123  }
124
125  if ( !_POSIX_Priority_Is_valid( the_attr->prio_ceiling ) )
126    return EINVAL;
127
128  _Thread_Disable_dispatch();
129
130  the_mutex = _POSIX_Mutex_Allocate();
131 
132  if ( !the_mutex ) {
133    _Thread_Enable_dispatch();
134    return EAGAIN;
135  }
136
137#if defined(RTEMS_MULTIPROCESSING)
138  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED &&
139       !( _Objects_MP_Allocate_and_open( &_POSIX_Mutex_Information, 0,
140                            the_mutex->Object.id, FALSE ) ) ) {
141    _POSIX_Mutex_Free( the_mutex );
142    _Thread_Enable_dispatch();
143    return EAGAIN;
144  }
145#endif
146
147  the_mutex->process_shared = the_attr->process_shared;
148
149  the_mutex_attr = &the_mutex->Mutex.Attributes;
150
151  if ( the_attr->recursive )
152    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
153  else
154    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
155  the_mutex_attr->only_owner_release = TRUE;
156  the_mutex_attr->priority_ceiling =
157    _POSIX_Priority_To_core( the_attr->prio_ceiling );
158  the_mutex_attr->discipline = the_discipline;
159
160  /*
161   *  Must be initialized to unlocked.
162   */
163
164  _CORE_mutex_Initialize(
165    &the_mutex->Mutex,
166    the_mutex_attr,
167    CORE_MUTEX_UNLOCKED
168  );
169
170  _Objects_Open( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
171
172  *mutex = the_mutex->Object.id;
173
174#if defined(RTEMS_MULTIPROCESSING)
175  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
176    _POSIX_Mutex_MP_Send_process_packet(
177      POSIX_MUTEX_MP_ANNOUNCE_CREATE,
178      the_mutex->Object.id,
179      0,                         /* Name not used */
180      0                          /* Not used */
181    );
182#endif
183
184  _Thread_Enable_dispatch();
185  return 0;
186}
Note: See TracBrowser for help on using the repository browser.