1
0
mirror of https://github.com/skeeto/w64devkit.git synced 2026-10-24 17:39:18 +03:00
Files
w64devkit/src/threads.h
Christopher Wellons 58dca7f70d Support both time_t ABIs in C11 threads on x86
thrd_sleep, mtx_timedlock, and cnd_timedwait take a struct timespec,
whose layout follows time_t. libmingwex.a was compiled for 32-bit
time_t only, so x86 programs built with 64-bit time_t read garbage
timeouts. The plain names keep the 32-bit ABI so existing objects still
link correctly, and threads.h redirects 64-bit time_t callers to new
*64 variants. x64 is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:09:55 -04:00

94 lines
2.3 KiB
C

// C11 threads — w64devkit toolchain implementation
// This is free and unencumbered software released into the public domain.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*thrd_start_t)(void *);
enum {
thrd_success = 0,
thrd_busy = 1,
thrd_error = 2,
thrd_nomem = 3,
thrd_timedout = 4,
};
enum {
mtx_plain = 0,
mtx_recursive = 1,
mtx_timed = 2,
};
struct timespec;
// On x86, time_t may be 32 or 64 bits. The plain names keep the 32-bit
// time_t ABI so that older objects still link correctly, and 64-bit
// time_t callers are routed to *64 variants.
#if defined(__i386__)
# include <_mingw.h>
#endif
#if defined(__i386__) && !defined(_USE_32BIT_TIME_T)
# define __THRD_TIME64(f) __MINGW_ASM_CALL(f##64)
#else
# define __THRD_TIME64(f)
#endif
typedef struct {
__INT32_TYPE__ __handle;
__INT32_TYPE__ __tid;
} thrd_t;
int thrd_create(thrd_t *, thrd_start_t, void *);
int thrd_equal(thrd_t, thrd_t);
thrd_t thrd_current(void);
int thrd_sleep(const struct timespec *, struct timespec *)
__THRD_TIME64(thrd_sleep);
void thrd_yield(void);
void thrd_exit[[noreturn]](int);
int thrd_detach(thrd_t);
int thrd_join(thrd_t, int *);
typedef struct { __UINTPTR_TYPE__ __; } mtx_t;
int mtx_init(mtx_t *, int);
int mtx_lock(mtx_t *);
int mtx_timedlock(mtx_t *, const struct timespec *)
__THRD_TIME64(mtx_timedlock);
int mtx_trylock(mtx_t *);
int mtx_unlock(mtx_t *);
void mtx_destroy(mtx_t *);
typedef struct { __UINTPTR_TYPE__ __; } once_flag;
#define ONCE_FLAG_INIT {0}
void call_once(once_flag *, void (*)(void));
typedef struct { __UINTPTR_TYPE__ __; } cnd_t;
int cnd_init(cnd_t *);
int cnd_signal(cnd_t *);
int cnd_broadcast(cnd_t *);
int cnd_wait(cnd_t *, mtx_t *);
int cnd_timedwait(cnd_t *, mtx_t *, const struct timespec *)
__THRD_TIME64(cnd_timedwait);
void cnd_destroy(cnd_t *);
#if !defined(__cplusplus) && __STDC_VERSION__ < 202311L
# define thread_local _Thread_local
#endif
enum { TSS_DTOR_ITERATIONS = 1 };
typedef struct { __INT32_TYPE__ __; } tss_t;
typedef void (*tss_dtor_t)(void *);
int tss_create(tss_t *, tss_dtor_t);
void *tss_get(tss_t);
int tss_set(tss_t, void *);
void tss_delete(tss_t);
#undef __THRD_TIME64
#ifdef __cplusplus
}
#endif