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