Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/libthread/main.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <thread.h>
4
#include "threadimpl.h"
5
 
6
typedef struct Mainarg Mainarg;
7
struct Mainarg
8
{
9
	int	argc;
10
	char	**argv;
11
};
12
 
13
int	mainstacksize;
14
int	_threadnotefd;
15
int	_threadpasserpid;
16
static jmp_buf _mainjmp;
17
static void mainlauncher(void*);
18
extern void (*_sysfatal)(char*, va_list);
19
extern void (*__assert)(char*);
20
extern int (*_dial)(char*, char*, char*, int*);
21
 
22
extern int _threaddial(char*, char*, char*, int*);
23
 
24
static Proc **mainp;
25
 
26
void
27
main(int argc, char **argv)
28
{
29
	Mainarg *a;
30
	Proc *p;
31
 
32
	rfork(RFREND);
33
	mainp = &p;
34
	if(setjmp(_mainjmp))
35
		_schedinit(p);
36
 
37
//_threaddebuglevel = (DBGSCHED|DBGCHAN|DBGREND)^~0;
38
	_systhreadinit();
39
	_qlockinit(_threadrendezvous);
40
	_sysfatal = _threadsysfatal;
41
	_dial = _threaddial;
42
	__assert = _threadassert;
43
	notify(_threadnote);
44
	if(mainstacksize == 0)
45
		mainstacksize = 8*1024;
46
 
47
	a = _threadmalloc(sizeof *a, 1);
48
	a->argc = argc;
49
	a->argv = argv;
50
 
51
	p = _newproc(mainlauncher, a, mainstacksize, "threadmain", 0, 0);
52
	_schedinit(p);
53
	abort();	/* not reached */
54
}
55
 
56
static void
57
mainlauncher(void *arg)
58
{
59
	Mainarg *a;
60
 
61
	a = arg;
62
	threadmain(a->argc, a->argv);
63
	threadexits("threadmain");
64
}
65
 
66
static char*
67
skip(char *p)
68
{
69
	while(*p == ' ')
70
		p++;
71
	while(*p != ' ' && *p != 0)
72
		p++;
73
	return p;
74
}
75
 
76
static long
77
_times(long *t)
78
{
79
	char b[200], *p;
80
	int f;
81
	ulong r;
82
 
83
	memset(b, 0, sizeof(b));
84
	f = open("/dev/cputime", OREAD|OCEXEC);
85
	if(f < 0)
86
		return 0;
87
	if(read(f, b, sizeof(b)) <= 0){
88
		close(f);
89
		return 0;
90
	}
91
	p = b;
92
	if(t)
93
		t[0] = atol(p);
94
	p = skip(p);
95
	if(t)
96
		t[1] = atol(p);
97
	p = skip(p);
98
	r = atol(p);
99
	if(t){
100
		p = skip(p);
101
		t[2] = atol(p);
102
		p = skip(p);
103
		t[3] = atol(p);
104
	}
105
	return r;
106
}
107
 
108
static void
109
efork(Execargs *e)
110
{
111
	char buf[ERRMAX];
112
 
113
	_threaddebug(DBGEXEC, "_schedexec %s", e->prog);
114
	close(e->fd[0]);
115
	exec(e->prog, e->args);
116
	_threaddebug(DBGEXEC, "_schedexec failed: %r");
117
	rerrstr(buf, sizeof buf);
118
	if(buf[0]=='\0')
119
		strcpy(buf, "exec failed");
120
	write(e->fd[1], buf, strlen(buf));
121
	close(e->fd[1]);
122
	_exits(buf);
123
}
124
 
125
int
126
_schedexec(Execargs *e)
127
{
128
	int pid;
129
 
130
	switch(pid = rfork(RFREND|RFNOTEG|RFFDG|RFMEM|RFPROC)){
131
	case 0:
132
		efork(e);
133
	default:
134
		return pid;
135
	}
136
}
137
 
138
int
139
_schedfork(Proc *p)
140
{
141
	int pid;
142
 
143
	switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT|p->rforkflag)){
144
	case 0:
145
		*mainp = p;	/* write to stack, so local to proc */
146
		longjmp(_mainjmp, 1);
147
	default:
148
		return pid;
149
	}
150
}
151
 
152
void
153
_schedexit(Proc *p)
154
{
155
	char ex[ERRMAX];
156
	Proc **l;
157
 
158
	lock(&_threadpq.lock);
159
	for(l=&_threadpq.head; *l; l=&(*l)->next){
160
		if(*l == p){
161
			*l = p->next;
162
			if(*l == nil)
163
				_threadpq.tail = l;
164
			break;
165
		}
166
	}
167
	unlock(&_threadpq.lock);
168
 
169
	utfecpy(ex, ex+sizeof ex, p->exitstr);
170
	free(p);
171
	_exits(ex);
172
}
173
 
174
void
175
_schedexecwait(void)
176
{
177
	int pid;
178
	Channel *c;
179
	Proc *p;
180
	Thread *t;
181
	Waitmsg *w;
182
 
183
	p = _threadgetproc();
184
	t = p->thread;
185
	pid = t->ret;
186
	_threaddebug(DBGEXEC, "_schedexecwait %d", t->ret);
187
 
188
	rfork(RFCFDG);
189
	for(;;){
190
		w = wait();
191
		if(w == nil)
192
			break;
193
		if(w->pid == pid)
194
			break;
195
		free(w);
196
	}
197
	if(w != nil){
198
		if((c = _threadwaitchan) != nil)
199
			sendp(c, w);
200
		else
201
			free(w);
202
	}
203
	threadexits("procexec");
204
}
205
 
206
static Proc **procp;
207
 
208
void
209
_systhreadinit(void)
210
{
211
	procp = privalloc();
212
}
213
 
214
Proc*
215
_threadgetproc(void)
216
{
217
	return *procp;
218
}
219
 
220
void
221
_threadsetproc(Proc *p)
222
{
223
	*procp = p;
224
}