OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [posix/] [src/] [mutexinit.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
 *  mutexinit.c,v 1.4 2002/07/01 22:33:47 joel Exp
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
 
31
int 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
 
181
    );
182
#endif
183
 
184
  _Thread_Enable_dispatch();
185
  return 0;
186
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.