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/create.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
Pqueue _threadpq;
7
 
8
static int
9
nextID(void)
10
{
11
	static Lock l;
12
	static int id;
13
	int i;
14
 
15
	lock(&l);
16
	i = ++id;
17
	unlock(&l);
18
	return i;
19
}
20
 
21
/*
22
 * Create and initialize a new Thread structure attached to a given proc.
23
 */
24
static int
25
newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp)
26
{
27
	int id;
28
	Thread *t;
29
 
30
	if(stacksize < 32)
31
		sysfatal("bad stacksize %d", stacksize);
32
	t = _threadmalloc(sizeof(Thread), 1);
33
	t->stksize = stacksize;
34
	t->stk = _threadmalloc(stacksize, 0);
35
	memset(t->stk, 0xFE, stacksize);
36
	_threadinitstack(t, f, arg);
37
	t->grp = grp;
38
	if(name)
39
		t->cmdname = strdup(name);
40
	t->id = nextID();
41
	id = t->id;
42
	t->next = (Thread*)~0;
43
	t->proc = p;
44
	_threaddebug(DBGSCHED, "create thread %d.%d name %s", p->pid, t->id, name);
45
	lock(&p->lock);
46
	p->nthreads++;
47
	if(p->threads.head == nil)
48
		p->threads.head = t;
49
	else
50
		*p->threads.tail = t;
51
	p->threads.tail = &t->nextt;
52
	t->nextt = nil;
53
	t->state = Ready;
54
	_threadready(t);
55
	unlock(&p->lock);
56
	return id;
57
}
58
 
59
/* 
60
 * Create a new thread and schedule it to run.
61
 * The thread grp is inherited from the currently running thread.
62
 */
63
int
64
threadcreate(void (*f)(void *arg), void *arg, uint stacksize)
65
{
66
	return newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
67
}
68
 
69
/*
70
 * Create and initialize a new Proc structure with a single Thread
71
 * running inside it.  Add the Proc to the global process list.
72
 */
73
Proc*
74
_newproc(void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp, int rforkflag)
75
{
76
	Proc *p;
77
 
78
	p = _threadmalloc(sizeof *p, 1);
79
	p->pid = -1;
80
	p->rforkflag = rforkflag;
81
	newthread(p, f, arg, stacksize, name, grp);
82
 
83
	lock(&_threadpq.lock);
84
	if(_threadpq.head == nil)
85
		_threadpq.head = p;
86
	else
87
		*_threadpq.tail = p;
88
	_threadpq.tail = &p->next;
89
	unlock(&_threadpq.lock);
90
	return p;
91
}
92
 
93
int
94
procrfork(void (*f)(void *), void *arg, uint stacksize, int rforkflag)
95
{
96
	Proc *p;
97
	int id;
98
 
99
	p = _threadgetproc();
100
	assert(p->newproc == nil);
101
	p->newproc = _newproc(f, arg, stacksize, nil, p->thread->grp, rforkflag);
102
	id = p->newproc->threads.head->id;
103
	_sched();
104
	return id;
105
}
106
 
107
int
108
proccreate(void (*f)(void*), void *arg, uint stacksize)
109
{
110
	return procrfork(f, arg, stacksize, 0);
111
}
112
 
113
void
114
_freeproc(Proc *p)
115
{
116
	Thread *t, *nextt;
117
 
118
	for(t = p->threads.head; t; t = nextt){
119
		if(t->cmdname)
120
			free(t->cmdname);
121
		assert(t->stk != nil);
122
		free(t->stk);
123
		nextt = t->nextt;
124
		free(t);
125
	}
126
	free(p);
127
}
128
 
129
void
130
_freethread(Thread *t)
131
{
132
	Proc *p;
133
	Thread **l;
134
 
135
	p = t->proc;
136
	lock(&p->lock);
137
	for(l=&p->threads.head; *l; l=&(*l)->nextt){
138
		if(*l == t){
139
			*l = t->nextt;
140
			if(*l == nil)
141
				p->threads.tail = l;
142
			break;
143
		}
144
	}
145
	unlock(&p->lock);
146
	if (t->cmdname)
147
		free(t->cmdname);
148
	assert(t->stk != nil);
149
	free(t->stk);
150
	free(t);
151
}
152