diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /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-x | sys/src/cmd/unix/drawterm/kern/posix.c | 225 |
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; +} |