various bug fixes
This commit is contained in:
parent
a796abef16
commit
1a8f27c350
14 changed files with 1236 additions and 9 deletions
|
|
@ -1308,7 +1308,7 @@ runproc(void *argvp)
|
|||
name[e-t] = 0;
|
||||
e = utfrrune(name, '/');
|
||||
if(e)
|
||||
strcpy(name, e+1);
|
||||
memmove(name, e+1, strlen(e+1)+1); /* strcpy but overlaps */
|
||||
strcat(name, " "); /* add blank here for ease in waittask */
|
||||
c->name = bytetorune(name, &c->nname);
|
||||
free(name);
|
||||
|
|
|
|||
|
|
@ -663,12 +663,12 @@ rowload(Row *row, char *file, int initing)
|
|||
break;
|
||||
wincleartag(w);
|
||||
textinsert(&w->tag, w->tag.file->b.nc, r+n+1, nr-(n+1), TRUE);
|
||||
free(r);
|
||||
if(ndumped >= 0){
|
||||
/* simplest thing is to put it in a file and load that */
|
||||
sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
|
||||
fd = create(buf, OWRITE|ORCLOSE, 0600);
|
||||
if(fd < 0){
|
||||
free(r);
|
||||
warning(nil, "can't create temp file: %r\n");
|
||||
goto Rescue2;
|
||||
}
|
||||
|
|
@ -679,6 +679,7 @@ rowload(Row *row, char *file, int initing)
|
|||
if(rune == '\n')
|
||||
line++;
|
||||
if(rune == (Rune)Beof){
|
||||
free(r);
|
||||
Bterm(bout);
|
||||
free(bout);
|
||||
close(fd);
|
||||
|
|
@ -696,6 +697,7 @@ rowload(Row *row, char *file, int initing)
|
|||
winsettag(w);
|
||||
}else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-')
|
||||
get(&w->body, nil, nil, FALSE, XXX, nil, 0);
|
||||
free(r);
|
||||
if(fontr){
|
||||
fontx(&w->body, nil, nil, 0, 0, fontr, nfontr);
|
||||
free(fontr);
|
||||
|
|
|
|||
|
|
@ -963,8 +963,11 @@ textshow(Text *t, uint q0, uint q1, int doselect)
|
|||
int nl;
|
||||
uint q;
|
||||
|
||||
if(t->what != Body)
|
||||
if(t->what != Body){
|
||||
if(doselect)
|
||||
textsetselect(t, q0, q1);
|
||||
return;
|
||||
}
|
||||
if(t->w!=nil && t->fr.maxlines==0)
|
||||
colgrow(t->col, t->w, 1);
|
||||
if(doselect)
|
||||
|
|
|
|||
167
src/lib9/rendez-futex.c
Normal file
167
src/lib9/rendez-futex.c
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
NAME
|
||||
rendezvous - user level process synchronization
|
||||
|
||||
SYNOPSIS
|
||||
ulong rendezvous(ulong tag, ulong value)
|
||||
|
||||
DESCRIPTION
|
||||
The rendezvous system call allows two processes to synchro-
|
||||
nize and exchange a value. In conjunction with the shared
|
||||
memory system calls (see segattach(2) and fork(2)), it
|
||||
enables parallel programs to control their scheduling.
|
||||
|
||||
Two processes wishing to synchronize call rendezvous with a
|
||||
common tag, typically an address in memory they share. One
|
||||
process will arrive at the rendezvous first; it suspends
|
||||
execution until a second arrives. When a second process
|
||||
meets the rendezvous the value arguments are exchanged
|
||||
between the processes and returned as the result of the
|
||||
respective rendezvous system calls. Both processes are
|
||||
awakened when the rendezvous succeeds.
|
||||
|
||||
The set of tag values which two processes may use to
|
||||
rendezvous-their tag space-is inherited when a process
|
||||
forks, unless RFREND is set in the argument to rfork; see
|
||||
fork(2).
|
||||
|
||||
If a rendezvous is interrupted the return value is ~0, so
|
||||
that value should not be used in normal communication.
|
||||
|
||||
* This simulates rendezvous with shared memory, pause, and SIGUSR1.
|
||||
*/
|
||||
|
||||
#include <u.h>
|
||||
typedef u32int u32;
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#define __user
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/futex.h>
|
||||
#include <libc.h>
|
||||
|
||||
enum
|
||||
{
|
||||
VOUSHASH = 257,
|
||||
};
|
||||
|
||||
typedef struct Vous Vous;
|
||||
struct Vous
|
||||
{
|
||||
Vous *link;
|
||||
Lock lk;
|
||||
int pid;
|
||||
ulong val;
|
||||
ulong tag;
|
||||
};
|
||||
|
||||
static Vous vouspool[2048];
|
||||
static int nvousused;
|
||||
static Vous *vousfree;
|
||||
static Vous *voushash[VOUSHASH];
|
||||
static Lock vouslock;
|
||||
|
||||
static Vous*
|
||||
getvous(void)
|
||||
{
|
||||
Vous *v;
|
||||
|
||||
if(vousfree){
|
||||
v = vousfree;
|
||||
vousfree = v->link;
|
||||
}else if(nvousused < nelem(vouspool))
|
||||
v = &vouspool[nvousused++];
|
||||
else
|
||||
abort();
|
||||
return v;
|
||||
}
|
||||
|
||||
static void
|
||||
putvous(Vous *v)
|
||||
{
|
||||
lock(&vouslock);
|
||||
v->link = vousfree;
|
||||
vousfree = v;
|
||||
unlock(&vouslock);
|
||||
}
|
||||
|
||||
static Vous*
|
||||
findvous(ulong tag, ulong val, int pid)
|
||||
{
|
||||
int h;
|
||||
Vous *v, **l;
|
||||
|
||||
lock(&vouslock);
|
||||
h = tag%VOUSHASH;
|
||||
for(l=&voushash[h], v=*l; v; l=&(*l)->link, v=*l){
|
||||
if(v->tag == tag){
|
||||
*l = v->link;
|
||||
unlock(&vouslock);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
v = getvous();
|
||||
v->pid = pid;
|
||||
v->link = voushash[h];
|
||||
v->val = val;
|
||||
v->tag = tag;
|
||||
lock(&v->lk);
|
||||
voushash[h] = v;
|
||||
unlock(&vouslock);
|
||||
return v;
|
||||
}
|
||||
|
||||
#define DBG 0
|
||||
ulong
|
||||
rendezvous(ulong tag, ulong val)
|
||||
{
|
||||
int me, vpid;
|
||||
ulong rval;
|
||||
Vous *v;
|
||||
|
||||
me = getpid();
|
||||
v = findvous(tag, val, me);
|
||||
if(v->pid == me){
|
||||
if(DBG)fprint(2, "pid is %d tag %lux, sleeping\n", me, tag);
|
||||
/*
|
||||
* No rendezvous partner was found; the next guy
|
||||
* through will find v and wake us, so we must go
|
||||
* to sleep.
|
||||
*
|
||||
* To go to sleep:
|
||||
* 1. disable USR1 signals.
|
||||
* 2. unlock v->lk (tells waker okay to signal us).
|
||||
* 3. atomically suspend and enable USR1 signals.
|
||||
*
|
||||
* The call to ignusr1() could be done once at
|
||||
* process creation instead of every time through rendezvous.
|
||||
*/
|
||||
v->val = val;
|
||||
unlock(&v->lk);
|
||||
while(sys_futex((u32int*)&v->tag, FUTEX_WAIT, tag, nil, nil) < 0 && errno==EINTR)
|
||||
;
|
||||
rval = v->val;
|
||||
if(DBG)fprint(2, "pid is %d, awake\n", me);
|
||||
putvous(v);
|
||||
}else{
|
||||
/*
|
||||
* Found someone to meet. Wake him:
|
||||
*
|
||||
* A. lock v->lk (waits for him to get to his step 2)
|
||||
* B. send a USR1
|
||||
*
|
||||
* He won't get the USR1 until he suspends, which
|
||||
* means it must wake him up (it can't get delivered
|
||||
* before he sleeps).
|
||||
*/
|
||||
vpid = v->pid;
|
||||
lock(&v->lk);
|
||||
rval = v->val;
|
||||
v->val = val;
|
||||
v->tag++;
|
||||
unlock(&v->lk);
|
||||
sys_futex((u32int*)&v->tag, FUTEX_WAKE, 1, nil, nil);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,13 @@ _allocmemimage(Rectangle r, u32int chan)
|
|||
return nil;
|
||||
|
||||
md->ref = 1;
|
||||
md->base = poolalloc(imagmem, (2+nw)*sizeof(u32int));
|
||||
/*
|
||||
* The first two words are the md and the callerpc.
|
||||
* Then nw words of data.
|
||||
* The final word lets the drawing routines be a little
|
||||
* sloppy about reading past the end of the block.
|
||||
*/
|
||||
md->base = poolalloc(imagmem, (2+nw+1)*sizeof(u32int));
|
||||
if(md->base == nil){
|
||||
free(md);
|
||||
return nil;
|
||||
|
|
|
|||
|
|
@ -86,19 +86,27 @@ fsunmount(Fsys *fs)
|
|||
void
|
||||
_fsdecref(Fsys *fs)
|
||||
{
|
||||
Fid *f, *next;
|
||||
Fid *f, **l, *next;
|
||||
|
||||
qlock(&fs->lk);
|
||||
--fs->ref;
|
||||
//fprint(2, "fsdecref %p to %d\n", fs, fs->ref);
|
||||
if(fs->ref == 0){
|
||||
close(fs->fd);
|
||||
/* trim the list down to just the first in each chunk */
|
||||
for(l=&fs->freefid; *l; ){
|
||||
if((*l)->fid%Fidchunk == 0)
|
||||
l = &(*l)->next;
|
||||
else
|
||||
*l = (*l)->next;
|
||||
}
|
||||
/* now free the list */
|
||||
for(f=fs->freefid; f; f=next){
|
||||
next = f->next;
|
||||
if(f->fid%Fidchunk == 0)
|
||||
free(f);
|
||||
free(f);
|
||||
}
|
||||
free(fs);
|
||||
return;
|
||||
}
|
||||
qunlock(&fs->lk);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,11 @@ nsmount(char *name, char *aname)
|
|||
fd = dial(addr, 0, 0, 0);
|
||||
if(fd < 0){
|
||||
werrstr("dial %s: %r", addr);
|
||||
free(addr);
|
||||
return nil;
|
||||
}
|
||||
free(addr);
|
||||
|
||||
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
||||
|
||||
fs = fsmount(fd, aname);
|
||||
|
|
|
|||
|
|
@ -174,8 +174,8 @@ _threadfdwait(int fd, int rw, ulong pc)
|
|||
|
||||
struct {
|
||||
Channel c;
|
||||
Alt *qentry[2];
|
||||
ulong x;
|
||||
Alt *qentry[2];
|
||||
} s;
|
||||
|
||||
threadfdwaitsetup();
|
||||
|
|
@ -214,11 +214,15 @@ threadsleep(int ms)
|
|||
struct {
|
||||
Channel c;
|
||||
ulong x;
|
||||
Alt *qentry[2];
|
||||
} 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);
|
||||
|
||||
sleepchan[nsleep] = &s.c;
|
||||
sleeptime[nsleep++] = p9nsec()/1000000+ms;
|
||||
recvul(&s.c);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue