Example #1
0
void
waitforkick(Round *r)
{
	int n;

	qlock(&r->lock);
	r->last = r->current;
	assert(r->current+1 == r->next);
	rwakeupall(&r->finish);
	while(!r->doanother)
		rsleep(&r->start);
	n = r->next++;
	r->current = n;
	r->doanother = 0;
	qunlock(&r->lock);
}
Example #2
0
File: proc.c Project: Shamar/harvey
void
unbreak(Proc *p)
{
	int b;

	qlock(&broken);
	for(b=0; b < broken.n; b++)
		if(broken.p[b] == p) {
			broken.n--;
			memmove(&broken.p[b], &broken.p[b+1],
					sizeof(Proc*)*(NBROKEN-(b+1)));
			ready(p);
			break;
		}
	qunlock(&broken);
}
Example #3
0
void
putbuf(Iobuf *p)
{

	if(canqlock(p))
		print("buffer not locked %Z(%lld)\n", p->dev, (Wideoff)p->addr);
	if(p->flags & Bimm) {
		if(!(p->flags & Bmod))
			print("imm and no mod %Z(%lld)\n",
				p->dev, (Wideoff)p->addr);
		if(!devwrite(p->dev, p->addr, p->iobuf))
			p->flags &= ~(Bmod|Bimm);
	}
	iobufunmap(p);
	qunlock(p);
}
Example #4
0
/*
 * main filesystem server loop.
 * entered by many processes.
 * they wait for message buffers and
 * then process them.
 */
void
serve(void *)
{
	int i;
	Chan *cp;
	Msgbuf *mb;

	for (;;) {
		qlock(&reflock);
		/* read 9P request from a network input process */
		mb = fs_recv(serveq, 0);
		assert(mb->magic == Mbmagic);
		/* fs kernel sets chan in /sys/src/fs/ip/il.c:/^getchan */
		cp = mb->chan;
		if (cp == nil)
			panic("serve: nil mb->chan");
		rlock(&cp->reflock);
		qunlock(&reflock);

		rlock(&mainlock);

		if (mb->data == nil)
			panic("serve: nil mb->data");
		/* better sniffing code in /sys/src/cmd/disk/kfs/9p12.c */
		if(cp->protocol == nil){
			/* do we recognise the protocol in this packet? */
			/* better sniffing code: /sys/src/cmd/disk/kfs/9p12.c */
			for(i = 0; fsprotocol[i] != nil; i++)
				if(fsprotocol[i](mb) != 0) {
					cp->protocol = fsprotocol[i];
					break;
				}
			if(cp->protocol == nil){
				print("no protocol for message\n");
				for(i = 0; i < 12; i++)
					print(" %2.2X", mb->data[i]);
				print("\n");
			}
		} else
			/* process the request, generate an answer and reply */
			cp->protocol(mb);

		mbfree(mb);
		runlock(&mainlock);
		runlock(&cp->reflock);
	}
}
Example #5
0
/*
 * allocate rest of mem
 * for io buffers.
 */
