g_system_thread_create: drop unused args
[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 GCond */
201
202 /**
203  * g_cond_init:
204  * @cond: an uninitialized #GCond
205  *
206  * Initialized a #GCond so that it can be used.
207  *
208  * This function is useful to initialize a #GCond that has been
209  * allocated on the stack, or as part of a larger structure.
210  * It is not necessary to initialize a #GCond that has been
211  * created with g_cond_new(). Also see #G_COND_INITIALIZER
212  * for an alternative way to initialize statically allocated
213  * #GConds.
214  *
215  * Since: 2.32
216  */
217 void
218 g_cond_init (GCond *cond)
219 {
220   gint status;
221
222   if G_UNLIKELY ((status = pthread_cond_init (&cond->impl, NULL)) != 0)
223     g_thread_abort (status, "pthread_cond_init");
224 }
225
226 /**
227  * g_cond_clear:
228  * @cond: an initialized #GCond
229  *
230  * Frees the resources allocated ot a #GCond with g_cond_init().
231  *
232  * #GConds that have been created with g_cond_new() should
233  * be freed with g_cond_free() instead.
234  *
235  * Since: 2.32
236  */
237 void
238 g_cond_clear (GCond *cond)
239 {
240   gint status;
241
242   if G_UNLIKELY ((status = pthread_cond_destroy (&cond->impl)) != 0)
243     g_thread_abort (status, "pthread_cond_destroy");
244 }
245
246 /**
247  * g_cond_wait:
248  * @cond: a #GCond
249  * @mutex: a #GMutex that is currently locked
250  *
251  * Waits until this thread is woken up on @cond.
252  * The @mutex is unlocked before falling asleep
253  * and locked again before resuming.
254  *
255  * This function can be used even if g_thread_init() has not yet been
256  * called, and, in that case, will immediately return.
257  */
258 void
259 g_cond_wait (GCond  *cond,
260              GMutex *mutex)
261 {
262   gint status;
263
264   if G_UNLIKELY ((status = pthread_cond_wait (&cond->impl, &mutex->impl)) != 0)
265     g_thread_abort (status, "pthread_cond_wait");
266 }
267
268 /**
269  * g_cond_signal:
270  * @cond: a #GCond
271  *
272  * If threads are waiting for @cond, exactly one of them is woken up.
273  * It is good practice to hold the same lock as the waiting thread
274  * while calling this function, though not required.
275  *
276  * This function can be used even if g_thread_init() has not yet been
277  * called, and, in that case, will do nothing.
278  */
279 void
280 g_cond_signal (GCond *cond)
281 {
282   gint status;
283
284   if G_UNLIKELY ((status = pthread_cond_signal (&cond->impl)) != 0)
285     g_thread_abort (status, "pthread_cond_signal");
286 }
287
288 /**
289  * g_cond_broadcast:
290  * @cond: a #GCond
291  *
292  * If threads are waiting for @cond, all of them are woken up.
293  * It is good practice to lock the same mutex as the waiting threads
294  * while calling this function, though not required.
295  *
296  * This function can be used even if g_thread_init() has not yet been
297  * called, and, in that case, will do nothing.
298  */
299 void
300 g_cond_broadcast (GCond *cond)
301 {
302   gint status;
303
304   if G_UNLIKELY ((status = pthread_cond_broadcast (&cond->impl)) != 0)
305     g_thread_abort (status, "pthread_cond_broadcast");
306 }
307
308 /**
309  * g_cond_timed_wait:
310  * @cond: a #GCond
311  * @mutex: a #GMutex that is currently locked
312  * @abs_time: a #GTimeVal, determining the final time
313  *
314  * Waits until this thread is woken up on @cond, but not longer than
315  * until the time specified by @abs_time. The @mutex is unlocked before
316  * falling asleep and locked again before resuming.
317  *
318  * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
319  *
320  * This function can be used even if g_thread_init() has not yet been
321  * called, and, in that case, will immediately return %TRUE.
322  *
323  * To easily calculate @abs_time a combination of g_get_current_time()
324  * and g_time_val_add() can be used.
325  *
326  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
327  */
328 gboolean
329 g_cond_timed_wait (GCond    *cond,
330                    GMutex   *mutex,
331                    GTimeVal *abs_time)
332 {
333   struct timespec end_time;
334   gint status;
335
336   if (abs_time == NULL)
337     {
338       g_cond_wait (cond, mutex);
339       return TRUE;
340     }
341
342   end_time.tv_sec = abs_time->tv_sec;
343   end_time.tv_nsec = abs_time->tv_usec * 1000;
344
345   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
346     return TRUE;
347
348   if G_UNLIKELY (status != ETIMEDOUT)
349     g_thread_abort (status, "pthread_cond_timedwait");
350
351   return FALSE;
352 }
353
354 /**
355  * g_cond_timedwait:
356  * @cond: a #GCond
357  * @mutex: a #GMutex that is currently locked
358  * @abs_time: the final time, in microseconds
359  *
360  * A variant of g_cond_timed_wait() that takes @abs_time
361  * as a #gint64 instead of a #GTimeVal.
362  * See g_cond_timed_wait() for details.
363  *
364  * Returns: %TRUE if @cond was signalled, or %FALSE on timeout
365  *
366  * Since: 2.32
367  */
368 gboolean
369 g_cond_timedwait (GCond  *cond,
370                   GMutex *mutex,
371                   gint64  abs_time)
372 {
373   struct timespec end_time;
374   gint status;
375
376   end_time.tv_sec = abs_time / 1000000;
377   end_time.tv_nsec = (abs_time % 1000000) * 1000;
378
379   if ((status = pthread_cond_timedwait (&cond->impl, &mutex->impl, &end_time)) == 0)
380     return TRUE;
381
382   if G_UNLIKELY (status != ETIMEDOUT)
383     g_thread_abort (status, "pthread_cond_timedwait");
384
385   return FALSE;
386 }
387
388 /* {{{1 GPrivate */
389
390 void
391 g_private_init (GPrivate       *key,
392                 GDestroyNotify  notify)
393 {
394   pthread_key_create (&key->key, notify);
395   key->ready = TRUE;
396 }
397
398 /**
399  * g_private_get:
400  * @private_key: a #GPrivate
401  *
402  * Returns the pointer keyed to @private_key for the current thread. If
403  * g_private_set() hasn't been called for the current @private_key and
404  * thread yet, this pointer will be %NULL.
405  *
406  * This function can be used even if g_thread_init() has not yet been
407  * called, and, in that case, will return the value of @private_key
408  * casted to #gpointer. Note however, that private data set
409  * <emphasis>before</emphasis> g_thread_init() will
410  * <emphasis>not</emphasis> be retained <emphasis>after</emphasis> the
411  * call. Instead, %NULL will be returned in all threads directly after
412  * g_thread_init(), regardless of any g_private_set() calls issued
413  * before threading system initialization.
414  *
415  * Returns: the corresponding pointer
416  */
417 gpointer
418 g_private_get (GPrivate *key)
419 {
420   if (!key->ready)
421     return key->single_value;
422
423   /* quote POSIX: No errors are returned from pthread_getspecific(). */
424   return pthread_getspecific (key->key);
425 }
426
427 /**
428  * g_private_set:
429  * @private_key: a #GPrivate
430  * @data: the new pointer
431  *
432  * Sets the pointer keyed to @private_key for the current thread.
433  *
434  * This function can be used even if g_thread_init() has not yet been
435  * called, and, in that case, will set @private_key to @data casted to
436  * #GPrivate*. See g_private_get() for resulting caveats.
437  */
438 void
439 g_private_set (GPrivate *key,
440                gpointer  value)
441 {
442   gint status;
443
444   if (!key->ready)
445     {
446       key->single_value = value;
447       return;
448     }
449
450   if G_UNLIKELY ((status = pthread_setspecific (key->key, value)) != 0)
451     g_thread_abort (status, "pthread_setspecific");
452 }
453
454 /* {{{1 GThread */
455
456 #include "glib.h"
457 #include "gthreadprivate.h"
458
459 #include <pthread.h>
460 #include <errno.h>
461 #include <stdlib.h>
462 #ifdef HAVE_SYS_TIME_H
463 # include <sys/time.h>
464 #endif
465 #ifdef HAVE_UNISTD_H
466 # include <unistd.h>
467 #endif
468
469 #ifdef HAVE_SCHED_H
470 #include <sched.h>
471 #endif
472
473 #define posix_check_err(err, name) G_STMT_START{                        \
474   int error = (err);                                                    \
475   if (error)                                                            \
476     g_error ("file %s: line %d (%s): error '%s' during '%s'",           \
477            __FILE__, __LINE__, G_STRFUNC,                               \
478            g_strerror (error), name);                                   \
479   }G_STMT_END
480
481 #define posix_check_cmd(cmd) posix_check_err (cmd, #cmd)
482
483 static gulong g_thread_min_stack_size = 0;
484
485 #define G_MUTEX_SIZE (sizeof (pthread_mutex_t))
486
487 void
488 _g_thread_impl_init(void)
489 {
490 #ifdef _SC_THREAD_STACK_MIN
491   g_thread_min_stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), 0);
492 #endif /* _SC_THREAD_STACK_MIN */
493 }
494
495 void
496 g_system_thread_create (GThreadFunc       thread_func,
497                         gpointer          arg,
498                         gulong            stack_size,
499                         gboolean          joinable,
500                         gpointer          thread,
501                         GError          **error)
502 {
503   pthread_attr_t attr;
504   gint ret;
505
506   g_return_if_fail (thread_func);
507
508   posix_check_cmd (pthread_attr_init (&attr));
509
510 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
511   if (stack_size)
512     {
513       stack_size = MAX (g_thread_min_stack_size, stack_size);
514       /* No error check here, because some systems can't do it and
515        * we simply don't want threads to fail because of that. */
516       pthread_attr_setstacksize (&attr, stack_size);
517     }
518 #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
519
520   posix_check_cmd (pthread_attr_setdetachstate (&attr,
521           joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
522
523   ret = pthread_create (thread, &attr, (void* (*)(void*))thread_func, arg);
524
525   posix_check_cmd (pthread_attr_destroy (&attr));
526
527   if (ret == EAGAIN)
528     {
529       g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
530                    "Error creating thread: %s", g_strerror (ret));
531       return;
532     }
533
534   posix_check_err (ret, "pthread_create");
535 }
536
537 /**
538  * g_thread_yield:
539  *
540  * Gives way to other threads waiting to be scheduled.
541  *
542  * This function is often used as a method to make busy wait less evil.
543  * But in most cases you will encounter, there are better methods to do
544  * that. So in general you shouldn't use this function.
545  */
546 void
547 g_thread_yield (void)
548 {
549   sched_yield ();
550 }
551
552 void
553 g_system_thread_join (gpointer thread)
554 {
555   gpointer ignore;
556   posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
557 }
558
559 void
560 g_system_thread_exit (void)
561 {
562   pthread_exit (NULL);
563 }
564
565 void
566 g_system_thread_self (gpointer thread)
567 {
568   *(pthread_t*)thread = pthread_self();
569 }
570
571 gboolean
572 g_system_thread_equal (gpointer thread1,
573                        gpointer thread2)
574 {
575   return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);
576 }
577
578 /* {{{1 Epilogue */
579 /* vim:set foldmethod=marker: */