source: rtems/cpukit/posix/src/mutexinit.c @ 23fec9f0

4.115
Last change on this file since 23fec9f0 was 23fec9f0, checked in by Sebastian Huber <sebastian.huber@…>, on 03/27/14 at 13:16:12

score: PR2152: Use allocator mutex for objects

Use allocator mutex for objects allocate/free. This prevents that the
thread dispatch latency depends on the workspace/heap fragmentation.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/**
2 * @file
3 *
4 * @brief Initialize a Mutex
5 * @ingroup POSIXAPI
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2009.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <errno.h>
22#include <pthread.h>
23
24#include <rtems/system.h>
25#include <rtems/score/coremuteximpl.h>
26#include <rtems/score/watchdog.h>
27#include <rtems/posix/muteximpl.h>
28#include <rtems/posix/priorityimpl.h>
29#include <rtems/posix/time.h>
30
31/**
32 * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
33 *
34 * NOTE:  XXX Could be optimized so all the attribute error checking
35 *            is not performed when attr is NULL.
36 */
37
38int pthread_mutex_init(
39  pthread_mutex_t           *mutex,
40  const pthread_mutexattr_t *attr
41)
42{
43  POSIX_Mutex_Control          *the_mutex;
44  CORE_mutex_Attributes        *the_mutex_attr;
45  const pthread_mutexattr_t    *the_attr;
46  CORE_mutex_Disciplines        the_discipline;
47
48  if ( attr ) the_attr = attr;
49  else        the_attr = &_POSIX_Mutex_Default_attributes;
50
51  /* Check for NULL mutex */
52  if ( !mutex )
53    return EINVAL;
54
55  /*
56   *  This code should eventually be removed.
57   *
58   *  Although the POSIX specification says:
59   *
60   *  "Attempting to initialize an already initialized mutex results
61   *  in undefined behavior."
62   *
63   *  Trying to keep the caller from doing the create when *mutex
64   *  is actually a valid ID causes grief.  All it takes is the wrong
65   *  value in an uninitialized variable to make this fail.  As best
66   *  I can tell, RTEMS was the only pthread implementation to choose
67   *  this option for "undefined behavior" and doing so has created
68   *  portability problems.  In particular, Rosimildo DaSilva
69   *  <rdasilva@connecttel.com> saw seemingly random failures in the
70   *  RTEMS port of omniORB2 when this code was enabled.
71   *
72   *  Joel Sherrill <joel@OARcorp.com>     14 May 1999
73   *  NOTE: Be careful to avoid infinite recursion on call to this
74   *        routine in _POSIX_Mutex_Get.
75   */
76  #if 0
77  {
78    POSIX_Mutex_Control *mutex_in_use;
79    Objects_Locations    location;
80
81    if ( *mutex != PTHREAD_MUTEX_INITIALIZER ) {
82
83      /* EBUSY if *mutex is a valid id */
84
85      mutex_in_use = _POSIX_Mutex_Get( mutex, &location );
86      switch ( location ) {
87        case OBJECTS_LOCAL:
88          _Objects_Put( &mutex_in_use->Object );
89          return EBUSY;
90        #if defined(RTEMS_MULTIPROCESSING)
91          case OBJECTS_REMOTE:
92        #endif
93        case OBJECTS_ERROR:
94          break;
95      }
96    }
97  }
98  #endif
99
100  if ( !the_attr->is_initialized )
101    return EINVAL;
102
103  /*
104   *  We only support process private mutexes.
105   */
106  if ( the_attr->process_shared == PTHREAD_PROCESS_SHARED )
107    return ENOSYS;
108
109  if ( the_attr->process_shared != PTHREAD_PROCESS_PRIVATE )
110    return EINVAL;
111
112  /*
113   *  Determine the discipline of the mutex
114   */
115  switch ( the_attr->protocol ) {
116    case PTHREAD_PRIO_NONE:
117      the_discipline = CORE_MUTEX_DISCIPLINES_FIFO;
118      break;
119    case PTHREAD_PRIO_INHERIT:
120      the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT;
121      break;
122    case PTHREAD_PRIO_PROTECT:
123      the_discipline = CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING;
124      break;
125    default:
126      return EINVAL;
127  }
128
129  /*
130   *  Validate the priority ceiling field -- should always be valid.
131   */
132  if ( !_POSIX_Priority_Is_valid( the_attr->prio_ceiling ) )
133    return EINVAL;
134
135#if defined(_UNIX98_THREAD_MUTEX_ATTRIBUTES)
136  /*
137   *  Validate the mutex type and set appropriate SuperCore mutex
138   *  attributes.
139   */
140  switch ( the_attr->type ) {
141    case PTHREAD_MUTEX_NORMAL:
142    case PTHREAD_MUTEX_RECURSIVE:
143    case PTHREAD_MUTEX_ERRORCHECK:
144    case PTHREAD_MUTEX_DEFAULT:
145      break;
146
147    default:
148      return EINVAL;
149  }
150#endif
151
152  the_mutex = _POSIX_Mutex_Allocate();
153
154  if ( !the_mutex ) {
155    _Objects_Allocator_unlock();
156    return EAGAIN;
157  }
158
159  the_mutex->process_shared = the_attr->process_shared;
160
161  the_mutex_attr = &the_mutex->Mutex.Attributes;
162
163  if ( the_attr->type == PTHREAD_MUTEX_RECURSIVE )
164    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_ACQUIRES;
165  else
166    the_mutex_attr->lock_nesting_behavior = CORE_MUTEX_NESTING_IS_ERROR;
167  the_mutex_attr->only_owner_release = true;
168  the_mutex_attr->priority_ceiling =
169    _POSIX_Priority_To_core( the_attr->prio_ceiling );
170  the_mutex_attr->discipline = the_discipline;
171
172  /*
173   *  Must be initialized to unlocked.
174   */
175  _CORE_mutex_Initialize(
176    &the_mutex->Mutex,
177    NULL,
178    the_mutex_attr,
179    CORE_MUTEX_UNLOCKED
180  );
181
182  _Objects_Open_u32( &_POSIX_Mutex_Information, &the_mutex->Object, 0 );
183
184  *mutex = the_mutex->Object.id;
185
186  _Objects_Allocator_unlock();
187  return 0;
188}
Note: See TracBrowser for help on using the repository browser.