#include "blis.h"
#if defined(BLIS_DISABLE_SYSTEM)
int bli_pthread_create
(
bli_pthread_t* thread,
const bli_pthread_attr_t* attr,
void* (*start_routine)(void*),
void* arg
)
{
start_routine( arg );
return 0;
}
int bli_pthread_join
(
bli_pthread_t thread,
void** retval
)
{
return 0;
}
int bli_pthread_mutex_init
(
bli_pthread_mutex_t* mutex,
const bli_pthread_mutexattr_t* attr
)
{
return 0;
}
int bli_pthread_mutex_destroy
(
bli_pthread_mutex_t* mutex
)
{
return 0;
}
int bli_pthread_mutex_lock
(
bli_pthread_mutex_t* mutex
)
{
return 0;
}
int bli_pthread_mutex_trylock
(
bli_pthread_mutex_t* mutex
)
{
return 0;
}
int bli_pthread_mutex_unlock
(
bli_pthread_mutex_t* mutex
)
{
return 0;
}
int bli_pthread_cond_init
(
bli_pthread_cond_t* cond,
const bli_pthread_condattr_t* attr
)
{
return 0;
}
int bli_pthread_cond_destroy
(
bli_pthread_cond_t* cond
)
{
return 0;
}
int bli_pthread_cond_wait
(
bli_pthread_cond_t* cond,
bli_pthread_mutex_t* mutex
)
{
return 0;
}
int bli_pthread_cond_broadcast
(
bli_pthread_cond_t* cond
)
{
return 0;
}
void bli_pthread_once
(
bli_pthread_once_t* once,
void (*init)(void)
)
{
init();
}
#if 0#endif
#elif defined(_MSC_VER)
#include <errno.h>
typedef struct
{
void* (*start_routine)( void* );
void* param;
void** retval;
} bli_thread_param;
static DWORD bli_thread_func
(
void* param_
)
{
bli_thread_param* param = param_;
*param->retval = param->start_routine( param->param );
return 0;
}
int bli_pthread_create
(
bli_pthread_t* thread,
const bli_pthread_attr_t* attr,
void* (*start_routine)(void*),
void* arg
)
{
if ( attr ) return EINVAL;
bli_thread_param param = { start_routine, arg, &thread->retval };
thread->handle = CreateThread( NULL, 0, bli_thread_func, ¶m, 0, NULL );
if ( !thread->handle ) return EAGAIN;
return 0;
}
int bli_pthread_join
(
bli_pthread_t thread,
void** retval
)
{
if ( !WaitForSingleObject( thread.handle, INFINITE ) ) return EAGAIN;
if ( retval ) *retval = thread.retval;
return 0;
}
int bli_pthread_mutex_init
(
bli_pthread_mutex_t* mutex,
const bli_pthread_mutexattr_t* attr
)
{
if ( attr ) return EINVAL;
InitializeSRWLock( mutex );
return 0;
}
int bli_pthread_mutex_destroy
(
bli_pthread_mutex_t* mutex
)
{
return 0;
}
int bli_pthread_mutex_lock
(
bli_pthread_mutex_t* mutex
)
{
AcquireSRWLockExclusive( mutex );
return 0;
}
int bli_pthread_mutex_trylock
(
bli_pthread_mutex_t* mutex
)
{
return TryAcquireSRWLockExclusive( mutex ) ? 0 : EBUSY;
}
int bli_pthread_mutex_unlock
(
bli_pthread_mutex_t* mutex
)
{
ReleaseSRWLockExclusive( mutex );
return 0;
}
int bli_pthread_cond_init
(
bli_pthread_cond_t* cond,
const bli_pthread_condattr_t* attr
)
{
if ( attr ) return EINVAL;
InitializeConditionVariable( cond );
return 0;
}
int bli_pthread_cond_destroy
(
bli_pthread_cond_t* cond
)
{
( void )cond;
return 0;
}
int bli_pthread_cond_wait
(
bli_pthread_cond_t* cond,
bli_pthread_mutex_t* mutex
)
{
if ( !SleepConditionVariableSRW( cond, mutex, INFINITE, 0 ) ) return EAGAIN;
return 0;
}
int bli_pthread_cond_broadcast
(
bli_pthread_cond_t* cond
)
{
WakeAllConditionVariable( cond );
return 0;
}
static BOOL bli_init_once_wrapper
(
bli_pthread_once_t* once,
void* param,
void** context
)
{
( void )once;
( void )context;
typedef void (*callback)( void );
((callback)param)();
return TRUE;
}
void bli_pthread_once
(
bli_pthread_once_t* once,
void (*init)(void)
)
{
InitOnceExecuteOnce( once, bli_init_once_wrapper, init, NULL );
}
#if 0#endif
#else
int bli_pthread_create
(
bli_pthread_t* thread,
const bli_pthread_attr_t* attr,
void* (*start_routine)(void*),
void* arg
)
{
return pthread_create( thread, attr, start_routine, arg );
}
int bli_pthread_join
(
bli_pthread_t thread,
void** retval
)
{
return pthread_join( thread, retval );
}
int bli_pthread_mutex_init
(
bli_pthread_mutex_t* mutex,
const bli_pthread_mutexattr_t* attr
)
{
return pthread_mutex_init( mutex, attr );
}
int bli_pthread_mutex_destroy
(
bli_pthread_mutex_t* mutex
)
{
return pthread_mutex_destroy( mutex );
}
int bli_pthread_mutex_lock
(
bli_pthread_mutex_t* mutex
)
{
return pthread_mutex_lock( mutex );
}
int bli_pthread_mutex_trylock
(
bli_pthread_mutex_t* mutex
)
{
return pthread_mutex_trylock( mutex );
}
int bli_pthread_mutex_unlock
(
bli_pthread_mutex_t* mutex
)
{
return pthread_mutex_unlock( mutex );
}
int bli_pthread_cond_init
(
bli_pthread_cond_t* cond,
const bli_pthread_condattr_t* attr
)
{
return pthread_cond_init( cond, attr );
}
int bli_pthread_cond_destroy
(
bli_pthread_cond_t* cond
)
{
return pthread_cond_destroy( cond );
}
int bli_pthread_cond_wait
(
bli_pthread_cond_t* cond,
bli_pthread_mutex_t* mutex
)
{
return pthread_cond_wait( cond, mutex );
}
int bli_pthread_cond_broadcast
(
bli_pthread_cond_t* cond
)
{
return pthread_cond_broadcast( cond );
}
void bli_pthread_once
(
bli_pthread_once_t* once,
void (*init)(void)
)
{
pthread_once( once, init );
}
#if 0#endif
#endif
#if defined(BLIS_DISABLE_SYSTEM)
int bli_pthread_barrier_init
(
bli_pthread_barrier_t* barrier,
const bli_pthread_barrierattr_t* attr,
unsigned int count
)
{
return 0;
}
int bli_pthread_barrier_destroy
(
bli_pthread_barrier_t* barrier
)
{
return 0;
}
int bli_pthread_barrier_wait
(
bli_pthread_barrier_t* barrier
)
{
return 0;
}
#elif defined(__APPLE__) || defined(_MSC_VER)
#include <errno.h>
int bli_pthread_barrier_init
(
bli_pthread_barrier_t* barrier,
const bli_pthread_barrierattr_t* attr,
unsigned int count )
{
if ( attr ) return EINVAL;
if ( count == 0 ) return EINVAL;
int err;
if ( (err = bli_pthread_mutex_init( &barrier->mutex, 0 )) != 0 ) return err;
if ( (err = bli_pthread_cond_init( &barrier->cond, 0 )) != 0 )
{
bli_pthread_mutex_destroy( &barrier->mutex );
return err;
}
barrier->tripCount = count;
barrier->count = 0;
return 0;
}
int bli_pthread_barrier_destroy
(
bli_pthread_barrier_t *barrier
)
{
bli_pthread_cond_destroy( &barrier->cond );
bli_pthread_mutex_destroy( &barrier->mutex );
return 0;
}
int bli_pthread_barrier_wait
(
bli_pthread_barrier_t *barrier
)
{
bli_pthread_mutex_lock( &barrier->mutex );
++(barrier->count);
if ( barrier->count >= barrier->tripCount )
{
barrier->count = 0;
bli_pthread_cond_broadcast( &barrier->cond );
bli_pthread_mutex_unlock( &barrier->mutex );
return 1;
}
else
{
bli_pthread_cond_wait( &barrier->cond, &(barrier->mutex) );
bli_pthread_mutex_unlock( &barrier->mutex );
return 0;
}
}
#else
int bli_pthread_barrier_init
(
bli_pthread_barrier_t* barrier,
const bli_pthread_barrierattr_t* attr,
unsigned int count
)
{
return pthread_barrier_init( barrier, attr, count );
}
int bli_pthread_barrier_destroy
(
bli_pthread_barrier_t* barrier
)
{
return pthread_barrier_destroy( barrier );
}
int bli_pthread_barrier_wait
(
bli_pthread_barrier_t* barrier
)
{
return pthread_barrier_wait( barrier );
}
#endif
int bli_pthread_switch_on
(
bli_pthread_switch_t* sw,
int (*init)(void)
)
{
int r_val = 0;
if ( sw->status == 0 )
{
bli_pthread_mutex_lock( &sw->mutex );
if ( sw->status == 0 )
{
r_val = init();
if ( r_val == 0 )
sw->status = 1;
}
bli_pthread_mutex_unlock( &sw->mutex );
}
return r_val;
}
int bli_pthread_switch_off
(
bli_pthread_switch_t* sw,
int (*deinit)(void)
)
{
int r_val = 0;
if ( sw->status == 1 )
{
bli_pthread_mutex_lock( &sw->mutex );
if ( sw->status == 1 )
{
r_val = deinit();
if ( r_val == 0 )
sw->status = 0;
}
bli_pthread_mutex_unlock( &sw->mutex );
}
return r_val;
}