Made bake.cmd faster and added most thrd_* functions

This commit is contained in:
NeGate 2022-06-29 03:21:35 -04:00
parent d70de47c01
commit e864a4904a
5 changed files with 119 additions and 21 deletions

View File

@ -29,23 +29,16 @@ mkdir bin
mkdir bin\%PLATFORM%
del ciabatta.lib 2> nul
for /R src\%PLATFORM% %%F in (*.c) do (
echo %%F
clang -Isrc/win -c -o bin\%PLATFORM%\%%~nF.obj %%F %CIABATTA_OPTIONS%
)
call bake_cc.cmd
for /R src\%PLATFORM% %%F in (*.asm) do (
echo %%F
nasm %%F -f win64 -o bin\%PLATFORM%\%%~nF.obj
)
for /R src\code %%F in (*.c) do (
echo %%F
clang -c -o bin\%%~nF.obj %%F %CIABATTA_OPTIONS%
)
llvm-ar rc ciabatta.lib bin\*.obj bin\%PLATFORM%\*.obj
:skip_crt_compilation
if "%TEST%"=="" set TEST=assert
if "%TEST%"=="" set TEST=threads
echo Compiling test_%TEST%.c
clang test\test_%TEST%.c ciabatta.lib -std=c11 -lDbghelp -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS%

8
bake_cc.cmd Normal file
View File

@ -0,0 +1,8 @@
for /R src\%PLATFORM% %%F in (*.c) do (
echo %%F
start /B clang -Isrc/win -c -o bin\%PLATFORM%\%%~nF.obj %%F %CIABATTA_OPTIONS%
)
for /R src\code %%F in (*.c) do (
echo %%F
start /B clang -c -o bin\%%~nF.obj %%F %CIABATTA_OPTIONS%
)

0
code/unicode/wctype.json Normal file
View File

View File

@ -6,10 +6,80 @@
// https://preshing.com/20120305/implementing-a-recursive-mutex/
// https://preshing.com/20120226/roll-your-own-lightweight-mutex/
#include <win.h>
#include <stdlib.h>
#include <threads.h>
DWORD _tls_index = 0;
typedef struct thrd__wrapper_info {
thrd_start_t func;
void* arg;
} thrd__wrapper_info;
static DWORD thrd__wrapper(void* arg) {
thrd__wrapper_info info = *((thrd__wrapper_info*) arg);
int result = info.func(info.arg);
// TODO(NeGate): setup TSS dtors here
return (DWORD) result;
}
thrd_t thrd_current(void) {
return (thrd_t){ GetCurrentThread() };
}
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
thrd__wrapper_info* info = malloc(sizeof(thrd__wrapper_info));
if (info == NULL) {
return thrd_nomem;
}
info->func = func;
info->arg = arg;
// technically thrd_start_t and LPTHREAD_START_ROUTINE aren't the same but are close
// enough to be ABI compatible, namely a difference in signedness of the return val.
thr->handle = CreateThread(NULL, 0, thrd__wrapper, info, 0, NULL);
return thr->handle != NULL ? thrd_success : thrd_error;
}
int thrd_detach(thrd_t thr) {
return CloseHandle(thr.handle) != 0 ? thrd_success : thrd_error;
}
int thrd_equal(thrd_t thr0, thrd_t thr1) {
return GetThreadId(thr0.handle) == GetThreadId(thr1.handle);
}
int thrd_join(thrd_t thr, int *res) {
if (WaitForSingleObject(thr.handle, INFINITE) == WAIT_FAILED) {
return thrd_error;
}
if (res != NULL) {
// snatch that exit code
DWORD ures;
if (GetExitCodeThread(thr.handle, &ures) == 0) {
CloseHandle(thr.handle);
return thrd_error;
}
*res = (int) ures;
}
CloseHandle(thr.handle);
return thrd_success;
}
void thrd_yield(void) {
Sleep(0);
}
_Noreturn void thrd_exit(int res) {
// TODO(NeGate): setup TSS dtors here
ExitThread((DWORD) res);
}
void mtx_destroy(mtx_t *mtx) {
CloseHandle(mtx->semaphore);
}
@ -30,9 +100,9 @@ int mtx_init(mtx_t *mtx, int type) {
int mtx_lock(mtx_t *mtx) {
bool try_recursive = (mtx->type == mtx_recursive);
#ifdef _DEBUG
#ifdef _DEBUG
try_recursive = true;
#endif
#endif
if (try_recursive) {
DWORD tid = GetCurrentThreadId();
@ -42,11 +112,11 @@ int mtx_lock(mtx_t *mtx) {
WaitForSingleObject(mtx->semaphore, INFINITE);
} else {
// we recursive and already locked
#ifdef _DEBUG
#ifdef _DEBUG
if (mtx->type != mtx_recursive) {
return thrd_error;
}
#endif
#endif
}
}
@ -67,20 +137,20 @@ int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts) {
int mtx_trylock(mtx_t *mtx) {
bool try_recursive = (mtx->type == mtx_recursive);
#ifdef _DEBUG
#ifdef _DEBUG
try_recursive = true;
#endif
#endif
if (try_recursive) {
DWORD tid = GetCurrentThreadId();
// Do we own this mutex on this thread already?
if (mtx->owner == tid) {
#ifdef _DEBUG
#ifdef _DEBUG
if (mtx->type != mtx_recursive) {
return thrd_error;
}
#endif
#endif
atomic_fetch_add(&mtx->counter, 1);
} else {
@ -106,9 +176,9 @@ int mtx_trylock(mtx_t *mtx) {
int mtx_unlock(mtx_t *mtx) {
bool try_recursive = (mtx->type == mtx_recursive);
#if _DEBUG
#if _DEBUG
try_recursive = true;
#endif
#endif
if (try_recursive) {
DWORD tid = GetCurrentThreadId();
@ -122,11 +192,11 @@ int mtx_unlock(mtx_t *mtx) {
if (atomic_fetch_sub_explicit(&mtx->counter, 1, memory_order_release) > 0) {
if (recur == 0) ReleaseSemaphore(mtx->semaphore, 1, NULL);
else {
#ifdef _DEBUG
#ifdef _DEBUG
if (mtx->type != mtx_recursive) {
return thrd_error;
}
#endif
#endif
}
}
} else {

27
test/test_threads.c Normal file
View File

@ -0,0 +1,27 @@
#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>
atomic_int acnt;
int cnt;
int f(void* thr_data)
{
for(int n = 0; n < 1000; ++n) {
atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); // atomic
++cnt; // undefined behavior, in practice some updates missed
}
return 0;
}
int main(void)
{
thrd_t thr[10];
for(int n = 0; n < 10; ++n)
thrd_create(&thr[n], f, NULL);
for(int n = 0; n < 10; ++n)
thrd_join(thr[n], NULL);
printf("The atomic counter is %d\n", acnt);
printf("The non-atomic counter is %d\n", cnt);
}