#define	HWIDTH	5	/* buffers per hash */
void
iobufinit(void)
{
	int32_t i;
	Iobuf *p, *q;
	Hiob *hp;

	i = conf.niobuf*RBUFSIZE;
	niob = i / (sizeof(Iobuf) + RBUFSIZE + sizeof(Hiob)/HWIDTH);
	nhiob = niob / HWIDTH;
	while(!prime(nhiob))
		nhiob++;
	if(chat)
		print("	%ld buffers; %ld hashes\n", niob, nhiob);
	hiob = ialloc(nhiob * sizeof(Hiob));
	hp = hiob;
	for(i=0; i<nhiob; i++) {
		lock(hp);
		unlock(hp);
		hp++;
	}
	p = ialloc(niob * sizeof(Iobuf));
	hp = hiob;
	for(i=0; i<niob; i++) {
		qlock(p);
		qunlock(p);
		if(hp == hiob)
			hp = hiob + nhiob;
		hp--;
		q = hp->link;
		if(q) {
			p->fore = q;
			p->back = q->back;
			q->back = p;
			p->back->fore = p;
		} else {
			hp->link = p;
			p->fore = p;
			p->back = p;
		}
		p->dev = devnone;
		p->addr = -1;
		p->xiobuf = ialloc(RBUFSIZE);
		p->iobuf = (char*)-1;
		p++;
	}
}
Example #6
0
ulong
procalarm(ulong time)
{
	Proc **l, *f;
	ulong when, old;

	if(up->alarm)
		old = tk2ms(up->alarm - MACHP(0)->ticks);
	else
		old = 0;
	if(time == 0) {
		up->alarm = 0;
		return old;
	}
	when = ms2tk(time)+MACHP(0)->ticks;

	qlock(&alarms);
	l = &alarms.head;
	for(f = *l; f; f = f->palarm) {
		if(up == f){
			*l = f->palarm;
			break;
		}
		l = &f->palarm;
	}

	up->palarm = 0;
	if(alarms.head) {
		l = &alarms.head;
		for(f = *l; f; f = f->palarm) {
			if(f->alarm > when) {
				up->palarm = f;
				*l = up;
				goto done;
			}
			l = &f->palarm;
		}
		*l = up;
	}
	else
		alarms.head = up;
done:
	up->alarm = when;
	qunlock(&alarms);

	return old;
}
Example #7
0
static void
pageouttext(int pgszi, int color)
{

	Proc *p;
	Pgsza *pa;
	int i, n, np, x;
	Segment *s;
	int prepaged;

	USED(color);
	pa = &pga.pgsza[pgszi];
	n = x = 0;
	prepaged = 0;

	/*
	 * Try first to steal text pages from non-prepaged processes,
	 * then from anyone.
	 */
Again:
	do{
		if((p = psincref(x)) == nil)
			break;
		np = 0;
		if(p->prepagemem == 0 || prepaged != 0)
		if(p->state != Dead && p->noswap == 0 && canqlock(&p->seglock)){
			for(i = 0; i < NSEG; i++){
				if((s = p->seg[i]) == nil)
					continue;
				if((s->type&SG_TYPE) == SG_TEXT)
					np = pageout(p, s);
			}
			qunlock(&p->seglock);
		}
		/*
		 * else process dead or locked or changing its segments
		 */
		psdecref(p);
		n += np;
		if(np > 0)
			DBG("pager: %d from proc #%d %#p\n", np, x, p);
		x++;
	}while(pa->freecount < Minpages);

	if(pa->freecount < Minpages && prepaged++ == 0)
		goto Again;
}
Example #8
0
/*
 * always called with cp->flock locked
 */
