diff options
| -rw-r--r-- | CHANGES | 4 | ||||
| -rw-r--r-- | emu/Linux/os.c | 62 | ||||
| -rw-r--r-- | emu/MacOSX/os.c | 794 | ||||
| -rw-r--r-- | emu/port/devtk.c | 32 | ||||
| -rw-r--r-- | include/logfsos.h | 1 | ||||
| -rw-r--r-- | include/version.h | 2 | ||||
| -rw-r--r-- | libtk/coval.c | 5 |
7 files changed, 462 insertions, 438 deletions
@@ -1,3 +1,7 @@ +20100801 + libtk/coval.c - simplify vlong expression for some compilers [issue 216, mechiel] +20100727 + on Linux and MacOSX, look at faulting address to decide if it's dereference of nil 20100722 include/bio.h add varargck and repair resulting diagnostics in utils and limbo/ [issue 237, mechiel] 20100719 diff --git a/emu/Linux/os.c b/emu/Linux/os.c index 86be1389..8db05f22 100644 --- a/emu/Linux/os.c +++ b/emu/Linux/os.c @@ -8,11 +8,15 @@ #include <sys/wait.h> #include <sys/time.h> +#include <stdint.h> + #include "dat.h" #include "fns.h" #include "error.h" #include <fpuctl.h> +#include <raise.h> + /* glibc 2.3.3-NTPL messes up getpid() by trying to cache the result, so we'll do it ourselves */ #include <sys/syscall.h> #define getpid() syscall(SYS_getpid) @@ -96,7 +100,7 @@ kproc(char *name, void (*func)(void*), void *arg, int flags) p = newproc(); if(0) - print("start %s:%.8lx\n", name, p); + print("start %s:%#p\n", name, p); if(p == nil) { print("kproc(%s): no memory", name); return; @@ -151,50 +155,49 @@ kproc(char *name, void (*func)(void*), void *arg, int flags) return 0; } -/* - * TO DO: - * To get pc on trap, use sigaction instead of signal and - * examine its siginfo structure - */ - -/* static void -diserr(char *s, int pc) +sysfault(char *what, void *addr) { - char buf[ERRMAX]; + char buf[64]; - snprint(buf, sizeof(buf), "%s: pc=0x%lux", s, pc); + snprint(buf, sizeof(buf), "sys: %s%#p", what, addr); disfault(nil, buf); } -*/ static void -trapILL(int signo) +trapILL(int signo, siginfo_t *si, void *a) { USED(signo); - disfault(nil, "Illegal instruction"); + USED(a); + sysfault("illegal instruction pc=", si->si_addr); } -static void -trapBUS(int signo) +static int +isnilref(siginfo_t *si) { - USED(signo); - disfault(nil, "Bus error"); + return si != 0 && (si->si_addr == (void*)~(uintptr_t)0 || (uintptr_t)si->si_addr < 512); } static void -trapSEGV(int signo) +trapmemref(int signo, siginfo_t *si, void *a) { - USED(signo); - disfault(nil, "Segmentation violation"); + USED(a); /* ucontext_t*, could fetch pc in machine-dependent way */ + if(isnilref(si)) + disfault(nil, exNilref); + else if(signo == SIGBUS) + sysfault("bad address addr=", si->si_addr); /* eg, misaligned */ + else + sysfault("segmentation violation addr=", si->si_addr); } static void -trapFPE(int signo) +trapFPE(int signo, siginfo_t *si, void *a) { char buf[64]; + USED(signo); - snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux", getfsr()); + USED(a); + snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux pc=%#p", getfsr(), si->si_addr); disfault(nil, buf); } @@ -348,14 +351,15 @@ libinit(char *imod) signal(SIGINT, cleanexit); if(sflag == 0) { - act.sa_handler = trapBUS; - sigaction(SIGBUS, &act, nil); - act.sa_handler = trapILL; + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = trapILL; sigaction(SIGILL, &act, nil); - act.sa_handler = trapSEGV; - sigaction(SIGSEGV, &act, nil); - act.sa_handler = trapFPE; + act.sa_sigaction = trapFPE; sigaction(SIGFPE, &act, nil); + act.sa_sigaction = trapmemref; + sigaction(SIGBUS, &act, nil); + sigaction(SIGSEGV, &act, nil); + act.sa_flags &= ~SA_SIGINFO; } p = newproc(); diff --git a/emu/MacOSX/os.c b/emu/MacOSX/os.c index 3363b5ad..379cfac7 100644 --- a/emu/MacOSX/os.c +++ b/emu/MacOSX/os.c @@ -9,6 +9,9 @@ #include "fns.h" #include "error.h" +#include <raise.h> +#include <fpuctl.h> + #undef _POSIX_C_SOURCE #undef getwd @@ -48,275 +51,265 @@ static pthread_key_t prdakey; extern int dflag; -Proc * -getup(void) { - return (Proc *)pthread_getspecific(prdakey); +Proc* +getup(void) +{ + return pthread_getspecific(prdakey); } -/* Pthread version */ void pexit(char *msg, int t) { - Osenv *e; - Proc *p; - - USED(t); - USED(msg); - - lock(&procs.l); - p = up; - if(p->prev) - p->prev->next = p->next; - else - procs.head = p->next; - - if(p->next) - p->next->prev = p->prev; - else - procs.tail = p->prev; - unlock(&procs.l); - - if(0) - print("pexit: %s: %s\n", p->text, msg); - - e = p->env; - if(e != nil) { - closefgrp(e->fgrp); - closepgrp(e->pgrp); - closeegrp(e->egrp); - closesigs(e->sigs); - } - free(e->user); - free(p->prog); - free(p); - pthread_exit(0); + Osenv * e; + Proc * p; + + USED(t); + USED(msg); + + lock(&procs.l); + p = up; + if(p->prev) + p->prev->next = p->next; + else + procs.head = p->next; + + if(p->next) + p->next->prev = p->prev; + else + procs.tail = p->prev; + unlock(&procs.l); + + if(0) + print("pexit: %s: %s\n", p->text, msg); + + e = p->env; + if(e != nil) { + closefgrp(e->fgrp); + closepgrp(e->pgrp); + closeegrp(e->egrp); + closesigs(e->sigs); + } + free(e->user); + free(p->prog); + free(p); + pthread_exit(0); } -void -trapBUS(int signo) + + +static void +sysfault(char *what, void *addr) { - USED(signo); - disfault(nil, "Bus error"); + char buf[64]; + + snprint(buf, sizeof(buf), "sys: %s%#p", what, addr); + disfault(nil, buf); } -void -trapUSR1(int signo) +static void +trapILL(int signo, siginfo_t *si, void *a) { - USED(signo); - - if(up->type != Interp) /* Used to unblock pending I/O */ - return; - if(up->intwait == 0) /* Not posted so its a sync error */ - disfault(nil, Eintr); /* Should never happen */ - - up->intwait = 0; /* Clear it so the proc can continue */ + USED(signo); + USED(a); + sysfault("illegal instruction pc=", si->si_addr); } -void -trapILL(int signo) +static int +isnilref(siginfo_t *si) { - USED(signo); - disfault(nil, "Illegal instruction"); + return si != 0 && (si->si_addr == (void*)~(uintptr_t)0 || (uintptr_t)si->si_addr < 512); } -/* from geoff collyer's port */ -void -printILL(int sig, siginfo_t *siginfo, void *v) +static void +trapmemref(int signo, siginfo_t *si, void *a) { - USED(sig); - USED(v); - panic("Illegal instruction with code=%d at address=%x, opcode=%x.\n" - ,siginfo->si_code, siginfo->si_addr,*(char*)siginfo->si_addr); + USED(a); /* ucontext_t*, could fetch pc in machine-dependent way */ + if(isnilref(si)) + disfault(nil, exNilref); + else if(signo == SIGBUS) + sysfault("bad address addr=", si->si_addr); /* eg, misaligned */ + else + sysfault("segmentation violation addr=", si->si_addr); +} + +static void +trapFPE(int signo, siginfo_t *si, void *a) +{ + char buf[64]; + + USED(signo); + USED(a); + snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux pc=%#p", getfsr(), si->si_addr); + disfault(nil, buf); } void -trapSEGV(int signo) +trapUSR1(int signo) { USED(signo); - disfault(nil, "Segmentation violation"); + + if(up->type != Interp) /* Used to unblock pending I/O */ + return; + if(up->intwait == 0) /* Not posted so its a sync error */ + disfault(nil, Eintr); /* Should never happen */ + + up->intwait = 0; /* Clear it so the proc can continue */ } +/* from geoff collyer's port */ void -trapFPE(int signo) +printILL(int sig, siginfo_t *si, void *v) { - USED(signo); - disfault(nil, "Floating point exception"); + USED(sig); + USED(v); + panic("illegal instruction with code=%d at address=%p, opcode=%#x\n", + si->si_code, si->si_addr, *(uchar*)si->si_addr); } static void setsigs(void) { - struct sigaction act; + struct sigaction act; - memset(&act, 0 , sizeof(act)); - - /* - * For the correct functioning of devcmd in the - * face of exiting slaves - */ - signal(SIGPIPE, SIG_IGN); - if(signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, cleanexit); - - act.sa_handler=trapUSR1; - sigaction(SIGUSR1, &act, nil); - - if(sflag == 0) { - act.sa_handler = trapBUS; - sigaction(SIGBUS, &act, nil); - act.sa_handler = trapILL; - sigaction(SIGILL, &act, nil); - act.sa_handler = trapSEGV; - sigaction(SIGSEGV, &act, nil); - act.sa_handler = trapFPE; - sigaction(SIGFPE, &act, nil); - if(signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, cleanexit); - } else { - act.sa_sigaction = printILL; - act.sa_flags=SA_SIGINFO; - sigaction(SIGILL, &act, nil); - } + memset(&act, 0 , sizeof(act)); + + /* + * For the correct functioning of devcmd in the + * face of exiting slaves + */ + signal(SIGPIPE, SIG_IGN); + if(signal(SIGTERM, SIG_IGN) != SIG_IGN) + signal(SIGTERM, cleanexit); + + act.sa_handler = trapUSR1; + sigaction(SIGUSR1, &act, nil); + + if(sflag == 0) { + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = trapILL; + sigaction(SIGILL, &act, nil); + act.sa_sigaction = trapFPE; + sigaction(SIGFPE, &act, nil); + act.sa_sigaction = trapmemref; + sigaction(SIGBUS, &act, nil); + sigaction(SIGSEGV, &act, nil); + if(signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, cleanexit); + } else { + act.sa_sigaction = printILL; + act.sa_flags = SA_SIGINFO; + sigaction(SIGILL, &act, nil); + } } + + void * tramp(void *arg) { - Proc *p = arg; - p->sigid = (int)pthread_self(); - if(pthread_setspecific(prdakey, arg)) { - print("set specific data failed in tramp\n"); - pthread_exit(0); - } - p->func(p->arg); - pexit("{Tramp}", 0); - return NULL; + Proc *p = arg; + p->sigid = (int)pthread_self(); + if(pthread_setspecific(prdakey, arg)) { + print("set specific data failed in tramp\n"); + pthread_exit(0); + } + p->func(p->arg); + pexit("{Tramp}", 0); + return NULL; } int kproc(char *name, void (*func)(void*), void *arg, int flags) { - pthread_t thread; - Proc *p; - Pgrp *pg; - Fgrp *fg; - Egrp *eg; - - pthread_attr_t attr; - - p = newproc(); - if(p == nil) - panic("kproc: no memory"); - - if(flags & KPDUPPG) { - pg = up->env->pgrp; - incref(&pg->r); - p->env->pgrp = pg; - } - if(flags & KPDUPFDG) { - fg = up->env->fgrp; - incref(&fg->r); - p->env->fgrp = fg; - } - if(flags & KPDUPENVG) { - eg = up->env->egrp; - incref(&eg->r); - p->env->egrp = eg; - } - - p->env->uid = up->env->uid; - p->env->gid = up->env->gid; - kstrdup(&p->env->user, up->env->user); - - strcpy(p->text, name); - - p->func = func; - p->arg = arg; - - lock(&procs.l); - if(procs.tail != nil) { - p->prev = procs.tail; - procs.tail->next = p; - } else { - procs.head = p; - p->prev = nil; - } - procs.tail = p; - unlock(&procs.l); - - up->kid = p; - - if((pthread_attr_init(&attr))== -1) - panic("pthread_attr_init failed"); - - errno=0; - pthread_attr_setschedpolicy(&attr,SCHED_OTHER); - if(errno) - panic("pthread_attr_setschedpolicy failed"); - - pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - if(pthread_create(&thread, &attr, tramp, p)) - panic("thr_create failed\n"); - pthread_attr_destroy(&attr); - - return (int)thread; + pthread_t thread; + Proc * p; + Pgrp * pg; + Fgrp * fg; + Egrp * eg; + + pthread_attr_t attr; + + p = newproc(); + if(p == nil) + panic("kproc: no memory"); + + if(flags & KPDUPPG) { + pg = up->env->pgrp; + incref(&pg->r); + p->env->pgrp = pg; + } + if(flags & KPDUPFDG) { + fg = up->env->fgrp; + incref(&fg->r); + p->env->fgrp = fg; + } + if(flags & KPDUPENVG) { + eg = up->env->egrp; + incref(&eg->r); + p->env->egrp = eg; + } + + p->env->uid = up->env->uid; + p->env->gid = up->env->gid; + kstrdup(&p->env->user, up->env->user); + + strcpy(p->text, name); + + p->func = func; + p->arg = arg; + + lock(&procs.l); + if(procs.tail != nil) { + p->prev = procs.tail; + procs.tail->next = p; + } else { + procs.head = p; + p->prev = nil; + } + procs.tail = p; + unlock(&procs.l); + + up->kid = p; + + if(pthread_attr_init(&attr) == -1) + panic("pthread_attr_init failed"); + + errno = 0; + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + if(errno) + panic("pthread_attr_setschedpolicy failed"); + + pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + if(pthread_create(&thread, &attr, tramp, p)) + panic("thr_create failed\n"); + pthread_attr_destroy(&attr); + + return (int)thread; } int segflush(void *va, ulong len) { - kern_return_t err; - vm_machine_attribute_val_t value = MATTR_VAL_ICACHE_FLUSH; - - err = vm_machine_attribute( (vm_map_t)mach_task_self(), - (vm_address_t)va, - (vm_size_t)len, - MATTR_CACHE, - &value); - if (err != KERN_SUCCESS) { - print("segflush: failure (%d) address %lud\n", err, va); - } - return (int)err; -} - -/* from geoff collyer's port -invalidate instruction cache and write back data cache from a to a+n-1, -at least. + kern_return_t err; + vm_machine_attribute_val_t value = MATTR_VAL_ICACHE_FLUSH; -void -segflush(void *a, ulong n) -{ - ulong *p; - - // paranoia, flush the world - __asm__("isync\n\t" - "eieio\n\t" - : // no output - : - ); - // cache blocks are often eight words (32 bytes) long, sometimes 16 bytes. - // need to determine it dynamically? - for (p = (ulong *)((ulong)a & ~3UL); (char *)p < (char *)a + n; p++) - __asm__("dcbst 0,%0\n\t" // not dcbf, which writes back, then invalidates - "icbi 0,%0\n\t" - : // no output - : "ar" (p) - ); - __asm__("isync\n\t" - "eieio\n\t" - : // no output - : - ); -} -*/ + err = vm_machine_attribute( (vm_map_t)mach_task_self(), + (vm_address_t)va, + (vm_size_t)len, + MATTR_CACHE, + &value); + if(err != KERN_SUCCESS) + print("segflush: failure (%d) address %lud\n", err, va); + return (int)err; +} void oshostintr(Proc *p) { - pthread_kill((pthread_t)p->sigid, SIGUSR1); + pthread_kill((pthread_t)p->sigid, SIGUSR1); } static ulong erendezvous(void*, ulong); @@ -324,20 +317,20 @@ static ulong erendezvous(void*, ulong); void osblock(void) { - erendezvous(up, 0); + erendezvous(up, 0); } void osready(Proc *p) { - erendezvous(p, 0); + erendezvous(p, 0); } void oslongjmp(void *regs, osjmpbuf env, int val) { - USED(regs); - siglongjmp(env, val); + USED(regs); + siglongjmp(env, val); } struct termios tinit; @@ -345,129 +338,136 @@ struct termios tinit; static void termset(void) { - struct termios t; + struct termios t; - tcgetattr(0, &t); - tinit = t; - t.c_lflag &= ~(ICANON|ECHO|ISIG); - t.c_cc[VMIN] = 1; - t.c_cc[VTIME] = 0; - tcsetattr(0, TCSANOW, &t); + tcgetattr(0, &t); + tinit = t; + t.c_lflag &= ~(ICANON | ECHO | ISIG); + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + tcsetattr(0, TCSANOW, &t); } - + static void termrestore(void) { - tcsetattr(0, TCSANOW, &tinit); + tcsetattr(0, TCSANOW, &tinit); } void cleanexit(int x) { - USED(x); - - if(up->intwait) { - up->intwait = 0; - return; - } - - if(dflag == 0) - termrestore(); - - exit(0); + USED(x); + + if(up->intwait) { + up->intwait = 0; + return; + } + + if(dflag == 0) + termrestore(); + + exit(0); } + + void osreboot(char *file, char **argv) { - if(dflag == 0) - termrestore(); - execvp(file, argv); - panic("reboot failure"); + if(dflag == 0) + termrestore(); + execvp(file, argv); + panic("reboot failure"); } + + int gidnobody= -1, uidnobody= -1; void getnobody() { - struct passwd *pwd; - - if((pwd = getpwnam("nobody"))) { - uidnobody = pwd->pw_uid; - gidnobody = pwd->pw_gid; - } + struct passwd *pwd; + + if((pwd = getpwnam("nobody"))) { + uidnobody = pwd->pw_uid; + gidnobody = pwd->pw_gid; + } } -/* Pthread version */ static pthread_mutex_t rendezvouslock; static pthread_mutexattr_t *pthread_mutexattr_default = NULL; void libinit(char *imod) { - struct passwd *pw; - Proc *p; - char sys[64]; + struct passwd *pw; + Proc * p; + char sys[64]; - setsid(); - - // setup personality - gethostname(sys, sizeof(sys)); - kstrdup(&ossysname, sys); - getnobody(); - - if(dflag == 0) - termset(); + setsid(); - setsigs(); + // setup personality + gethostname(sys, sizeof(sys)); + kstrdup(&ossysname, sys); + getnobody(); - if(pthread_mutex_init(&rendezvouslock, pthread_mutexattr_default)) - panic("pthread_mutex_init"); + if(dflag == 0) + termset(); - if(pthread_key_create(&prdakey,NULL)) - print("key_create failed\n"); - - p = newproc(); - if(pthread_setspecific(prdakey, p)) - panic("set specific thread data failed\n"); - - pw = getpwuid(getuid()); - if(pw != nil) - kstrdup(&eve, pw->pw_name); - else - print("cannot getpwuid\n"); - - up->env->uid = getuid(); - up->env->gid = getgid(); + setsigs(); - emuinit(imod); + if(pthread_mutex_init(&rendezvouslock, pthread_mutexattr_default)) + panic("pthread_mutex_init"); + + if(pthread_key_create(&prdakey, NULL)) + print("key_create failed\n"); + + p = newproc(); + if(pthread_setspecific(prdakey, p)) + panic("set specific thread data failed\n"); + + pw = getpwuid(getuid()); + if(pw != nil) + kstrdup(&eve, pw->pw_name); + else + print("cannot getpwuid\n"); + + up->env->uid = getuid(); + up->env->gid = getgid(); + + emuinit(imod); } + + int readkbd(void) { - int n; - char buf[1]; - - n = read(0, buf, sizeof(buf)); - if(n < 0) - print("keyboard close (n=%d, %s)\n", n, strerror(errno)); - if(n <= 0) - pexit("keyboard thread", 0); - - switch(buf[0]) { - case '\r': - buf[0] = '\n'; - break; - case DELETE: - cleanexit(0); - break; - } - return buf[0]; + int n; + char buf[1]; + + n = read(0, buf, sizeof(buf)); + if(n < 0) + print("keyboard close (n=%d, %s)\n", n, strerror(errno)); + if(n <= 0) + pexit("keyboard thread", 0); + + switch(buf[0]) { + case '\r': + buf[0] = '\n'; + break; + case DELETE: + cleanexit(0); + break; + } + return buf[0]; } + + enum { NHLOG = 7, @@ -477,10 +477,10 @@ enum typedef struct Tag Tag; struct Tag { - void* tag; - ulong val; - pthread_cond_t cv; - Tag* next; + void* tag; + ulong val; + pthread_cond_t cv; + Tag* next; }; static Tag* ht[NHASH]; @@ -490,66 +490,66 @@ static Tag* ft; static ulong erendezvous(void *tag, ulong value) { - int h; - ulong rval; - Tag *t, **l, *f; - - h = (ulong)tag & (NHASH-1); - -// lock(&hlock); - pthread_mutex_lock(&rendezvouslock); - l = &ht[h]; - for(t = ht[h]; t; t = t->next) { - if(t->tag == tag) { - rval = t->val; - t->val = value; - t->tag = 0; - pthread_mutex_unlock(&rendezvouslock); -// unlock(&hlock); - if(pthread_cond_signal(&(t->cv))) - panic("pthread_cond_signal"); - return rval; - } - } - - t = ft; - if(t == 0) { - t = malloc(sizeof(Tag)); - if(t == nil) - panic("rendezvous: no memory"); - if(pthread_cond_init(&(t->cv), NULL)) { - print("pthread_cond_init (errno: %s) \n", strerror(errno)); - panic("pthread_cond_init"); - } - } else - ft = t->next; - - t->tag = tag; - t->val = value; - t->next = *l; - *l = t; -// pthread_mutex_unlock(&rendezvouslock); -// unlock(&hlock); - - while(t->tag != nil) - pthread_cond_wait(&(t->cv),&rendezvouslock); - -// pthread_mutex_lock(&rendezvouslock); -// lock(&hlock); - rval = t->val; - for(f = *l; f; f = f->next){ - if(f == t) { - *l = f->next; - break; - } - l = &f->next; - } - t->next = ft; - ft = t; - pthread_mutex_unlock(&rendezvouslock); -// unlock(&hlock); - - return rval; + int h; + ulong rval; + Tag * t, **l, *f; + + h = (ulong)tag & (NHASH - 1); + + // lock(&hlock); + pthread_mutex_lock(&rendezvouslock); + l = &ht[h]; + for(t = ht[h]; t; t = t->next) { + if(t->tag == tag) { + rval = t->val; + t->val = value; + t->tag = 0; + pthread_mutex_unlock(&rendezvouslock); + // unlock(&hlock); + if(pthread_cond_signal(&(t->cv))) + panic("pthread_cond_signal"); + return rval; + } + } + + t = ft; + if(t == 0) { + t = malloc(sizeof(Tag)); + if(t == nil) + panic("rendezvous: no memory"); + if(pthread_cond_init(&(t->cv), NULL)) { + print("pthread_cond_init (errno: %s) \n", strerror(errno)); + panic("pthread_cond_init"); + } + } else + ft = t->next; + + t->tag = tag; + t->val = value; + t->next = *l; + *l = t; + // pthread_mutex_unlock(&rendezvouslock); + // unlock(&hlock); + + while(t->tag != nil) + pthread_cond_wait(&(t->cv), &rendezvouslock); + + // pthread_mutex_lock(&rendezvouslock); + // lock(&hlock); + rval = t->val; + for(f = *l; f; f = f->next) { + if(f == t) { + *l = f->next; + break; + } + l = &f->next; + } + t->next = ft; + ft = t; + pthread_mutex_unlock(&rendezvouslock); + // unlock(&hlock); + + return rval; } /* @@ -558,18 +558,20 @@ erendezvous(void *tag, ulong value) long osmillisec(void) { - static long sec0 = 0, usec0; - struct timeval t; + static long sec0 = 0, usec0; + struct timeval t; - if(gettimeofday(&t, NULL)<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); + if(gettimeofday(&t, NULL) < 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); } + + /* * Return the time since the epoch in nanoseconds and microseconds * The epoch is defined at 1 Jan 1970 @@ -586,62 +588,64 @@ osnsec(void) vlong osusectime(void) { - struct timeval t; + struct timeval t; - gettimeofday(&t, nil); - return (vlong)t.tv_sec * 1000000 + t.tv_usec; + gettimeofday(&t, nil); + return (vlong)t.tv_sec * 1000000 + t.tv_usec; } + + int osmillisleep(ulong milsec) { - struct timespec time; - time.tv_sec = milsec / 1000; - time.tv_nsec = (milsec % 1000) * 1000000; - nanosleep(&time, nil); - return 0; + struct timespec time; + time.tv_sec = milsec / 1000; + time.tv_nsec = (milsec % 1000) * 1000000; + nanosleep(&time, nil); + return 0; } + + int limbosleep(ulong milsec) { - return osmillisleep(milsec); + return osmillisleep(milsec); } void osyield(void) { - pthread_yield_np(); - // sched_yield(); + pthread_yield_np(); } void ospause(void) { - for(;;) - pause(); + for(;;) + pause(); } void oslopri(void) { -// pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); - setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS,0)+4); +// pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param); + setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS,0)+4); } __typeof__(sbrk(0)) sbrk(int size) { - void *brk; - kern_return_t err; + void *brk; + kern_return_t err; - err = vm_allocate( (vm_map_t) mach_task_self(), + err = vm_allocate( (vm_map_t) mach_task_self(), (vm_address_t *)&brk, size, VM_FLAGS_ANYWHERE); - if (err != KERN_SUCCESS) - brk = (void*)-1; - - return brk; + if(err != KERN_SUCCESS) + brk = (void*)-1; + return brk; } diff --git a/emu/port/devtk.c b/emu/port/devtk.c index 6f31967b..a64f6dcb 100644 --- a/emu/port/devtk.c +++ b/emu/port/devtk.c @@ -4,8 +4,8 @@ #include <interp.h> -#include "image.h" -#include <memimage.h> +#include "draw.h" +#include <memdraw.h> #include <memlayer.h> #include <cursor.h> @@ -15,7 +15,9 @@ enum{ }; static -Dirtab tkdirtab[]={ +Dirtab tkdirtab[]= +{ + ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, "tkevents", {Qtkevents, 0}, 0, 0600, }; @@ -32,6 +34,9 @@ tkwiretapper(void *top, char *cmd, char *result, void *image, Rectangle *rp) int n; char *s, *e; +//fprint(2, "wiretap %p %q %q\n", top, cmd, result); + if(tkevents.eq == nil) + return; n = 12; if(cmd != nil) n += strlen(cmd)+2+1; @@ -71,6 +76,9 @@ tkwiretapper(void *top, char *cmd, char *result, void *image, Rectangle *rp) } if(tkevents.eq != nil) qbwrite(tkevents.eq, b); + else + freeb(b); + poperror(); qunlock(&tkevents.l); acquire(); } @@ -84,16 +92,16 @@ tkattach(char* spec) return devattach(L'τ', spec); } -static int -tkwalk(Chan* c, char* name) +static Walkqid* +tkwalk(Chan *c, Chan *nc, char **name, int nname) { - return devwalk(c, name, tkdirtab, nelem(tkdirtab), devgen); + return devwalk(c, nc, name, nname, tkdirtab, nelem(tkdirtab), devgen); } -static void -tkstat(Chan* c, char* db) +static int +tkstat(Chan *c, uchar *db, int n) { - devstat(c, db, tkdirtab, nelem(tkdirtab), devgen); + return devstat(c, db, n, tkdirtab, nelem(tkdirtab), devgen); } static Chan* @@ -134,9 +142,10 @@ static long tkread(Chan* c, void* a, long n, vlong offset) { USED(offset); - switch(c->qid.path & ~CHDIR){ - case Qdir: + if(c->qid.type & QTDIR) return devdirread(c, a, n, tkdirtab, nelem(tkdirtab), devgen); + + switch((ulong)c->qid.path){ case Qtkevents: return qread(tkevents.eq, a, n); default: @@ -162,7 +171,6 @@ Dev tkdevtab = { devinit, tkattach, // devdetach, - devclone, tkwalk, tkstat, tkopen, diff --git a/include/logfsos.h b/include/logfsos.h new file mode 100644 index 00000000..569ea280 --- /dev/null +++ b/include/logfsos.h @@ -0,0 +1 @@ +#include "lib9.h" diff --git a/include/version.h b/include/version.h index f783ac1f..ec6f9852 100644 --- a/include/version.h +++ b/include/version.h @@ -1 +1 @@ -#define VERSION "Fourth Edition (20100722)" +#define VERSION "Fourth Edition (20100801)" diff --git a/libtk/coval.c b/libtk/coval.c index c70a607e..196e50fd 100644 --- a/libtk/coval.c +++ b/libtk/coval.c @@ -228,6 +228,7 @@ tkcvsovalhit(TkCitem *i, Point p) TkCoval *o; int w, dx, dy; Rectangle d; + vlong v; o = TKobj(TkCoval, i); w = TKF2I(o->width)/2; @@ -244,5 +245,7 @@ tkcvsovalhit(TkCitem *i, Point p) dy *= dy; /* XXX can we do this nicely without overflow and without vlongs? */ - return (vlong)(p.x*p.x)*dy + (vlong)(p.y*p.y)*dx < (vlong)dx*dy; + v = (vlong)(p.x*p.x)*dy; + v += (vlong)(p.y*p.y)*dx; + return v < (vlong)dx*dy; } |
