File dp_thread.h¶
File List > doppler > dp_thread.h
Go to the documentation of this file
#ifndef DP_THREAD_H
#define DP_THREAD_H
#include "doppler/dp_once.h"
#ifdef _WIN32
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#endif
#define WIN32_LEAN_AND_MEAN
#include <process.h>
#include <windows.h>
typedef SRWLOCK dp_mutex_t;
typedef CONDITION_VARIABLE dp_cond_t;
typedef HANDLE dp_thread_t;
#define DP_THREAD_FN(name, arg) static unsigned __stdcall name (void *arg)
#define DP_THREAD_RETURN return 0
static inline void
dp_mutex_init (dp_mutex_t *m)
{
InitializeSRWLock (m);
}
static inline void
dp_mutex_destroy (dp_mutex_t *m)
{
(void)m; /* an SRWLOCK owns nothing to release */
}
static inline void
dp_mutex_lock (dp_mutex_t *m)
{
AcquireSRWLockExclusive (m);
}
static inline void
dp_mutex_unlock (dp_mutex_t *m)
{
ReleaseSRWLockExclusive (m);
}
static inline void
dp_cond_init (dp_cond_t *c)
{
InitializeConditionVariable (c);
}
static inline void
dp_cond_destroy (dp_cond_t *c)
{
(void)c; /* likewise */
}
static inline void
dp_cond_wait (dp_cond_t *c, dp_mutex_t *m)
{
SleepConditionVariableSRW (c, m, INFINITE, 0);
}
static inline void
dp_cond_signal (dp_cond_t *c)
{
WakeConditionVariable (c);
}
static inline void
dp_cond_broadcast (dp_cond_t *c)
{
WakeAllConditionVariable (c);
}
static inline int
dp_thread_create (dp_thread_t *t, unsigned (__stdcall *fn) (void *), void *arg)
{
uintptr_t h = _beginthreadex (NULL, 0, fn, arg, 0, NULL);
if (!h)
return -1;
*t = (HANDLE)h;
return 0;
}
static inline int
dp_thread_join (dp_thread_t t)
{
DWORD waited = WaitForSingleObject (t, INFINITE);
BOOL closed = CloseHandle (t);
return (waited == WAIT_OBJECT_0 && closed) ? 0 : -1;
}
static inline int
dp_cpu_count (void)
{
DWORD n = GetActiveProcessorCount (ALL_PROCESSOR_GROUPS);
return n ? (int)n : 1;
}
static inline void
dp_thread_yield (void)
{
SwitchToThread ();
}
static inline void
dp_thread_sleep_us (unsigned us)
{
Sleep ((DWORD)((us + 999u) / 1000u));
}
#else /* POSIX */
#include <pthread.h>
#include <sched.h>
#include <time.h>
#include <unistd.h>
typedef pthread_mutex_t dp_mutex_t;
typedef pthread_cond_t dp_cond_t;
typedef pthread_t dp_thread_t;
#define DP_THREAD_FN(name, arg) static void *name (void *arg)
#define DP_THREAD_RETURN return NULL
static inline void
dp_mutex_init (dp_mutex_t *m)
{
pthread_mutex_init (m, NULL);
}
static inline void
dp_mutex_destroy (dp_mutex_t *m)
{
pthread_mutex_destroy (m);
}
static inline void
dp_mutex_lock (dp_mutex_t *m)
{
pthread_mutex_lock (m);
}
static inline void
dp_mutex_unlock (dp_mutex_t *m)
{
pthread_mutex_unlock (m);
}
static inline void
dp_cond_init (dp_cond_t *c)
{
pthread_cond_init (c, NULL);
}
static inline void
dp_cond_destroy (dp_cond_t *c)
{
pthread_cond_destroy (c);
}
static inline void
dp_cond_wait (dp_cond_t *c, dp_mutex_t *m)
{
pthread_cond_wait (c, m);
}
static inline void
dp_cond_signal (dp_cond_t *c)
{
pthread_cond_signal (c);
}
static inline void
dp_cond_broadcast (dp_cond_t *c)
{
pthread_cond_broadcast (c);
}
static inline int
dp_thread_create (dp_thread_t *t, void *(*fn) (void *), void *arg)
{
return pthread_create (t, NULL, fn, arg);
}
static inline int
dp_thread_join (dp_thread_t t)
{
return pthread_join (t, NULL);
}
static inline int
dp_cpu_count (void)
{
long n = sysconf (_SC_NPROCESSORS_ONLN);
return n > 0 ? (int)n : 1;
}
static inline void
dp_thread_yield (void)
{
sched_yield ();
}
static inline void
dp_thread_sleep_us (unsigned us)
{
struct timespec ts;
ts.tv_sec = (time_t)(us / 1000000u);
ts.tv_nsec = (long)(us % 1000000u) * 1000L;
nanosleep (&ts, NULL);
}
#endif /* _WIN32 */
#endif /* DP_THREAD_H */