File*
newfp(Chan *cp)
{
	File *f, *e;

retry:
	lock(&suballoc.flock);
	f = suballoc.ffree;
	if(f != nil){
		suballoc.ffree = f->list;
		unlock(&suballoc.flock);
		f->list = 0;
		f->cp = cp;
		f->next = cp->flist;
		f->wpath = 0;
		f->tlock = 0;
		f->dslot = 0;
		f->doffset = 0;
		f->uid = 0;
		f->cuid = 0;
		cp->flist = f;
		return f;
	}
	unlock(&suballoc.flock);

	if(conf.nfile > Fmax){
		print("%d: out of files\n", cp->chan);
		return 0;
	}

	/*
	 *  create a few new files
	 */
	f = malloc(Finc*sizeof(*f));
	memset(f, 0, Finc*sizeof(*f));
	lock(&suballoc.flock);
	for(e = f+Finc; f < e; f++){
		qlock(f);
		qunlock(f);
		f->list = suballoc.ffree;
		suballoc.ffree = f;
	}
	conf.nfile += Finc;
	unlock(&suballoc.flock);
	goto retry;
}
Example #9
0
static Chan *
cecattach(char *spec)
{
	Chan *c;
	static QLock q;
	static int inited;

	qlock(&q);
	if(inited == 0){
		kproc("cectimer", cectimer, nil);
		inited++;
	}
	qunlock(&q);
	c = devattach(L'©', spec);
	c->qid.path = Qdir;
	return c;
}
Example #10
0
static Walkqid*
loopbackwalk(Chan *c, Chan *nc, char **name, int nname)
{
	Walkqid *wq;
	Loop *lb;

	wq = devwalk(c, nc, name, nname, nil, 0, loopbackgen);
	if(wq != nil && wq->clone != nil && wq->clone != c){
		lb = c->aux;
		qlock(lb);
		lb->ref++;
		if((c->flag & COPEN) && TYPE(c->qid.path) == Qdata)
			lb->link[ID(c->qid.path)].ref++;
		qunlock(lb);
	}
	return wq;
}
Example #11
0
void
addbroken(Proc *p)
{
	qlock(&broken);
	if(broken.n == NBROKEN) {
		ready(broken.p[0]);
		memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
		--broken.n;
	}
	broken.p[broken.n++] = p;
	qunlock(&broken);

	edfstop(up);
	p->state = Broken;
	p->psstate = nil;
	sched();
}
Example #12
0
void
usbfsdirdump(void)
{
	int i;

	qlock(&fslck);
	fprint(2, "%s: fs list: (%d used %d total)\n", argv0, fsused, nfs);
	for(i = 1; i < nfs; i++)
		if(fs[i] != nil) {
			if(fs[i]->dev != nil)
				fprint(2, "%s\t%s dev %#p refs %ld\n",
					argv0, fs[i]->name, fs[i]->dev, fs[i]->dev->Ref.ref);
			else
				fprint(2, "%s:\t%s\n", argv0, fs[i]->name);
		}
	qunlock(&fslck);
}
Example #13
0
static void
aoeinit(void)
{
	static int init;
	static QLock l;

	if(!canqlock(&l))
		return;
	if(init == 0){
		fmtinstall(L'æ', fmtæ);
		events.rp = events.wp = events.buf;
		kproc("aoesweep", aoesweepproc, nil);
		aoecfg();
		init = 1;
	}
	qunlock(&l);
}
Example #14
0
static int32_t
unionread(Chan *c, void *va, int32_t n)
{
	Proc *up = externup();
	int i;
	int32_t nr;
	Mhead *mh;
	Mount *mount;

	qlock(&c->umqlock);
	mh = c->umh;
	rlock(&mh->lock);
	mount = mh->mount;
	/* bring mount in sync with c->uri and c->umc */
	for(i = 0; mount != nil && i < c->uri; i++)
		mount = mount->next;

	nr = 0;
	while(mount != nil){
		/* Error causes component of union to be skipped */
		if(mount->to && !waserror()){
			if(c->umc == nil){
				c->umc = cclone(mount->to);
				c->umc = c->umc->dev->open(c->umc, OREAD);
			}

			nr = c->umc->dev->read(c->umc, va, n, c->umc->offset);
			c->umc->offset += nr;
			poperror();
		}
		if(nr > 0)
			break;

		/* Advance to next element */
		c->uri++;
		if(c->umc){
			cclose(c->umc);
			c->umc = nil;
		}
		mount = mount->next;
	}
	runlock(&mh->lock);
	qunlock(&c->umqlock);
	return nr;
}
Example #15
0
File: esp.c Project: npe9/harvey
/* called from icmp(v6) for unreachable hosts, time exceeded, etc. */
void
espadvise(Proto *esp, Block *bp, char *msg)
{
	Conv *c;
	Versdep vers;

	getverslens(pktipvers(esp->f, &bp), &vers);
	getpktspiaddrs(bp->rp, &vers);

	qlock(esp);
	c = convlookup(esp, vers.spi);
	if(c != nil) {
		qhangup(c->rq, msg);
		qhangup(c->wq, msg);
	}
	qunlock(esp);
	freeblist(bp);
}
Example #16
0
int
sendq(Queue *q, void *p)
{
	Qel *e;

	e = emalloc(sizeof(Qel));
	qlock(&q->lk);
	e->p = p;
	e->next = nil;
	if(q->head == nil)
		q->head = e;
	else
		q->tail->next = e;
	q->tail = e;
	rwakeup(&q->r);
	qunlock(&q->lk);
	return 0;
}
Example #17
0
int
cursoron(int dolock)
{
	int retry;

	if (dolock)
		lock(&cursor);
	if (canqlock(&drawlock)) {
		retry = 0;
		swcursorhide();
		swcursordraw();
		qunlock(&drawlock);
	} else
		retry = 1;
	if (dolock)
		unlock(&cursor);
	return retry;
}
Example #18
0
File: rudp.c Project: Shamar/harvey
static void
rudpstartackproc(Proto *rudp)
{
	Rudppriv *rpriv;
	char kpname[KNAMELEN];

	rpriv = rudp->priv;
	if(rpriv->ackprocstarted == 0){
		qlock(&rpriv->apl);
		if(rpriv->ackprocstarted == 0){
			snprint(kpname, sizeof kpname, "#I%drudpack",
				rudp->f->dev);
			kproc(kpname, relackproc, rudp);
			rpriv->ackprocstarted = 1;
		}
		qunlock(&rpriv->apl);
	}
}
Example #19
0
File: proc.c Project: npe9/harvey
/*
 * wire this proc to a machine
 */
