std/thread.zc
Rama main · réplica de lectura del repositorio original.
include <pthread.h>
include <time.h>
include <unistd.h>
import "./core.zc"
import "./result.zc"
import "./mem.zc"
import "./sync.zc"
// Essential raw block: required for pthread operations and closure trampolining
// This block cannot be eliminated because:
// 1. z_closure_T is an internal compiler type for Zen-C closures
// 2. pthread_t, pthread_mutex_t are opaque types that can't be extern'd with void*
// 3. The trampoline function needs to cast and execute Zen-C closures
raw {
typedef void (*ZenThreadFunc)(void*);
struct ZenThreadCtx {
void *func_ptr;
void *ctx;
};
static void* _z_thread_trampoline(void *arg) {
z_closure_T *closure = (z_closure_T*)arg;
void (*f)(void*) = (void(*)(void*))closure->func;
f(closure->ctx);
if (closure->drop) closure->drop(closure->ctx);
// In MISRA mode, we don't freeCtx.
// In non-MISRA mode, this still uses free() which is fine as it's raw C.
// Actually, we should use a macro prefix to be consistent.
#ifndef ZC_MISRA
free(closure);
#endif
return NULL;
}
static int _z_thread_equal(void* handle1, void* handle2) {
return pthread_equal((pthread_t)handle1, (pthread_t)handle2);
}
static int _z_thread_spawn(void *ctx_copy, size_t *out_handle) {
pthread_t pt;
int ret = pthread_create(&pt, NULL, _z_thread_trampoline, ctx_copy);
if (ret == 0) {
*out_handle = (size_t)pt;
}
return (int)ret;
}
static int _z_thread_join(void *handle) {
return (int)pthread_join((pthread_t)handle, NULL);
}
static int _z_thread_detach(void* handle) {
return pthread_detach((pthread_t)handle);
}
static int _z_thread_cancel(void* handle) {
return pthread_cancel((pthread_t)handle);
}
static void _z_usleep(int micros) {
usleep(micros);
}
}
extern fn _z_thread_equal(handle1: void*, handle2: void*) -> c_int;
extern fn _z_thread_spawn(ctx: void*, out: usize*) -> c_int;
extern fn _z_thread_join(handle: void*) -> c_int;
extern fn _z_thread_detach(handle: void*) -> c_int;
extern fn _z_thread_cancel(handle: void*) -> c_int;
extern fn _z_usleep(micros: c_int);
struct Thread {
handle: void*;
}
impl Thread {
/// Spawns a thread running the closure.
fn spawn(func: fn()) -> Result<Thread> {
let out_handle: usize = 0;
let ctx = alloc_bytes(sizeof(fn()));
if (ctx == NULL) return Result<Thread>::Err("OOM");
memcpy(ctx, &func, sizeof(fn()));
// Zero out the drop field to prevent f64-free by this function's cleanup
raw {
((z_closure_T*)&func)->drop = NULL;
}
let ret = _z_thread_spawn(ctx, &out_handle);
if ret != 0 {
dealloc<void>(ctx);
return Result<Thread>::Err("Failed to create thread");
}
return Result<Thread>::Ok(Thread { handle: (void*)out_handle });
}
/// Waits for the thread to finish.
fn join(self) -> Result<bool> {
let err = _z_thread_join(self.handle);
if err {
return Result<bool>::Err("Join failed");
}
return Result<bool>::Ok(true);
}
/// Detaches the thread (runs independently).
fn detach(self) -> Result<bool> {
let err = _z_thread_detach(self.handle);
if err {
return Result<bool>::Err("Detach failed");
}
return Result<bool>::Ok(true);
}
fn cancel(self) -> Result<bool> {
let err = _z_thread_cancel(self.handle);
if err {
return Result<bool>::Err("Cancel failed");
}
return Result<bool>::Ok(true);
}
}
fn sleep_ms(ms: int) {
let micros: c_int = (c_int)(ms * 1000);
_z_usleep(micros);
}