1 #define _MTHREADIFY_PTHREADS
2 #include <minix/mthread.h>
3 #include "global.h"
4 #include "proto.h"
5
6 /* WARNING:
7 * The following works under the hypothesis that we have only green threads,
8 * which implies that we have no preemption, unless explicit yield or possible
9 * calls done to mthread functions.
10 *
11 * This has impact on the fact we do not maintain a table of currently being
12 * initialized mutexes or condition variables, to prevent double initialization
13 * and/or TOCTU problems. TOCTU could appear between the test against the
14 * initializer value, and the actual initialization, which could lead to double
15 * initialization of the same mutex AND get two threads at the same time in the
16 * critical section as they both hold a (different) mutex.
17 */
18
19
20 /*===========================================================================*
21 * pthread_mutex_init *
22 *===========================================================================*/
pthread_mutex_init(pthread_mutex_t * mutex,pthread_mutexattr_t * mattr)23 int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *mattr)
24 {
25 return mthread_mutex_init(mutex, mattr);
26 }
27
28 /*===========================================================================*
29 * pthread_mutex_destroy *
30 *===========================================================================*/
pthread_mutex_destroy(pthread_mutex_t * mutex)31 int pthread_mutex_destroy(pthread_mutex_t *mutex)
32 {
33 if (PTHREAD_MUTEX_INITIALIZER == *mutex) {
34 *mutex = NULL;
35 return 0;
36 }
37
38 return mthread_mutex_destroy(mutex);
39 }
40
41 /*===========================================================================*
42 * pthread_mutex_lock *
43 *===========================================================================*/
pthread_mutex_lock(pthread_mutex_t * mutex)44 int pthread_mutex_lock(pthread_mutex_t *mutex)
45 {
46 if (PTHREAD_MUTEX_INITIALIZER == *mutex) {
47 mthread_mutex_init(mutex, NULL);
48 }
49
50 return mthread_mutex_lock(mutex);
51 }
52
53 /*===========================================================================*
54 * pthread_mutex_trylock *
55 *===========================================================================*/
pthread_mutex_trylock(pthread_mutex_t * mutex)56 int pthread_mutex_trylock(pthread_mutex_t *mutex)
57 {
58 if (PTHREAD_MUTEX_INITIALIZER == *mutex) {
59 mthread_mutex_init(mutex, NULL);
60 }
61
62 return pthread_mutex_trylock(mutex);
63 }
64
65 /*===========================================================================*
66 * pthread_mutex_unlock *
67 *===========================================================================*/
pthread_mutex_unlock(pthread_mutex_t * mutex)68 int pthread_mutex_unlock(pthread_mutex_t *mutex)
69 {
70 if (PTHREAD_MUTEX_INITIALIZER == *mutex) {
71 mthread_mutex_init(mutex, NULL);
72 }
73
74 return mthread_mutex_unlock(mutex);
75 }
76
77 /*===========================================================================*
78 * pthread_cond_init *
79 *===========================================================================*/
pthread_cond_init(pthread_cond_t * cond,pthread_condattr_t * cattr)80 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cattr)
81 {
82 return mthread_cond_init(cond, cattr);
83 }
84
85 /*===========================================================================*
86 * pthread_cond_broadcast *
87 *===========================================================================*/
pthread_cond_broadcast(pthread_cond_t * cond)88 int pthread_cond_broadcast(pthread_cond_t *cond)
89 {
90 if (PTHREAD_COND_INITIALIZER == *cond) {
91 mthread_cond_init(cond, NULL);
92 }
93
94 return mthread_cond_broadcast(cond);
95 }
96
97 /*===========================================================================*
98 * pthread_cond_destroy *
99 *===========================================================================*/
pthread_cond_destroy(pthread_cond_t * cond)100 int pthread_cond_destroy(pthread_cond_t *cond)
101 {
102 if (PTHREAD_COND_INITIALIZER == *cond) {
103 *cond = NULL;
104 return 0;
105 }
106
107 return mthread_cond_destroy(cond);
108 }
109
110 /*===========================================================================*
111 * pthread_cond_signal *
112 *===========================================================================*/
pthread_cond_signal(pthread_cond_t * cond)113 int pthread_cond_signal(pthread_cond_t *cond)
114 {
115 if (PTHREAD_COND_INITIALIZER == *cond) {
116 mthread_cond_init(cond, NULL);
117 }
118
119 return mthread_cond_signal(cond);
120 }
121
122 /*===========================================================================*
123 * pthread_cond_wait *
124 *===========================================================================*/
pthread_cond_wait(pthread_cond_t * cond,pthread_mutex_t * mutex)125 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
126 {
127 if (PTHREAD_COND_INITIALIZER == *cond) {
128 mthread_cond_init(cond, NULL);
129 }
130
131 return mthread_cond_wait(cond, mutex);
132 }
133
134 /*===========================================================================*
135 * pthread_rwlock_init *
136 *===========================================================================*/
pthread_rwlock_init(pthread_rwlock_t * rwlock,pthread_rwlockattr_t * UNUSED (attr))137 int pthread_rwlock_init(pthread_rwlock_t *rwlock, pthread_rwlockattr_t *UNUSED(attr))
138 {
139 return mthread_rwlock_init(rwlock);
140 }
141
142 #if !defined(__weak_alias)
143 #error __weak_alias is required to compile the pthread compat library
144 #endif
145
146