shithub: npe

Download patch

ref: c301ec771ed9f63937062178fb1d78d8773c8701
parent: de724d7023c52e335c82bd6f102bf24343c53240
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Fri Mar 19 07:05:07 EDT 2021

add pthread

diff: cannot open b/libnpe_pthread//null: file does not exist: 'b/libnpe_pthread//null'
--- a/README.md
+++ b/README.md
@@ -5,13 +5,19 @@
 *WIP*
 
 The project tries to provide a minimalistic (and mostly
-non-conformant) POSIX environment with several additional libraries
-(cut-down version of SDL2 from scratch for now) to ease up porting of
-software to 9front.  The goal is to be able to build and run
-non-native GUI software with very minimal changes, if any.
+non-conformant) POSIX environment with several additional libraries to
+ease up porting of software to 9front.  The goal is to be able to
+build and run non-native GUI software with very minimal changes, if
+any.
 
 Unlike APE, NPE is fully native and is not trying to hide any of the
 native Plan 9 APIs.
+
+## Status
+
+* Some POSIX stuff is available
+* SDL2 basics (video, audio, input, events)
+* pthread basics
 
 ## Using NPE
 
--- /dev/null
+++ b/include/npe/pthread.h
@@ -1,0 +1,42 @@
+#ifndef _npe_pthread_h_
+#define _npe_pthread_h_
+
+#pragma lib "libnpe_pthread.a"
+
+typedef struct npe_pthread_t npe_pthread_t;
+typedef struct pthread_attr_t pthread_attr_t;
+typedef struct pthread_cond_t pthread_cond_t;
+typedef struct pthread_mutex_t pthread_mutex_t;
+typedef struct pthread_once_t pthread_once_t;
+
+#pragma incomplete npe_pthread_t
+#pragma incomplete pthread_attr_t
+#pragma incomplete pthread_cond_t
+#pragma incomplete pthread_mutex_t
+#pragma incomplete pthread_once_t
+
+typedef npe_pthread_t* pthread_t;
+
+#define PTHREAD_ONCE_INIT {0}
+
+int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*f)(void *), void *arg);
+int pthread_join(pthread_t thread, void **retval);
+
+int pthread_attr_init(pthread_attr_t *const attr);
+int pthread_attr_destroy(pthread_attr_t *const attr);
+int pthread_attr_setstacksize(pthread_attr_t *const attr, int stack_size);
+
+int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
+
+int pthread_mutex_init(pthread_mutex_t *const mutex, const void *const attr);
+int pthread_mutex_destroy(pthread_mutex_t *const mutex);
+int pthread_mutex_lock(pthread_mutex_t *const mutex);
+int pthread_mutex_unlock(pthread_mutex_t *const mutex);
+
+int pthread_cond_init(pthread_cond_t *const cond, const void *const attr);
+int pthread_cond_destroy(pthread_cond_t *const cond);
+int pthread_cond_wait(pthread_cond_t *const cond, pthread_mutex_t *const mutex);
+int pthread_cond_signal(pthread_cond_t *const cond);
+int pthread_cond_broadcast(pthread_cond_t *const cond);
+
+#endif
--- /dev/null
+++ b/libnpe_pthread/_pthread.h
@@ -1,0 +1,27 @@
+#include <npe.h>
+#include <pthread.h>
+
+struct pthread_attr_t {
+    unsigned stack_size;
+};
+
+struct pthread_cond_t {
+    Rendez;
+    QLock lock;
+};
+
+struct pthread_once_t {
+	QLock;
+	int done;
+};
+
+struct pthread_mutex_t {
+	QLock;
+};
+
+struct npe_pthread_t {
+    void *waitchan;
+    void *(*func)(void*);
+    void *arg;
+    int pid;
+};
--- /dev/null
+++ b/libnpe_pthread/mkfile
@@ -1,0 +1,32 @@
+</$objtype/mkfile
+
+LIB=/$objtype/lib/libnpe_pthread.a
+CFLAGS=$CFLAGS -p -I../include/npe -D__plan9__ -D__${objtype}__
+
+HFILES=\
+	_pthread.h\
+
+OFILES=\
+	pthread_attr_destroy.$O\
+	pthread_attr_init.$O\
+	pthread_attr_setstacksize.$O\
+	pthread_cond_broadcast.$O\
+	pthread_cond_destroy.$O\
+	pthread_cond_init.$O\
+	pthread_cond_signal.$O\
+	pthread_cond_wait.$O\
+	pthread_create.$O\
+	pthread_join.$O\
+	pthread_mutex_destroy.$O\
+	pthread_mutex_init.$O\
+	pthread_mutex_lock.$O\
+	pthread_mutex_unlock.$O\
+	pthread_once.$O\
+
+UPDATE=\
+	mkfile\
+	$HFILES\
+	${OFILES:%.$O=%.c}\
+	${LIB:/$objtype/%=/386/%}\
+
+</sys/src/cmd/mksyslib
--- /dev/null
+++ b/libnpe_pthread/pthread_attr_destroy.c
@@ -1,0 +1,8 @@
+#include "_pthread.h"
+
+int
+pthread_attr_destroy(pthread_attr_t *const attr)
+{
+	USED(attr);
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_attr_init.c
@@ -1,0 +1,8 @@
+#include "_pthread.h"
+
+int
+pthread_attr_init(pthread_attr_t *const attr)
+{
+    attr->stack_size = 0;
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_attr_setstacksize.c
@@ -1,0 +1,8 @@
+#include "_pthread.h"
+
+int
+pthread_attr_setstacksize(pthread_attr_t *const attr, const int stack_size)
+{
+    attr->stack_size = stack_size;
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_cond_broadcast.c
@@ -1,0 +1,11 @@
+#include "_pthread.h"
+
+int
+pthread_cond_broadcast(pthread_cond_t *const cond)
+{
+	qlock(cond->l);
+	rwakeupall(cond);
+	qunlock(cond->l);
+
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_cond_destroy.c
@@ -1,0 +1,8 @@
+#include "_pthread.h"
+
+int
+pthread_cond_destroy(pthread_cond_t *const cond)
+{
+	USED(cond);
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_cond_init.c
@@ -1,0 +1,11 @@
+#include "_pthread.h"
+
+int
+pthread_cond_init(pthread_cond_t *const cond, const void *const attr)
+{
+	USED(attr);
+    memset(cond, 0, sizeof(*cond));
+    cond->l = &cond->lock;
+
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_cond_signal.c
@@ -1,0 +1,11 @@
+#include "_pthread.h"
+
+int
+pthread_cond_signal(pthread_cond_t *const cond)
+{
+	qlock(cond->l);
+	rwakeup(cond);
+	qunlock(cond->l);
+
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_cond_wait.c
@@ -1,0 +1,13 @@
+#include "_pthread.h"
+
+int
+pthread_cond_wait(pthread_cond_t *const cond, pthread_mutex_t *const mutex)
+{
+	qlock(cond->l);
+	qunlock(mutex);
+	rsleep(cond);
+	qunlock(cond->l);
+	qlock(mutex);
+
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_create.c
@@ -1,0 +1,36 @@
+#include "_pthread.h"
+
+static void
+thread(void *x)
+{
+	pthread_t t;
+	void *p;
+
+	t = x;
+	p = t->func(t->arg);
+	send(t->waitchan, p);
+	chanfree(t->waitchan);
+	free(t);
+
+	threadexits(nil);
+}
+
+int
+pthread_create(pthread_t *pt, const pthread_attr_t *attr, void *(*func)(void*), void *arg)
+{
+	npe_pthread_t *t;
+	int stacksz;
+
+	stacksz = attr == nil ? 0 : attr->stack_size;
+	if(stacksz == 0)
+		stacksz = mainstacksize;
+
+	t = calloc(1, sizeof(npe_pthread_t));
+	t->waitchan = chancreate(sizeof(void*), 0);
+	t->func = func;
+	t->arg = arg;
+	t->pid = proccreate(thread, t, stacksz);
+	*pt = t;
+
+	return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_join.c
@@ -1,0 +1,10 @@
+#include "_pthread.h"
+
+int
+pthread_join(pthread_t pt, void **res)
+{
+	if(pt->waitchan != nil)
+		recv(pt->waitchan, res);
+
+	return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_mutex_destroy.c
@@ -1,0 +1,8 @@
+#include "_pthread.h"
+
+int
+pthread_mutex_destroy(pthread_mutex_t *const mutex)
+{
+	USED(mutex);
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_mutex_init.c
@@ -1,0 +1,10 @@
+#include "_pthread.h"
+
+int
+pthread_mutex_init(pthread_mutex_t *const mutex, const void *const attr)
+{
+	USED(attr);
+	memset(mutex, 0, sizeof(*mutex));
+
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_mutex_lock.c
@@ -1,0 +1,8 @@
+#include "_pthread.h"
+
+int
+pthread_mutex_lock(pthread_mutex_t *const mutex)
+{
+    qlock(mutex);
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_mutex_unlock.c
@@ -1,0 +1,8 @@
+#include "_pthread.h"
+
+int
+pthread_mutex_unlock(pthread_mutex_t *const mutex)
+{
+    qunlock(mutex);
+    return 0;
+}
--- /dev/null
+++ b/libnpe_pthread/pthread_once.c
@@ -1,0 +1,22 @@
+#include <npe.h>
+#include <pthread.h>
+#include "_pthread.h"
+
+enum {
+	Done = 13666,
+};
+
+int
+pthread_once(pthread_once_t *once, void (*init_routine)(void))
+{
+	if(once->done != Done){
+		qlock(once);
+		if(once->done != Done){
+			once->done = Done;
+			init_routine();
+		}
+		qunlock(once);
+	}
+
+	return 0;
+}
--- a/mkfile
+++ b/mkfile
@@ -2,6 +2,7 @@
 
 LIBS=\
 	libnpe\
+	libnpe_pthread\
 	libnpe_sdl2\
 
 all clean:VQ: