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