void
procwired(Proc *p, int bm)
{
	Mach *m = machp();
	Proc *pp;
	int i;
	char nwired[MACHMAX];
	Mach *wm;

	if(bm < 0){
		/* pick a machine to wire to */
		memset(nwired, 0, sizeof(nwired));
		p->wired = 0;
		for(i=0; (pp = psincref(i)) != nil; i++){
			wm = pp->wired;
			if(wm && pp->pid)
				nwired[wm->machno]++;
			psdecref(pp);
		}
		bm = 0;
		for(i=0; i<sys->nmach; i++)
			if(nwired[i] < nwired[bm])
				bm = i;
	} else {
		/* use the virtual machine requested */
		bm = bm % sys->nmach;
	}

	p->wired = sys->machptr[bm];
	p->mp = p->wired;

	/*
	 * adjust our color to the new domain.
	 */
	if(m->externup == nil || p != m->externup)
		return;
	m->externup->color = corecolor(m->externup->mp->machno);
	qlock(&m->externup->seglock);
	for(i = 0; i < NSEG; i++)
		if(m->externup->seg[i])
			m->externup->seg[i]->color = m->externup->color;
	qunlock(&m->externup->seglock);
}
Example #20
0
static void pipeclose(struct chan *c)
{
	Pipe *p;

	p = c->aux;
	qlock(&p->qlock);

	if (c->flag & COPEN) {
		/*
		 *  closing either side hangs up the stream
		 */
		switch (NETTYPE(c->qid.path)) {
			case Qdata0:
				p->qref[0]--;
				if (p->qref[0] == 0) {
					qhangup(p->q[1], 0);
					qclose(p->q[0]);
				}
				break;
			case Qdata1:
				p->qref[1]--;
				if (p->qref[1] == 0) {
					qhangup(p->q[0], 0);
					qclose(p->q[1]);
				}
				break;
		}
	}

	/*
	 *  if both sides are closed, they are reusable
	 */
	if (p->qref[0] == 0 && p->qref[1] == 0) {
		qreopen(p->q[0]);
		qreopen(p->q[1]);
	}

	qunlock(&p->qlock);
	/*
	 *  free the structure on last close
	 */
	kref_put(&p->ref);
}
Example #21
0
void
putseg(Segment *s)
{
	Pte **pp, **emap;
	Image *i;

	if(s == 0)
		return;

	i = s->image;
	if(i != 0) {
		lock(i);
		lock(s);
		if(i->s == s && s->ref == 1)
			i->s = 0;
		unlock(i);
	}
	else
		lock(s);

	s->ref--;
	if(s->ref != 0) {
		unlock(s);
		return;
	}
	unlock(s);

	qlock(&s->lk);
	if(i)
		putimage(i);

	emap = &s->map[s->mapsize];
	for(pp = s->map; pp < emap; pp++)
		if(*pp)
			freepte(s, *pp);

	qunlock(&s->lk);
	if(s->map != s->ssegmap)
		free(s->map);
	if(s->profile != 0)
		free(s->profile);
	free(s);
}
Example #22
0
void
f_fstat(Chan *cp, Fcall *in, Fcall *ou)
{
	File *f;
	Iobuf *p;
	Dentry *d;
	int i;

	if(CHAT(cp)) {
		fprint(2, "c_fstat %d\n", cp->chan);
		fprint(2, "\tfid = %d\n", in->fid);
	}

	p = 0;
	f = filep(cp, in->fid, 0);
	if(!f) {
		ou->err = Efid;
		goto out;
	}
	p = getbuf(f->fs->dev, f->addr, Brd);
	d = getdir(p, f->slot);
	if(d == 0)
		goto out;

	print("name = %.*s\n", NAMELEN, d->name);
	print("uid = %d; gid = %d; muid = %d\n", d->uid, d->gid, d->muid);
	print("size = %lld; qid = %llux/%lux\n", (Wideoff)d->size,
		(Wideoff)d->qid.path, d->qid.version);
	print("atime = %ld; mtime = %ld\n", d->atime, d->mtime);
	print("dblock =");
	for(i=0; i<NDBLOCK; i++)
		print(" %lld", (Wideoff)d->dblock[i]);
	for (i = 0; i < NIBLOCK; i++)
		print("; iblocks[%d] = %lld", i, (Wideoff)d->iblocks[i]);
	print("\n\n");

out:
	if(p)
		putbuf(p);
	ou->fid = in->fid;
	if(f)
		qunlock(f);
}
Example #23
0
/*
 * read a clump of data
 * n is a hint of the size of the data, not including the header
 * make sure it won't run off the end, then return the number of bytes actually read
 */
