main.c

来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 220 行

C
220
字号
#include <u.h>#include <libc.h>#include <thread.h>#include "threadimpl.h"typedef struct Mainarg Mainarg;struct Mainarg{	int	argc;	char	**argv;};int	mainstacksize;int	_threadnotefd;int	_threadpasserpid;static jmp_buf _mainjmp;static void mainlauncher(void*);extern void (*_sysfatal)(char*, va_list);extern void (*__assert)(char*);static Proc **mainp;voidmain(int argc, char **argv){	Mainarg *a;	Proc *p;	rfork(RFREND);	mainp = &p;	if(setjmp(_mainjmp))		_schedinit(p);//_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0;	_systhreadinit();	_qlockinit(_threadrendezvous);	_sysfatal = _threadsysfatal;	__assert = _threadassert;	notify(_threadnote);	if(mainstacksize == 0)		mainstacksize = 8*1024;	a = _threadmalloc(sizeof *a, 1);	a->argc = argc;	a->argv = argv;	p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0);	_schedinit(p);	abort();	/* not reached */}static voidmainlauncher(void *arg){	Mainarg *a;	a = arg;	threadmain(a->argc, a->argv);	threadexits("threadmain");}static char*skip(char *p){	while(*p == ' ')		p++;	while(*p != ' ' && *p != 0)		p++;	return p;}static long_times(long *t){	char b[200], *p;	int f;	ulong r;	memset(b, 0, sizeof(b));	f = open("/dev/cputime", OREAD|OCEXEC);	if(f < 0)		return 0;	if(read(f, b, sizeof(b)) <= 0){		close(f);		return 0;	}	p = b;	if(t)		t[0] = atol(p);	p = skip(p);	if(t)		t[1] = atol(p);	p = skip(p);	r = atol(p);	if(t){		p = skip(p);		t[2] = atol(p);		p = skip(p);		t[3] = atol(p);	}	return r;}static voidefork(Execargs *e){	char buf[ERRMAX];	_threaddebug(DBGEXEC, "_schedexec %s", e->prog);	close(e->fd[0]);	exec(e->prog, e->args);	_threaddebug(DBGEXEC, "_schedexec failed: %r");	rerrstr(buf, sizeof buf);	if(buf[0]=='\0')		strcpy(buf, "exec failed");	write(e->fd[1], buf, strlen(buf));	close(e->fd[1]);	_exits(buf);}int_schedexec(Execargs *e){	int pid;	switch(pid = rfork(RFREND|RFNOTEG|RFFDG|RFMEM|RFPROC)){	case 0:		efork(e);	default:		return pid;	}}int_schedfork(Proc *p){	int pid;	switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT|p->rforkflag)){	case 0:		*mainp = p;	/* write to stack, so local to proc */		longjmp(_mainjmp, 1);	default:		return pid;	}}void_schedexit(Proc *p){	char ex[ERRMAX];	Proc **l;	lock(&_threadpq.lock);	for(l=&_threadpq.head; *l; l=&(*l)->next){		if(*l == p){			*l = p->next;			if(*l == nil)				_threadpq.tail = l;			break;		}	}	unlock(&_threadpq.lock);	utfecpy(ex, ex+sizeof ex, p->exitstr);	free(p);	_exits(ex);}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");}static Proc **procp;void_systhreadinit(void){	procp = privalloc();}Proc*_threadgetproc(void){	return *procp;}void_threadsetproc(Proc *p){	*procp = p;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?