27 #include "precompiled.h"
45 return (
HANDLE)((
char*)0 + p);
64 WARN_IF_FALSE(DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS));
82 if(
cpu_CAS((
volatile intptr_t*)once, 0, 1))
92 DWORD pc = GetPriorityClass(GetCurrentProcess());
109 DWORD pri_class = NORMAL_PRIORITY_CLASS;
112 pri_class = HIGH_PRIORITY_CLASS;
114 pri_class = REALTIME_PRIORITY_CLASS;
116 SetPriorityClass(GetCurrentProcess(), pri_class);
120 SetThreadPriority(hThread, pri);
148 DWORD idx = TlsAlloc();
149 if(idx == TLS_OUT_OF_INDEXES)
159 if(
cpu_CAS((
volatile intptr_t*)&
dtors[i].
dtor, (intptr_t)0, (intptr_t)dtor))
178 BOOL ret = TlsFree(idx);
191 DWORD last_err = GetLastError();
193 void* data = TlsGetValue(idx);
196 if(GetLastError() == 0)
201 SetLastError(last_err);
215 BOOL ret = TlsSetValue(idx, (
void*)value);
224 bool had_valid_tls =
false;
242 had_valid_tls =
true;
302 return (CRITICAL_SECTION*)*m;
307 CRITICAL_SECTION*
cs = (CRITICAL_SECTION*)
wutil_Allocate(
sizeof(CRITICAL_SECTION));
308 InitializeCriticalSection(cs);
317 DeleteCriticalSection(cs);
334 EnterCriticalSection(cs);
343 const BOOL successfullyEnteredOrAlreadyOwns = TryEnterCriticalSection(cs);
344 return successfullyEnteredOrAlreadyOwns? 0 : -1;
352 LeaveCriticalSection(cs);
377 const bool create = (oflag & O_CREAT) != 0;
378 const bool exclusive = (oflag & O_EXCL) != 0;
382 ENSURE((oflag & ~(O_CREAT|O_EXCL)) == 0);
383 ENSURE(!exclusive || create);
386 unsigned initialValue = 0;
390 va_start(args, oflag);
391 const mode_t mode = va_arg(args, mode_t);
392 initialValue = va_arg(args,
unsigned);
394 ENSURE(mode == 0700 &&
"this implementation ignores mode_t");
399 const LONG maxValue = 0x7fffffff;
400 const HANDLE hSemaphore = CreateSemaphore(0, (
LONG)initialValue, maxValue, 0);
403 const bool existed = (GetLastError() == ERROR_ALREADY_EXISTS);
406 if(exclusive && existed)
408 CloseHandle(hSemaphore);
414 if(!create && !existed)
416 CloseHandle(hSemaphore);
425 *sem = (
sem_t)hSemaphore;
446 SECURITY_ATTRIBUTES sec = {
sizeof(SECURITY_ATTRIBUTES) };
447 sec.bInheritHandle = (
BOOL)pshared;
448 HANDLE h = CreateSemaphore(&sec, (
LONG)value, 0x7fffffff, 0);
471 DWORD ret = WaitForSingleObject(h, INFINITE);
472 ENSURE(ret == WAIT_OBJECT_0);
484 bool& timeout_is_valid)
486 timeout_is_valid =
false;
492 if(abs_timeout->
tv_nsec >= 1000000000)
499 timeout_is_valid =
true;
505 i64 length_ms = ds*1000 + (dn+500000)/1000000;
512 if(length_ms >= 0xFFFFFFFF)
515 length_ms = 0xfffffffe;
517 return (
DWORD)(length_ms & 0xFFFFFFFF);
522 bool timeout_is_valid;
526 DWORD ret = WaitForSingleObject(h, timeout_ms);
528 if(ret == WAIT_OBJECT_0)
533 if(!timeout_is_valid)
536 else if(ret == WAIT_TIMEOUT)
560 DWORD ret = MsgWaitForMultipleObjects(1, &h, FALSE, INFINITE, QS_ALLEVENTS);
562 if(ret == WAIT_OBJECT_0)
567 if(ret == WAIT_OBJECT_0+1)
607 void* (*func)(
void*);
615 void* (*func)(
void*) = func_and_arg->
func;
616 void* arg = func_and_arg->
arg;
632 return (
unsigned)(uintptr_t)ret;
649 func_and_arg->
func = func;
650 func_and_arg->
arg = arg;
673 TerminateThread(hThread, 0);
685 DWORD ret = WaitForSingleObject(hThread, INFINITE);
686 if(ret != WAIT_OBJECT_0)
695 GetExitCodeThread(hThread, (LPDWORD)value_ptr);
697 CloseHandle(hThread);
static const size_t TLS_LIMIT
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param)
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
#define WARN_IF_ERR(expression)
static __declspec(align(64)) TimerState timerStates[2]
some WinAPI functions SetLastError(0) on success, which is bad because it can hide previous errors...
void * wutil_Allocate(size_t size)
int clock_gettime(clockid_t clock, struct timespec *ts)
int sem_close(sem_t *sem)
static struct @29 dtors[MAX_DTORS]
int sem_unlink(const char *name)
pthread_mutex_t pthread_mutex_initializer()
static void NotifyCurrentThread()
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
int pthread_key_create(pthread_key_t *key, void(*dtor)(void *))
static pthread_t pthread_from_HANDLE(HANDLE h)
static HANDLE HANDLE_from_pthread(pthread_t p)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
void * pthread_mutexattr_t
int pthread_create(pthread_t *thread_id, const void *attr, void *(*func)(void *), void *arg)
#define WINIT_REGISTER_CRITICAL_INIT(func)
int sem_msgwait_np(sem_t *sem)
int sem_destroy(sem_t *sem)
int pthread_mutex_trylock(pthread_mutex_t *m)
int pthread_mutex_lock(pthread_mutex_t *m)
int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *abs_timeout)
int sem_init(sem_t *sem, int pshared, unsigned value)
int pthread_key_delete(pthread_key_t key)
i64 Status
Error handling system.
static CRITICAL_SECTION * CRITICAL_SECTION_from_pthread_mutex_t(pthread_mutex_t *m)
int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *)
static CRITICAL_SECTION cs[NUM_CS]
int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
static const size_t MAX_DTORS
void * pthread_getspecific(pthread_key_t key)
#define DEBUG_WARN_ERR(status)
display the error dialog with text corresponding to the given error code.
static HANDLE HANDLE_from_sem_t(sem_t *sem)
static void call_tls_dtors()
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
int pthread_setspecific(pthread_key_t key, const void *value)
bool cpu_CAS(volatile intptr_t *location, intptr_t expected, intptr_t newValue)
atomic "compare and swap".
#define WARN_IF_FALSE(expression)
int pthread_mutex_unlock(pthread_mutex_t *m)
int pthread_once(pthread_once_t *once, void(*init_routine)())
int pthread_equal(pthread_t t1, pthread_t t2)
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
static unsigned __stdcall thread_start(void *param)
int pthread_join(pthread_t thread, void **value_ptr)
int pthread_mutex_destroy(pthread_mutex_t *m)
sem_t * sem_open(const char *name, int oflag,...)
long __stdcall wseh_ExceptionFilter(struct _EXCEPTION_POINTERS *ep)
unsigned int pthread_key_t
static Status wpthread_Init()
int pthread_cancel(pthread_t thread)
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
static DWORD calc_timeout_length_ms(const struct timespec *abs_timeout, bool &timeout_is_valid)
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
int pthread_mutexattr_init(pthread_mutexattr_t *attr)