* 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
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);
#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
}
#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
}
{
#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
*****************************************************************************/
#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
}
#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
}
#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
*****************************************************************************/
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
}
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
}
#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
}
-