123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /*
- * Posix generic OS implementation for drawterm.
- */
- #define _XOPEN_SOURCE 500
- #include <pthread.h>
- #include <time.h>
- #include <sys/time.h>
- #include <sys/select.h>
- #include <signal.h>
- #include <pwd.h>
- #include <errno.h>
- #include "u.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;
- }
|