📄 posix.c
字号:
/* * 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");}voidosinit(void){ if(pthread_key_create(&prdakey, 0)) panic("cannot pthread_key_create");}#undef pipevoidosnewproc(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);}voidosmsleep(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");}voidosyield(void){ sched_yield();}voidoserrstr(void){ char *p; if((p = strerror(errno)) != nil) strecpy(up->errstr, up->errstr+ERRMAX, p); else snprint(up->errstr, ERRMAX, "unix error %d", errno);}voidoserror(void){ oserrstr(); nexterror();}static void* tramp(void*);voidosproc(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;}voidprocsleep(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);}voidprocwakeup(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 openvoidrandominit(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 readulongrandomread(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 timelongseconds(void){ return time(0);}ulongticks(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;}longshowfilewrite(char *a, int n){ error("not implemented"); return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -