Use adaptive mutexes when available
[platform/upstream/glib.git] / glib / gthread-posix.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * gthread.c: posix thread system implementation
5  * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /*
24  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
25  * file for a list of people on the GLib Team.  See the ChangeLog
26  * files for a list of changes.  These files are distributed with
27  * GLib at ftp://ftp.gtk.org/pub/gtk/.
28  */
29
30 /* The GMutex, GCond and GPrivate implementations in this file are some
31  * of the lowest-level code in GLib.  All other parts of GLib (messages,
32  * memory, slices, etc) assume that they can freely use these facilities
33  * without risking recursion.
34  *
35  * As such, these functions are NOT permitted to call any other part of
36  * GLib.
37  *
38  * The thread manipulation functions (create, exit, join, etc.) have
39  * more freedom -- they can do as they please.
40  */
41
42 #include "config.h"
43
44 #include "gthread.h"
45 #include "gthreadprivate.h"
46 #include "gslice.h"
47
48 #include <pthread.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <errno.h>
52 #include <stdio.h>
53
54 static void
55 g_thread_abort (gint         status,
56                 const gchar *function)
57 {
58   fprintf (stderr, "GLib (gthread-posix.c): Unexpected error from C library during '%s': %s.  Aborting.\n",
59            strerror (status), function);
60   abort ();
61 }
62
63 /* {{{1 GMutex */
64
65 /**
66  * g_mutex_init:
67  * @mutex: an uninitialized #GMutex
68  *
69  * Initializes a #GMutex so that it can be used.
70  *
71  * This function is useful to initialize a mutex that has been
72  * allocated on the stack, or as part of a larger structure.
73  * It is not necessary to initialize a mutex that has been
74  * created with g_mutex_new(). Also see #G_MUTEX_INITIALIZER
75  * for an alternative way to initialize statically allocated mutexes.
76  *
77  * |[
78  *   typedef struct {
79  *     GMutex m;
80  *     /&ast; ... &ast;/
81  *   } Blob;
82  *
83  * Blob *b;
84  *
85  * b = g_new (Blob, 1);
86  * g_mutex_init (&b->m);
87  * /&ast; ... &ast;/
88  * ]|
89  *
90  * To undo the effect of g_mutex_init() when a mutex is no longer
91  * needed, use g_mutex_clear().
92  *
93  * Since: 2.32
94  */
95 void
96 g_mutex_init (GMutex *mutex)
97 {
98   gint status;
99   pthread_mutexattr_t *pattr = NULL;
100 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
101   pthread_mutexattr_t attr;
102   pthread_mutexattr_init (&attr);
103   pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
104   pattr = &attr;
105 #endif
106
107   if G_UNLIKELY ((status = pthread_mutex_init (&mutex->impl, pattr)) != 0)
108     g_thread_abort (status, "pthread_mutex_init");
109
110 #ifdef PTHREAD_ADAPTIVE_MUTEX_NP
111   pthread_mutexattr_destroy (&attr);
112 #endif
113 }
114
115 /**
116  * g_mutex_clear:
117  * @mutex: an initialized #GMutex
118  *
119  * Frees the resources allocated to a mutex with g_mutex_init().
120  *
121  * #GMutexes that have have been created with g_mutex_new() should
122  * be freed with g_mutex_free() instead.
123  *
124  * Sine: 2.32
125  */
126 void
127 g_mutex_clear (GMutex *mutex)
128 {
129   gint status;
130
131   if G_UNLIKELY ((status = pthread_mutex_destroy (&mutex->impl)) != 0)
132     g_thread_abort (status, "pthread_mutex_destroy");
133 }
134
135 /**
136  * g_mutex_lock:
137  * @mutex: a #GMutex
138  *
139  * Locks @mutex. If @mutex is already locked by another thread, the
140  * current thread will block until @mutex is unlocked by the other
141  * thread.
142  *
143  * This function can be used even if g_thread_init() has not yet been
144  * called, and, in that case, will do nothing.
145  *
146  * <note>#GMutex is neither guaranteed to be recursive nor to be
147  * non-recursive, i.e. a thread could deadlock while calling
148  * g_mutex_lock(), if it already has locked @mutex. Use
149  * #GStaticRecMutex, if you need recursive mutexes.</note>
150  */
151 void
152 g_mutex_lock (GMutex *mutex)
153 {
154   gint status;
155
156   if G_UNLIKELY ((status = pthread_mutex_lock (&mutex->impl)) != 0)
157     g_thread_abort (status, "pthread_mutex_lock");
158 }
159
160 /**
161  * g_mutex_unlock:
162  * @mutex: a #GMutex
163  *
164  * Unlocks @mutex. If another thread is blocked in a g_mutex_lock()
165  * call for @mutex, it will be woken and can lock @mutex itself.
166  *
167  * This function can be used even if g_thread_init() has not yet been
168  * called, and, in that case, will do nothing.
169  */
170 void
171 g_mutex_unlock (GMutex *mutex)
172 {
173   gint status;
174
175   if G_UNLIKELY ((status = pthread_mutex_unlock (&mutex->impl)) != 0)
176     g_thread_abort (status, "pthread_mutex_lock");
177 }
178
179 /**
180  * g_mutex_trylock:
181  * @mutex: a #GMutex
182  *
183  * Tries to lock @mutex. If @mutex is already locked by another thread,
184  * it immediately returns %FALSE. Otherwise it locks @mutex and returns
185  * %TRUE.
186  *
187  * This function can be used even if g_thread_init() has not yet been
188  * called, and, in that case, will immediately return %TRUE.
189  *
190  * <note>#GMutex is neither guaranteed to be recursive nor to be
191  * non-recursive, i.e. the return value of g_mutex_trylock() could be
192  * both %FALSE or %TRUE, if the current thread already has locked
193  * @mutex. Use #GStaticRecMutex, if you need recursive
194  * mutexes.</note>
195
196  * Returns: %TRUE, if @mutex could be locked
197  */
198 gboolean
199 g_mutex_trylock (GMutex *mutex)
200 {
201   gint status;
202
203   if G_LIKELY ((status = pthread_mutex_trylock (&mutex->impl)) == 0)
204     return TRUE;
205
206   if G_UNLIKELY (status != EBUSY)
207     g_thread_abort (status, "pthread_mutex_trylock");
208
209   return FALSE;
210 }
211
212 /* {{{1 GRecMutex */
213
214 static pthread_mutex_t *
215 g_rec_mutex_impl_new (void)
216 {
217   pthread_mutexattr_t attr;
218   pthread_mutex_t *mutex;
219
220   mutex = g_slice_new (pthread_mutex_t);
221   pthread_mutexattr_init (&attr);
222   pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
223   pthread_mutex_init (mutex, &attr);
224   pthread_mutexattr_destroy (&attr);
225
226   return mutex;
227 }
228
229 static void
230 g_rec_mutex_impl_free (pthread_mutex_t *mutex)
231 {
232   pthread_mutex_destroy (mutex);
233   g_slice_free (pthread_mutex_t, mutex);
234 }
235
236 static pthread_mutex_t *
237 g_rec_mutex_get_impl (GRecMutex *mutex)
238 {
239   pthread_mutex_t *impl = mutex->impl;
240
241   if G_UNLIKELY (mutex->impl == NULL)
242     {
243       impl = g_rec_mutex_impl_new ();
244       if (!g_atomic_pointer_compare_and_exchange (&mutex->impl, NULL, impl))
245         g_rec_mutex_impl_free (impl);
246       impl = mutex->impl;
247     }
248
249   return impl;
250 }
251
252 void
253 g_rec_mutex_init (GRecMutex *mutex)
254 {
255   mutex->impl = g_rec_mutex_impl_new ();
256 }
257
258 void
259 g_rec_mutex_clear (GRecMutex *mutex)
260 {
261   if (mutex->impl)
262     g_rec_mutex_impl_free (mutex->impl);
263 }
264
265 void
266 g_rec_mutex_lock (GRecMutex *mutex)
267 {
268   pthread_mutex_lock (g_rec_mutex_get_impl (mutex));
269 }
270
271 void
272 g_rec_mutex_unlock (GRecMutex *mutex)
273 {
274   pthread_mutex_unlock (mutex->impl);
275 }
276
277 gboolean
278 g_rec_mutex_trylock (GRecMutex *mutex)
279 {
280   return pthread_mutex_trylock (g_rec_mutex_get_impl (mutex));
281 }
282
283 /* {{{1 GRWLock */
284
285 void
286 g_rw_lock_init (GRWLock *lock)
287 {
288   pthread_rwlock_init (&lock->impl, NULL);
289 }
290
291 void
292 g_rw_lock_clear (GRWLock *lock)
293 {
294   pthread_rwlock_destroy (&lock->impl);
295 }
296
297 void
298 g_rw_lock_writer_lock (GRWLock *lock)
299 {
300   pthread_rwlock_wrlock (&lock->impl);
301 }
302
303 gboolean
304 g_rw_lock_writer_trylock (GRWLock *lock)
305 {
306   return pthread_rwlock_trywrlock (&lock->impl);
307 }
308
309 void
310 g_rw_lock_writer_unlock (GRWLock *lock)
311 {
312   pthread_rwlock_unlock (&lock->impl);
313 }
314
315 void
316 g_rw_lock_reader_lock (GRWLock *lock)
317 {
318   pthread_rwlock_rdlock (&lock->impl);
319 }
320
321 gboolean
322 g_rw_lock_reader_trylock (GRWLock *lock)
323 {
324   return pthread_rwlock_tryrdlock (&lock->impl);
325 }
326
327 void
328 g_rw_lock_reader_unlock (GRWLock *lock)
329 {
330   pthread_rwlock_unlock (&lock->impl);
331 }
332
333 /* {{{1 GCond */
334
335 /**
336  * g_cond_init:
337  * @cond: an uninitialized #GCond
338  *
339  * Initialized a #GCond so that it can be used.
340  *
341  * This function is useful to initialize a #GCond that has been
342  * allocated on the stack, or as part of a larger structure.
343  * It is not necessary to initialize a #GCond that has been
344  * created with g_cond_new(). Also see #G_COND_INITIALIZER
345  * for an alternative way to initialize statically allocated
346  * #GConds.
347  *
348  * Since: 2.32
349  */
350 void
351 g_cond_init (GCond *cond)
352 {
353   gint status;
354
355   if G_UNLIKELY ((status = pthread_cond_init (&cond->impl, NULL)) != 0)
356     g_thread_abort (status, "pthread_cond_init");
357 }
358
359 /**
360  * g_cond_clear:
361  * @cond: an initialized #GCond
362  *
363  * Frees the resources allocated ot a #GCond with g_cond_init().
364  *
365  * #GConds that have been created with g_cond_new() should
366  * be freed with g_cond_free() instead.
367  *
368  * Since: 2.32
369  */
370 void
371 g_cond_clear (GCond *cond)
372 {
373   gint status;
374
375   if G_UNLIKELY ((status = pthread_cond_destroy (&cond->impl)) != 0)
376     g_thread_abort (status, "pthread_cond_destroy");
377 }
378
379 /**
380  * g_cond_wait:
381  * @cond: a #GCond
382  * @mutex: a #GMutex that is currently locked
383  *
384  * Waits until this thread is woken up on @cond.
385  * The @mutex is unlocked before falling asleep
386  * and locked again before resuming.
387  *
388  * This function can be used even if g_thread_init() has not yet been
389  * called, and, in that case, will immediately return.
390  */
391 void
392 g_cond_wait (GCond  *cond,
393              GMutex *mutex)
394 {
395   gint status;
396
397   if G_UNLIKELY ((status = pthread_cond_wait (&cond->impl, &mutex->impl)) != 0)
398     g_thread_abort (status, "pthread_cond_wait");
399 }
400
401 /**
402  * g_cond_signal:
403  * @cond: a #GCond
404  *
405  * If threads are waiting for @cond, exactly one of them is woken up.
406  * It is good practice to hold the same lock as the waiting thread
407  * while calling this function, though not required.
408  *
409  * This function can be used even if g_thread_init() has not yet been
410  * called, and, in that case, will do nothing.
411  */
412 void
413 g_cond_signal (GCond *cond)
414 {
415   gint status;
416
417   if G_UNLIKELY ((status = pthread_cond_signal (&cond->impl)) != 0)
418     g_thread_abort (status, "pthread_cond_signal");
419 }
420
421 /**
422  * g_cond_broadcast:
423  * @cond: a #GCond
424  *
425  * If threads are waiting for @cond, all of them are woken up.
426  * It is good practice to lock the same mutex as the waiting threads
427  * while calling this function, though not required.
428  *
429  * This function can be used even if g_thread_init() has not yet been
430  * called, and, in that case, will do nothing.
431  */
432 void
433 g_cond_broadcast (GCond *cond)
434 {
435   gint status;
436
437   if G_UNLIKELY ((status = pthread_cond_broadcast (&cond->impl)) != 0)
438     g_thread_abort (status, "pthread_cond_broadcast");
439 }
440
441 /**
442  * g_cond_timed_wait:
443  * @cond: a #GCond
444  * @mutex: a #GMutex that is currently locked
445  * @abs_time: a #GTimeVal, determining the final time
446  *
447  * Waits until this thread is woken up on @cond, but not longer than
448  * until the time specified by @abs_time. The @mutex is unlocked before
449  * falling asleep and locked again before resuming.
450  *
451  * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
452  *
453  * This function can be used even if g_thread_init() has not yet been
454  * called, and, in that case, will immediately return %TRUE.
455  *
456  * To easily calculate @abs_time a combination of g_get_current_time()
457  * and g_time_val_add() can be used.
458  *
459  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
460  */
461 gboolean
462 g_cond_timed_wait (GCond    *cond,
463                    GMutex   *mutex,
464                    GTimeVal *abs_time)
465 {
466   struct timespec end_time;
467   gint status;
468
469   if (abs_time == NULL)
470     {
471       g_cond_wait (cond, mutex);
472       return TRUE;
473     }
474
475   end_time.tv_sec = abs_time->tv_sec;
476   end_time.tv_nsec = abs_time->tv_usec * 1000;
477
478   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
479     return TRUE;
480
481   if G_UNLIKELY (status != ETIMEDOUT)
482     g_thread_abort (status, "pthread_cond_timedwait");
483
484   return FALSE;
485 }
486
487 /**
488  * g_cond_timedwait:
489  * @cond: a #GCond
490  * @mutex: a #GMutex that is currently locked
491  * @abs_time: the final time, in microseconds
492  *
493  * A variant of g_cond_timed_wait() that takes @abs_time
494  * as a #gint64 instead of a #GTimeVal.
495  * See g_cond_timed_wait() for details.
496  *
497  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
498  *
499  * Since: 2.32
500  */
501 gboolean
502 g_cond_timedwait (GCond  *cond,
503                   GMutex *mutex,
504                   gint64  abs_time)
505 {
506   struct timespec end_time;
507   gint status;
508
509   end_time.tv_sec = abs_time / 1000000;
510   end_time.tv_nsec = (abs_time % 1000000) * 1000;
511
512   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
513     return TRUE;
514
515   if G_UNLIKELY (status != ETIMEDOUT)
516     g_thread_abort (status, "pthread_cond_timedwait");
517
518   return FALSE;
519 }
520
521 /* {{{1 GPrivate */
522
523 void
524 g_private_init (GPrivate       *key,
525                 GDestroyNotify  notify)
526 {
527   pthread_key_create (&key->key, notify);
528   key->ready = TRUE;
529 }
530
531 /**
532  * g_private_get:
533  * @private_key: a #GPrivate
534  *
535  * Returns the pointer keyed to @private_key for the current thread. If
536  * g_private_set() hasn't been called for the current @private_key and
537  * thread yet, this pointer will be %NULL.
538  *
539  * This function can be used even if g_thread_init() has not yet been
540  * called, and, in that case, will return the value of @private_key
541  * casted to #gpointer. Note however, that private data set
542  * <emphasis>before</emphasis> g_thread_init() will
543  * <emphasis>not</emphasis> be retained <emphasis>after</emphasis> the
544  * call. Instead, %NULL will be returned in all threads directly after
545  * g_thread_init(), regardless of any g_private_set() calls issued
546  * before threading system initialization.
547  *
548  * Returns: the corresponding pointer
549  */
550 gpointer
551 g_private_get (GPrivate *key)
552 {
553   if (!key->ready)
554     return key->single_value;
555
556   /* quote POSIX: No errors are returned from pthread_getspecific(). */
557   return pthread_getspecific (key->key);
558 }
559
560 /**
561  * g_private_set:
562  * @private_key: a #GPrivate
563  * @data: the new pointer
564  *
565  * Sets the pointer keyed to @private_key for the current thread.
566  *
567  * This function can be used even if g_thread_init() has not yet been
568  * called, and, in that case, will set @private_key to @data casted to
569  * #GPrivate*. See g_private_get() for resulting caveats.
570  */
571 void
572 g_private_set (GPrivate *key,
573                gpointer  value)
574 {
575   gint status;
576
577   if (!key->ready)
578     {
579       key->single_value = value;
580       return;
581     }
582
583   if G_UNLIKELY ((status = pthread_setspecific (key->key, value)) != 0)
584     g_thread_abort (status, "pthread_setspecific");
585 }
586
587 /* {{{1 GThread */
588
589 #include "glib.h"
590 #include "gthreadprivate.h"
591
592 #include <pthread.h>
593 #include <errno.h>
594 #include <stdlib.h>
595 #ifdef HAVE_SYS_TIME_H
596 # include <sys/time.h>
597 #endif
598 #ifdef HAVE_UNISTD_H
599 # include <unistd.h>
600 #endif
601
602 #ifdef HAVE_SCHED_H
603 #include <sched.h>
604 #endif
605
606 #define posix_check_err(err, name) G_STMT_START{                        \
607   int error = (err);                                                    \
608   if (error)                                                            \
609     g_error ("file %s: line %d (%s): error '%s' during '%s'",           \
610            __FILE__, __LINE__, G_STRFUNC,                               \
611            g_strerror (error), name);                                   \
612   }G_STMT_END
613
614 #define posix_check_cmd(cmd) posix_check_err (cmd, #cmd)
615
616 #define G_MUTEX_SIZE (sizeof (pthread_mutex_t))
617
618 void
619 g_system_thread_create (GThreadFunc       thread_func,
620                         gpointer          arg,
621                         gulong            stack_size,
622                         gboolean          joinable,
623                         gpointer          thread,
624                         GError          **error)
625 {
626   pthread_attr_t attr;
627   gint ret;
628
629   g_return_if_fail (thread_func);
630
631   posix_check_cmd (pthread_attr_init (&attr));
632
633 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
634   if (stack_size)
635     {
636 #ifdef _SC_THREAD_STACK_MIN
637       stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), stack_size);
638 #endif /* _SC_THREAD_STACK_MIN */
639       /* No error check here, because some systems can't do it and
640        * we simply don't want threads to fail because of that. */
641       pthread_attr_setstacksize (&attr, stack_size);
642     }
643 #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
644
645   posix_check_cmd (pthread_attr_setdetachstate (&attr,
646           joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
647
648   ret = pthread_create (thread, &attr, (void* (*)(void*))thread_func, arg);
649
650   posix_check_cmd (pthread_attr_destroy (&attr));
651
652   if (ret == EAGAIN)
653     {
654       g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
655                    "Error creating thread: %s", g_strerror (ret));
656       return;
657     }
658
659   posix_check_err (ret, "pthread_create");
660 }
661
662 /**
663  * g_thread_yield:
664  *
665  * Gives way to other threads waiting to be scheduled.
666  *
667  * This function is often used as a method to make busy wait less evil.
668  * But in most cases you will encounter, there are better methods to do
669  * that. So in general you shouldn't use this function.
670  */
671 void
672 g_thread_yield (void)
673 {
674   sched_yield ();
675 }
676
677 void
678 g_system_thread_join (gpointer thread)
679 {
680   gpointer ignore;
681   posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
682 }
683
684 void
685 g_system_thread_exit (void)
686 {
687   pthread_exit (NULL);
688 }
689
690 void
691 g_system_thread_self (gpointer thread)
692 {
693   *(pthread_t*)thread = pthread_self();
694 }
695
696 gboolean
697 g_system_thread_equal (gpointer thread1,
698                        gpointer thread2)
699 {
700   return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);
701 }
702
703 /* {{{1 Epilogue */
704 /* vim:set foldmethod=marker: */