Fix g_rec_mutex_trylock
[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   if (pthread_mutex_trylock (g_rec_mutex_get_impl (mutex)) != 0)
281     return FALSE;
282
283   return TRUE;
284 }
285
286 /* {{{1 GRWLock */
287
288 void
289 g_rw_lock_init (GRWLock *lock)
290 {
291   pthread_rwlock_init (&lock->impl, NULL);
292 }
293
294 void
295 g_rw_lock_clear (GRWLock *lock)
296 {
297   pthread_rwlock_destroy (&lock->impl);
298 }
299
300 void
301 g_rw_lock_writer_lock (GRWLock *lock)
302 {
303   pthread_rwlock_wrlock (&lock->impl);
304 }
305
306 gboolean
307 g_rw_lock_writer_trylock (GRWLock *lock)
308 {
309   return pthread_rwlock_trywrlock (&lock->impl);
310 }
311
312 void
313 g_rw_lock_writer_unlock (GRWLock *lock)
314 {
315   pthread_rwlock_unlock (&lock->impl);
316 }
317
318 void
319 g_rw_lock_reader_lock (GRWLock *lock)
320 {
321   pthread_rwlock_rdlock (&lock->impl);
322 }
323
324 gboolean
325 g_rw_lock_reader_trylock (GRWLock *lock)
326 {
327   return pthread_rwlock_tryrdlock (&lock->impl);
328 }
329
330 void
331 g_rw_lock_reader_unlock (GRWLock *lock)
332 {
333   pthread_rwlock_unlock (&lock->impl);
334 }
335
336 /* {{{1 GCond */
337
338 /**
339  * g_cond_init:
340  * @cond: an uninitialized #GCond
341  *
342  * Initialized a #GCond so that it can be used.
343  *
344  * This function is useful to initialize a #GCond that has been
345  * allocated on the stack, or as part of a larger structure.
346  * It is not necessary to initialize a #GCond that has been
347  * created with g_cond_new(). Also see #G_COND_INITIALIZER
348  * for an alternative way to initialize statically allocated
349  * #GConds.
350  *
351  * Since: 2.32
352  */
353 void
354 g_cond_init (GCond *cond)
355 {
356   gint status;
357
358   if G_UNLIKELY ((status = pthread_cond_init (&cond->impl, NULL)) != 0)
359     g_thread_abort (status, "pthread_cond_init");
360 }
361
362 /**
363  * g_cond_clear:
364  * @cond: an initialized #GCond
365  *
366  * Frees the resources allocated ot a #GCond with g_cond_init().
367  *
368  * #GConds that have been created with g_cond_new() should
369  * be freed with g_cond_free() instead.
370  *
371  * Since: 2.32
372  */
373 void
374 g_cond_clear (GCond *cond)
375 {
376   gint status;
377
378   if G_UNLIKELY ((status = pthread_cond_destroy (&cond->impl)) != 0)
379     g_thread_abort (status, "pthread_cond_destroy");
380 }
381
382 /**
383  * g_cond_wait:
384  * @cond: a #GCond
385  * @mutex: a #GMutex that is currently locked
386  *
387  * Waits until this thread is woken up on @cond.
388  * The @mutex is unlocked before falling asleep
389  * and locked again before resuming.
390  *
391  * This function can be used even if g_thread_init() has not yet been
392  * called, and, in that case, will immediately return.
393  */
394 void
395 g_cond_wait (GCond  *cond,
396              GMutex *mutex)
397 {
398   gint status;
399
400   if G_UNLIKELY ((status = pthread_cond_wait (&cond->impl, &mutex->impl)) != 0)
401     g_thread_abort (status, "pthread_cond_wait");
402 }
403
404 /**
405  * g_cond_signal:
406  * @cond: a #GCond
407  *
408  * If threads are waiting for @cond, exactly one of them is woken up.
409  * It is good practice to hold the same lock as the waiting thread
410  * while calling this function, though not required.
411  *
412  * This function can be used even if g_thread_init() has not yet been
413  * called, and, in that case, will do nothing.
414  */
415 void
416 g_cond_signal (GCond *cond)
417 {
418   gint status;
419
420   if G_UNLIKELY ((status = pthread_cond_signal (&cond->impl)) != 0)
421     g_thread_abort (status, "pthread_cond_signal");
422 }
423
424 /**
425  * g_cond_broadcast:
426  * @cond: a #GCond
427  *
428  * If threads are waiting for @cond, all of them are woken up.
429  * It is good practice to lock the same mutex as the waiting threads
430  * while calling this function, though not required.
431  *
432  * This function can be used even if g_thread_init() has not yet been
433  * called, and, in that case, will do nothing.
434  */
435 void
436 g_cond_broadcast (GCond *cond)
437 {
438   gint status;
439
440   if G_UNLIKELY ((status = pthread_cond_broadcast (&cond->impl)) != 0)
441     g_thread_abort (status, "pthread_cond_broadcast");
442 }
443
444 /**
445  * g_cond_timed_wait:
446  * @cond: a #GCond
447  * @mutex: a #GMutex that is currently locked
448  * @abs_time: a #GTimeVal, determining the final time
449  *
450  * Waits until this thread is woken up on @cond, but not longer than
451  * until the time specified by @abs_time. The @mutex is unlocked before
452  * falling asleep and locked again before resuming.
453  *
454  * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
455  *
456  * This function can be used even if g_thread_init() has not yet been
457  * called, and, in that case, will immediately return %TRUE.
458  *
459  * To easily calculate @abs_time a combination of g_get_current_time()
460  * and g_time_val_add() can be used.
461  *
462  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
463  */
464 gboolean
465 g_cond_timed_wait (GCond    *cond,
466                    GMutex   *mutex,
467                    GTimeVal *abs_time)
468 {
469   struct timespec end_time;
470   gint status;
471
472   if (abs_time == NULL)
473     {
474       g_cond_wait (cond, mutex);
475       return TRUE;
476     }
477
478   end_time.tv_sec = abs_time->tv_sec;
479   end_time.tv_nsec = abs_time->tv_usec * 1000;
480
481   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
482     return TRUE;
483
484   if G_UNLIKELY (status != ETIMEDOUT)
485     g_thread_abort (status, "pthread_cond_timedwait");
486
487   return FALSE;
488 }
489
490 /**
491  * g_cond_timedwait:
492  * @cond: a #GCond
493  * @mutex: a #GMutex that is currently locked
494  * @abs_time: the final time, in microseconds
495  *
496  * A variant of g_cond_timed_wait() that takes @abs_time
497  * as a #gint64 instead of a #GTimeVal.
498  * See g_cond_timed_wait() for details.
499  *
500  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
501  *
502  * Since: 2.32
503  */
504 gboolean
505 g_cond_timedwait (GCond  *cond,
506                   GMutex *mutex,
507                   gint64  abs_time)
508 {
509   struct timespec end_time;
510   gint status;
511
512   end_time.tv_sec = abs_time / 1000000;
513   end_time.tv_nsec = (abs_time % 1000000) * 1000;
514
515   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
516     return TRUE;
517
518   if G_UNLIKELY (status != ETIMEDOUT)
519     g_thread_abort (status, "pthread_cond_timedwait");
520
521   return FALSE;
522 }
523
524 /* {{{1 GPrivate */
525
526 void
527 g_private_init (GPrivate       *key,
528                 GDestroyNotify  notify)
529 {
530   pthread_key_create (&key->key, notify);
531   key->ready = TRUE;
532 }
533
534 /**
535  * g_private_get:
536  * @private_key: a #GPrivate
537  *
538  * Returns the pointer keyed to @private_key for the current thread. If
539  * g_private_set() hasn't been called for the current @private_key and
540  * thread yet, this pointer will be %NULL.
541  *
542  * This function can be used even if g_thread_init() has not yet been
543  * called, and, in that case, will return the value of @private_key
544  * casted to #gpointer. Note however, that private data set
545  * <emphasis>before</emphasis> g_thread_init() will
546  * <emphasis>not</emphasis> be retained <emphasis>after</emphasis> the
547  * call. Instead, %NULL will be returned in all threads directly after
548  * g_thread_init(), regardless of any g_private_set() calls issued
549  * before threading system initialization.
550  *
551  * Returns: the corresponding pointer
552  */
553 gpointer
554 g_private_get (GPrivate *key)
555 {
556   if (!key->ready)
557     return key->single_value;
558
559   /* quote POSIX: No errors are returned from pthread_getspecific(). */
560   return pthread_getspecific (key->key);
561 }
562
563 /**
564  * g_private_set:
565  * @private_key: a #GPrivate
566  * @data: the new pointer
567  *
568  * Sets the pointer keyed to @private_key for the current thread.
569  *
570  * This function can be used even if g_thread_init() has not yet been
571  * called, and, in that case, will set @private_key to @data casted to
572  * #GPrivate*. See g_private_get() for resulting caveats.
573  */
574 void
575 g_private_set (GPrivate *key,
576                gpointer  value)
577 {
578   gint status;
579
580   if (!key->ready)
581     {
582       key->single_value = value;
583       return;
584     }
585
586   if G_UNLIKELY ((status = pthread_setspecific (key->key, value)) != 0)
587     g_thread_abort (status, "pthread_setspecific");
588 }
589
590 /* {{{1 GThread */
591
592 #include "glib.h"
593 #include "gthreadprivate.h"
594
595 #include <pthread.h>
596 #include <errno.h>
597 #include <stdlib.h>
598 #ifdef HAVE_SYS_TIME_H
599 # include <sys/time.h>
600 #endif
601 #ifdef HAVE_UNISTD_H
602 # include <unistd.h>
603 #endif
604
605 #ifdef HAVE_SCHED_H
606 #include <sched.h>
607 #endif
608
609 #define posix_check_err(err, name) G_STMT_START{                        \
610   int error = (err);                                                    \
611   if (error)                                                            \
612     g_error ("file %s: line %d (%s): error '%s' during '%s'",           \
613            __FILE__, __LINE__, G_STRFUNC,                               \
614            g_strerror (error), name);                                   \
615   }G_STMT_END
616
617 #define posix_check_cmd(cmd) posix_check_err (cmd, #cmd)
618
619 #define G_MUTEX_SIZE (sizeof (pthread_mutex_t))
620
621 void
622 g_system_thread_create (GThreadFunc       thread_func,
623                         gpointer          arg,
624                         gulong            stack_size,
625                         gboolean          joinable,
626                         gpointer          thread,
627                         GError          **error)
628 {
629   pthread_attr_t attr;
630   gint ret;
631
632   g_return_if_fail (thread_func);
633
634   posix_check_cmd (pthread_attr_init (&attr));
635
636 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
637   if (stack_size)
638     {
639 #ifdef _SC_THREAD_STACK_MIN
640       stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), stack_size);
641 #endif /* _SC_THREAD_STACK_MIN */
642       /* No error check here, because some systems can't do it and
643        * we simply don't want threads to fail because of that. */
644       pthread_attr_setstacksize (&attr, stack_size);
645     }
646 #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
647
648   posix_check_cmd (pthread_attr_setdetachstate (&attr,
649           joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
650
651   ret = pthread_create (thread, &attr, (void* (*)(void*))thread_func, arg);
652
653   posix_check_cmd (pthread_attr_destroy (&attr));
654
655   if (ret == EAGAIN)
656     {
657       g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
658                    "Error creating thread: %s", g_strerror (ret));
659       return;
660     }
661
662   posix_check_err (ret, "pthread_create");
663 }
664
665 /**
666  * g_thread_yield:
667  *
668  * Gives way to other threads waiting to be scheduled.
669  *
670  * This function is often used as a method to make busy wait less evil.
671  * But in most cases you will encounter, there are better methods to do
672  * that. So in general you shouldn't use this function.
673  */
674 void
675 g_thread_yield (void)
676 {
677   sched_yield ();
678 }
679
680 void
681 g_system_thread_join (gpointer thread)
682 {
683   gpointer ignore;
684   posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
685 }
686
687 void
688 g_system_thread_exit (void)
689 {
690   pthread_exit (NULL);
691 }
692
693 void
694 g_system_thread_self (gpointer thread)
695 {
696   *(pthread_t*)thread = pthread_self();
697 }
698
699 gboolean
700 g_system_thread_equal (gpointer thread1,
701                        gpointer thread2)
702 {
703   return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);
704 }
705
706 /* {{{1 Epilogue */
707 /* vim:set foldmethod=marker: */