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