xref: /minix/minix/lib/libmthread/pthread_compat.c (revision 433d6423)
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