]> git.sesse.net Git - vlc/blobdiff - include/threads.h
D�but du portage BeOS. Beaucoup de fuchiers ont �t� modifi� car il a fallu
[vlc] / include / threads.h
index 73fb41d67a6a6e051df935cd5ad13a0e05bc6ca9..56c5e7d5e72d7e7f04c5cc4cec3e77c41de0705c 100644 (file)
  * Boston, MA 02111-1307, USA.
  *****************************************************************************/
 
+
 #ifdef SYS_GNU
 #include <cthreads.h>
-#else
+#endif
+
+#ifdef SYS_BEOS
+#include <kernel/OS.h>
+#include <kernel/scheduler.h>
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)
 #include <pthread.h>
 #endif
 
@@ -80,13 +88,38 @@ typedef struct s_condition {
     struct cond_imp *implications;
 } vlc_cond_t;
 
-#else /* SYS_GNU */
+#endif /* SYS_GNU */
+
+#ifdef SYS_BEOS
+
+typedef thread_id vlc_thread_t;
+
+typedef struct
+{
+    int32           init;
+    sem_id          lock;
+    thread_id       owner;
+} vlc_mutex_t;
+
+typedef struct
+{
+    int32           init;
+    sem_id          sem;
+    sem_id          handshakeSem;
+    sem_id          signalSem;
+    volatile int32  nw;
+    volatile int32  ns;
+} vlc_cond_t;
+
+#endif /* SYS_BEOS */
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)
 
 typedef pthread_t        vlc_thread_t;
 typedef pthread_mutex_t  vlc_mutex_t;
 typedef pthread_cond_t   vlc_cond_t;
 
-#endif /* SYS_GNU */
+#endif /* SYS_LINUX || SYS_BSD */
 
 typedef void *(*vlc_thread_func_t)(void *p_data);
 
@@ -122,7 +155,14 @@ static __inline__ int vlc_thread_create( vlc_thread_t *p_thread,
 #ifdef SYS_GNU
     *p_thread = cthread_fork( (cthread_fn_t)func, (any_t)p_data );
     return( 0 );
-#else
+#endif
+
+#ifdef SYS_BEOS
+    *p_thread = spawn_thread( (thread_func)func, psz_name, B_NORMAL_PRIORITY, p_data );
+    return resume_thread( *p_thread );
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)
     return pthread_create( p_thread, NULL, func, p_data );
 #endif
 }
@@ -135,7 +175,13 @@ static __inline__ void vlc_thread_exit( void )
 #ifdef SYS_GNU
     int result;
     cthread_exit( &result );
-#else          
+#endif
+
+#ifdef SYS_BEOS
+    exit_thread( 0 );
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     pthread_exit( 0 );
 #endif
 }
@@ -147,11 +193,34 @@ static __inline__ void vlc_thread_join( vlc_thread_t thread )
 {
 #ifdef SYS_GNU
     cthread_join( thread );
-#else  
+#endif
+
+#ifdef SYS_BEOS
+    int32 exit_value;  
+    wait_for_thread( thread, &exit_value );
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     pthread_join( thread, NULL );
 #endif
 }
 
+#ifdef SYS_BEOS
+/* lazy_init_mutex */
+static __inline__ void lazy_init_mutex(vlc_mutex_t* p_mutex)
+{
+    int32 v = atomic_or( &p_mutex->init, 1 );
+    if( 2000 == v ) // we're the first, so do the init
+    {
+        vlc_mutex_init( p_mutex );
+    }
+    else // we're not the first, so wait until the init is finished
+    {
+        while( p_mutex->init != 9999 ) snooze( 10000 );
+    }
+}
+#endif
+
 /*****************************************************************************
  * vlc_mutex_init: initialize a mutex
  *****************************************************************************/
@@ -160,7 +229,20 @@ static __inline__ int vlc_mutex_init( vlc_mutex_t *p_mutex )
 #ifdef SYS_GNU
     mutex_init( p_mutex );
     return( 0 );
-#else
+#endif
+
+#ifdef SYS_BEOS
+    // check the arguments and whether it's already been initialized
+    if( !p_mutex ) return B_BAD_VALUE;
+    if( p_mutex->init == 9999 ) return EALREADY;
+
+    p_mutex->lock = create_sem( 1, "BeMutex" );
+    p_mutex->owner = -1;
+    p_mutex->init = 9999;
+    return B_OK;
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     return pthread_mutex_init( p_mutex, NULL );
 #endif
 }
@@ -173,7 +255,21 @@ static __inline__ int vlc_mutex_lock( vlc_mutex_t *p_mutex )
 #ifdef SYS_GNU
     mutex_lock( p_mutex );
     return( 0 );
-#else
+#endif
+
+#ifdef SYS_BEOS
+    status_t err;
+
+    if( !p_mutex ) return B_BAD_VALUE;
+    if( p_mutex->init < 2000 ) return B_NO_INIT;
+    lazy_init_mutex( p_mutex );
+
+    err = acquire_sem( p_mutex->lock );
+    if( !err ) p_mutex->owner = find_thread( NULL );
+    return err;
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     return pthread_mutex_lock( p_mutex );
 #endif
 }
