ref: fadbab49dc34508f835d31aaaa86135e51b3154e
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 = opaque; export type attr = opaque; export type cond = opaque; export type condattr = opaque; export type mutex = opaque; export type mutexattr = opaque; export type rwlock = opaque; export type rwlockattr = opaque; export type barrier = opaque; export type barrierattr = opaque; export type spinlock = opaque; // 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 = *opaque; type startroutine_t = *fn(*opaque) 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 export type mutextype = enum int { Timed = 0, Recursive = 1, ErrorCheck = 2, Adaptive = 3, Max }; export type pthreadfn = *const fn(*opaque) nullable *opaque; // 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 *opaque, }; fn thread_start(arg: *opaque) nullable *opaque = { 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); exit(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; if(mutexattr_init(&mtxattr) != 0) { fmt::fatal("pthread::mutexattr_init"); }; if(mutex_init(&wrmtx, &mtxattr) != 0) { fmt::fatal("pthread::mutex_init"); }; 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"); }; }; 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); }; if(attr_destroy(&attr) != 0) { fmt::fatal("pthread::attr_destroy"); }; if(mutexattr_destroy(&mtxattr) != 0) { fmt::fatal("pthread::mutexattr_destroy"); }; };