ref: 1c557dc95cee8934e942cab92e3f1c85fbf0a9c9
dir: /pthread.ha/
// POSIX pthread interface // // Based off of /usr/include/pthread.h from OpenBSD 7.0-STABLE use types; use fmt; use rt; // Run-time invariant values export const Destructor_Iterations: int = 4; export const Keys_Max: int = 256; export const Stack_Min: u32 = ((1: u32) << 12); export const Threads_Max: u64 = types::U64_MAX; //Flags for threads and thread attributes export const Detached: int = 0x1; export const Scope_System: int = 0x2; export const Inherit_Sched: int = 0x4; export const NoFloat: int = 0x8; export const Create_Detached: int = 0x1; export const Create_Joinable: int = 0; export const Scope_Process: int = 0; export const Explicit_Sched: int = 0; // Flags for read/write lock attributes export const Process_Private: int = 0; export const Process_Shared: int = 1; // Flags for cancelling threads export const Cancel_Enable: int = 0; export const Cancel_Disable: int = 1; export const Cancel_Deferred: int = 0; export const Cancel_Asynchronous: int = 2; export const Canceled: int = -1; // Barrier flags export const Barrier_Serial_Thread: int = -1; // Forward structure definitions. // // These are mostly opaque to the user. export type pthread = void; export type attr = void; export type cond = void; export type condattr = void; export type mutex = void; export type mutexattr = void; export type rwlock = void; export type rwlockattr = void; export type barrier = void; export type barrierattr = void; export type spinlock = void; // Primitive system data type definitions required by P1003.1c. export type pthread_t = nullable *pthread; export type attr_t = nullable *attr; export type mutex_t = nullable *mutex; export type mutexattr_t = nullable *mutexattr; export type cond_t = nullable *cond; export type condattr_t = nullable *condattr; export type key_t = int; export type rwlock_t = nullable *rwlock; export type rwlockattr_t = nullable *rwlockattr; export type barrier_t = nullable *barrier; export type barrierattr_t = nullable *barrierattr; export type spinlock_t = nullable *spinlock; // Additional type definitions type addr_t = *void; type startroutine_t = *fn(_: *void) void; // Once definitions export type once_t = struct{ state: int, mutex: mutex_t }; // Flags for once initialization export const Needs_Init: int = 0; export const Done_Init: int = 1; export const PRIO_None: int = 0; export const PRIO_Inherit: int = 1; export const PRIO_Protect: int = 2; // Mutex types type mutextype = enum int { ErrorCheck = 1, Recursive = 2, Normal = 3, Strict_NP = 4, Max }; export type pthreadfn = *const fn(_: *void) nullable *void; // From /usr/include/sched.h export type sched_param = struct { sched_priority: int }; export type clockid_t = i32; type thread_info = struct { thread_id: pthread_t, thread_num: int, thread_data: nullable *void, }; fn thread_start(arg: *void) nullable *void = { let tinfo: *thread_info = (arg: *thread_info); let wrmtx: *mutex_t = (tinfo.thread_data: *mutex_t); mutex_lock(wrmtx); fmt::printf("Thread {}\n", tinfo.thread_num)!; mutex_unlock(wrmtx); return null; }; @test fn primary_test() void = { const num_threads: int = 4; let attr: attr_t = null; if(attr_init(&attr) != 0) { fmt::fatal("pthread::attr_init"); }; let wrmtx: mutex_t = null; let mtxattr: mutexattr_t = null; mutexattr_init(&mtxattr); mutex_init(&wrmtx, &mtxattr); let tinfo: [4]thread_info = [thread_info { thread_id = null, thread_num = 0, thread_data = &wrmtx }...]; for (let i = 0; i < num_threads; i += 1) { tinfo[i].thread_num = i + 1; if(create(&tinfo[i].thread_id, &attr, &thread_start, &tinfo[i]) != 0){ fmt::fatal("pthread::create"); }; }; if(attr_destroy(&attr) != 0) { fmt::fatal("pthread::attr_destroy"); }; for (let i = 0; i < num_threads; i += 1) { if (join(tinfo[i].thread_id, null) != 0) { fmt::fatal("pthread::join"); }; mutex_lock(&wrmtx); fmt::printf("Joined with thread {}...\n", tinfo[i].thread_num)!; mutex_unlock(&wrmtx); }; };