uint32_t
readarena(Arena *arena, uint64_t aa, uint8_t *buf, int32_t n)
{
	DBlock *b;
	uint64_t a;
	uint32_t blocksize, off, m;
	int32_t nn;

	if(n == 0)
		return -1;

	qlock(&arena->lock);
	a = arena->size - arenadirsize(arena, arena->memstats.clumps);
	qunlock(&arena->lock);
	if(aa >= a){
		seterr(EOk, "reading beyond arena clump storage: clumps=%d aa=%lld a=%lld -1 clumps=%lld\n", arena->memstats.clumps, aa, a, arena->size - arenadirsize(arena, arena->memstats.clumps - 1));
		return -1;
	}
	if(aa + n > a)
		n = a - aa;

	blocksize = arena->blocksize;
	a = arena->base + aa;
	off = a & (blocksize - 1);
	a -= off;
	nn = 0;
	for(;;){
		b = getdblock(arena->part, a, OREAD);
		if(b == nil)
			return -1;
		m = blocksize - off;
		if(m > n - nn)
			m = n - nn;
		memmove(&buf[nn], &b->data[off], m);
		putdblock(b);
		nn += m;
		if(nn == n)
			break;
		off = 0;
		a += blocksize;
	}
	return n;
}
Example #24
0
char *
nbdgramlisten(NbName to, int (*deliver)(void *magic, NbDgram *s), void *magic)
{
	Listen *l;
	char *e;
	nbnametablefind(to, 1);
	e = startlistener();
	if (e)
		return e;
	l = nbemalloc(sizeof(Listen));
	nbnamecpy(l->to, to);
	l->deliver = deliver;
	l->magic = magic;
	qlock(&listens);
	l->next = listens.head;
	listens.head = l;
	qunlock(&listens);
	return 0;
}
Example #25
0
File: proc.c Project: npe9/harvey
void
addbroken(Proc *p)
{
	Mach *m = machp();
	qlock(&broken);
	if(broken.n == NBROKEN) {
		ready(broken.p[0]);
		memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
		--broken.n;
	}
	broken.p[broken.n++] = p;
	qunlock(&broken);

	stopac();
	edfstop(m->externup);
	p->state = Broken;
	p->psstate = 0;
	sched();
}
Example #26
0
void
swcursorclock(void)
{
	int x;
	if(!swenabled)
		return;
	if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
		return;

	x = splhi();
	if(swenabled)
	if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
	if(canqlock(&drawlock)){
		swcursorhide();
		swcursordraw();
		qunlock(&drawlock);
	}
	splx(x);
}
Example #27
0
File: esp.c Project: 8l/inferno
void
espadvise(Proto *esp, Block *bp, char *msg)
{
	Esphdr *h;
	Conv *c;
	ulong spi;

	h = (Esphdr*)(bp->rp);

	spi = nhgets(h->espspi);
	qlock(esp);
	c = convlookup(esp, spi);
	if(c != nil) {
		qhangup(c->rq, msg);
		qhangup(c->wq, msg);
	}
	qunlock(esp);
	freeblist(bp);
}
Example #28
0
static long
dsoaction(char** args, int nargs){
	long r = 0;

	// Comprobar que no introdujo '/'
	if(nargs > 1)
		validname(args[1],0);

	// Bloqueo al introducir nuevo dispositivos
	qlock(&fichLock);

	if(strcmp(args[0],"+") == 0){
		if(nargs > 3)
			r = dsoconcat(args,nargs);
		else{
			qunlock(&fichLock);
			error("#Q: USO: + <dest> <origen1> ... <origenN>");
		}
	}else
	if(strcmp(args[0],"p") == 0){
		if(nargs == 5)
			r = dsopart(args,nargs);
		else{
			qunlock(&fichLock);
			error("#Q: USO: p <dest> <offset> <size> <origen>");
		}
	}else
	if(strcmp(args[0],"m") == 0){
		if(nargs > 3)
			r = dsomirror(args,nargs);
		else{
			qunlock(&fichLock);
			error("#Q: USO: m <dest> <origen1> ... <origenN>");
		}
	}else
	if(strcmp(args[0],"i") == 0){
		if(nargs > 3)
			r = dsointerl(args,nargs);
		else{
			qunlock(&fichLock);
			error("#Q: USO: i <dest> <origen1> ... <origenN>");
		}
	}else{
		qunlock(&fichLock);
		error("#Q: Comando invalido");
	}

	qunlock(&fichLock);
	return r;
}
Example #29
0
void
killbig(char *why)
{
	int i;
	Segment *s;
	ulong l, max;
	Proc *p, *ep, *kp;

	max = 0;
	kp = 0;
	ep = procalloc.arena+conf.nproc;
	for(p = procalloc.arena; p < ep; p++) {
		if(p->state == Dead || p->kp)
			continue;
		l = 0;
		for(i=1; i<NSEG; i++) {
			s = p->seg[i];
			if(s != 0)
				l += s->top - s->base;
		}
		if(l > max && ((p->procmode&0222) || strcmp(eve, p->user)!=0)) {
			kp = p;
			max = l;
		}
	}

	print("%lud: %s killed: %s\n", kp->pid, kp->text, why);
	for(p = procalloc.arena; p < ep; p++) {
		if(p->state == Dead || p->kp)
			continue;
		if(p != kp && p->seg[BSEG] && p->seg[BSEG] == kp->seg[BSEG])
			p->procctl = Proc_exitbig;
	}
	kp->procctl = Proc_exitbig;
	for(i = 0; i < NSEG; i++) {
		s = kp->seg[i];
		if(s != 0 && canqlock(&s->lk)) {
			mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
			qunlock(&s->lk);
		}
	}
}
Example #30
0
void
sdadddevs(SDev *sdev)
{
	int i, j, id;
	SDev *next;

	for(; sdev; sdev=next){
		next = sdev->next;

		sdev->unit = (SDunit**)malloc(sdev->nunit * sizeof(SDunit*));
		sdev->unitflg = (int*)malloc(sdev->nunit * sizeof(int));
		if(sdev->unit == nil || sdev->unitflg == nil){
			print("sdadddevs: out of memory\n");
		giveup:
			free(sdev->unit);
			free(sdev->unitflg);
			if(sdev->ifc->clear)
				sdev->ifc->clear(sdev);
			free(sdev);
			continue;
		}
		id = sdindex(sdev->idno);
		if(id == -1){
			print("sdadddevs: bad id number %d (%C)\n", id, id);
			goto giveup;
		}
		qlock(&devslock);
		for(i=0; i<nelem(devs); i++){
			if(devs[j = (id+i)%nelem(devs)] == nil){
				sdev->idno = devletters[j];
				devs[j] = sdev;
				snprint(sdev->name, sizeof sdev->name, "sd%c", devletters[j]);
				break;
			}
		}
		qunlock(&devslock);
		if(i == nelem(devs)){
			print("sdadddevs: out of device letters\n");
			goto giveup;
		}
	}
}