summaryrefslogtreecommitdiff
path: root/sys/src/cmd/unix/drawterm/kern/posix.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/unix/drawterm/kern/posix.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/unix/drawterm/kern/posix.c')
-rwxr-xr-xsys/src/cmd/unix/drawterm/kern/posix.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/sys/src/cmd/unix/drawterm/kern/posix.c b/sys/src/cmd/unix/drawterm/kern/posix.c
new file mode 100755
index 000000000..069d6531f
--- /dev/null
+++ b/sys/src/cmd/unix/drawterm/kern/posix.c
@@ -0,0 +1,225 @@
+/*
+ * Posix generic OS implementation for drawterm.
+ */
+
+#include "u.h"
+
+#ifndef _XOPEN_SOURCE /* for Apple and OpenBSD; not sure if needed */
+#define _XOPEN_SOURCE 500
+#endif
+
+#include <pthread.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/select.h>
+#include <signal.h>
+#include <pwd.h>
+#include <errno.h>
+
+#include "lib.h"
+#include "dat.h"
+#include "fns.h"
+
+typedef struct Oproc Oproc;
+struct Oproc
+{
+ int nsleep;
+ int nwakeup;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+};
+
+static pthread_key_t prdakey;
+
+Proc*
+_getproc(void)
+{
+ void *v;
+
+ if((v = pthread_getspecific(prdakey)) == nil)
+ panic("cannot getspecific");
+ return v;
+}
+
+void
+_setproc(Proc *p)
+{
+ if(pthread_setspecific(prdakey, p) != 0)
+ panic("cannot setspecific");
+}
+
+void
+osinit(void)
+{
+ if(pthread_key_create(&prdakey, 0))
+ panic("cannot pthread_key_create");
+}
+
+#undef pipe
+void
+osnewproc(Proc *p)
+{
+ Oproc *op;
+ pthread_mutexattr_t attr;
+
+ op = (Oproc*)p->oproc;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
+ pthread_mutex_init(&op->mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ pthread_cond_init(&op->cond, 0);
+}
+
+void
+osmsleep(int ms)
+{
+ struct timeval tv;
+
+ tv.tv_sec = ms / 1000;
+ tv.tv_usec = (ms % 1000) * 1000; /* micro */
+ if(select(0, NULL, NULL, NULL, &tv) < 0)
+ panic("select");
+}
+
+void
+osyield(void)
+{
+ sched_yield();
+}
+
+void
+oserrstr(void)
+{
+ char *p;
+
+ if((p = strerror(errno)) != nil)
+ strecpy(up->errstr, up->errstr+ERRMAX, p);
+ else
+ snprint(up->errstr, ERRMAX, "unix error %d", errno);
+}
+
+void
+oserror(void)
+{
+ oserrstr();
+ nexterror();
+}
+
+static void* tramp(void*);
+
+void
+osproc(Proc *p)
+{
+ pthread_t pid;
+
+ if(pthread_create(&pid, nil, tramp, p)){
+ oserrstr();
+ panic("osproc: %r");
+ }
+ sched_yield();
+}
+
+static void*
+tramp(void *vp)
+{
+ Proc *p;
+
+ p = vp;
+ if(pthread_setspecific(prdakey, p))
+ panic("cannot setspecific");
+ (*p->fn)(p->arg);
+ /* BUG: leaks Proc */
+ pthread_setspecific(prdakey, 0);
+ pthread_exit(0);
+ return 0;
+}
+
+void
+procsleep(void)
+{
+ Proc *p;
+ Oproc *op;
+
+ p = up;
+ op = (Oproc*)p->oproc;
+ pthread_mutex_lock(&op->mutex);
+ op->nsleep++;
+ while(op->nsleep > op->nwakeup)
+ pthread_cond_wait(&op->cond, &op->mutex);
+ pthread_mutex_unlock(&op->mutex);
+}
+
+void
+procwakeup(Proc *p)
+{
+ Oproc *op;
+
+ op = (Oproc*)p->oproc;
+ pthread_mutex_lock(&op->mutex);
+ op->nwakeup++;
+ if(op->nwakeup == op->nsleep)
+ pthread_cond_signal(&op->cond);
+ pthread_mutex_unlock(&op->mutex);
+}
+
+int randfd;
+#undef open
+void
+randominit(void)
+{
+#ifdef USE_RANDOM
+ srandom(getpid()+fastticks(nil)+ticks());
+#else
+ if((randfd = open("/dev/urandom", OREAD)) < 0)
+ if((randfd = open("/dev/random", OREAD)) < 0)
+ panic("open /dev/random: %r");
+#endif
+}
+
+#undef read
+ulong
+randomread(void *v, ulong n)
+{
+#ifdef USE_RANDOM
+ int i;
+
+ for(i=0; i<n; i++)
+ ((uchar*)v)[i] = random();
+ return n;
+#else
+ int m;
+
+ if((m = read(randfd, v, n)) != n)
+ panic("short read from /dev/random: %d but %d", n, m);
+ return m;
+#endif
+}
+
+#undef time
+long
+seconds(void)
+{
+ return time(0);
+}
+
+ulong
+ticks(void)
+{
+ static long sec0 = 0, usec0;
+ struct timeval t;
+
+ if(gettimeofday(&t, nil) < 0)
+ return 0;
+ if(sec0 == 0){
+ sec0 = t.tv_sec;
+ usec0 = t.tv_usec;
+ }
+ return (t.tv_sec-sec0)*1000+(t.tv_usec-usec0+500)/1000;
+}
+
+long
+showfilewrite(char *a, int n)
+{
+ error("not implemented");
+ return -1;
+}