48 |
|
|
49 |
scm_t_mutexattr scm_i_plugin_rec_mutex; |
scm_t_mutexattr scm_i_plugin_rec_mutex; |
50 |
|
|
51 |
#ifndef SCM_MUTEX_RECURSIVE |
#if !defined (SCM_MUTEX_RECURSIVE) || defined (SCM_DEBUG_THREADS) |
52 |
#error hej |
|
53 |
typedef struct rec_mutex { |
typedef struct rec_mutex { |
54 |
|
#ifdef SCM_DEBUG_THREADS |
55 |
|
int kind; |
56 |
|
#endif |
57 |
scm_t_mutex mutex; |
scm_t_mutex mutex; |
58 |
scm_thread *owner; |
scm_thread *owner; |
59 |
int count; |
int count; |
62 |
/* Mutex for recursive mutex administration */ |
/* Mutex for recursive mutex administration */ |
63 |
static scm_t_mutex rec_mutex_mutex; |
static scm_t_mutex rec_mutex_mutex; |
64 |
|
|
65 |
|
#ifdef SCM_DEBUG_THREADS |
66 |
|
|
67 |
|
#define FAST_MUTEX 1 |
68 |
|
#define REC_MUTEX 2 |
69 |
|
|
70 |
|
typedef struct mutex { |
71 |
|
#ifdef SCM_DEBUG_THREADS |
72 |
|
int kind; |
73 |
|
#endif |
74 |
|
pthread_mutex_t mutex; |
75 |
|
scm_thread *owner; |
76 |
|
int count; |
77 |
|
} mutex; |
78 |
|
|
79 |
|
static pthread_mutex_t mutex_mutex; |
80 |
|
|
81 |
|
int |
82 |
|
scm_i_plugin_mutex_init (scm_t_mutex *mx, const scm_t_mutexattr *a) |
83 |
|
{ |
84 |
|
mutex *m = (mutex *) mx; |
85 |
|
pthread_mutex_init (&m->mutex, &scm_i_plugin_mutex); |
86 |
|
m->owner = 0; |
87 |
|
m->count = 0; |
88 |
|
m->kind = FAST_MUTEX; |
89 |
|
return 0; |
90 |
|
} |
91 |
|
|
92 |
|
int |
93 |
|
scm_i_plugin_mutex_lock (scm_t_mutex *mx) |
94 |
|
{ |
95 |
|
mutex *m = (mutex *) mx; |
96 |
|
scm_thread *t = SCM_CURRENT_THREAD; |
97 |
|
pthread_mutex_lock (&mutex_mutex); |
98 |
|
if (m->kind != FAST_MUTEX) |
99 |
|
{ |
100 |
|
fprintf (stderr, |
101 |
|
m->kind == REC_MUTEX |
102 |
|
? "locking wrong mutex type\n" |
103 |
|
: "locking uninitialized mutex\n"); |
104 |
|
abort (); |
105 |
|
} |
106 |
|
if (m->owner == t) |
107 |
|
{ |
108 |
|
fprintf (stderr, "locking mutex already locked by self\n"); |
109 |
|
abort (); |
110 |
|
} |
111 |
|
pthread_mutex_unlock (&mutex_mutex); |
112 |
|
pthread_mutex_lock (&m->mutex); |
113 |
|
m->count = 1; |
114 |
|
m->owner = t; |
115 |
|
return 0; |
116 |
|
} |
117 |
|
|
118 |
|
int |
119 |
|
scm_i_plugin_mutex_unlock (scm_t_mutex *mx) |
120 |
|
{ |
121 |
|
mutex *m = (mutex *) mx; |
122 |
|
pthread_mutex_lock (&mutex_mutex); |
123 |
|
if (m->kind != FAST_MUTEX) |
124 |
|
{ |
125 |
|
fprintf (stderr, |
126 |
|
m->kind == REC_MUTEX |
127 |
|
? "locking wrong mutex type\n" |
128 |
|
: "locking uninitialized mutex\n"); |
129 |
|
abort (); |
130 |
|
} |
131 |
|
if (m->count != 1) |
132 |
|
{ |
133 |
|
fprintf (stderr, |
134 |
|
m->count == 0 |
135 |
|
? "unlocking unlocked mutex\n" |
136 |
|
: "bogus internal state"); |
137 |
|
abort (); |
138 |
|
} |
139 |
|
m->owner = 0; |
140 |
|
m->count = 0; |
141 |
|
pthread_mutex_unlock (&m->mutex); |
142 |
|
pthread_mutex_unlock (&mutex_mutex); |
143 |
|
return 0; |
144 |
|
} |
145 |
|
#endif |
146 |
|
|
147 |
|
/* The following section belongs in threads.c, or rather |
148 |
|
thread-plugin.c. It is generic and not tied to any particular |
149 |
|
thread library. */ |
150 |
|
|
151 |
int |
int |
152 |
scm_i_plugin_rec_mutex_init (scm_t_rec_mutex *mx, const scm_t_mutexattr *a) |
scm_i_plugin_rec_mutex_init (scm_t_rec_mutex *mx, const scm_t_mutexattr *a) |
153 |
{ |
{ |
155 |
scm_i_plugin_mutex_init (&m->mutex, &scm_i_plugin_mutex); |
scm_i_plugin_mutex_init (&m->mutex, &scm_i_plugin_mutex); |
156 |
m->owner = 0; |
m->owner = 0; |
157 |
m->count = 0; |
m->count = 0; |
158 |
|
#ifdef SCM_DEBUG_THREADS |
159 |
|
m->kind = REC_MUTEX; |
160 |
|
#endif |
161 |
return 0; |
return 0; |
162 |
} |
} |
163 |
|
|
167 |
rec_mutex *m = (rec_mutex *) mx; |
rec_mutex *m = (rec_mutex *) mx; |
168 |
scm_thread *t = SCM_CURRENT_THREAD; |
scm_thread *t = SCM_CURRENT_THREAD; |
169 |
scm_i_plugin_mutex_lock (&rec_mutex_mutex); |
scm_i_plugin_mutex_lock (&rec_mutex_mutex); |
170 |
|
#ifdef SCM_DEBUG_THREADS |
171 |
|
if (m->kind != REC_MUTEX) |
172 |
|
{ |
173 |
|
fprintf (stderr, |
174 |
|
m->kind == FAST_MUTEX |
175 |
|
? "locking wrong mutex type\n" |
176 |
|
: "locking uninitialized mutex\n"); |
177 |
|
abort (); |
178 |
|
} |
179 |
|
#endif |
180 |
if (m->count && m->owner == t) |
if (m->count && m->owner == t) |
181 |
{ |
{ |
182 |
++m->count; |
++m->count; |
220 |
{ |
{ |
221 |
rec_mutex *m = (rec_mutex *) mx; |
rec_mutex *m = (rec_mutex *) mx; |
222 |
scm_i_plugin_mutex_lock (&rec_mutex_mutex); |
scm_i_plugin_mutex_lock (&rec_mutex_mutex); |
223 |
|
#ifdef SCM_DEBUG_THREADS |
224 |
|
if (m->kind != REC_MUTEX) |
225 |
|
{ |
226 |
|
fprintf (stderr, |
227 |
|
m->kind == FAST_MUTEX |
228 |
|
? "locking wrong mutex type\n" |
229 |
|
: "locking uninitialized mutex\n"); |
230 |
|
abort (); |
231 |
|
} |
232 |
|
if (m->count == 0) |
233 |
|
{ |
234 |
|
fprintf (stderr, "unlocking unlocked mutex\n"); |
235 |
|
abort (); |
236 |
|
} |
237 |
|
#endif |
238 |
if (!--m->count) |
if (!--m->count) |
239 |
{ |
{ |
240 |
m->owner = 0; |
m->owner = 0; |
253 |
void |
void |
254 |
scm_init_pthread_threads () |
scm_init_pthread_threads () |
255 |
{ |
{ |
|
if (sizeof (scm_t_rec_mutex) > SCM_REC_MUTEX_MAXSIZE) |
|
|
{ |
|
|
fprintf (stderr, "Internal error: Need to upgrade mutex size\n"); |
|
|
abort (); |
|
|
} |
|
|
|
|
256 |
pthread_mutexattr_init (&scm_i_plugin_mutex); |
pthread_mutexattr_init (&scm_i_plugin_mutex); |
257 |
#ifdef SCM_MUTEX_FAST |
#ifdef SCM_MUTEX_FAST |
258 |
pthread_mutexattr_settype (&scm_i_plugin_mutex, SCM_MUTEX_FAST); |
pthread_mutexattr_settype (&scm_i_plugin_mutex, SCM_MUTEX_FAST); |
259 |
#endif |
#endif |
260 |
|
|
261 |
#ifdef SCM_MUTEX_RECURSIVE /* Use the POSIX 1003.1c identifier */ |
#if defined (SCM_MUTEX_RECURSIVE) && !defined (SCM_DEBUG_THREADS) |
262 |
pthread_mutexattr_init (&scm_i_plugin_rec_mutex); |
if (sizeof (pthread_mutex_t) > SCM_REC_MUTEX_MAXSIZE) |
263 |
|
{ |
264 |
|
fprintf (stderr, "Internal error: Need to upgrade mutex size\n"); |
265 |
|
abort (); |
266 |
|
} |
267 |
|
pthread_mutexattr_init (&scm_i_plugin_rec_mutex); |
268 |
pthread_mutexattr_settype (&scm_i_plugin_rec_mutex, SCM_MUTEX_RECURSIVE); |
pthread_mutexattr_settype (&scm_i_plugin_rec_mutex, SCM_MUTEX_RECURSIVE); |
269 |
#else |
#else |
270 |
/* If PTHREAD_MUTEX_RECURSIVE is not defined, |
/* If PTHREAD_MUTEX_RECURSIVE is not defined, |
271 |
scm_i_plugin_rec_mutex_init won't pay attention to it anyway |
scm_i_plugin_rec_mutex_init won't pay attention to it anyway |
272 |
*/ |
*/ |
273 |
|
if (sizeof (rec_mutex) > SCM_REC_MUTEX_MAXSIZE) |
274 |
|
{ |
275 |
|
fprintf (stderr, "Internal error: Need to upgrade mutex size\n"); |
276 |
|
abort (); |
277 |
|
} |
278 |
scm_i_plugin_mutex_init (&rec_mutex_mutex, &scm_i_plugin_mutex); |
scm_i_plugin_mutex_init (&rec_mutex_mutex, &scm_i_plugin_mutex); |
279 |
#endif |
#endif |
280 |
|
#ifdef SCM_DEBUG_THREADS |
281 |
|
pthread_mutex_init (&mutex_mutex, &scm_i_plugin_mutex); |
282 |
|
#endif |
283 |
} |
} |
284 |
|
|
285 |
/* |
/* |