Add a new recursive mutex type, GRecMutex
[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
100   if G_UNLIKELY ((status = pthread_mutex_init (&mutex->impl, NULL)) != 0)
101     g_thread_abort (status, "pthread_mutex_init");
102 }
103
104 /**
105  * g_mutex_clear:
106  * @mutex: an initialized #GMutex
107  *
108  * Frees the resources allocated to a mutex with g_mutex_init().
109  *
110  * #GMutexes that have have been created with g_mutex_new() should
111  * be freed with g_mutex_free() instead.
112  *
113  * Sine: 2.32
114  */
115 void
116 g_mutex_clear (GMutex *mutex)
117 {
118   gint status;
119
120   if G_UNLIKELY ((status = pthread_mutex_destroy (&mutex->impl)) != 0)
121     g_thread_abort (status, "pthread_mutex_destroy");
122 }
123
124 /**
125  * g_mutex_lock:
126  * @mutex: a #GMutex
127  *
128  * Locks @mutex. If @mutex is already locked by another thread, the
129  * current thread will block until @mutex is unlocked by the other
130  * thread.
131  *
132  * This function can be used even if g_thread_init() has not yet been
133  * called, and, in that case, will do nothing.
134  *
135  * <note>#GMutex is neither guaranteed to be recursive nor to be
136  * non-recursive, i.e. a thread could deadlock while calling
137  * g_mutex_lock(), if it already has locked @mutex. Use
138  * #GStaticRecMutex, if you need recursive mutexes.</note>
139  */
140 void
141 g_mutex_lock (GMutex *mutex)
142 {
143   gint status;
144
145   if G_UNLIKELY ((status = pthread_mutex_lock (&mutex->impl)) != 0)
146     g_thread_abort (status, "pthread_mutex_lock");
147 }
148
149 /**
150  * g_mutex_unlock:
151  * @mutex: a #GMutex
152  *
153  * Unlocks @mutex. If another thread is blocked in a g_mutex_lock()
154  * call for @mutex, it will be woken and can lock @mutex itself.
155  *
156  * This function can be used even if g_thread_init() has not yet been
157  * called, and, in that case, will do nothing.
158  */
159 void
160 g_mutex_unlock (GMutex *mutex)
161 {
162   gint status;
163
164   if G_UNLIKELY ((status = pthread_mutex_unlock (&mutex->impl)) != 0)
165     g_thread_abort (status, "pthread_mutex_lock");
166 }
167
168 /**
169  * g_mutex_trylock:
170  * @mutex: a #GMutex
171  *
172  * Tries to lock @mutex. If @mutex is already locked by another thread,
173  * it immediately returns %FALSE. Otherwise it locks @mutex and returns
174  * %TRUE.
175  *
176  * This function can be used even if g_thread_init() has not yet been
177  * called, and, in that case, will immediately return %TRUE.
178  *
179  * <note>#GMutex is neither guaranteed to be recursive nor to be
180  * non-recursive, i.e. the return value of g_mutex_trylock() could be
181  * both %FALSE or %TRUE, if the current thread already has locked
182  * @mutex. Use #GStaticRecMutex, if you need recursive
183  * mutexes.</note>
184
185  * Returns: %TRUE, if @mutex could be locked
186  */
187 gboolean
188 g_mutex_trylock (GMutex *mutex)
189 {
190   gint status;
191
192   if G_LIKELY ((status = pthread_mutex_trylock (&mutex->impl)) == 0)
193     return TRUE;
194
195   if G_UNLIKELY (status != EBUSY)
196     g_thread_abort (status, "pthread_mutex_trylock");
197
198   return FALSE;
199 }
200
201 /* {{{1 GRecMutex */
202
203 static pthread_mutex_t *
204 g_rec_mutex_impl_new (void)
205 {
206   pthread_mutexattr_t attr;
207   pthread_mutex_t *mutex;
208
209   mutex = g_slice_new (pthread_mutex_t);
210   pthread_mutexattr_init (&attr);
211   pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
212   pthread_mutex_init (mutex, &attr);
213   pthread_mutexattr_destroy (&attr);
214
215   return mutex;
216 }
217
218 static void
219 g_rec_mutex_impl_free (pthread_mutex_t *mutex)
220 {
221   pthread_mutex_destroy (mutex);
222   g_slice_free (pthread_mutex_t, mutex);
223 }
224
225 static pthread_mutex_t *
226 g_rec_mutex_get_impl (GRecMutex *mutex)
227 {
228   pthread_mutex_t *impl = mutex->impl;
229
230   if G_UNLIKELY (mutex->impl == NULL)
231     {
232       impl = g_rec_mutex_impl_new ();
233       if (!g_atomic_pointer_compare_and_exchange (&mutex->impl, NULL, impl))
234         g_rec_mutex_impl_free (impl);
235       impl = mutex->impl;
236     }
237
238   return impl;
239 }
240
241 void
242 g_rec_mutex_init (GRecMutex *mutex)
243 {
244   mutex->impl = g_rec_mutex_impl_new ();
245 }
246
247 void
248 g_rec_mutex_clear (GRecMutex *mutex)
249 {
250   if (mutex->impl)
251     g_rec_mutex_impl_free (mutex->impl);
252 }
253
254 void
255 g_rec_mutex_lock (GRecMutex *mutex)
256 {
257   pthread_mutex_lock (g_rec_mutex_get_impl (mutex));
258 }
259
260 void
261 g_rec_mutex_unlock (GRecMutex *mutex)
262 {
263   pthread_mutex_unlock (mutex->impl);
264 }
265
266 gboolean
267 g_rec_mutex_trylock (GRecMutex *mutex)
268 {
269   return pthread_mutex_trylock (g_rec_mutex_get_impl (mutex));
270 }
271
272 /* {{{1 GRWLock */
273
274 void
275 g_rw_lock_init (GRWLock *lock)
276 {
277   pthread_rwlock_init (&lock->impl, NULL);
278 }
279
280 void
281 g_rw_lock_clear (GRWLock *lock)
282 {
283   pthread_rwlock_destroy (&lock->impl);
284 }
285
286 void
287 g_rw_lock_writer_lock (GRWLock *lock)
288 {
289   pthread_rwlock_wrlock (&lock->impl);
290 }
291
292 gboolean
293 g_rw_lock_writer_trylock (GRWLock *lock)
294 {
295   return pthread_rwlock_trywrlock (&lock->impl);
296 }
297
298 void
299 g_rw_lock_writer_unlock (GRWLock *lock)
300 {
301   pthread_rwlock_unlock (&lock->impl);
302 }
303
304 void
305 g_rw_lock_reader_lock (GRWLock *lock)
306 {
307   pthread_rwlock_rdlock (&lock->impl);
308 }
309
310 gboolean
311 g_rw_lock_reader_trylock (GRWLock *lock)
312 {
313   return pthread_rwlock_tryrdlock (&lock->impl);
314 }
315
316 void
317 g_rw_lock_reader_unlock (GRWLock *lock)
318 {
319   pthread_rwlock_unlock (&lock->impl);
320 }
321
322 /* {{{1 GCond */
323
324 /**
325  * g_cond_init:
326  * @cond: an uninitialized #GCond
327  *
328  * Initialized a #GCond so that it can be used.
329  *
330  * This function is useful to initialize a #GCond that has been
331  * allocated on the stack, or as part of a larger structure.
332  * It is not necessary to initialize a #GCond that has been
333  * created with g_cond_new(). Also see #G_COND_INITIALIZER
334  * for an alternative way to initialize statically allocated
335  * #GConds.
336  *
337  * Since: 2.32
338  */
339 void
340 g_cond_init (GCond *cond)
341 {
342   gint status;
343
344   if G_UNLIKELY ((status = pthread_cond_init (&cond->impl, NULL)) != 0)
345     g_thread_abort (status, "pthread_cond_init");
346 }
347
348 /**
349  * g_cond_clear:
350  * @cond: an initialized #GCond
351  *
352  * Frees the resources allocated ot a #GCond with g_cond_init().
353  *
354  * #GConds that have been created with g_cond_new() should
355  * be freed with g_cond_free() instead.
356  *
357  * Since: 2.32
358  */
359 void
360 g_cond_clear (GCond *cond)
361 {
362   gint status;
363
364   if G_UNLIKELY ((status = pthread_cond_destroy (&cond->impl)) != 0)
365     g_thread_abort (status, "pthread_cond_destroy");
366 }
367
368 /**
369  * g_cond_wait:
370  * @cond: a #GCond
371  * @mutex: a #GMutex that is currently locked
372  *
373  * Waits until this thread is woken up on @cond.
374  * The @mutex is unlocked before falling asleep
375  * and locked again before resuming.
376  *
377  * This function can be used even if g_thread_init() has not yet been
378  * called, and, in that case, will immediately return.
379  */
380 void
381 g_cond_wait (GCond  *cond,
382              GMutex *mutex)
383 {
384   gint status;
385
386   if G_UNLIKELY ((status = pthread_cond_wait (&cond->impl, &mutex->impl)) != 0)
387     g_thread_abort (status, "pthread_cond_wait");
388 }
389
390 /**
391  * g_cond_signal:
392  * @cond: a #GCond
393  *
394  * If threads are waiting for @cond, exactly one of them is woken up.
395  * It is good practice to hold the same lock as the waiting thread
396  * while calling this function, though not required.
397  *
398  * This function can be used even if g_thread_init() has not yet been
399  * called, and, in that case, will do nothing.
400  */
401 void
402 g_cond_signal (GCond *cond)
403 {
404   gint status;
405
406   if G_UNLIKELY ((status = pthread_cond_signal (&cond->impl)) != 0)
407     g_thread_abort (status, "pthread_cond_signal");
408 }
409
410 /**
411  * g_cond_broadcast:
412  * @cond: a #GCond
413  *
414  * If threads are waiting for @cond, all of them are woken up.
415  * It is good practice to lock the same mutex as the waiting threads
416  * while calling this function, though not required.
417  *
418  * This function can be used even if g_thread_init() has not yet been
419  * called, and, in that case, will do nothing.
420  */
421 void
422 g_cond_broadcast (GCond *cond)
423 {
424   gint status;
425
426   if G_UNLIKELY ((status = pthread_cond_broadcast (&cond->impl)) != 0)
427     g_thread_abort (status, "pthread_cond_broadcast");
428 }
429
430 /**
431  * g_cond_timed_wait:
432  * @cond: a #GCond
433  * @mutex: a #GMutex that is currently locked
434  * @abs_time: a #GTimeVal, determining the final time
435  *
436  * Waits until this thread is woken up on @cond, but not longer than
437  * until the time specified by @abs_time. The @mutex is unlocked before
438  * falling asleep and locked again before resuming.
439  *
440  * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
441  *
442  * This function can be used even if g_thread_init() has not yet been
443  * called, and, in that case, will immediately return %TRUE.
444  *
445  * To easily calculate @abs_time a combination of g_get_current_time()
446  * and g_time_val_add() can be used.
447  *
448  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
449  */
450 gboolean
451 g_cond_timed_wait (GCond    *cond,
452                    GMutex   *mutex,
453                    GTimeVal *abs_time)
454 {
455   struct timespec end_time;
456   gint status;
457
458   if (abs_time == NULL)
459     {
460       g_cond_wait (cond, mutex);
461       return TRUE;
462     }
463
464   end_time.tv_sec = abs_time->tv_sec;
465   end_time.tv_nsec = abs_time->tv_usec * 1000;
466
467   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
468     return TRUE;
469
470   if G_UNLIKELY (status != ETIMEDOUT)
471     g_thread_abort (status, "pthread_cond_timedwait");
472
473   return FALSE;
474 }
475
476 /**
477  * g_cond_timedwait:
478  * @cond: a #GCond
479  * @mutex: a #GMutex that is currently locked
480  * @abs_time: the final time, in microseconds
481  *
482  * A variant of g_cond_timed_wait() that takes @abs_time
483  * as a #gint64 instead of a #GTimeVal.
484  * See g_cond_timed_wait() for details.
485  *
486  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
487  *
488  * Since: 2.32
489  */
490 gboolean
491 g_cond_timedwait (GCond  *cond,
492                   GMutex *mutex,
493                   gint64  abs_time)
494 {
495   struct timespec end_time;
496   gint status;
497
498   end_time.tv_sec = abs_time / 1000000;
499   end_time.tv_nsec = (abs_time % 1000000) * 1000;
500
501   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
502     return TRUE;
503
504   if G_UNLIKELY (status != ETIMEDOUT)
505     g_thread_abort (status, "pthread_cond_timedwait");
506
507   return FALSE;
508 }
509
510 /* {{{1 GPrivate */
511
512 void
513 g_private_init (GPrivate       *key,
514                 GDestroyNotify  notify)
515 {
516   pthread_key_create (&key->key, notify);
517   key->ready = TRUE;
518 }
519
520 /**
521  * g_private_get:
522  * @private_key: a #GPrivate
523  *
524  * Returns the pointer keyed to @private_key for the current thread. If
525  * g_private_set() hasn't been called for the current @private_key and
526  * thread yet, this pointer will be %NULL.
527  *
528  * This function can be used even if g_thread_init() has not yet been
529  * called, and, in that case, will return the value of @private_key
530  * casted to #gpointer. Note however, that private data set
531  * <emphasis>before</emphasis> g_thread_init() will
532  * <emphasis>not</emphasis> be retained <emphasis>after</emphasis> the
533  * call. Instead, %NULL will be returned in all threads directly after
534  * g_thread_init(), regardless of any g_private_set() calls issued
535  * before threading system initialization.
536  *
537  * Returns: the corresponding pointer
538  */
539 gpointer
540 g_private_get (GPrivate *key)
541 {
542   if (!key->ready)
543     return key->single_value;
544
545   /* quote POSIX: No errors are returned from pthread_getspecific(). */
546   return pthread_getspecific (key->key);
547 }
548
549 /**
550  * g_private_set:
551  * @private_key: a #GPrivate
552  * @data: the new pointer
553  *
554  * Sets the pointer keyed to @private_key for the current thread.
555  *
556  * This function can be used even if g_thread_init() has not yet been
557  * called, and, in that case, will set @private_key to @data casted to
558  * #GPrivate*. See g_private_get() for resulting caveats.
559  */
560 void
561 g_private_set (GPrivate *key,
562                gpointer  value)
563 {
564   gint status;
565
566   if (!key->ready)
567     {
568       key->single_value = value;
569       return;
570     }
571
572   if G_UNLIKELY ((status = pthread_setspecific (key->key, value)) != 0)
573     g_thread_abort (status, "pthread_setspecific");
574 }
575
576 /* {{{1 GThread */
577
578 #include "glib.h"
579 #include "gthreadprivate.h"
580
581 #include <pthread.h>
582 #include <errno.h>
583 #include <stdlib.h>
584 #ifdef HAVE_SYS_TIME_H
585 # include <sys/time.h>
586 #endif
587 #ifdef HAVE_UNISTD_H
588 # include <unistd.h>
589 #endif
590
591 #ifdef HAVE_SCHED_H
592 #include <sched.h>
593 #endif
594
595 #define posix_check_err(err, name) G_STMT_START{                        \
596   int error = (err);                                                    \
597   if (error)                                                            \
598     g_error ("file %s: line %d (%s): error '%s' during '%s'",           \
599            __FILE__, __LINE__, G_STRFUNC,                               \
600            g_strerror (error), name);                                   \
601   }G_STMT_END
602
603 #define posix_check_cmd(cmd) posix_check_err (cmd, #cmd)
604
605 #define G_MUTEX_SIZE (sizeof (pthread_mutex_t))
606
607 void
608 g_system_thread_create (GThreadFunc       thread_func,
609                         gpointer          arg,
610                         gulong            stack_size,
611                         gboolean          joinable,
612                         gpointer          thread,
613                         GError          **error)
614 {
615   pthread_attr_t attr;
616   gint ret;
617
618   g_return_if_fail (thread_func);
619
620   posix_check_cmd (pthread_attr_init (&attr));
621
622 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
623   if (stack_size)
624     {
625 #ifdef _SC_THREAD_STACK_MIN
626       stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), stack_size);
627 #endif /* _SC_THREAD_STACK_MIN */
628       /* No error check here, because some systems can't do it and
629        * we simply don't want threads to fail because of that. */
630       pthread_attr_setstacksize (&attr, stack_size);
631     }
632 #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
633
634   posix_check_cmd (pthread_attr_setdetachstate (&attr,
635           joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
636
637   ret = pthread_create (thread, &attr, (void* (*)(void*))thread_func, arg);
638
639   posix_check_cmd (pthread_attr_destroy (&attr));
640
641   if (ret == EAGAIN)
642     {
643       g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
644                    "Error creating thread: %s", g_strerror (ret));
645       return;
646     }
647
648   posix_check_err (ret, "pthread_create");
649 }
650
651 /**
652  * g_thread_yield:
653  *
654  * Gives way to other threads waiting to be scheduled.
655  *
656  * This function is often used as a method to make busy wait less evil.
657  * But in most cases you will encounter, there are better methods to do
658  * that. So in general you shouldn't use this function.
659  */
660 void
661 g_thread_yield (void)
662 {
663   sched_yield ();
664 }
665
666 void
667 g_system_thread_join (gpointer thread)
668 {
669   gpointer ignore;
670   posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
671 }
672
673 void
674 g_system_thread_exit (void)
675 {
676   pthread_exit (NULL);
677 }
678
679 void
680 g_system_thread_self (gpointer thread)
681 {
682   *(pthread_t*)thread = pthread_self();
683 }
684
685 gboolean
686 g_system_thread_equal (gpointer thread1,
687                        gpointer thread2)
688 {
689   return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);
690 }
691
692 /* {{{1 Epilogue */
693 /* vim:set foldmethod=marker: */