@@ -186,11 +282,40 @@ static __inline__ int vlc_mutex_unlock( vlc_mutex_t *p_mutex )
 #ifdef SYS_GNU
     mutex_unlock( p_mutex );
     return( 0 );
-#else
+#endif
+
+#ifdef SYS_BEOS
+    if(! p_mutex) return B_BAD_VALUE;
+    if( p_mutex->init < 2000 ) return B_NO_INIT;
+    lazy_init_mutex( p_mutex );
+
+    if( p_mutex->owner != find_thread(NULL) ) return ENOLCK;
+    p_mutex->owner = -1;
+    release_sem( p_mutex->lock );
+    return B_OK;
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     return pthread_mutex_unlock( p_mutex );
 #endif
 }
 
+#ifdef SYS_BEOS
+/* lazy_init_cond */
+static __inline__ void lazy_init_cond( vlc_cond_t* p_condvar )
+{
+    int32 v = atomic_or( &p_condvar->init, 1 );
+    if( 2000 == v ) // we're the first, so do the init
+    {
+        vlc_cond_init( p_condvar );
+    }
+    else // we're not the first, so wait until the init is finished
+    {
+        while( p_condvar->init != 9999 ) snooze( 10000 );
+    }
+}
+#endif
+
 /*****************************************************************************
  * vlc_cond_init: initialize a condition
  *****************************************************************************/
@@ -204,7 +329,21 @@ static __inline__ int vlc_cond_init( vlc_cond_t *p_condvar )
     p_condvar->implications = 0;
 
     return( 0 );
-#else                      
+#endif
+
+#ifdef SYS_BEOS
+    if( !p_condvar ) return B_BAD_VALUE;
+    if( p_condvar->init == 9999 ) return EALREADY;
+
+    p_condvar->sem = create_sem( 0, "CVSem" );
+    p_condvar->handshakeSem = create_sem( 0, "CVHandshake" );
+    p_condvar->signalSem = create_sem( 1, "CVSignal" );
+    p_condvar->ns = p_condvar->nw = 0;
+    p_condvar->init = 9999;
+    return B_OK;
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     return pthread_cond_init( p_condvar, NULL );
 #endif
 }
@@ -221,7 +360,33 @@ static __inline__ int vlc_cond_signal( vlc_cond_t *p_condvar )
         cond_signal( (condition_t)p_condvar );
     }
     return( 0 );
-#else          
+#endif
+
+#ifdef SYS_BEOS
+    status_t err = B_OK;
+
+    if( !p_condvar ) return B_BAD_VALUE;
+    if( p_condvar->init < 2000 ) return B_NO_INIT;
+    lazy_init_cond( p_condvar );
+
+    if( acquire_sem(p_condvar->signalSem) == B_INTERRUPTED) return B_INTERRUPTED;
+
+    if( p_condvar->nw > p_condvar->ns )
+    {
+        p_condvar->ns += 1;
+        release_sem( p_condvar->sem );
+        release_sem( p_condvar->signalSem );
+        while( acquire_sem(p_condvar->handshakeSem) == B_INTERRUPTED )
+            { err = B_INTERRUPTED; }
+    }
+    else
+    {
+        release_sem( p_condvar->signalSem );
+    }
+    return err;
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     return pthread_cond_signal( p_condvar );
 #endif
 }
@@ -234,8 +399,39 @@ static __inline__ int vlc_cond_wait( vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex
 #ifdef SYS_GNU
     condition_wait( (condition_t)p_condvar, (mutex_t)p_mutex );
     return( 0 );
-#else
+#endif
+
+#ifdef SYS_BEOS
+    status_t err;
+
+    if( !p_condvar ) return B_BAD_VALUE;
+    if( !p_mutex ) return B_BAD_VALUE;
+    if( p_condvar->init < 2000 ) return B_NO_INIT;
+    lazy_init_cond( p_condvar );
+
+    if( acquire_sem(p_condvar->signalSem) == B_INTERRUPTED ) return B_INTERRUPTED;
+    p_condvar->nw += 1;
+    release_sem( p_condvar->signalSem );
+
+    vlc_mutex_unlock( p_mutex );
+    err = acquire_sem( p_condvar->sem );
+
+    while( acquire_sem(p_condvar->signalSem) == B_INTERRUPTED)
+        { err = B_INTERRUPTED; }
+    if( p_condvar->ns > 0 )
+    {
+        release_sem( p_condvar->handshakeSem );
+        p_condvar->ns -= 1;
+    }
+    p_condvar->nw -= 1;
+    release_sem( p_condvar->signalSem );
+
+    while( vlc_mutex_lock(p_mutex) == B_INTERRUPTED)
+        { err = B_INTERRUPTED; }
+    return err;
+#endif
+
+#if defined(SYS_LINUX) || defined(SYS_BSD)     
     return pthread_cond_wait( p_condvar, p_mutex );
 #endif
 }
-