~ubuntu-branches/ubuntu/vivid/nodejs/vivid

« back to all changes in this revision

Viewing changes to deps/uv/src/unix/thread.c

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
 
2
 *
 
3
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
4
 * of this software and associated documentation files (the "Software"), to
 
5
 * deal in the Software without restriction, including without limitation the
 
6
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 
7
 * sell copies of the Software, and to permit persons to whom the Software is
 
8
 * furnished to do so, subject to the following conditions:
 
9
 *
 
10
 * The above copyright notice and this permission notice shall be included in
 
11
 * all copies or substantial portions of the Software.
 
12
 *
 
13
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
14
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
15
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
17
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
18
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 
19
 * IN THE SOFTWARE.
 
20
 */
 
21
 
 
22
#include "uv.h"
 
23
#include "internal.h"
 
24
 
 
25
#include <pthread.h>
 
26
#include <assert.h>
 
27
#include <errno.h>
 
28
 
 
29
#if defined(__APPLE__) && defined(__MACH__)
 
30
#include <sys/time.h>
 
31
#endif /* defined(__APPLE__) && defined(__MACH__) */
 
32
 
 
33
#undef NANOSEC
 
34
#define NANOSEC ((uint64_t) 1e9)
 
35
 
 
36
int uv_thread_join(uv_thread_t *tid) {
 
37
  if (pthread_join(*tid, NULL))
 
38
    return -1;
 
39
  else
 
40
    return 0;
 
41
}
 
42
 
 
43
 
 
44
int uv_mutex_init(uv_mutex_t* mutex) {
 
45
#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
 
46
  if (pthread_mutex_init(mutex, NULL))
 
47
    return -1;
 
48
  else
 
49
    return 0;
 
50
#else
 
51
  pthread_mutexattr_t attr;
 
52
  int r;
 
53
 
 
54
  if (pthread_mutexattr_init(&attr))
 
55
    abort();
 
56
 
 
57
  if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK))
 
58
    abort();
 
59
 
 
60
  r = pthread_mutex_init(mutex, &attr);
 
61
 
 
62
  if (pthread_mutexattr_destroy(&attr))
 
63
    abort();
 
64
 
 
65
  return r ? -1 : 0;
 
66
#endif
 
67
}
 
68
 
 
69
 
 
70
void uv_mutex_destroy(uv_mutex_t* mutex) {
 
71
  if (pthread_mutex_destroy(mutex))
 
72
    abort();
 
73
}
 
74
 
 
75
 
 
76
void uv_mutex_lock(uv_mutex_t* mutex) {
 
77
  if (pthread_mutex_lock(mutex))
 
78
    abort();
 
79
}
 
80
 
 
81
 
 
82
int uv_mutex_trylock(uv_mutex_t* mutex) {
 
83
  int r;
 
84
 
 
85
  r = pthread_mutex_trylock(mutex);
 
86
 
 
87
  if (r && r != EBUSY && r != EAGAIN)
 
88
    abort();
 
89
 
 
90
  if (r)
 
91
    return -1;
 
92
  else
 
93
    return 0;
 
94
}
 
95
 
 
96
 
 
97
void uv_mutex_unlock(uv_mutex_t* mutex) {
 
98
  if (pthread_mutex_unlock(mutex))
 
99
    abort();
 
100
}
 
101
 
 
102
 
 
103
int uv_rwlock_init(uv_rwlock_t* rwlock) {
 
104
  if (pthread_rwlock_init(rwlock, NULL))
 
105
    return -1;
 
106
  else
 
107
    return 0;
 
108
}
 
109
 
 
110
 
 
111
void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
 
112
  if (pthread_rwlock_destroy(rwlock))
 
113
    abort();
 
114
}
 
115
 
 
116
 
 
117
void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
 
118
  if (pthread_rwlock_rdlock(rwlock))
 
119
    abort();
 
120
}
 
121
 
 
122
 
 
123
int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
 
124
  int r;
 
125
 
 
126
  r = pthread_rwlock_tryrdlock(rwlock);
 
127
 
 
128
  if (r && r != EBUSY && r != EAGAIN)
 
129
    abort();
 
130
 
 
131
  if (r)
 
132
    return -1;
 
133
  else
 
134
    return 0;
 
135
}
 
136
 
 
137
 
 
138
void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
 
139
  if (pthread_rwlock_unlock(rwlock))
 
140
    abort();
 
141
}
 
142
 
 
143
 
 
144
void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
 
145
  if (pthread_rwlock_wrlock(rwlock))
 
146
    abort();
 
147
}
 
148
 
 
149
 
 
150
int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
 
151
  int r;
 
152
 
 
153
  r = pthread_rwlock_trywrlock(rwlock);
 
