home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 May / maximum-cd-2009-05.iso / DiscContents / vlc-0.9.8a-win32.exe / sdk / include / vlc / plugins / vlc_threads.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-06  |  19.2 KB  |  602 lines

  1. /*****************************************************************************
  2.  * vlc_threads.h : threads implementation for the VideoLAN client
  3.  * This header provides portable declarations for mutexes & conditions
  4.  *****************************************************************************
  5.  * Copyright (C) 1999, 2002 the VideoLAN team
  6.  * $Id: e2810e945155daff03c39a134bbb4e6e90e60d68 $
  7.  *
  8.  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  9.  *          Samuel Hocevar <sam@via.ecp.fr>
  10.  *          Gildas Bazin <gbazin@netcourrier.com>
  11.  *          Christophe Massiot <massiot@via.ecp.fr>
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or
  16.  * (at your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  26.  *****************************************************************************/
  27.  
  28. #ifndef VLC_THREADS_H_
  29. #define VLC_THREADS_H_
  30.  
  31. /**
  32.  * \file
  33.  * This file defines structures and functions for handling threads in vlc
  34.  *
  35.  */
  36.  
  37. #if defined( UNDER_CE )
  38.                                                                 /* WinCE API */
  39. #elif defined( WIN32 )
  40. #   include <process.h>                                         /* Win32 API */
  41. #   include <errno.h>
  42.  
  43. #elif defined( SYS_BEOS )                                            /* BeOS */
  44. #   include <kernel/OS.h>
  45. #   include <kernel/scheduler.h>
  46. #   include <byteorder.h>
  47.  
  48. #else                                         /* pthreads (like Linux & BSD) */
  49. #   define LIBVLC_USE_PTHREAD 1
  50. #   define _APPLE_C_SOURCE    1 /* Proper pthread semantics on OSX */
  51.  
  52. #   include <stdlib.h> /* lldiv_t definition (only in C99) */
  53. #   include <unistd.h> /* _POSIX_SPIN_LOCKS */
  54. #   include <pthread.h>
  55.     /* Needed for pthread_cond_timedwait */
  56. #   include <errno.h>
  57. #   include <time.h>
  58.  
  59. #endif
  60.  
  61. /*****************************************************************************
  62.  * Constants
  63.  *****************************************************************************/
  64.  
  65. /* Thread priorities */
  66. #ifdef __APPLE__
  67. #   define VLC_THREAD_PRIORITY_LOW      0
  68. #   define VLC_THREAD_PRIORITY_INPUT   22
  69. #   define VLC_THREAD_PRIORITY_AUDIO   22
  70. #   define VLC_THREAD_PRIORITY_VIDEO    0
  71. #   define VLC_THREAD_PRIORITY_OUTPUT  22
  72. #   define VLC_THREAD_PRIORITY_HIGHEST 22
  73.  
  74. #elif defined(SYS_BEOS)
  75. #   define VLC_THREAD_PRIORITY_LOW 5
  76. #   define VLC_THREAD_PRIORITY_INPUT 10
  77. #   define VLC_THREAD_PRIORITY_AUDIO 10
  78. #   define VLC_THREAD_PRIORITY_VIDEO 5
  79. #   define VLC_THREAD_PRIORITY_OUTPUT 15
  80. #   define VLC_THREAD_PRIORITY_HIGHEST 15
  81.  
  82. #elif defined(LIBVLC_USE_PTHREAD)
  83. #   define VLC_THREAD_PRIORITY_LOW      0
  84. #   define VLC_THREAD_PRIORITY_INPUT   10
  85. #   define VLC_THREAD_PRIORITY_AUDIO    5
  86. #   define VLC_THREAD_PRIORITY_VIDEO    0
  87. #   define VLC_THREAD_PRIORITY_OUTPUT  15
  88. #   define VLC_THREAD_PRIORITY_HIGHEST 20
  89.  
  90. #elif defined(WIN32) || defined(UNDER_CE)
  91. /* Define different priorities for WinNT/2K/XP and Win9x/Me */
  92. #   define VLC_THREAD_PRIORITY_LOW 0
  93. #   define VLC_THREAD_PRIORITY_INPUT \
  94.         (IS_WINNT ? THREAD_PRIORITY_ABOVE_NORMAL : 0)
  95. #   define VLC_THREAD_PRIORITY_AUDIO \
  96.         (IS_WINNT ? THREAD_PRIORITY_HIGHEST : 0)
  97. #   define VLC_THREAD_PRIORITY_VIDEO \
  98.         (IS_WINNT ? 0 : THREAD_PRIORITY_BELOW_NORMAL )
  99. #   define VLC_THREAD_PRIORITY_OUTPUT \
  100.         (IS_WINNT ? THREAD_PRIORITY_ABOVE_NORMAL : 0)
  101. #   define VLC_THREAD_PRIORITY_HIGHEST \
  102.         (IS_WINNT ? THREAD_PRIORITY_TIME_CRITICAL : 0)
  103.  
  104. #else
  105. #   define VLC_THREAD_PRIORITY_LOW 0
  106. #   define VLC_THREAD_PRIORITY_INPUT 0
  107. #   define VLC_THREAD_PRIORITY_AUDIO 0
  108. #   define VLC_THREAD_PRIORITY_VIDEO 0
  109. #   define VLC_THREAD_PRIORITY_OUTPUT 0
  110. #   define VLC_THREAD_PRIORITY_HIGHEST 0
  111.  
  112. #endif
  113.  
  114. /*****************************************************************************
  115.  * Type definitions
  116.  *****************************************************************************/
  117.  
  118. #if defined (LIBVLC_USE_PTHREAD)
  119. typedef pthread_t       vlc_thread_t;
  120. typedef pthread_mutex_t vlc_mutex_t;
  121. typedef pthread_cond_t  vlc_cond_t;
  122. typedef pthread_key_t   vlc_threadvar_t;
  123.  
  124. #elif defined( WIN32 ) || defined( UNDER_CE )
  125. typedef HANDLE  vlc_thread_t;
  126. typedef HANDLE  vlc_mutex_t;
  127. typedef HANDLE  vlc_cond_t;
  128. typedef DWORD   vlc_threadvar_t;
  129.  
  130. #elif defined( SYS_BEOS )
  131. /* This is the BeOS implementation of the vlc threads, note that the mutex is
  132.  * not a real mutex and the cond_var is not like a pthread cond_var but it is
  133.  * enough for what we need */
  134.  
  135. typedef thread_id vlc_thread_t;
  136.  
  137. typedef struct
  138. {
  139.     int32_t         init;
  140.     sem_id          lock;
  141. } vlc_mutex_t;
  142.  
  143. typedef struct
  144. {
  145.     int32_t         init;
  146.     thread_id       thread;
  147. } vlc_cond_t;
  148.  
  149. typedef struct
  150. {
  151. } vlc_threadvar_t;
  152.  
  153. #endif
  154.  
  155. #if defined( WIN32 ) && !defined ETIMEDOUT
  156. #  define ETIMEDOUT 10060 /* This is the value in winsock.h. */
  157. #endif
  158.  
  159. /*****************************************************************************
  160.  * Function definitions
  161.  *****************************************************************************/
  162. VLC_EXPORT( int,  vlc_mutex_init,    ( vlc_mutex_t * ) );
  163. VLC_EXPORT( int,  vlc_mutex_init_recursive, ( vlc_mutex_t * ) );
  164. VLC_EXPORT( void,  __vlc_mutex_destroy, ( const char *, int, vlc_mutex_t * ) );
  165. VLC_EXPORT( int,  __vlc_cond_init,     ( vlc_cond_t * ) );
  166. VLC_EXPORT( void,  __vlc_cond_destroy,  ( const char *, int, vlc_cond_t * ) );
  167. VLC_EXPORT( int, vlc_threadvar_create, (vlc_threadvar_t * , void (*) (void *) ) );
  168. VLC_EXPORT( void, vlc_threadvar_delete, (vlc_threadvar_t *) );
  169. VLC_EXPORT( int,  __vlc_thread_create, ( vlc_object_t *, const char *, int, const char *, void * ( * ) ( vlc_object_t * ), int, bool ) );
  170. VLC_EXPORT( int,  __vlc_thread_set_priority, ( vlc_object_t *, const char *, int, int ) );
  171. VLC_EXPORT( void, __vlc_thread_join,   ( vlc_object_t *, const char *, int ) );
  172.  
  173. #define vlc_thread_ready vlc_object_signal
  174.  
  175. /*****************************************************************************
  176.  * vlc_mutex_lock: lock a mutex
  177.  *****************************************************************************/
  178. #define vlc_mutex_lock( P_MUTEX )                                           \
  179.     __vlc_mutex_lock( __FILE__, __LINE__, P_MUTEX )
  180.  
  181. VLC_EXPORT(void, vlc_pthread_fatal, (const char *action, int error, const char *file, unsigned line));
  182.  
  183. #if defined(LIBVLC_USE_PTHREAD)
  184. # define VLC_THREAD_ASSERT( action ) \
  185.     if (val) \
  186.         vlc_pthread_fatal (action, val, psz_file, i_line)
  187. #else
  188. # define VLC_THREAD_ASSERT ((void)(val))
  189. #endif
  190.  
  191. static inline void __vlc_mutex_lock( const char * psz_file, int i_line,
  192.                                     vlc_mutex_t * p_mutex )
  193. {
  194. #if defined(LIBVLC_USE_PTHREAD)
  195. #   define vlc_assert_locked( m ) \
  196.            assert (pthread_mutex_lock (m) == EDEADLK)
  197.     int val = pthread_mutex_lock( p_mutex );
  198.     VLC_THREAD_ASSERT ("locking mutex");
  199.  
  200. #elif defined( UNDER_CE )
  201.     (void)psz_file; (void)i_line;
  202.  
  203.     EnterCriticalSection( &p_mutex->csection );
  204.  
  205. #elif defined( WIN32 )
  206.     (void)psz_file; (void)i_line;
  207.  
  208.     WaitForSingleObject( *p_mutex, INFINITE );
  209.  
  210. #elif defined( SYS_BEOS )
  211.     acquire_sem( p_mutex->lock );
  212.  
  213. #endif
  214. }
  215.  
  216. #ifndef vlc_assert_locked
  217. # define vlc_assert_locked( m ) (void)m
  218. #endif
  219.  
  220. /*****************************************************************************
  221.  * vlc_mutex_unlock: unlock a mutex
  222.  *****************************************************************************/
  223. #define vlc_mutex_unlock( P_MUTEX )                                         \
  224.     __vlc_mutex_unlock( __FILE__, __LINE__, P_MUTEX )
  225.  
  226. static inline void __vlc_mutex_unlock( const char * psz_file, int i_line,
  227.                                       vlc_mutex_t *p_mutex )
  228. {
  229. #if defined(LIBVLC_USE_PTHREAD)
  230.     int val = pthread_mutex_unlock( p_mutex );
  231.     VLC_THREAD_ASSERT ("unlocking mutex");
  232.  
  233. #elif defined( UNDER_CE )
  234.     (void)psz_file; (void)i_line;
  235.  
  236.     LeaveCriticalSection( &p_mutex->csection );
  237.  
  238. #elif defined( WIN32 )
  239.     (void)psz_file; (void)i_line;
  240.  
  241.     ReleaseMutex( *p_mutex );
  242.  
  243. #elif defined( SYS_BEOS )
  244.     release_sem( p_mutex->lock );
  245.  
  246. #endif
  247. }
  248.  
  249. /*****************************************************************************
  250.  * vlc_mutex_destroy: destroy a mutex
  251.  *****************************************************************************/
  252. #define vlc_mutex_destroy( P_MUTEX )                                        \
  253.     __vlc_mutex_destroy( __FILE__, __LINE__, P_MUTEX )
  254.  
  255. /*****************************************************************************
  256.  * vlc_cond_init: initialize a condition
  257.  *****************************************************************************/
  258. #define vlc_cond_init( P_THIS, P_COND )                                     \
  259.     __vlc_cond_init( P_COND )
  260.  
  261. /*****************************************************************************
  262.  * vlc_cond_signal: start a thread on condition completion
  263.  *****************************************************************************/
  264. #define vlc_cond_signal( P_COND )                                           \
  265.     __vlc_cond_signal( __FILE__, __LINE__, P_COND )
  266.  
  267. static inline void __vlc_cond_signal( const char * psz_file, int i_line,
  268.                                       vlc_cond_t *p_condvar )
  269. {
  270. #if defined(LIBVLC_USE_PTHREAD)
  271.     int val = pthread_cond_signal( p_condvar );
  272.     VLC_THREAD_ASSERT ("signaling condition variable");
  273.  
  274. #elif defined( UNDER_CE ) || defined( WIN32 )
  275.     (void)psz_file; (void)i_line;
  276.  
  277.     /* Release one waiting thread if one is available. */
  278.     /* For this trick to work properly, the vlc_cond_signal must be surrounded
  279.      * by a mutex. This will prevent another thread from stealing the signal */
  280.     /* PulseEvent() only works if none of the waiting threads is suspended.
  281.      * This is particularily problematic under a debug session.
  282.      * as documented in http://support.microsoft.com/kb/q173260/ */
  283.     PulseEvent( *p_condvar );
  284.  
  285. #elif defined( SYS_BEOS )
  286.     while( p_condvar->thread != -1 )
  287.     {
  288.         thread_info info;
  289.         if( get_thread_info(p_condvar->thread, &info) == B_BAD_VALUE )
  290.             return;
  291.  
  292.         if( info.state != B_THREAD_SUSPENDED )
  293.         {
  294.             /* The  waiting thread is not suspended so it could
  295.              * have been interrupted beetwen the unlock and the
  296.              * suspend_thread line. That is why we sleep a little
  297.              * before retesting p_condver->thread. */
  298.             snooze( 10000 );
  299.         }
  300.         else
  301.         {
  302.             /* Ok, we have to wake up that thread */
  303.             resume_thread( p_condvar->thread );
  304.         }
  305.     }
  306.  
  307. #endif
  308. }
  309.  
  310. /*****************************************************************************
  311.  * vlc_cond_wait: wait until condition completion
  312.  *****************************************************************************/
  313. #define vlc_cond_wait( P_COND, P_MUTEX )                                     \
  314.     __vlc_cond_wait( __FILE__, __LINE__, P_COND, P_MUTEX  )
  315.  
  316. static inline void __vlc_cond_wait( const char * psz_file, int i_line,
  317.                                     vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex )
  318. {
  319. #if defined(LIBVLC_USE_PTHREAD)
  320.     int val = pthread_cond_wait( p_condvar, p_mutex );
  321.     VLC_THREAD_ASSERT ("waiting on condition");
  322.  
  323. #elif defined( UNDER_CE )
  324.     LeaveCriticalSection( &p_mutex->csection );
  325.     WaitForSingleObject( *p_condvar, INFINITE );
  326.  
  327.     /* Reacquire the mutex before returning. */
  328.     vlc_mutex_lock( p_mutex );
  329.  
  330. #elif defined( WIN32 )
  331.     (void)psz_file; (void)i_line;
  332.  
  333.     /* Increase our wait count */
  334.     SignalObjectAndWait( *p_mutex, *p_condvar, INFINITE, FALSE );
  335.  
  336.     /* Reacquire the mutex before returning. */
  337.     vlc_mutex_lock( p_mutex );
  338.  
  339. #elif defined( SYS_BEOS )
  340.     /* The p_condvar->thread var is initialized before the unlock because
  341.      * it enables to identify when the thread is interrupted beetwen the
  342.      * unlock line and the suspend_thread line */
  343.     p_condvar->thread = find_thread( NULL );
  344.     vlc_mutex_unlock( p_mutex );
  345.     suspend_thread( p_condvar->thread );
  346.     p_condvar->thread = -1;
  347.  
  348.     vlc_mutex_lock( p_mutex );
  349.  
  350. #endif
  351. }
  352.  
  353.  
  354. /*****************************************************************************
  355.  * vlc_cond_timedwait: wait until condition completion or expiration
  356.  *****************************************************************************
  357.  * Returns 0 if object signaled, an error code in case of timeout or error.
  358.  *****************************************************************************/
  359. #define vlc_cond_timedwait( P_COND, P_MUTEX, DEADLINE )                      \
  360.     __vlc_cond_timedwait( __FILE__, __LINE__, P_COND, P_MUTEX, DEADLINE  )
  361.  
  362. static inline int __vlc_cond_timedwait( const char * psz_file, int i_line,
  363.                                         vlc_cond_t *p_condvar,
  364.                                         vlc_mutex_t *p_mutex,
  365.                                         mtime_t deadline )
  366. {
  367. #if defined(LIBVLC_USE_PTHREAD)
  368.     lldiv_t d = lldiv( deadline, 1000000 );
  369.     struct timespec ts = { d.quot, d.rem * 1000 };
  370.  
  371.     int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts);
  372.     if (val == ETIMEDOUT)
  373.         return ETIMEDOUT; /* this error is perfectly normal */
  374.     VLC_THREAD_ASSERT ("timed-waiting on condition");
  375.  
  376. #elif defined( UNDER_CE )
  377.     mtime_t delay_ms = (deadline - mdate())/1000;
  378.     DWORD result;
  379.     if( delay_ms < 0 )
  380.         delay_ms = 0;
  381.  
  382.     LeaveCriticalSection( &p_mutex->csection );
  383.     result = WaitForSingleObject( *p_condvar, delay_ms );
  384.  
  385.     /* Reacquire the mutex before returning. */
  386.     vlc_mutex_lock( p_mutex );
  387.  
  388.     if(result == WAIT_TIMEOUT)
  389.        return ETIMEDOUT; /* this error is perfectly normal */
  390.  
  391.     (void)psz_file; (void)i_line;
  392.  
  393. #elif defined( WIN32 )
  394.     mtime_t total = (deadline - mdate())/1000;
  395.     DWORD result;
  396.     if( total < 0 )
  397.         total = 0;
  398.  
  399.     do
  400.     {
  401.         DWORD delay = (total > 0x7fffffff) ? 0x7fffffff : total;
  402.         result = SignalObjectAndWait( *p_mutex, *p_condvar,
  403.                                       delay, FALSE );
  404.         total -= delay;
  405.         vlc_mutex_lock (p_mutex);
  406.     }
  407.     while (total);
  408.  
  409.     /* Reacquire the mutex before returning. */
  410.     if(result == WAIT_TIMEOUT)
  411.        return ETIMEDOUT; /* this error is perfectly normal */
  412.  
  413.     (void)psz_file; (void)i_line;
  414.  
  415. #elif defined( SYS_BEOS )
  416. #   error Unimplemented
  417.  
  418. #endif
  419.  
  420.     return 0;
  421. }
  422.  
  423. /*****************************************************************************
  424.  * vlc_cond_destroy: destroy a condition
  425.  *****************************************************************************/
  426. #define vlc_cond_destroy( P_COND )                                          \
  427.     __vlc_cond_destroy( __FILE__, __LINE__, P_COND )
  428.  
  429. /*****************************************************************************
  430.  * vlc_threadvar_set: create: set the value of a thread-local variable
  431.  *****************************************************************************/
  432. static inline int vlc_threadvar_set( vlc_threadvar_t * p_tls, void *p_value )
  433. {
  434.     int i_ret;
  435.  
  436. #if defined(LIBVLC_USE_PTHREAD)
  437.     i_ret = pthread_setspecific( *p_tls, p_value );
  438.  
  439. #elif defined( SYS_BEOS )
  440.     i_ret = EINVAL;
  441.  
  442. #elif defined( UNDER_CE ) || defined( WIN32 )
  443.     i_ret = TlsSetValue( *p_tls, p_value ) ? EINVAL : 0;
  444.  
  445. #endif
  446.  
  447.     return i_ret;
  448. }
  449.  
  450. /*****************************************************************************
  451.  * vlc_threadvar_get: create: get the value of a thread-local variable
  452.  *****************************************************************************/
  453. static inline void* vlc_threadvar_get( vlc_threadvar_t * p_tls )
  454. {
  455.     void *p_ret;
  456.  
  457. #if defined(LIBVLC_USE_PTHREAD)
  458.     p_ret = pthread_getspecific( *p_tls );
  459.  
  460. #elif defined( SYS_BEOS )
  461.     p_ret = NULL;
  462.  
  463. #elif defined( UNDER_CE ) || defined( WIN32 )
  464.     p_ret = TlsGetValue( *p_tls );
  465.  
  466. #endif
  467.  
  468.     return p_ret;
  469. }
  470.  
  471. # if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0)
  472. typedef pthread_spinlock_t vlc_spinlock_t;
  473.  
  474. /**
  475.  * Initializes a spinlock.
  476.  */
  477. static inline int vlc_spin_init (vlc_spinlock_t *spin)
  478. {
  479.     return pthread_spin_init (spin, PTHREAD_PROCESS_PRIVATE);
  480. }
  481.  
  482. /**
  483.  * Acquires a spinlock.
  484.  */
  485. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  486. {
  487.     pthread_spin_lock (spin);
  488. }
  489.  
  490. /**
  491.  * Releases a spinlock.
  492.  */
  493. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  494. {
  495.     pthread_spin_unlock (spin);
  496. }
  497.  
  498. /**
  499.  * Deinitializes a spinlock.
  500.  */
  501. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  502. {
  503.     pthread_spin_destroy (spin);
  504. }
  505.  
  506. #elif defined( WIN32 )
  507.  
  508. typedef CRITICAL_SECTION vlc_spinlock_t;
  509.  
  510. /**
  511.  * Initializes a spinlock.
  512.  */
  513. static inline int vlc_spin_init (vlc_spinlock_t *spin)
  514. {
  515.     return !InitializeCriticalSectionAndSpinCount(spin, 4000);
  516. }
  517.  
  518. /**
  519.  * Acquires a spinlock.
  520.  */
  521. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  522. {
  523.     EnterCriticalSection(spin);
  524. }
  525.  
  526. /**
  527.  * Releases a spinlock.
  528.  */
  529. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  530. {
  531.     LeaveCriticalSection(spin);
  532. }
  533.  
  534. /**
  535.  * Deinitializes a spinlock.
  536.  */
  537. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  538. {
  539.     DeleteCriticalSection(spin);
  540. }
  541.  
  542. #else
  543.  
  544. /* Fallback to plain mutexes if spinlocks are not available */
  545. typedef vlc_mutex_t vlc_spinlock_t;
  546.  
  547. static inline int vlc_spin_init (vlc_spinlock_t *spin)
  548. {
  549.     return vlc_mutex_init (spin);
  550. }
  551.  
  552. # define vlc_spin_lock    vlc_mutex_lock
  553. # define vlc_spin_unlock  vlc_mutex_unlock
  554. # define vlc_spin_destroy vlc_mutex_destroy
  555. #endif
  556.  
  557. /**
  558.  * Issues a full memory barrier.
  559.  */
  560. #if defined (__APPLE__)
  561. # include <libkern/OSAtomic.h> /* OSMemoryBarrier() */
  562. #endif
  563. static inline void barrier (void)
  564. {
  565. #if defined (__GNUC__) && \
  566.             ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
  567.     __sync_synchronize ();
  568. #elif defined(__APPLE__)
  569.     OSMemoryBarrier ();
  570. #elif defined(__powerpc__)
  571.     asm volatile ("sync":::"memory");
  572. #elif 0 // defined(__i386__) /*  Requires SSE2 support */
  573.     asm volatile ("mfence":::"memory");
  574. #else
  575.     vlc_spinlock_t spin;
  576.     vlc_spin_init (&spin);
  577.     vlc_spin_lock (&spin);
  578.     vlc_spin_unlock (&spin);
  579.     vlc_spin_destroy (&spin);
  580. #endif
  581. }
  582.  
  583. /*****************************************************************************
  584.  * vlc_thread_create: create a thread
  585.  *****************************************************************************/
  586. #define vlc_thread_create( P_THIS, PSZ_NAME, FUNC, PRIORITY, WAIT )         \
  587.     __vlc_thread_create( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PSZ_NAME, FUNC, PRIORITY, WAIT )
  588.  
  589. /*****************************************************************************
  590.  * vlc_thread_set_priority: set the priority of the calling thread
  591.  *****************************************************************************/
  592. #define vlc_thread_set_priority( P_THIS, PRIORITY )                         \
  593.     __vlc_thread_set_priority( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PRIORITY )
  594.  
  595. /*****************************************************************************
  596.  * vlc_thread_join: wait until a thread exits
  597.  *****************************************************************************/
  598. #define vlc_thread_join( P_THIS )                                           \
  599.     __vlc_thread_join( VLC_OBJECT(P_THIS), __FILE__, __LINE__ )
  600.  
  601. #endif /* !_VLC_THREADS_H */
  602.