tFix small bugs. - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit c4097c29512269f4547ebefb8abdc57a2892b479 | |
parent 2f2df5e02ef22c9727ae2b8269d5c76a061d296f | |
Author: rsc <devnull@localhost> | |
Date: Tue, 11 May 2004 17:51:27 +0000 | |
Fix small bugs. | |
Diffstat: | |
M include/thread.h | 2 +- | |
M src/cmd/ls.C | 2 ++ | |
M src/cmd/rc/plan9ish.c | 2 +- | |
M src/cmd/time.c | 7 +++++-- | |
M src/lib9/notify.c | 15 +++++++++++++-- | |
M src/libthread/386.c | 13 +++++++------ | |
M src/libthread/PowerMacintosh.c | 2 +- | |
M src/libthread/create.c | 1 + | |
M src/libthread/fdwait.c | 25 ++++++++++++++++++++++++- | |
M src/libthread/main.c | 12 ------------ | |
M src/libthread/mkfile | 1 + | |
M src/libthread/sched.c | 15 ++++++++++----- | |
M src/libthread/sun4u.c | 2 +- | |
M src/libthread/threadimpl.h | 6 ++++-- | |
14 files changed, 71 insertions(+), 34 deletions(-) | |
--- | |
diff --git a/include/thread.h b/include/thread.h | |
t@@ -121,7 +121,7 @@ Channel* threadwaitchan(void); | |
int tprivalloc(void); | |
void tprivfree(int); | |
void **tprivaddr(int); | |
-void yield(void); | |
+int yield(void); | |
long threadstack(void); | |
diff --git a/src/cmd/ls.C b/src/cmd/ls.C | |
t@@ -101,6 +101,8 @@ ls(char *s, int multi) | |
return 1; | |
} | |
if(db->qid.type&QTDIR && dflag==0){ | |
+ free(db); | |
+ db = nil; | |
output(); | |
fd = open(s, OREAD); | |
if(fd == -1) | |
diff --git a/src/cmd/rc/plan9ish.c b/src/cmd/rc/plan9ish.c | |
t@@ -71,7 +71,7 @@ void Vinit(void){ | |
for(s=*env;*s && *s!='(' && *s!='=';s++); | |
switch(*s){ | |
case '\0': | |
- pfmt(err, "rc: odd environment %q?\n", *env); | |
+ // pfmt(err, "rc: odd environment %q?\n", *env); | |
break; | |
case '=': | |
*s='\0'; | |
diff --git a/src/cmd/time.c b/src/cmd/time.c | |
t@@ -11,6 +11,7 @@ main(int argc, char *argv[]) | |
{ | |
int i; | |
Waitmsg *w; | |
+ vlong t0, t1; | |
long l; | |
char *p; | |
char err[ERRMAX]; | |
t@@ -20,6 +21,7 @@ main(int argc, char *argv[]) | |
exits("usage"); | |
} | |
+ t0 = nsec(); | |
switch(fork()){ | |
case -1: | |
error("fork"); | |
t@@ -37,8 +39,9 @@ main(int argc, char *argv[]) | |
loop: | |
w = wait(); | |
+ t1 = nsec(); | |
if(w == nil){ | |
- errstr(err, sizeof err); | |
+ rerrstr(err, sizeof err); | |
if(strcmp(err, "interrupted") == 0) | |
goto loop; | |
error("wait"); | |
t@@ -47,7 +50,7 @@ main(int argc, char *argv[]) | |
add("%ld.%.2ldu", l/1000, (l%1000)/10); | |
l = w->time[1]; | |
add("%ld.%.2lds", l/1000, (l%1000)/10); | |
- l = w->time[2]; | |
+ l = (t1-t0)/1000000; | |
add("%ld.%.2ldr", l/1000, (l%1000)/10); | |
add("\t"); | |
for(i=1; i<argc; i++){ | |
diff --git a/src/lib9/notify.c b/src/lib9/notify.c | |
t@@ -66,7 +66,7 @@ int | |
notify(void (*f)(void*, char*)) | |
{ | |
int i; | |
- struct sigaction sa; | |
+ struct sigaction sa, osa; | |
_p9uproc(0); | |
memset(&sa, 0, sizeof sa); | |
t@@ -77,11 +77,22 @@ notify(void (*f)(void*, char*)) | |
sa.sa_handler = notifysigf; | |
} | |
for(i=0; i<nelem(sigs); i++){ | |
+ /* | |
+ * If someone has already installed a handler, | |
+ * It's probably some ld preload nonsense, | |
+ * like pct (a SIGVTALRM-based profiler). | |
+ * Leave it alone. | |
+ */ | |
+ sigaction(sigs[i].sig, nil, &osa); | |
+ if(osa.sa_handler != SIG_DFL) | |
+ continue; | |
+ sigemptyset(&sa.sa_mask); | |
+ sigaddset(&sa.sa_mask, i); | |
if(sigs[i].restart) | |
sa.sa_flags |= SA_RESTART; | |
else | |
sa.sa_flags &= ~SA_RESTART; | |
- sigaction(sigs[i].sig, &sa, 0); | |
+ sigaction(sigs[i].sig, &sa, nil); | |
} | |
return 0; | |
} | |
diff --git a/src/libthread/386.c b/src/libthread/386.c | |
t@@ -15,7 +15,7 @@ launcher386(void (*f)(void *arg), void *arg) | |
p = _threadgetproc(); | |
t = p->thread; | |
- _threadstacklimit(t->stk); | |
+ _threadstacklimit(t->stk, t->stk+t->stksize); | |
(*f)(arg); | |
threadexits(nil); | |
t@@ -39,18 +39,19 @@ _threadinswitch(int enter) | |
USED(enter); | |
#ifdef USEVALGRIND | |
if(enter) | |
- VALGRIND_SET_STACK_LIMIT(0, 0, 1); | |
- else | |
VALGRIND_SET_STACK_LIMIT(0, 0, 0); | |
+ else | |
+ VALGRIND_SET_STACK_LIMIT(0, 0, 1); | |
#endif | |
} | |
void | |
-_threadstacklimit(void *addr) | |
+_threadstacklimit(void *bottom, void *top) | |
{ | |
- USED(addr); | |
+ USED(bottom); | |
+ USED(top); | |
#ifdef USEVALGRIND | |
- VALGRIND_SET_STACK_LIMIT(1, addr, 0); | |
+ VALGRIND_SET_STACK_LIMIT(1, bottom, top); | |
#endif | |
} | |
diff --git a/src/libthread/PowerMacintosh.c b/src/libthread/PowerMacintosh.c | |
t@@ -32,7 +32,7 @@ _threadinswitch(int enter) | |
} | |
void | |
-_threadstacklimit(void *addr) | |
+_threadstacklimit(void *addr, void *addr2) | |
{ | |
USED(addr); | |
} | |
diff --git a/src/libthread/create.c b/src/libthread/create.c | |
t@@ -24,6 +24,7 @@ newthread(Proc *p, void (*f)(void *arg), void *arg, uint sta… | |
if(stacksize < 32) | |
sysfatal("bad stacksize %d", stacksize); | |
t = _threadmalloc(sizeof(Thread), 1); | |
+ t->lastfd = -1; | |
s = _threadmalloc(stacksize, 0); | |
t->stk = (uchar*)s; | |
t->stksize = stacksize; | |
diff --git a/src/libthread/fdwait.c b/src/libthread/fdwait.c | |
t@@ -2,12 +2,13 @@ | |
#include <u.h> | |
#include <libc.h> | |
#include <thread.h> | |
- | |
+#include "threadimpl.h" | |
#include <errno.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#define debugpoll 0 | |
+static int noblocked[4096/32]; | |
#ifdef __APPLE__ | |
#include <sys/time.h> | |
t@@ -174,11 +175,15 @@ _threadfdwait(int fd, int rw, ulong pc) | |
struct { | |
Channel c; | |
+ Alt *qentry[2]; | |
ulong x; | |
} s; | |
threadfdwaitsetup(); | |
chaninit(&s.c, sizeof(ulong), 1); | |
+ s.c.qentry = (volatile Alt**)s.qentry; | |
+ s.c.nentry = 2; | |
+ memset(s.qentry, 0, sizeof s.qentry); | |
for(i=0; i<npoll; i++) | |
if(pfd[i].fd == -1) | |
break; | |
t@@ -223,7 +228,25 @@ threadsleep(int ms) | |
void | |
threadfdnoblock(int fd) | |
{ | |
+ Thread *t; | |
+ | |
+ if(fd<0) | |
+ return; | |
+ if(fd < 8*sizeof(int)*nelem(noblocked) | |
+ && (noblocked[fd/(8*sizeof(int))] & (1<<(fd%(8*sizeof(int)))))) | |
+ return; | |
+ t = _threadgetproc()->thread; | |
+ if(t && t->lastfd == fd) | |
+ return; | |
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK); | |
+ if(t) | |
+ t->lastfd = fd; | |
+ | |
+ /* We could lock this but we're probably single-threaded | |
+ * and the worst that will happen is we'll run fcntl | |
+ * a few more times. | |
+ */ | |
+ noblocked[fd/(8*sizeof(int))] |= 1<<(fd%(8*sizeof(int))); | |
} | |
long | |
diff --git a/src/libthread/main.c b/src/libthread/main.c | |
t@@ -32,24 +32,12 @@ _threaddie(int x) | |
exit(_threadexitsallstatus[0] ? 1 : 0); | |
} | |
-static void | |
-_nop(int x) | |
-{ | |
- USED(x); | |
-} | |
- | |
int | |
main(int argc, char **argv) | |
{ | |
Mainarg *a; | |
Proc *p; | |
- signal(SIGTERM, _threaddie); | |
- signal(SIGCHLD, _nop); | |
- signal(SIGALRM, _nop); | |
-// signal(SIGINFO, _threadstatus); | |
-// rfork(RFREND); | |
- | |
//_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0; | |
_systhreadinit(); | |
_qlockinit(_threadrendezvous); | |
diff --git a/src/libthread/mkfile b/src/libthread/mkfile | |
t@@ -59,6 +59,7 @@ asm-OpenBSD-386.$O: asm-FreeBSD-386.s | |
# sorry | |
VG=`test -d /home/rsc/pub/valgrind-debian && echo -DUSEVALGRIND` | |
+# VG= | |
CFLAGS=$CFLAGS $VG | |
diff --git a/src/libthread/sched.c b/src/libthread/sched.c | |
t@@ -171,7 +171,7 @@ needstack(int howmuch) | |
} | |
} | |
-void | |
+int | |
_sched(void) | |
{ | |
Proc *p; | |
t@@ -186,8 +186,8 @@ Resched: | |
// psstate(t->state), &t->sched, &p->sched); | |
if(_setlabel(&t->sched)==0) | |
_gotolabel(&p->sched); | |
- _threadstacklimit(t->stk); | |
- return; | |
+ _threadstacklimit(t->stk, t->stk+t->stksize); | |
+ return p->nsched++; | |
}else{ | |
t = runthread(p); | |
if(t == nil){ | |
t@@ -277,10 +277,15 @@ _threadidle(void) | |
unlock(&p->readylock); | |
} | |
-void | |
+int | |
yield(void) | |
{ | |
- _sched(); | |
+ Proc *p; | |
+ int nsched; | |
+ | |
+ p = _threadgetproc(); | |
+ nsched = p->nsched; | |
+ return _sched() - nsched; | |
} | |
void | |
diff --git a/src/libthread/sun4u.c b/src/libthread/sun4u.c | |
t@@ -46,7 +46,7 @@ _threadinswitch(int enter) | |
} | |
void | |
-_threadstacklimit(void *addr) | |
+_threadstacklimit(void *addr, void *addr2) | |
{ | |
USED(addr); | |
} | |
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h | |
t@@ -99,6 +99,7 @@ struct Thread | |
ulong userpc; | |
void* udata[NPRIV]; /* User per-thread data pointer */ | |
+ int lastfd; | |
}; | |
struct Execargs | |
t@@ -143,6 +144,7 @@ struct Proc | |
Waitmsg *waitmsg; | |
void* udata; /* User per-proc data pointer */ | |
+ int nsched; | |
}; | |
struct Pqueue { /* Proc queue */ | |
t@@ -169,7 +171,7 @@ void _freeproc(Proc*); | |
Proc* _newproc(void(*)(void*), void*, uint, char*, int, int); | |
int _procsplhi(void); | |
void _procsplx(int); | |
-void _sched(void); | |
+int _sched(void); | |
int _schedexec(Execargs*); | |
void _schedexecwait(void); | |
void _schedexit(Proc*); | |
t@@ -219,4 +221,4 @@ extern int _threadgetpid(void); | |
extern void _threadmemset(void*, int, int); | |
extern void _threaddebugmemset(void*, int, int); | |
extern int _threadprocs; | |
-extern void _threadstacklimit(void*); | |
+extern void _threadstacklimit(void*, void*); |