home: hub: hare-pthread

Download patch

ref: 68db3e9d5d605e581337692be1e7ba02739af9af
author: grobe0ba <grobe0ba@tcp80.org>
date: Sun Dec 25 13:00:48 CST 2022

initial commit

--- /dev/null
+++ b/filter.awk
@@ -1,0 +1,56 @@
+#!/home/grobe0ba/opt/x86_64/bin/awk -f
+
+BEGIN { print "use rt;" }
+
+/^$/ { print; next }
+
+{
+    rettype=""
+    fn=""
+    start=3
+    noret=0
+    nullable=0
+    if($1 != "noret"){
+        rettype=$1
+        fn=$2
+    }
+    if($1 == "noret"){
+        start=4
+        rettype=$2
+        fn=$3
+        noret=1
+    }
+    if($1 == "nullable"){
+        start=4
+        rettype=$2
+        fn=$3
+        nullable=1
+    }
+    printf "export @symbol(\"pthread_%s\") ", fn
+    if(noret == 1){
+        printf "@noreturn "
+    }
+    printf "fn %s(", fn
+    for(i = start; i <= NF; i++){
+        printf "_: "
+        if($i == "const"){
+            i++
+            printf "const "
+        }
+
+        if($i == "nullable"){
+            i++
+            printf "nullable "
+        }
+
+        printf "%s", $i
+        if(i < NF){
+            printf ", "
+        }
+    }
+    printf ") "
+    if(nullable == 1){
+        printf "nullable "
+    }
+    printf "%s;\n", rettype
+}
--- /dev/null
+++ b/fix.awk
@@ -1,0 +1,14 @@
+#!/home/grobe0ba/opt/x86_64/bin/awk -f
+
+/^export (fn|@noreturn) (.*)\(/ {
+    if ($3 == "fn") {
+        split($4, line, "(")
+    } else {
+        split($3, line, "(")
+    }
+    fname=line[1]
+    print "@symbol(\"pthread_" fname "\") " $0
+    next
+}
+
+{ print }
--- /dev/null
+++ b/fns
@@ -1,0 +1,118 @@
+int atfork pthreadfn pthreadfn pthreadfn
+
+int attr_destroy *attr_t
+int attr_getstack *attr_t nullable **void *u64
+int attr_getstacksize const *attr_t *u64
+int attr_getstackaddr const *attr_t *u64
+int attr_getguardsize const *attr_t *u64
+int attr_getdetachstate const *attr_t *int
+int attr_init *attr_t
+int attr_setstacksize *attr_t u64
+int attr_setstack *attr_t nullable *void *u64
+int attr_setstackaddr *attr_t nullable *void
+int attr_setguardsize *attr_t u64
+int attr_setdetachstate *attr_t int
+
+void cleanup_pop int
+void cleanup_push pthreadfn nullable *void
+
+int condattr_destroy *condattr_t
+int condattr_init *condattr_t
+
+int cond_broadcast *cond_t
+int cond_destroy *cond_t
+int cond_init *cond_t const *condattr_t
+int cond_signal *cond_t
+int cond_timedwait *cond_t *mutex_t const *rt::timespec
+int cond_wait *cond_t *mutex_t
+
+int create *pthread_t const *attr_t pthreadfn nullable *void
+int detach pthread_t
+int equal pthread_t pthread_t
+noret void exit nullable *void
+nullable *void getspecific key_t
+int join pthread_t nullable **void
+
+int key_create *key_t pthreadfn
+int key_delete key_t
+
+int kill pthread_t int
+
+int mutexattr_init *mutexattr_t
+int mutexattr_destroy *mutexattr_t
+int mutexattr_gettype *mutexattr_t *int
+int mutexattr_settype *mutexattr_t int
+
+int mutex_destroy *mutex_t
+int mutex_init *mutex_t const *mutexattr_t
+int mutex_lock *mutex_t
+int mutex_timedlock *mutex_t const *rt::timespec
+int mutex_trylock *mutex_t
+int mutex_unlock *mutex_t
+
+int once *once_t pthreadfn
+
+int rwlock_destroy *rwlock_t
+int rwlock_init *rwlock_t const *rwlockattr_t
+int rwlock_rdlock *rwlock_t
+int rwlock_timedrdlock *rwlock_t const *rt::timespec
+int rwlock_timedwrlock *rwlock_t const *rt::timespec
+int rwlock_tryrdlock *rwlock_t
+int rwlock_trywrlock *rwlock_t
+int rwlock_unlock *rwlock_t
+int rwlock_wrlock *rwlock_t
+int rwlockattr_init *rwlockattr_t
+int rwlockattr_getpshared *rwlockattr_t *int
+int rwlockattr_setpshared *rwlockattr_t *int
+int rwlockattr_destroy *rwlockattr_t
+
+pthread_t self
+int setspecific key_t nullable *void
+int cancel pthread_t
+int setcancelstate int *int
+int setcanceltype int *int
+void testcancel
+int getprio pthread_t
+int setprio pthread_t int
+
+void pyield
+
+int mutexattr_getprioceiling *mutexattr_t *int
+int mutexattr_setprioceiling *mutexattr_t int
+
+int mutex_getprioceiling *mutex_t *int
+int mutex_setprioceiling *mutex_t int *int
+
+int mutexattr_getprotocol *mutexattr_t *int
+int mutexattr_setprotocol *mutexattr_t int
+
+int condattr_getclock *condattr_t *clockid_t
+int condattr_setclock *condattr_t clockid_t
+
+int attr_getinheritsched *attr_t *int
+int attr_getschedparam *attr_t *sched_param
+int attr_getschedpolicy *attr_t *int
+int attr_getscope *attr_t *int
+int attr_setinheritsched *attr_t int
+int attr_setschedparam *attr_t *sched_param
+int attr_setschedpolicy *attr_t int
+int attr_setscope *attr_t int
+
+int getschedparam *attr_t *int *sched_param
+int setschedparam *attr_t int *sched_param
+int getconcurrency
+int setconcurrency int
+
+int barrier_init *barrier_t *barrierattr_t uint
+int barrier_destroy *barrier_t
+int barrier_wait *barrier_t
+int barrierattr_init *barrierattr_t
+int barrierattr_destroy *barrierattr_t
+int barrierattr_getpshared *barrierattr_t *int
+int barrierattr_setpshared *barrierattr_t int
+
+int spin_init *spinlock_t int
+int spin_destroy *spinlock_t
+int spin_trylock *spinlock_t
+int spin_lock *spinlock_t
+int spin_unlock *spinlock_t
--- /dev/null
+++ b/fns.ha
@@ -1,0 +1,119 @@
+use rt;
+export @symbol("pthread_atfork") fn atfork(_: pthreadfn, _: pthreadfn, _: pthreadfn) int;
+
+export @symbol("pthread_attr_destroy") fn attr_destroy(_: *attr_t) int;
+export @symbol("pthread_attr_getstack") fn attr_getstack(_: *attr_t, _: nullable **void, _: *u64) int;
+export @symbol("pthread_attr_getstacksize") fn attr_getstacksize(_: const *attr_t, _: *u64) int;
+export @symbol("pthread_attr_getstackaddr") fn attr_getstackaddr(_: const *attr_t, _: *u64) int;
+export @symbol("pthread_attr_getguardsize") fn attr_getguardsize(_: const *attr_t, _: *u64) int;
+export @symbol("pthread_attr_getdetachstate") fn attr_getdetachstate(_: const *attr_t, _: *int) int;
+export @symbol("pthread_attr_init") fn attr_init(_: *attr_t) int;
+export @symbol("pthread_attr_setstacksize") fn attr_setstacksize(_: *attr_t, _: u64) int;
+export @symbol("pthread_attr_setstack") fn attr_setstack(_: *attr_t, _: nullable *void, _: *u64) int;
+export @symbol("pthread_attr_setstackaddr") fn attr_setstackaddr(_: *attr_t, _: nullable *void) int;
+export @symbol("pthread_attr_setguardsize") fn attr_setguardsize(_: *attr_t, _: u64) int;
+export @symbol("pthread_attr_setdetachstate") fn attr_setdetachstate(_: *attr_t, _: int) int;
+
+export @symbol("pthread_cleanup_pop") fn cleanup_pop(_: int) void;
+export @symbol("pthread_cleanup_push") fn cleanup_push(_: pthreadfn, _: nullable *void) void;
+
+export @symbol("pthread_condattr_destroy") fn condattr_destroy(_: *condattr_t) int;
+export @symbol("pthread_condattr_init") fn condattr_init(_: *condattr_t) int;
+
+export @symbol("pthread_cond_broadcast") fn cond_broadcast(_: *cond_t) int;
+export @symbol("pthread_cond_destroy") fn cond_destroy(_: *cond_t) int;
+export @symbol("pthread_cond_init") fn cond_init(_: *cond_t, _: const *condattr_t) int;
+export @symbol("pthread_cond_signal") fn cond_signal(_: *cond_t) int;
+export @symbol("pthread_cond_timedwait") fn cond_timedwait(_: *cond_t, _: *mutex_t, _: const *rt::timespec) int;
+export @symbol("pthread_cond_wait") fn cond_wait(_: *cond_t, _: *mutex_t) int;
+
+export @symbol("pthread_create") fn create(_: *pthread_t, _: const *attr_t, _: pthreadfn, _: nullable *void) int;
+export @symbol("pthread_detach") fn detach(_: pthread_t) int;
+export @symbol("pthread_equal") fn equal(_: pthread_t, _: pthread_t) int;
+export @symbol("pthread_exit") @noreturn fn exit(_: nullable *void) void;
+export @symbol("pthread_getspecific") fn getspecific(_: key_t) nullable *void;
+export @symbol("pthread_join") fn join(_: pthread_t, _: nullable **void) int;
+
+export @symbol("pthread_key_create") fn key_create(_: *key_t, _: pthreadfn) int;
+export @symbol("pthread_key_delete") fn key_delete(_: key_t) int;
+
+export @symbol("pthread_kill") fn kill(_: pthread_t, _: int) int;
+
+export @symbol("pthread_mutexattr_init") fn mutexattr_init(_: *mutexattr_t) int;
+export @symbol("pthread_mutexattr_destroy") fn mutexattr_destroy(_: *mutexattr_t) int;
+export @symbol("pthread_mutexattr_gettype") fn mutexattr_gettype(_: *mutexattr_t, _: *int) int;
+export @symbol("pthread_mutexattr_settype") fn mutexattr_settype(_: *mutexattr_t, _: int) int;
+
+export @symbol("pthread_mutex_destroy") fn mutex_destroy(_: *mutex_t) int;
+export @symbol("pthread_mutex_init") fn mutex_init(_: *mutex_t, _: const *mutexattr_t) int;
+export @symbol("pthread_mutex_lock") fn mutex_lock(_: *mutex_t) int;
+export @symbol("pthread_mutex_timedlock") fn mutex_timedlock(_: *mutex_t, _: const *rt::timespec) int;
+export @symbol("pthread_mutex_trylock") fn mutex_trylock(_: *mutex_t) int;
+export @symbol("pthread_mutex_unlock") fn mutex_unlock(_: *mutex_t) int;
+
+export @symbol("pthread_once") fn once(_: *once_t, _: pthreadfn) int;
+
+export @symbol("pthread_rwlock_destroy") fn rwlock_destroy(_: *rwlock_t) int;
+export @symbol("pthread_rwlock_init") fn rwlock_init(_: *rwlock_t, _: const *rwlockattr_t) int;
+export @symbol("pthread_rwlock_rdlock") fn rwlock_rdlock(_: *rwlock_t) int;
+export @symbol("pthread_rwlock_timedrdlock") fn rwlock_timedrdlock(_: *rwlock_t, _: const *rt::timespec) int;
+export @symbol("pthread_rwlock_timedwrlock") fn rwlock_timedwrlock(_: *rwlock_t, _: const *rt::timespec) int;
+export @symbol("pthread_rwlock_tryrdlock") fn rwlock_tryrdlock(_: *rwlock_t) int;
+export @symbol("pthread_rwlock_trywrlock") fn rwlock_trywrlock(_: *rwlock_t) int;
+export @symbol("pthread_rwlock_unlock") fn rwlock_unlock(_: *rwlock_t) int;
+export @symbol("pthread_rwlock_wrlock") fn rwlock_wrlock(_: *rwlock_t) int;
+export @symbol("pthread_rwlockattr_init") fn rwlockattr_init(_: *rwlockattr_t) int;
+export @symbol("pthread_rwlockattr_getpshared") fn rwlockattr_getpshared(_: *rwlockattr_t, _: *int) int;
+export @symbol("pthread_rwlockattr_setpshared") fn rwlockattr_setpshared(_: *rwlockattr_t, _: *int) int;
+export @symbol("pthread_rwlockattr_destroy") fn rwlockattr_destroy(_: *rwlockattr_t) int;
+
+export @symbol("pthread_self") fn self() pthread_t;
+export @symbol("pthread_setspecific") fn setspecific(_: key_t, _: nullable *void) int;
+export @symbol("pthread_cancel") fn cancel(_: pthread_t) int;
+export @symbol("pthread_setcancelstate") fn setcancelstate(_: int, _: *int) int;
+export @symbol("pthread_setcanceltype") fn setcanceltype(_: int, _: *int) int;
+export @symbol("pthread_testcancel") fn testcancel() void;
+export @symbol("pthread_getprio") fn getprio(_: pthread_t) int;
+export @symbol("pthread_setprio") fn setprio(_: pthread_t, _: int) int;
+
+export @symbol("pthread_pyield") fn pyield() void;
+
+export @symbol("pthread_mutexattr_getprioceiling") fn mutexattr_getprioceiling(_: *mutexattr_t, _: *int) int;
+export @symbol("pthread_mutexattr_setprioceiling") fn mutexattr_setprioceiling(_: *mutexattr_t, _: int) int;
+
+export @symbol("pthread_mutex_getprioceiling") fn mutex_getprioceiling(_: *mutex_t, _: *int) int;
+export @symbol("pthread_mutex_setprioceiling") fn mutex_setprioceiling(_: *mutex_t, _: int, _: *int) int;
+
+export @symbol("pthread_mutexattr_getprotocol") fn mutexattr_getprotocol(_: *mutexattr_t, _: *int) int;
+export @symbol("pthread_mutexattr_setprotocol") fn mutexattr_setprotocol(_: *mutexattr_t, _: int) int;
+
+export @symbol("pthread_condattr_getclock") fn condattr_getclock(_: *condattr_t, _: *clockid_t) int;
+export @symbol("pthread_condattr_setclock") fn condattr_setclock(_: *condattr_t, _: clockid_t) int;
+
+export @symbol("pthread_attr_getinheritsched") fn attr_getinheritsched(_: *attr_t, _: *int) int;
+export @symbol("pthread_attr_getschedparam") fn attr_getschedparam(_: *attr_t, _: *sched_param) int;
+export @symbol("pthread_attr_getschedpolicy") fn attr_getschedpolicy(_: *attr_t, _: *int) int;
+export @symbol("pthread_attr_getscope") fn attr_getscope(_: *attr_t, _: *int) int;
+export @symbol("pthread_attr_setinheritsched") fn attr_setinheritsched(_: *attr_t, _: int) int;
+export @symbol("pthread_attr_setschedparam") fn attr_setschedparam(_: *attr_t, _: *sched_param) int;
+export @symbol("pthread_attr_setschedpolicy") fn attr_setschedpolicy(_: *attr_t, _: int) int;
+export @symbol("pthread_attr_setscope") fn attr_setscope(_: *attr_t, _: int) int;
+
+export @symbol("pthread_getschedparam") fn getschedparam(_: *attr_t, _: *int, _: *sched_param) int;
+export @symbol("pthread_setschedparam") fn setschedparam(_: *attr_t, _: int, _: *sched_param) int;
+export @symbol("pthread_getconcurrency") fn getconcurrency() int;
+export @symbol("pthread_setconcurrency") fn setconcurrency(_: int) int;
+
+export @symbol("pthread_barrier_init") fn barrier_init(_: *barrier_t, _: *barrierattr_t, _: uint) int;
+export @symbol("pthread_barrier_destroy") fn barrier_destroy(_: *barrier_t) int;
+export @symbol("pthread_barrier_wait") fn barrier_wait(_: *barrier_t) int;
+export @symbol("pthread_barrierattr_init") fn barrierattr_init(_: *barrierattr_t) int;
+export @symbol("pthread_barrierattr_destroy") fn barrierattr_destroy(_: *barrierattr_t) int;
+export @symbol("pthread_barrierattr_getpshared") fn barrierattr_getpshared(_: *barrierattr_t, _: *int) int;
+export @symbol("pthread_barrierattr_setpshared") fn barrierattr_setpshared(_: *barrierattr_t, _: int) int;
+
+export @symbol("pthread_spin_init") fn spin_init(_: *spinlock_t, _: int) int;
+export @symbol("pthread_spin_destroy") fn spin_destroy(_: *spinlock_t) int;
+export @symbol("pthread_spin_trylock") fn spin_trylock(_: *spinlock_t) int;
+export @symbol("pthread_spin_lock") fn spin_lock(_: *spinlock_t) int;
+export @symbol("pthread_spin_unlock") fn spin_unlock(_: *spinlock_t) int;
--- /dev/null
+++ b/pthread.ha
@@ -1,0 +1,158 @@
+// 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,
+};
+
+fn thread_start(arg: *void) nullable *void = {
+	let tinfo: *thread_info = (arg: *thread_info);
+
+	fmt::printf("Thread {}\n", tinfo.thread_num)!;
+
+	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 tinfo: [4]thread_info = [thread_info { thread_id = null, thread_num = 0 }...];
+
+
+	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");
+		};
+
+		fmt::printf("Joined with thread {}...", tinfo[i].thread_num)!;
+	};
+
+};