154
 
 
155
  if (r && r != EBUSY && r != EAGAIN)
 
156
    abort();
 
157
 
 
158
  if (r)
 
159
    return -1;
 
160
  else
 
161
    return 0;
 
162
}
 
163
 
 
164
 
 
165
void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
 
166
  if (pthread_rwlock_unlock(rwlock))
 
167
    abort();
 
168
}
 
169
 
 
170
 
 
171
void uv_once(uv_once_t* guard, void (*callback)(void)) {
 
172
  if (pthread_once(guard, callback))
 
173
    abort();
 
174
}
 
175
 
 
176
#if defined(__APPLE__) && defined(__MACH__)
 
177
 
 
178
int uv_sem_init(uv_sem_t* sem, unsigned int value) {
 
179
  if (semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value))
 
180
    return -1;
 
181
  else
 
182
    return 0;
 
183
}
 
184
 
 
185
 
 
186
void uv_sem_destroy(uv_sem_t* sem) {
 
187
  if (semaphore_destroy(mach_task_self(), *sem))
 
188
    abort();
 
189
}
 
190
 
 
191
 
 
192
void uv_sem_post(uv_sem_t* sem) {
 
193
  if (semaphore_signal(*sem))
 
194
    abort();
 
195
}
 
196
 
 
197
 
 
198
void uv_sem_wait(uv_sem_t* sem) {
 
199
  int r;
 
200
 
 
201
  do
 
202
    r = semaphore_wait(*sem);
 
203
  while (r == KERN_ABORTED);
 
204
 
 
205
  if (r != KERN_SUCCESS)
 
206
    abort();
 
207
}
 
208
 
 
209
 
 
210
int uv_sem_trywait(uv_sem_t* sem) {
 
211
  mach_timespec_t interval;
 
212
 
 
213
  interval.tv_sec = 0;
 
214
  interval.tv_nsec = 0;
 
215
 
 
216
  if (semaphore_timedwait(*sem, interval) == KERN_SUCCESS)
 
217
    return 0;
 
218
  else
 
219
    return -1;
 
220
}
 
221
 
 
222
#else /* !(defined(__APPLE__) && defined(__MACH__)) */
 
223
 
 
224
int uv_sem_init(uv_sem_t* sem, unsigned int value) {
 
225
  return sem_init(sem, 0, value);
 
226
}
 
227
 
 
228
 
 
229
void uv_sem_destroy(uv_sem_t* sem) {
 
230
  if (sem_destroy(sem))
 
231
    abort();
 
232
}
 
233
 
 
234
 
 
235
void uv_sem_post(uv_sem_t* sem) {
 
236
  if (sem_post(sem))
 
237
    abort();
 
238
}
 
239
 
 
240
 
 
241
void uv_sem_wait(uv_sem_t* sem) {
 
242
  int r;
 
243
 
 
244
  do
 
245
    r = sem_wait(sem);
 
246
  while (r == -1 && errno == EINTR);
 
247
 
 
248
  if (r)
 
249
    abort();
 
250
}
 
251
 
 
252
 
 
253
int uv_sem_trywait(uv_sem_t* sem) {
 
254
  int r;
 
255
 
 
256
  do
 
257
    r = sem_trywait(sem);
 
258
  while (r == -1 && errno == EINTR);
 
259
 
 
260
  if (r && errno != EAGAIN)
 
261
    abort();
 
262
 
 
263
  return r;
 
264
}
 
265
 
 
266
#endif /* defined(__APPLE__) && defined(__MACH__) */
 
267
 
 
268
 
 
269
#if defined(__APPLE__) && defined(__MACH__)
 
270
 
 
271
int uv_cond_init(uv_cond_t* cond) {
 
272
  if (pthread_cond_init(cond, NULL))
 
273
    return -1;
 
274
  else
 
275
    return 0;
 
276
}
 
277
 
 
278
#else /* !(defined(__APPLE__) && defined(__MACH__)) */
 
279
 
 
280
int uv_cond_init(uv_cond_t* cond) {
 
281
  pthread_condattr_t attr;
 
282
 
 
283
  if (pthread_condattr_init(&attr))
 
284
    return -1;
 
285
 
 
286
  if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
 
287
    goto error2;
 
288
 
 
289
  if (pthread_cond_init(cond, &attr))
 
290
    goto error2;
 
291
 
 
292
  if (pthread_condattr_destroy(&attr))
 
293
    goto error;
 
294
 
 
295
  return 0;
 
296
 
 
297
error:
 
298
  pthread_cond_destroy(cond);
 
299
error2:
 
300
  pthread_condattr_destroy(&attr);
 
301
  return -1;
 
302
}
 
