#pragma once
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdint.h>
#include <stdlib.h>
#define PTHREAD_MUTEX_INITIALIZER {0}
#define pthread_cond_signal WakeConditionVariable
#define pthread_cond_broadcast WakeAllConditionVariable
#define pthread_mutex_init(mutex, attr) (InitializeCriticalSection(mutex), 0)
#define pthread_mutex_destroy(mutex) (DeleteCriticalSection(mutex), 0)
#define pthread_cond_init(cond, attr) (InitializeConditionVariable(cond), 0)
#define pthread_cond_destroy(x)
typedef CRITICAL_SECTION pthread_mutex_t;
typedef CONDITION_VARIABLE pthread_cond_t;
typedef HANDLE pthread_t;
static inline int pthread_mutex_lock(pthread_mutex_t* mutex)
{
EnterCriticalSection(mutex);
return 0;
}
static inline int pthread_mutex_trylock(pthread_mutex_t* mutex)
{
return !TryEnterCriticalSection(mutex);
}
static inline int pthread_mutex_unlock(pthread_mutex_t* mutex)
{
LeaveCriticalSection(mutex);
return 0;
}
static inline int pthread_join(pthread_t thread, void** exit_code)
{
if (WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0) {
if (exit_code) {
DWORD ex = 0;
GetExitCodeThread(thread, &ex);
*exit_code = (void*)(uint64_t)ex;
}
CloseHandle(thread);
return 0;
}
return -1;
}
typedef struct fi_thread_arg
{
void* (*routine)(void*);
void* arg;
} fi_thread_arg;
static DWORD WINAPI ofi_thread_starter(void* arg)
{
fi_thread_arg data = *(fi_thread_arg*)arg;
free(arg);
return (DWORD)(uint64_t)data.routine(data.arg);
}
static inline int pthread_create(pthread_t* thread, void* attr, void *(*routine)(void*), void* arg)
{
attr;
fi_thread_arg* data = (fi_thread_arg*)malloc(sizeof(*data));
data->routine = routine;
data->arg = arg;
DWORD threadid;
*thread = CreateThread(0, 0, ofi_thread_starter, data, 0, &threadid);
return *thread == 0;
}