示例#1
0
文件: debug.c 项目: aahud/harvey
void
_threaddebug(uint32_t flag, char *fmt, ...)
{
	char buf[128];
	va_list arg;
	Fmt f;
	Proc *p;

	if((_threaddebuglevel&flag) == 0)
		return;

	fmtfdinit(&f, 2, buf, sizeof buf);

	p = _threadgetproc();
	if(p==nil)
		fmtprint(&f, "noproc ");
	else if(p->thread)
		fmtprint(&f, "%d.%d ", p->pid, p->thread->id);
	else
		fmtprint(&f, "%d._ ", p->pid);

	va_start(arg, fmt);
	fmtvprint(&f, fmt, arg);
	va_end(arg);
	fmtprint(&f, "\n");
	fmtfdflush(&f);
}
示例#2
0
文件: note.c 项目: dancrossnyc/harvey
void
_threadnote(void *v, char *s)
{
	Proc *p;
	Note *n;

	_threaddebug(DBGNOTE, "Got note %s", s);
//	if(strncmp(s, "sys:", 4) == 0)
//		noted(NDFLT);

//	if(_threadexitsallstatus){
//		_threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
//		_exits(_threadexitsallstatus);
//	}

	if(strcmp(s, "threadint")==0)
		noted(NCONT);

	p = _threadgetproc();
	if(p == nil)
		noted(NDFLT);

	for(n=notes; n<enotes; n++)
		if(canlock(&n->inuse))
			break;
	if(n==enotes)
		sysfatal("libthread: too many delayed notes");
	utfecpy(n->s, n->s+ERRMAX, s);
	n->proc = p;
	p->pending = 1;
	if(!p->splhi)
		delayednotes(p, v);
	noted(NCONT);
}
示例#3
0
文件: id.c 项目: aahud/harvey
int
threadpid(int id)
{
	int pid;
	Proc *p;
	Thread *t;

	if (id < 0)
		return -1;
	if (id == 0)
		return _threadgetproc()->pid;
	lock(&_threadpq.lock);
	for (p = _threadpq.head; p; p = p->next){
		lock(&p->lock);
		for (t = p->threads.head; t; t = t->nextt)
			if (t->id == id){
				pid = p->pid;
				unlock(&p->lock);
				unlock(&_threadpq.lock);
				return pid;
			}
		unlock(&p->lock);
	}
	unlock(&_threadpq.lock);
	return -1;
}
示例#4
0
文件: sched.c 项目: bhanug/harvey
void
_sched(void)
{
	Proc *p;
	Thread *t;

Resched:
	p = _threadgetproc();
	if((t = p->thread) != nil){
		needstack(128);
		_threaddebug(DBGSCHED, "pausing, state=%s", psstate(t->state));
		if(setjmp(t->sched)==0)
			longjmp(p->sched, 1);
		return;
	}else{
		t = runthread(p);
		if(t == nil){
			_threaddebug(DBGSCHED, "all threads gone; exiting");
			_schedexit(p);
		}
		_threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id);
		p->thread = t;
		if(t->moribund){
			_threaddebug(DBGSCHED, "%d.%d marked to die");
			goto Resched;
		}
		t->state = Running;
		t->nextstate = Ready;
		longjmp(t->sched, 1);
	}
}
示例#5
0
文件: main.c 项目: npe9/harvey
void
_schedexecwait(void)
{
	int pid;
	Channel *c;
	Proc *p;
	Thread *t;
	Waitmsg *w;

	p = _threadgetproc();
	t = p->thread;
	pid = t->ret;
	_threaddebug(DBGEXEC, "_schedexecwait %d", t->ret);

	rfork(RFCFDG);
	for(;;){
		w = wait();
		if(w == nil)
			break;
		if(w->pid == pid)
			break;
		free(w);
	}
	if(w != nil){
		if((c = _threadwaitchan) != nil)
			sendp(c, w);
		else
			free(w);
	}
	threadexits("procexec");
}
示例#6
0
文件: note.c 项目: dancrossnyc/harvey
int
threadnotify(int (*f)(void*, char*), int in)
{
	int i, topid;
	int (*from)(void*, char*), (*to)(void*, char*);

	if(in){
		from = nil;
		to = f;
		topid = _threadgetproc()->pid;
	}else{
		from = f;
		to = nil;
		topid = 0;
	}
	lock(&onnotelock);
	for(i=0; i<NFN; i++)
		if(onnote[i]==from){
			onnote[i] = to;
			onnotepid[i] = topid;
			break;
		}
	unlock(&onnotelock);
	return i<NFN;
}
示例#7
0
文件: id.c 项目: aahud/harvey
char*
threadgetname(void)
{
	Proc *p;

	if((p = _threadgetproc()) && p->thread)
		return p->thread->cmdname;
	return nil;
}
示例#8
0
文件: note.c 项目: dancrossnyc/harvey
int
_procsplhi(void)
{
	int s;
	Proc *p;

	p = _threadgetproc();
	s = p->splhi;
	p->splhi = 1;
	return s;
}
示例#9
0
文件: id.c 项目: aahud/harvey
int
threadsetgrp(int ng)
{
	int og;
	Thread *t;

	t = _threadgetproc()->thread;
	og = t->grp;
	t->grp = ng;
	return og;
}
示例#10
0
文件: note.c 项目: dancrossnyc/harvey
void
_procsplx(int s)
{
	Proc *p;

	p = _threadgetproc();
	p->splhi = s;
	if(s)
		return;
	if(p->pending)
		delayednotes(p, nil);
}
示例#11
0
文件: create.c 项目: keedon/harvey
int
procrfork(void (*f)(void *), void *arg, uint stacksize, int rforkflag)
{
	Proc *p;
	int id;

	p = _threadgetproc();
	assert(p->newproc == nil);
	p->newproc = _newproc(f, arg, stacksize, nil, p->thread->grp, rforkflag);
	id = p->newproc->threads.head->id;
	_sched();
	return id;
}
示例#12
0
文件: exit.c 项目: CoryXie/nix-os
void
threadexits(char *exitstr)
{
	Proc *p;
	Thread *t;

	p = _threadgetproc();
	t = p->thread;
	t->moribund = 1;
	if(exitstr==nil)
		exitstr="";
	utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
	_sched();
}
示例#13
0
文件: debug.c 项目: aahud/harvey
void
_threadassert(char *s)
{
	char buf[256];
	int n;
	Proc *p;

	p = _threadgetproc();
	if(p && p->thread)
		n = sprint(buf, "%d.%d ", p->pid, p->thread->id);
	else
		n = 0;
	snprint(buf+n, sizeof(buf)-n, "%s: assertion failed\n", s);
	write(2, buf, strlen(buf));
	abort();
}
示例#14
0
文件: sched.c 项目: bhanug/harvey
void
needstack(int n)
{
	int x;
	Proc *p;
	Thread *t;
	
	p = _threadgetproc();
	t = p->thread;
	
	if((uint8_t*)&x - n < (uint8_t*)t->stk){
		fprint(2, "%s %lud: &x=%p n=%d t->stk=%p\n",
			argv0, _tos->pid, &x, n, t->stk);
		fprint(2, "%s %lud: stack overflow\n", argv0, _tos->pid);
		abort();
	}
}
示例#15
0
文件: id.c 项目: aahud/harvey
void
threadsetname(char *fmt, ...)
{
	int fd;
	char buf[128];
	va_list arg;
	Proc *p;
	Thread *t;

	p = _threadgetproc();
	t = p->thread;
	if (t->cmdname)
		free(t->cmdname);
	va_start(arg, fmt);
	t->cmdname = vsmprint(fmt, arg);
	va_end(arg);
	if(t->cmdname && p->nthreads == 1){
		snprint(buf, sizeof buf, "#p/%lu/args", _tos->pid); //getpid());
		if((fd = open(buf, OWRITE)) >= 0){
			write(fd, t->cmdname, strlen(t->cmdname)+1);
			close(fd);
		}
	}
}
示例#16
0
文件: exec.c 项目: 99years/plan9
void
procexec(Channel *pidc, char *prog, char *args[])
{
	int n;
	Proc *p;
	Thread *t;

	_threaddebug(DBGEXEC, "procexec %s", prog);
	/* must be only thread in proc */
	p = _threadgetproc();
	t = p->thread;
	if(p->threads.head != t || p->threads.head->nextt != nil){
		werrstr("not only thread in proc");
	Bad:
		if(pidc)
			sendul(pidc, ~0);
		return;
	}

	/*
	 * We want procexec to behave like exec; if exec succeeds,
	 * never return, and if it fails, return with errstr set.
	 * Unfortunately, the exec happens in another proc since
	 * we have to wait for the exec'ed process to finish.
	 * To provide the semantics, we open a pipe with the 
	 * write end close-on-exec and hand it to the proc that
	 * is doing the exec.  If the exec succeeds, the pipe will
	 * close so that our read below fails.  If the exec fails,
	 * then the proc doing the exec sends the errstr down the
	 * pipe to us.
	 */
	if(bind("#|", PIPEMNT, MREPL) < 0)
		goto Bad;
	if((p->exec.fd[0] = open(PIPEMNT "/data", OREAD)) < 0){
		unmount(nil, PIPEMNT);
		goto Bad;
	}
	if((p->exec.fd[1] = open(PIPEMNT "/data1", OWRITE|OCEXEC)) < 0){
		close(p->exec.fd[0]);
		unmount(nil, PIPEMNT);
		goto Bad;
	}
	unmount(nil, PIPEMNT);

	/* exec in parallel via the scheduler */
	assert(p->needexec==0);
	p->exec.prog = prog;
	p->exec.args = args;
	p->needexec = 1;
	_sched();

	close(p->exec.fd[1]);
	if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){	/* exec failed */
		p->exitstr[n] = '\0';
		errstr(p->exitstr, ERRMAX);
		close(p->exec.fd[0]);
		goto Bad;
	}
	close(p->exec.fd[0]);

	if(pidc)
		sendul(pidc, t->ret);

	/* wait for exec'ed program, then exit */
	_schedexecwait();
}
示例#17
0
文件: id.c 项目: aahud/harvey
int
threadid(void)
{
	return _threadgetproc()->thread->id;
}
示例#18
0
文件: id.c 项目: aahud/harvey
int
threadgetgrp(void)
{
	return _threadgetproc()->thread->grp;
}
示例#19
0
文件: channel.c 项目: 99years/plan9
int
alt(Alt *alts)
{
	Alt *a, *xa, *ca;
	Channel volatile *c;
	int n, s, waiting, allreadycl;
	void* r;
	Thread *t;

	/*
	 * The point of going splhi here is that note handlers
	 * might reasonably want to use channel operations,
	 * but that will hang if the note comes while we hold the
	 * chanlock.  Instead, we delay the note until we've dropped
	 * the lock.
	 */
	t = _threadgetproc()->thread;
	if(t->moribund || _threadexitsallstatus)
		yield();	/* won't return */
	s = _procsplhi();
	lock(&chanlock);
	t->alt = alts;
	t->chan = Chanalt;

	/* test whether any channels can proceed */
	n = 0;
	a = nil;

	for(xa=alts; xa->op!=CHANEND && xa->op!=CHANNOBLK; xa++){
		xa->entryno = -1;
		if(xa->op == CHANNOP)
			continue;

		c = xa->c;
		if(c==nil){
			unlock(&chanlock);
			_procsplx(s);
			t->chan = Channone;
			return -1;
		}

		if(isopenfor(c, xa->op) && canexec(xa))
			if(nrand(++n) == 0)
				a = xa;
	}


	if(a==nil){
		/* nothing can proceed */
		if(xa->op == CHANNOBLK){
			unlock(&chanlock);
			_procsplx(s);
			t->chan = Channone;
			if(xa->op == CHANNOBLK)
				return xa - alts;
		}

		/* enqueue on all channels open for us. */
		c = nil;
		ca = nil;
		waiting = 0;
		allreadycl = 0;
		for(xa=alts; xa->op!=CHANEND; xa++)
			if(xa->op==CHANNOP)
				continue;
			else if(isopenfor(xa->c, xa->op)){
				waiting = 1;
				enqueue(xa, &c);
			} else if(xa->err != errcl)
				ca = xa;
			else
				allreadycl = 1;

		if(waiting == 0)
			if(ca != nil){
				/* everything was closed, select last channel */
				ca->err = errcl;
				unlock(&chanlock);
				_procsplx(s);
				t->chan = Channone;
				return ca - alts;
			} else if(allreadycl){
				/* everything was already closed */
				unlock(&chanlock);
				_procsplx(s);
				t->chan = Channone;
				return -1;
			}
		/*
		 * wait for successful rendezvous.
		 * we can't just give up if the rendezvous
		 * is interrupted -- someone else might come
		 * along and try to rendezvous with us, so
		 * we need to be here.
		 * if the channel was closed, the op is done
		 * and we flag an error for the entry.
		 */
	    Again:
		unlock(&chanlock);
		_procsplx(s);
		r = _threadrendezvous(&c, 0);
		s = _procsplhi();
		lock(&chanlock);

		if(r==Intred){		/* interrupted */
			if(c!=nil)	/* someone will meet us; go back */
				goto Again;
			c = (Channel*)~0;	/* so no one tries to meet us */
		}

		/* dequeue from channels, find selected one */
		a = nil;
		for(xa=alts; xa->op!=CHANEND; xa++){
			if(xa->op==CHANNOP)
				continue;
			if(xa->c == c){
				a = xa;
				a->err = nil;
				if(r == Closed)
					a->err = errcl;
			}
			dequeue(xa);
		}
		unlock(&chanlock);
		_procsplx(s);
		if(a == nil){	/* we were interrupted */
			assert(c==(Channel*)~0);
			return -1;
		}
	}else
		altexec(a, s);	/* unlocks chanlock, does splx */
	_sched();
	t->chan = Channone;
	return a - alts;
}
示例#20
0
文件: create.c 项目: keedon/harvey
/*
 * Create a new thread and schedule it to run.
 * The thread grp is inherited from the currently running thread.
 */
int
threadcreate(void (*f)(void *arg), void *arg, uint stacksize)
{
	return newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
}
示例#21
0
文件: id.c 项目: CoryXie/nix-os
char*
threadgetname(void)
{
	return _threadgetproc()->thread->cmdname;
}