303
 
 
304
#endif /* defined(__APPLE__) && defined(__MACH__) */
 
305
 
 
306
void uv_cond_destroy(uv_cond_t* cond) {
 
307
  if (pthread_cond_destroy(cond))
 
308
    abort();
 
309
}
 
310
 
 
311
void uv_cond_signal(uv_cond_t* cond) {
 
312
  if (pthread_cond_signal(cond))
 
313
    abort();
 
314
}
 
315
 
 
316
void uv_cond_broadcast(uv_cond_t* cond) {
 
317
  if (pthread_cond_broadcast(cond))
 
318
    abort();
 
319
}
 
320
 
 
321
void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
 
322
  if (pthread_cond_wait(cond, mutex))
 
323
    abort();
 
324
}
 
325
 
 
326
 
 
327
int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
 
328
  int r;
 
329
  struct timespec ts;
 
330
 
 
331
#if defined(__APPLE__) && defined(__MACH__)
 
332
  ts.tv_sec = timeout / NANOSEC;
 
333
  ts.tv_nsec = timeout % NANOSEC;
 
334
  r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
 
335
#else
 
336
  timeout += uv__hrtime();
 
337
  ts.tv_sec = timeout / NANOSEC;
 
338
  ts.tv_nsec = timeout % NANOSEC;
 
339
  r = pthread_cond_timedwait(cond, mutex, &ts);
 
340
#endif
 
341
 
 
342
 
 
343
  if (r == 0)
 
344
    return 0;
 
345
 
 
346
  if (r == ETIMEDOUT)
 
347
    return -1;
 
348
 
 
349
  abort();
 
350
  return -1; /* Satisfy the compiler. */
 
351
}
 
352
 
 
353
 
 
354
#if defined(__APPLE__) && defined(__MACH__)
 
355
 
 
356
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
 
357
  barrier->n = count;
 
358
  barrier->count = 0;
 
359
 
 
360
  if (uv_mutex_init(&barrier->mutex))
 
361
    return -1;
 
362
 
 
363
  if (uv_sem_init(&barrier->turnstile1, 0))
 
364
    goto error2;
 
365
 
 
366
  if (uv_sem_init(&barrier->turnstile2, 1))
 
367
    goto error;
 
368
 
 
369
  return 0;
 
370
 
 
371
error:
 
372
  uv_sem_destroy(&barrier->turnstile1);
 
373
error2:
 
374
  uv_mutex_destroy(&barrier->mutex);
 
375
  return -1;
 
376
 
 
377
}
 
378
 
 
379
 
 
380
void uv_barrier_destroy(uv_barrier_t* barrier) {
 
381
  uv_sem_destroy(&barrier->turnstile2);
 
382
  uv_sem_destroy(&barrier->turnstile1);
 
383
  uv_mutex_destroy(&barrier->mutex);
 
384
}
 
385
 
 
386
 
 
387
void uv_barrier_wait(uv_barrier_t* barrier) {
 
388
  uv_mutex_lock(&barrier->mutex);
 
389
  if (++barrier->count == barrier->n) {
 
390
    uv_sem_wait(&barrier->turnstile2);
 
391
    uv_sem_post(&barrier->turnstile1);
 
392
  }
 
393
  uv_mutex_unlock(&barrier->mutex);
 
394
 
 
395
  uv_sem_wait(&barrier->turnstile1);
 
396
  uv_sem_post(&barrier->turnstile1);
 
397
 
 
398
  uv_mutex_lock(&barrier->mutex);
 
399
  if (--barrier->count == 0) {
 
400
    uv_sem_wait(&barrier->turnstile1);
 
401
    uv_sem_post(&barrier->turnstile2);
 
402
  }
 
403
  uv_mutex_unlock(&barrier->mutex);
 
404
 
 
405
  uv_sem_wait(&barrier->turnstile2);
 
406
  uv_sem_post(&barrier->turnstile2);
 
407
}
 
408
 
 
409
#else /* !(defined(__APPLE__) && defined(__MACH__)) */
 
410
 
 
411
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
 
412
  if (pthread_barrier_init(barrier, NULL, count))
 
413
    return -1;
 
414
  else
 
415
    return 0;
 
416
}
 
417
 
 
418
 
 
419
void uv_barrier_destroy(uv_barrier_t* barrier) {
 
420
  if (pthread_barrier_destroy(barrier))
 
421
    abort();
 
422
}
 
423
 
 
424
 
 
425
void uv_barrier_wait(uv_barrier_t* barrier) {
 
426
  int r = pthread_barrier_wait(barrier);
 
427
  if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
 
428
    abort();
 
429
}
 
430
 
 
431
#endif /* defined(__APPLE__) && defined(__MACH__) */