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