]> git.sesse.net Git - vlc/blob - src/posix/thread.c
8e94ead26537eb398c3555288877eb0d2d70e28d
[vlc] / src / posix / thread.c
1 /*****************************************************************************
2  * thread.c : pthread back-end for LibVLC
3  *****************************************************************************
4  * Copyright (C) 1999-2009 the VideoLAN team
5  *
6  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
7  *          Samuel Hocevar <sam@zoy.org>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *          Clément Sténac
10  *          Rémi Denis-Courmont
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc_common.h>
32 #include <vlc_atomic.h>
33
34 #include "libvlc.h"
35 #include <stdarg.h>
36 #include <assert.h>
37 #include <unistd.h> /* fsync() */
38 #include <signal.h>
39 #include <errno.h>
40 #include <time.h>
41
42 #include <pthread.h>
43 #include <sched.h>
44 #include <sys/time.h> /* gettimeofday() */
45
46 #ifdef __linux__
47 # include <sys/syscall.h> /* SYS_gettid */
48 #endif
49
50 #ifdef HAVE_EXECINFO_H
51 # include <execinfo.h>
52 #endif
53
54 #ifdef __APPLE__
55 # include <mach/mach_init.h> /* mach_task_self in semaphores */
56 # include <sys/sysctl.h>
57 #endif
58
59 #if defined(__OpenBSD__)
60 # include <sys/param.h>
61 # include <sys/sysctl.h>
62 # include <machine/cpu.h>
63 #endif
64
65 #if defined(__SunOS)
66 # include <unistd.h>
67 # include <sys/types.h>
68 # include <sys/processor.h>
69 # include <sys/pset.h>
70 #endif
71
72 #if !defined (_POSIX_TIMERS)
73 # define _POSIX_TIMERS (-1)
74 #endif
75 #if !defined (_POSIX_CLOCK_SELECTION)
76 /* Clock selection was defined in 2001 and became mandatory in 2008. */
77 # define _POSIX_CLOCK_SELECTION (-1)
78 #endif
79 #if !defined (_POSIX_MONOTONIC_CLOCK)
80 # define _POSIX_MONOTONIC_CLOCK (-1)
81 #endif
82
83 #if (_POSIX_TIMERS > 0)
84 static unsigned vlc_clock_prec;
85
86 # if (_POSIX_MONOTONIC_CLOCK > 0)
87 /* Compile-time POSIX monotonic clock support */
88 #  define vlc_clock_id (CLOCK_MONOTONIC)
89
90 # elif (_POSIX_MONOTONIC_CLOCK == 0)
91 /* Run-time POSIX monotonic clock support (see clock_setup() below) */
92 static clockid_t vlc_clock_id;
93
94 # else
95 /* No POSIX monotonic clock support */
96 #   define vlc_clock_id (CLOCK_REALTIME)
97 #   warning Monotonic clock not available. Expect timing issues.
98
99 # endif /* _POSIX_MONOTONIC_CLOKC */
100
101 static void vlc_clock_setup_once (void)
102 {
103 # if (_POSIX_MONOTONIC_CLOCK == 0)
104     long val = sysconf (_SC_MONOTONIC_CLOCK);
105     assert (val != 0);
106     vlc_clock_id = (val < 0) ? CLOCK_REALTIME : CLOCK_MONOTONIC;
107 # endif
108
109     struct timespec res;
110     if (unlikely(clock_getres (vlc_clock_id, &res) != 0 || res.tv_sec != 0))
111         abort ();
112     vlc_clock_prec = (res.tv_nsec + 500) / 1000;
113 }
114
115 static pthread_once_t vlc_clock_once = PTHREAD_ONCE_INIT;
116
117 # define vlc_clock_setup() \
118     pthread_once(&vlc_clock_once, vlc_clock_setup_once)
119
120 #else /* _POSIX_TIMERS */
121
122 # include <sys/time.h> /* gettimeofday() */
123 # if defined (HAVE_DECL_NANOSLEEP) && !HAVE_DECL_NANOSLEEP
124 int nanosleep (struct timespec *, struct timespec *);
125 # endif
126
127 # define vlc_clock_setup() (void)0
128 # warning Monotonic clock not available. Expect timing issues.
129 #endif /* _POSIX_TIMERS */
130
131 static struct timespec mtime_to_ts (mtime_t date)
132 {
133     lldiv_t d = lldiv (date, CLOCK_FREQ);
134     struct timespec ts = { d.quot, d.rem * (1000000000 / CLOCK_FREQ) };
135
136     return ts;
137 }
138
139 /**
140  * Print a backtrace to the standard error for debugging purpose.
141  */
142 void vlc_trace (const char *fn, const char *file, unsigned line)
143 {
144      fprintf (stderr, "at %s:%u in %s\n", file, line, fn);
145      fflush (stderr); /* needed before switch to low-level I/O */
146 #ifdef HAVE_BACKTRACE
147      void *stack[20];
148      int len = backtrace (stack, sizeof (stack) / sizeof (stack[0]));
149      backtrace_symbols_fd (stack, len, 2);
150 #endif
151      fsync (2);
152 }
153
154 static inline unsigned long vlc_threadid (void)
155 {
156 #if defined (__linux__)
157      /* glibc does not provide a call for this */
158      return syscall (SYS_gettid);
159
160 #else
161      union { pthread_t th; unsigned long int i; } v = { };
162      v.th = pthread_self ();
163      return v.i;
164
165 #endif
166 }
167
168 #ifndef NDEBUG
169 /*****************************************************************************
170  * vlc_thread_fatal: Report an error from the threading layer
171  *****************************************************************************
172  * This is mostly meant for debugging.
173  *****************************************************************************/
174 static void
175 vlc_thread_fatal (const char *action, int error,
176                   const char *function, const char *file, unsigned line)
177 {
178     int canc = vlc_savecancel ();
179     fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ",
180              action, error, vlc_threadid ());
181     vlc_trace (function, file, line);
182
183     /* Sometimes strerror_r() crashes too, so make sure we print an error
184      * message before we invoke it */
185 #ifdef __GLIBC__
186     /* Avoid the strerror_r() prototype brain damage in glibc */
187     errno = error;
188     fprintf (stderr, " Error message: %m\n");
189 #else
190     char buf[1000];
191     const char *msg;
192
193     switch (strerror_r (error, buf, sizeof (buf)))
194     {
195         case 0:
196             msg = buf;
197             break;
198         case ERANGE: /* should never happen */
199             msg = "unknown (too big to display)";
200             break;
201         default:
202             msg = "unknown (invalid error number)";
203             break;
204     }
205     fprintf (stderr, " Error message: %s\n", msg);
206 #endif
207     fflush (stderr);
208
209     vlc_restorecancel (canc);
210     abort ();
211 }
212
213 # define VLC_THREAD_ASSERT( action ) \
214     if (unlikely(val)) \
215         vlc_thread_fatal (action, val, __func__, __FILE__, __LINE__)
216 #else
217 # define VLC_THREAD_ASSERT( action ) ((void)val)
218 #endif
219
220 #if defined (__GLIBC__) && (__GLIBC_MINOR__ < 6)
221 /* This is not prototyped under glibc, though it exists. */
222 int pthread_mutexattr_setkind_np( pthread_mutexattr_t *attr, int kind );
223 #endif
224
225 /*****************************************************************************
226  * vlc_mutex_init: initialize a mutex
227  *****************************************************************************/
228 void vlc_mutex_init( vlc_mutex_t *p_mutex )
229 {
230     pthread_mutexattr_t attr;
231
232     if (unlikely(pthread_mutexattr_init (&attr)))
233         abort();
234 #ifdef NDEBUG
235     pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_NORMAL );
236 #else
237     /* Create error-checking mutex to detect problems more easily. */
238 # if defined (__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ < 6)
239     pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_ERRORCHECK_NP );
240 # else
241     pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );
242 # endif
243 #endif
244     if (unlikely(pthread_mutex_init (p_mutex, &attr)))
245         abort();
246     pthread_mutexattr_destroy( &attr );
247 }
248
249 /*****************************************************************************
250  * vlc_mutex_init: initialize a recursive mutex (Do not use)
251  *****************************************************************************/
252 void vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
253 {
254     pthread_mutexattr_t attr;
255
256     if (unlikely(pthread_mutexattr_init (&attr)))
257         abort();
258 #if defined (__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ < 6)
259     pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_RECURSIVE_NP );
260 #else
261     pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
262 #endif
263     if (unlikely(pthread_mutex_init (p_mutex, &attr)))
264         abort();
265     pthread_mutexattr_destroy( &attr );
266 }
267
268
269 /**
270  * Destroys a mutex. The mutex must not be locked.
271  *
272  * @param p_mutex mutex to destroy
273  * @return always succeeds
274  */
275 void vlc_mutex_destroy (vlc_mutex_t *p_mutex)
276 {
277     int val = pthread_mutex_destroy( p_mutex );
278     VLC_THREAD_ASSERT ("destroying mutex");
279 }
280
281 #ifndef NDEBUG
282 # ifdef HAVE_VALGRIND_VALGRIND_H
283 #  include <valgrind/valgrind.h>
284 # else
285 #  define RUNNING_ON_VALGRIND (0)
286 # endif
287
288 void vlc_assert_locked (vlc_mutex_t *p_mutex)
289 {
290     if (RUNNING_ON_VALGRIND > 0)
291         return;
292     assert (pthread_mutex_lock (p_mutex) == EDEADLK);
293 }
294 #endif
295
296 /**
297  * Acquires a mutex. If needed, waits for any other thread to release it.
298  * Beware of deadlocks when locking multiple mutexes at the same time,
299  * or when using mutexes from callbacks.
300  * This function is not a cancellation-point.
301  *
302  * @param p_mutex mutex initialized with vlc_mutex_init() or
303  *                vlc_mutex_init_recursive()
304  */
305 void vlc_mutex_lock (vlc_mutex_t *p_mutex)
306 {
307     int val = pthread_mutex_lock( p_mutex );
308     VLC_THREAD_ASSERT ("locking mutex");
309 }
310
311 /**
312  * Acquires a mutex if and only if it is not currently held by another thread.
313  * This function never sleeps and can be used in delay-critical code paths.
314  * This function is not a cancellation-point.
315  *
316  * <b>Beware</b>: If this function fails, then the mutex is held... by another
317  * thread. The calling thread must deal with the error appropriately. That
318  * typically implies postponing the operations that would have required the
319  * mutex. If the thread cannot defer those operations, then it must use
320  * vlc_mutex_lock(). If in doubt, use vlc_mutex_lock() instead.
321  *
322  * @param p_mutex mutex initialized with vlc_mutex_init() or
323  *                vlc_mutex_init_recursive()
324  * @return 0 if the mutex could be acquired, an error code otherwise.
325  */
326 int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
327 {
328     int val = pthread_mutex_trylock( p_mutex );
329
330     if (val != EBUSY)
331         VLC_THREAD_ASSERT ("locking mutex");
332     return val;
333 }
334
335 /**
336  * Releases a mutex (or crashes if the mutex is not locked by the caller).
337  * @param p_mutex mutex locked with vlc_mutex_lock().
338  */
339 void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
340 {
341     int val = pthread_mutex_unlock( p_mutex );
342     VLC_THREAD_ASSERT ("unlocking mutex");
343 }
344
345 /**
346  * Initializes a condition variable.
347  */
348 void vlc_cond_init (vlc_cond_t *p_condvar)
349 {
350     pthread_condattr_t attr;
351
352     vlc_clock_setup ();
353     if (unlikely(pthread_condattr_init (&attr)))
354         abort ();
355 #if (_POSIX_CLOCK_SELECTION > 0)
356     pthread_condattr_setclock (&attr, vlc_clock_id);
357 #endif
358     if (unlikely(pthread_cond_init (p_condvar, &attr)))
359         abort ();
360     pthread_condattr_destroy (&attr);
361 }
362
363 /**
364  * Initializes a condition variable.
365  * Contrary to vlc_cond_init(), the wall clock will be used as a reference for
366  * the vlc_cond_timedwait() time-out parameter.
367  */
368 void vlc_cond_init_daytime (vlc_cond_t *p_condvar)
369 {
370     if (unlikely(pthread_cond_init (p_condvar, NULL)))
371         abort ();
372 }
373
374 /**
375  * Destroys a condition variable. No threads shall be waiting or signaling the
376  * condition.
377  * @param p_condvar condition variable to destroy
378  */
379 void vlc_cond_destroy (vlc_cond_t *p_condvar)
380 {
381     int val = pthread_cond_destroy( p_condvar );
382     VLC_THREAD_ASSERT ("destroying condition");
383 }
384
385 /**
386  * Wakes up one thread waiting on a condition variable, if any.
387  * @param p_condvar condition variable
388  */
389 void vlc_cond_signal (vlc_cond_t *p_condvar)
390 {
391     int val = pthread_cond_signal( p_condvar );
392     VLC_THREAD_ASSERT ("signaling condition variable");
393 }
394
395 /**
396  * Wakes up all threads (if any) waiting on a condition variable.
397  * @param p_cond condition variable
398  */
399 void vlc_cond_broadcast (vlc_cond_t *p_condvar)
400 {
401     pthread_cond_broadcast (p_condvar);
402 }
403
404 /**
405  * Waits for a condition variable. The calling thread will be suspended until
406  * another thread calls vlc_cond_signal() or vlc_cond_broadcast() on the same
407  * condition variable, the thread is cancelled with vlc_cancel(), or the
408  * system causes a "spurious" unsolicited wake-up.
409  *
410  * A mutex is needed to wait on a condition variable. It must <b>not</b> be
411  * a recursive mutex. Although it is possible to use the same mutex for
412  * multiple condition, it is not valid to use different mutexes for the same
413  * condition variable at the same time from different threads.
414  *
415  * In case of thread cancellation, the mutex is always locked before
416  * cancellation proceeds.
417  *
418  * The canonical way to use a condition variable to wait for event foobar is:
419  @code
420    vlc_mutex_lock (&lock);
421    mutex_cleanup_push (&lock); // release the mutex in case of cancellation
422
423    while (!foobar)
424        vlc_cond_wait (&wait, &lock);
425
426    --- foobar is now true, do something about it here --
427
428    vlc_cleanup_run (); // release the mutex
429   @endcode
430  *
431  * @param p_condvar condition variable to wait on
432  * @param p_mutex mutex which is unlocked while waiting,
433  *                then locked again when waking up.
434  * @param deadline <b>absolute</b> timeout
435  */
436 void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
437 {
438     int val = pthread_cond_wait( p_condvar, p_mutex );
439     VLC_THREAD_ASSERT ("waiting on condition");
440 }
441
442 /**
443  * Waits for a condition variable up to a certain date.
444  * This works like vlc_cond_wait(), except for the additional time-out.
445  *
446  * If the variable was initialized with vlc_cond_init(), the timeout has the
447  * same arbitrary origin as mdate(). If the variable was initialized with
448  * vlc_cond_init_daytime(), the timeout is expressed from the Unix epoch.
449  *
450  * @param p_condvar condition variable to wait on
451  * @param p_mutex mutex which is unlocked while waiting,
452  *                then locked again when waking up.
453  * @param deadline <b>absolute</b> timeout
454  *
455  * @return 0 if the condition was signaled, an error code in case of timeout.
456  */
457 int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
458                         mtime_t deadline)
459 {
460 #if (_POSIX_MONOTONIC_CLOCK > 0) && (_POSIX_CLOCK_SELECTION < 0)
461     /* Without clock selection, the real-time clock is used for the absolute
462      * timeout in pthread_cond_timedwait(). We may need to adjust. */
463 # error FIXME: breaks vlc_cond_init_daytime()
464     if (vlc_clock_id != CLOCK_REALTIME)
465     {
466         struct timeval tv;
467
468         deadline -= mdate ();
469         gettimeofday (&tv, NULL);
470         deadline += tv.tv_sec * UINT64_C(1000000) + tv.tv_usec;
471     }
472 #endif
473
474     struct timespec ts = mtime_to_ts (deadline);
475     int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts);
476     if (val != ETIMEDOUT)
477         VLC_THREAD_ASSERT ("timed-waiting on condition");
478     return val;
479 }
480
481 /**
482  * Initializes a semaphore.
483  */
484 void vlc_sem_init (vlc_sem_t *sem, unsigned value)
485 {
486 #if defined(__APPLE__)
487     if (unlikely(semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value) != KERN_SUCCESS))
488         abort ();
489 #else
490     if (unlikely(sem_init (sem, 0, value)))
491         abort ();
492 #endif
493 }
494
495 /**
496  * Destroys a semaphore.
497  */
498 void vlc_sem_destroy (vlc_sem_t *sem)
499 {
500     int val;
501
502 #if defined(__APPLE__)
503     if (likely(semaphore_destroy(mach_task_self(), *sem) == KERN_SUCCESS))
504         return;
505
506     val = EINVAL;
507 #else
508     if (likely(sem_destroy (sem) == 0))
509         return;
510
511     val = errno;
512 #endif
513
514     VLC_THREAD_ASSERT ("destroying semaphore");
515 }
516
517 /**
518  * Increments the value of a semaphore.
519  * @return 0 on success, EOVERFLOW in case of integer overflow
520  */
521 int vlc_sem_post (vlc_sem_t *sem)
522 {
523     int val;
524
525 #if defined(__APPLE__)
526     if (likely(semaphore_signal(*sem) == KERN_SUCCESS))
527         return 0;
528
529     val = EINVAL;
530 #else
531     if (likely(sem_post (sem) == 0))
532         return 0;
533
534     val = errno;
535 #endif
536
537     if (unlikely(val != EOVERFLOW))
538         VLC_THREAD_ASSERT ("unlocking semaphore");
539     return val;
540 }
541
542 /**
543  * Atomically wait for the semaphore to become non-zero (if needed),
544  * then decrements it.
545  */
546 void vlc_sem_wait (vlc_sem_t *sem)
547 {
548     int val;
549
550 #if defined(__APPLE__)
551     if (likely(semaphore_wait(*sem) == KERN_SUCCESS))
552         return;
553
554     val = EINVAL;
555 #else
556     do
557         if (likely(sem_wait (sem) == 0))
558             return;
559     while ((val = errno) == EINTR);
560 #endif
561
562     VLC_THREAD_ASSERT ("locking semaphore");
563 }
564
565 /**
566  * Initializes a read/write lock.
567  */
568 void vlc_rwlock_init (vlc_rwlock_t *lock)
569 {
570     if (unlikely(pthread_rwlock_init (lock, NULL)))
571         abort ();
572 }
573
574 /**
575  * Destroys an initialized unused read/write lock.
576  */
577 void vlc_rwlock_destroy (vlc_rwlock_t *lock)
578 {
579     int val = pthread_rwlock_destroy (lock);
580     VLC_THREAD_ASSERT ("destroying R/W lock");
581 }
582
583 /**
584  * Acquires a read/write lock for reading. Recursion is allowed.
585  */
586 void vlc_rwlock_rdlock (vlc_rwlock_t *lock)
587 {
588     int val = pthread_rwlock_rdlock (lock);
589     VLC_THREAD_ASSERT ("acquiring R/W lock for reading");
590 }
591
592 /**
593  * Acquires a read/write lock for writing. Recursion is not allowed.
594  */
595 void vlc_rwlock_wrlock (vlc_rwlock_t *lock)
596 {
597     int val = pthread_rwlock_wrlock (lock);
598     VLC_THREAD_ASSERT ("acquiring R/W lock for writing");
599 }
600
601 /**
602  * Releases a read/write lock.
603  */
604 void vlc_rwlock_unlock (vlc_rwlock_t *lock)
605 {
606     int val = pthread_rwlock_unlock (lock);
607     VLC_THREAD_ASSERT ("releasing R/W lock");
608 }
609
610 /**
611  * Allocates a thread-specific variable.
612  * @param key where to store the thread-specific variable handle
613  * @param destr a destruction callback. It is called whenever a thread exits
614  * and the thread-specific variable has a non-NULL value.
615  * @return 0 on success, a system error code otherwise. This function can
616  * actually fail because there is a fixed limit on the number of
617  * thread-specific variable in a process on most systems.
618  */
619 int vlc_threadvar_create (vlc_threadvar_t *key, void (*destr) (void *))
620 {
621     return pthread_key_create (key, destr);
622 }
623
624 void vlc_threadvar_delete (vlc_threadvar_t *p_tls)
625 {
626     pthread_key_delete (*p_tls);
627 }
628
629 /**
630  * Sets a thread-specific variable.
631  * @param key thread-local variable key (created with vlc_threadvar_create())
632  * @param value new value for the variable for the calling thread
633  * @return 0 on success, a system error code otherwise.
634  */
635 int vlc_threadvar_set (vlc_threadvar_t key, void *value)
636 {
637     return pthread_setspecific (key, value);
638 }
639
640 /**
641  * Gets the value of a thread-local variable for the calling thread.
642  * This function cannot fail.
643  * @return the value associated with the given variable for the calling
644  * or NULL if there is no value.
645  */
646 void *vlc_threadvar_get (vlc_threadvar_t key)
647 {
648     return pthread_getspecific (key);
649 }
650
651 static bool rt_priorities = false;
652 static int rt_offset;
653
654 void vlc_threads_setup (libvlc_int_t *p_libvlc)
655 {
656     static vlc_mutex_t lock = VLC_STATIC_MUTEX;
657     static bool initialized = false;
658
659     vlc_mutex_lock (&lock);
660     /* Initializes real-time priorities before any thread is created,
661      * just once per process. */
662     if (!initialized)
663     {
664 #ifndef __APPLE__
665         if (var_InheritBool (p_libvlc, "rt-priority"))
666 #endif
667         {
668             rt_offset = var_InheritInteger (p_libvlc, "rt-offset");
669             rt_priorities = true;
670         }
671         initialized = true;
672     }
673     vlc_mutex_unlock (&lock);
674 }
675
676
677 static int vlc_clone_attr (vlc_thread_t *th, pthread_attr_t *attr,
678                            void *(*entry) (void *), void *data, int priority)
679 {
680     int ret;
681
682     /* Block the signals that signals interface plugin handles.
683      * If the LibVLC caller wants to handle some signals by itself, it should
684      * block these before whenever invoking LibVLC. And it must obviously not
685      * start the VLC signals interface plugin.
686      *
687      * LibVLC will normally ignore any interruption caused by an asynchronous
688      * signal during a system call. But there may well be some buggy cases
689      * where it fails to handle EINTR (bug reports welcome). Some underlying
690      * libraries might also not handle EINTR properly.
691      */
692     sigset_t oldset;
693     {
694         sigset_t set;
695         sigemptyset (&set);
696         sigdelset (&set, SIGHUP);
697         sigaddset (&set, SIGINT);
698         sigaddset (&set, SIGQUIT);
699         sigaddset (&set, SIGTERM);
700
701         sigaddset (&set, SIGPIPE); /* We don't want this one, really! */
702         pthread_sigmask (SIG_BLOCK, &set, &oldset);
703     }
704
705 #if defined (_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING >= 0) \
706  && defined (_POSIX_THREAD_PRIORITY_SCHEDULING) \
707  && (_POSIX_THREAD_PRIORITY_SCHEDULING >= 0)
708     if (rt_priorities)
709     {
710         struct sched_param sp = { .sched_priority = priority + rt_offset, };
711         int policy;
712
713         if (sp.sched_priority <= 0)
714             sp.sched_priority += sched_get_priority_max (policy = SCHED_OTHER);
715         else
716             sp.sched_priority += sched_get_priority_min (policy = SCHED_RR);
717
718         pthread_attr_setschedpolicy (attr, policy);
719         pthread_attr_setschedparam (attr, &sp);
720     }
721 #else
722     (void) priority;
723 #endif
724
725     /* The thread stack size.
726      * The lower the value, the less address space per thread, the highest
727      * maximum simultaneous threads per process. Too low values will cause
728      * stack overflows and weird crashes. Set with caution. Also keep in mind
729      * that 64-bits platforms consume more stack than 32-bits one.
730      *
731      * Thanks to on-demand paging, thread stack size only affects address space
732      * consumption. In terms of memory, threads only use what they need
733      * (rounded up to the page boundary).
734      *
735      * For example, on Linux i386, the default is 2 mega-bytes, which supports
736      * about 320 threads per processes. */
737 #define VLC_STACKSIZE (128 * sizeof (void *) * 1024)
738
739 #ifdef VLC_STACKSIZE
740     ret = pthread_attr_setstacksize (attr, VLC_STACKSIZE);
741     assert (ret == 0); /* fails iif VLC_STACKSIZE is invalid */
742 #endif
743
744     ret = pthread_create (th, attr, entry, data);
745     pthread_sigmask (SIG_SETMASK, &oldset, NULL);
746     pthread_attr_destroy (attr);
747     return ret;
748 }
749
750 /**
751  * Creates and starts new thread.
752  *
753  * The thread must be <i>joined</i> with vlc_join() to reclaim resources
754  * when it is not needed anymore.
755  *
756  * @param th [OUT] pointer to write the handle of the created thread to
757  *                 (mandatory, must be non-NULL)
758  * @param entry entry point for the thread
759  * @param data data parameter given to the entry point
760  * @param priority thread priority value
761  * @return 0 on success, a standard error code on error.
762  */
763 int vlc_clone (vlc_thread_t *th, void *(*entry) (void *), void *data,
764                int priority)
765 {
766     pthread_attr_t attr;
767
768     pthread_attr_init (&attr);
769     return vlc_clone_attr (th, &attr, entry, data, priority);
770 }
771
772 /**
773  * Waits for a thread to complete (if needed), then destroys it.
774  * This is a cancellation point; in case of cancellation, the join does _not_
775  * occur.
776  * @warning
777  * A thread cannot join itself (normally VLC will abort if this is attempted).
778  * Also, a detached thread <b>cannot</b> be joined.
779  *
780  * @param handle thread handle
781  * @param p_result [OUT] pointer to write the thread return value or NULL
782  */
783 void vlc_join (vlc_thread_t handle, void **result)
784 {
785     int val = pthread_join (handle, result);
786     VLC_THREAD_ASSERT ("joining thread");
787 }
788
789 /**
790  * Creates and starts new detached thread.
791  * A detached thread cannot be joined. Its resources will be automatically
792  * released whenever the thread exits (in particular, its call stack will be
793  * reclaimed).
794  *
795  * Detached thread are particularly useful when some work needs to be done
796  * asynchronously, that is likely to be completed much earlier than the thread
797  * can practically be joined. In this case, thread detach can spare memory.
798  *
799  * A detached thread may be cancelled, so as to expedite its termination.
800  * Be extremely careful if you do this: while a normal joinable thread can
801  * safely be cancelled after it has already exited, cancelling an already
802  * exited detached thread is undefined: The thread handle would is destroyed
803  * immediately when the detached thread exits. So you need to ensure that the
804  * detached thread is still running before cancellation is attempted.
805  *
806  * @warning Care must be taken that any resources used by the detached thread
807  * remains valid until the thread completes.
808  *
809  * @note A detached thread must eventually exit just like another other
810  * thread. In practice, LibVLC will wait for detached threads to exit before
811  * it unloads the plugins.
812  *
813  * @param th [OUT] pointer to hold the thread handle, or NULL
814  * @param entry entry point for the thread
815  * @param data data parameter given to the entry point
816  * @param priority thread priority value
817  * @return 0 on success, a standard error code on error.
818  */
819 int vlc_clone_detach (vlc_thread_t *th, void *(*entry) (void *), void *data,
820                       int priority)
821 {
822     vlc_thread_t dummy;
823     pthread_attr_t attr;
824
825     if (th == NULL)
826         th = &dummy;
827
828     pthread_attr_init (&attr);
829     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
830     return vlc_clone_attr (th, &attr, entry, data, priority);
831 }
832
833 int vlc_set_priority (vlc_thread_t th, int priority)
834 {
835 #if defined (_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING >= 0) \
836  && defined (_POSIX_THREAD_PRIORITY_SCHEDULING) \
837  && (_POSIX_THREAD_PRIORITY_SCHEDULING >= 0)
838     if (rt_priorities)
839     {
840         struct sched_param sp = { .sched_priority = priority + rt_offset, };
841         int policy;
842
843         if (sp.sched_priority <= 0)
844             sp.sched_priority += sched_get_priority_max (policy = SCHED_OTHER);
845         else
846             sp.sched_priority += sched_get_priority_min (policy = SCHED_RR);
847
848         if (pthread_setschedparam (th, policy, &sp))
849             return VLC_EGENERIC;
850     }
851 #else
852     (void) priority;
853 #endif
854     return VLC_SUCCESS;
855 }
856
857 /**
858  * Marks a thread as cancelled. Next time the target thread reaches a
859  * cancellation point (while not having disabled cancellation), it will
860  * run its cancellation cleanup handler, the thread variable destructors, and
861  * terminate. vlc_join() must be used afterward regardless of a thread being
862  * cancelled or not.
863  */
864 void vlc_cancel (vlc_thread_t thread_id)
865 {
866     pthread_cancel (thread_id);
867 #ifdef HAVE_MAEMO
868     pthread_kill (thread_id, SIGRTMIN);
869 #endif
870 }
871
872 /**
873  * Save the current cancellation state (enabled or disabled), then disable
874  * cancellation for the calling thread.
875  * This function must be called before entering a piece of code that is not
876  * cancellation-safe, unless it can be proven that the calling thread will not
877  * be cancelled.
878  * @return Previous cancellation state (opaque value for vlc_restorecancel()).
879  */
880 int vlc_savecancel (void)
881 {
882     int state;
883     int val = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
884
885     VLC_THREAD_ASSERT ("saving cancellation");
886     return state;
887 }
888
889 /**
890  * Restore the cancellation state for the calling thread.
891  * @param state previous state as returned by vlc_savecancel().
892  * @return Nothing, always succeeds.
893  */
894 void vlc_restorecancel (int state)
895 {
896 #ifndef NDEBUG
897     int oldstate, val;
898
899     val = pthread_setcancelstate (state, &oldstate);
900     /* This should fail if an invalid value for given for state */
901     VLC_THREAD_ASSERT ("restoring cancellation");
902
903     if (unlikely(oldstate != PTHREAD_CANCEL_DISABLE))
904          vlc_thread_fatal ("restoring cancellation while not disabled", EINVAL,
905                            __func__, __FILE__, __LINE__);
906 #else
907     pthread_setcancelstate (state, NULL);
908 #endif
909 }
910
911 /**
912  * Issues an explicit deferred cancellation point.
913  * This has no effect if thread cancellation is disabled.
914  * This can be called when there is a rather slow non-sleeping operation.
915  * This is also used to force a cancellation point in a function that would
916  * otherwise "not always" be a one (block_FifoGet() is an example).
917  */
918 void vlc_testcancel (void)
919 {
920     pthread_testcancel ();
921 }
922
923 void vlc_control_cancel (int cmd, ...)
924 {
925     (void) cmd;
926     assert (0);
927 }
928
929 /**
930  * Precision monotonic clock.
931  *
932  * In principles, the clock has a precision of 1 MHz. But the actual resolution
933  * may be much lower, especially when it comes to sleeping with mwait() or
934  * msleep(). Most general-purpose operating systems provide a resolution of
935  * only 100 to 1000 Hz.
936  *
937  * @warning The origin date (time value "zero") is not specified. It is
938  * typically the time the kernel started, but this is platform-dependent.
939  * If you need wall clock time, use gettimeofday() instead.
940  *
941  * @return a timestamp in microseconds.
942  */
943 mtime_t mdate (void)
944 {
945 #if (_POSIX_TIMERS > 0)
946     struct timespec ts;
947
948     vlc_clock_setup ();
949     if (unlikely(clock_gettime (vlc_clock_id, &ts) != 0))
950         abort ();
951
952     return (INT64_C(1000000) * ts.tv_sec) + (ts.tv_nsec / 1000);
953
954 #else
955     struct timeval tv;
956
957     if (unlikely(gettimeofday (&tv, NULL) != 0))
958         abort ();
959     return (INT64_C(1000000) * tv.tv_sec) + tv.tv_usec;
960
961 #endif
962 }
963
964 #undef mwait
965 /**
966  * Waits until a deadline (possibly later due to OS scheduling).
967  * @param deadline timestamp to wait for (see mdate())
968  */
969 void mwait (mtime_t deadline)
970 {
971 #if (_POSIX_CLOCK_SELECTION > 0)
972     vlc_clock_setup ();
973     /* If the deadline is already elapsed, or within the clock precision,
974      * do not even bother the system timer. */
975     deadline -= vlc_clock_prec;
976
977     struct timespec ts = mtime_to_ts (deadline);
978
979     while (clock_nanosleep (vlc_clock_id, TIMER_ABSTIME, &ts, NULL) == EINTR);
980
981 #else
982     deadline -= mdate ();
983     if (deadline > 0)
984         msleep (deadline);
985
986 #endif
987 }
988
989 #undef msleep
990 /**
991  * Waits for an interval of time.
992  * @param delay how long to wait (in microseconds)
993  */
994 void msleep (mtime_t delay)
995 {
996     struct timespec ts = mtime_to_ts (delay);
997
998 #if (_POSIX_CLOCK_SELECTION > 0)
999     vlc_clock_setup ();
1000     while (clock_nanosleep (vlc_clock_id, 0, &ts, &ts) == EINTR);
1001
1002 #else
1003     while (nanosleep (&ts, &ts) == -1)
1004         assert (errno == EINTR);
1005
1006 #endif
1007 }
1008
1009
1010 struct vlc_timer
1011 {
1012     vlc_thread_t thread;
1013     vlc_cond_t   reschedule;
1014     vlc_mutex_t  lock;
1015     void       (*func) (void *);
1016     void        *data;
1017     mtime_t      value, interval;
1018     vlc_atomic_t overruns;
1019 };
1020
1021 VLC_NORETURN
1022 static void *vlc_timer_thread (void *data)
1023 {
1024     struct vlc_timer *timer = data;
1025
1026     vlc_mutex_lock (&timer->lock);
1027     mutex_cleanup_push (&timer->lock);
1028
1029     for (;;)
1030     {
1031         while (timer->value == 0)
1032             vlc_cond_wait (&timer->reschedule, &timer->lock);
1033
1034         if (vlc_cond_timedwait (&timer->reschedule, &timer->lock,
1035                                 timer->value) == 0)
1036             continue;
1037         if (timer->interval == 0)
1038             timer->value = 0; /* disarm */
1039         vlc_mutex_unlock (&timer->lock);
1040
1041         int canc = vlc_savecancel ();
1042         timer->func (timer->data);
1043         vlc_restorecancel (canc);
1044
1045         mtime_t now = mdate ();
1046         unsigned misses;
1047
1048         vlc_mutex_lock (&timer->lock);
1049         if (timer->interval == 0)
1050             continue;
1051
1052         misses = (now - timer->value) / timer->interval;
1053         timer->value += timer->interval;
1054         /* Try to compensate for one miss (mwait() will return immediately)
1055          * but no more. Otherwise, we might busy loop, after extended periods
1056          * without scheduling (suspend, SIGSTOP, RT preemption, ...). */
1057         if (misses > 1)
1058         {
1059             misses--;
1060             timer->value += misses * timer->interval;
1061             vlc_atomic_add (&timer->overruns, misses);
1062         }
1063     }
1064
1065     vlc_cleanup_pop ();
1066     assert (0);
1067 }
1068
1069 /**
1070  * Initializes an asynchronous timer.
1071  * @warning Asynchronous timers are processed from an unspecified thread.
1072  * Multiple occurences of a single interval timer are serialized; they cannot
1073  * run concurrently.
1074  *
1075  * @param id pointer to timer to be initialized
1076  * @param func function that the timer will call
1077  * @param data parameter for the timer function
1078  * @return 0 on success, a system error code otherwise.
1079  */
1080 int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data)
1081 {
1082     struct vlc_timer *timer = malloc (sizeof (*timer));
1083
1084     if (unlikely(timer == NULL))
1085         return ENOMEM;
1086     vlc_mutex_init (&timer->lock);
1087     vlc_cond_init (&timer->reschedule);
1088     assert (func);
1089     timer->func = func;
1090     timer->data = data;
1091     timer->value = 0;
1092     timer->interval = 0;
1093     vlc_atomic_set(&timer->overruns, 0);
1094
1095     if (vlc_clone (&timer->thread, vlc_timer_thread, timer,
1096                    VLC_THREAD_PRIORITY_INPUT))
1097     {
1098         vlc_cond_destroy (&timer->reschedule);
1099         vlc_mutex_destroy (&timer->lock);
1100         free (timer);
1101         return ENOMEM;
1102     }
1103
1104     *id = timer;
1105     return 0;
1106 }
1107
1108 /**
1109  * Destroys an initialized timer. If needed, the timer is first disarmed.
1110  * This function is undefined if the specified timer is not initialized.
1111  *
1112  * @warning This function <b>must</b> be called before the timer data can be
1113  * freed and before the timer callback function can be unloaded.
1114  *
1115  * @param timer timer to destroy
1116  */
1117 void vlc_timer_destroy (vlc_timer_t timer)
1118 {
1119     vlc_cancel (timer->thread);
1120     vlc_join (timer->thread, NULL);
1121     vlc_cond_destroy (&timer->reschedule);
1122     vlc_mutex_destroy (&timer->lock);
1123     free (timer);
1124 }
1125
1126 /**
1127  * Arm or disarm an initialized timer.
1128  * This functions overrides any previous call to itself.
1129  *
1130  * @note A timer can fire later than requested due to system scheduling
1131  * limitations. An interval timer can fail to trigger sometimes, either because
1132  * the system is busy or suspended, or because a previous iteration of the
1133  * timer is still running. See also vlc_timer_getoverrun().
1134  *
1135  * @param timer initialized timer
1136  * @param absolute the timer value origin is the same as mdate() if true,
1137  *                 the timer value is relative to now if false.
1138  * @param value zero to disarm the timer, otherwise the initial time to wait
1139  *              before firing the timer.
1140  * @param interval zero to fire the timer just once, otherwise the timer
1141  *                 repetition interval.
1142  */
1143 void vlc_timer_schedule (vlc_timer_t timer, bool absolute,
1144                          mtime_t value, mtime_t interval)
1145 {
1146     if (!absolute && value != 0)
1147         value += mdate();
1148
1149     vlc_mutex_lock (&timer->lock);
1150     timer->value = value;
1151     timer->interval = interval;
1152     vlc_cond_signal (&timer->reschedule);
1153     vlc_mutex_unlock (&timer->lock);
1154 }
1155
1156 /**
1157  * Fetch and reset the overrun counter for a timer.
1158  * @param timer initialized timer
1159  * @return the timer overrun counter, i.e. the number of times that the timer
1160  * should have run but did not since the last actual run. If all is well, this
1161  * is zero.
1162  */
1163 unsigned vlc_timer_getoverrun (vlc_timer_t timer)
1164 {
1165     return vlc_atomic_swap (&timer->overruns, 0);
1166 }
1167
1168
1169 /**
1170  * Count CPUs.
1171  * @return number of available (logical) CPUs.
1172  */
1173 unsigned vlc_GetCPUCount(void)
1174 {
1175 #if defined(HAVE_SCHED_GETAFFINITY)
1176     cpu_set_t cpu;
1177
1178     CPU_ZERO(&cpu);
1179     if (sched_getaffinity (getpid(), sizeof (cpu), &cpu) < 0)
1180         return 1;
1181
1182     return CPU_COUNT (&cpu);
1183
1184 #elif defined(__APPLE__)
1185     int count;
1186     size_t size = sizeof(count) ;
1187
1188     if (sysctlbyname ("hw.ncpu", &count, &size, NULL, 0))
1189         return 1; /* Failure */
1190     return count;
1191
1192 #elif defined(__OpenBSD__)
1193     int selectors[2] = { CTL_HW, HW_NCPU };
1194     int count;
1195     size_t size = sizeof(count);
1196
1197     if (sysctl (selectors, 2, &count, &size, NULL, 0))
1198         return 1; /* Failure */
1199     return count;
1200
1201 #elif defined(__SunOS)
1202     unsigned count = 0;
1203     int type;
1204     u_int numcpus;
1205     processor_info_t cpuinfo;
1206
1207     processorid_t *cpulist = malloc (sizeof (*cpulist) * sysconf(_SC_NPROCESSORS_MAX));
1208     if (unlikely(cpulist == NULL))
1209         return 1;
1210
1211     if (pset_info(PS_MYID, &type, &numcpus, cpulist) == 0)
1212     {
1213         for (u_int i = 0; i < numcpus; i++)
1214             if (processor_info (cpulist[i], &cpuinfo) == 0)
1215                 count += (cpuinfo.pi_state == P_ONLINE);
1216     }
1217     else
1218         count = sysconf (_SC_NPROCESSORS_ONLN);
1219     free (cpulist);
1220     return count ? count : 1;
1221
1222 #else
1223 #   warning "vlc_GetCPUCount is not implemented for your platform"
1224     return 1;
1225 #endif
1226 }