Ctrl K
ComunidadGuías…

std/thread.zc

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot

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);
}