Blame


1 76193d7c 2003-09-30 devnull #include "threadimpl.h"
2 76193d7c 2003-09-30 devnull
3 76193d7c 2003-09-30 devnull #define free
4 76193d7c 2003-09-30 devnull Pqueue _threadpq;
5 76193d7c 2003-09-30 devnull
6 76193d7c 2003-09-30 devnull static int nextID(void);
7 76193d7c 2003-09-30 devnull
8 76193d7c 2003-09-30 devnull /*
9 76193d7c 2003-09-30 devnull * Create and initialize a new Thread structure attached to a given proc.
10 76193d7c 2003-09-30 devnull */
11 76193d7c 2003-09-30 devnull
12 76193d7c 2003-09-30 devnull typedef struct Stack Stack;
13 76193d7c 2003-09-30 devnull struct Stack {
14 76193d7c 2003-09-30 devnull ulong magic;
15 76193d7c 2003-09-30 devnull Thread *thr;
16 76193d7c 2003-09-30 devnull Stack *next;
17 76193d7c 2003-09-30 devnull uchar buf[STKSIZE-12];
18 76193d7c 2003-09-30 devnull };
19 76193d7c 2003-09-30 devnull
20 76193d7c 2003-09-30 devnull static Stack *stkfree;
21 76193d7c 2003-09-30 devnull static Lock stklock;
22 76193d7c 2003-09-30 devnull
23 76193d7c 2003-09-30 devnull void
24 76193d7c 2003-09-30 devnull _stackfree(void *v)
25 76193d7c 2003-09-30 devnull {
26 76193d7c 2003-09-30 devnull Stack *s;
27 76193d7c 2003-09-30 devnull
28 76193d7c 2003-09-30 devnull s = v;
29 76193d7c 2003-09-30 devnull lock(&stklock);
30 76193d7c 2003-09-30 devnull s->thr = nil;
31 76193d7c 2003-09-30 devnull s->magic = 0;
32 76193d7c 2003-09-30 devnull s->next = stkfree;
33 76193d7c 2003-09-30 devnull stkfree = s;
34 76193d7c 2003-09-30 devnull unlock(&stklock);
35 76193d7c 2003-09-30 devnull }
36 76193d7c 2003-09-30 devnull
37 76193d7c 2003-09-30 devnull static Stack*
38 76193d7c 2003-09-30 devnull stackalloc(void)
39 76193d7c 2003-09-30 devnull {
40 76193d7c 2003-09-30 devnull char *buf;
41 76193d7c 2003-09-30 devnull Stack *s;
42 76193d7c 2003-09-30 devnull int i;
43 76193d7c 2003-09-30 devnull
44 76193d7c 2003-09-30 devnull lock(&stklock);
45 76193d7c 2003-09-30 devnull while(stkfree == nil){
46 76193d7c 2003-09-30 devnull unlock(&stklock);
47 76193d7c 2003-09-30 devnull assert(STKSIZE == sizeof(Stack));
48 76193d7c 2003-09-30 devnull buf = malloc(STKSIZE+128*STKSIZE);
49 76193d7c 2003-09-30 devnull s = (Stack*)(((ulong)buf+STKSIZE)&~(STKSIZE-1));
50 76193d7c 2003-09-30 devnull for(i=0; i<128; i++)
51 76193d7c 2003-09-30 devnull _stackfree(&s[i]);
52 76193d7c 2003-09-30 devnull lock(&stklock);
53 76193d7c 2003-09-30 devnull }
54 76193d7c 2003-09-30 devnull s = stkfree;
55 76193d7c 2003-09-30 devnull stkfree = stkfree->next;
56 76193d7c 2003-09-30 devnull unlock(&stklock);
57 76193d7c 2003-09-30 devnull s->magic = STKMAGIC;
58 76193d7c 2003-09-30 devnull return s;
59 76193d7c 2003-09-30 devnull }
60 76193d7c 2003-09-30 devnull
61 76193d7c 2003-09-30 devnull static int
62 76193d7c 2003-09-30 devnull newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp)
63 76193d7c 2003-09-30 devnull {
64 76193d7c 2003-09-30 devnull int id;
65 76193d7c 2003-09-30 devnull Thread *t;
66 76193d7c 2003-09-30 devnull Stack *s;
67 76193d7c 2003-09-30 devnull
68 76193d7c 2003-09-30 devnull if(stacksize < 32)
69 76193d7c 2003-09-30 devnull sysfatal("bad stacksize %d", stacksize);
70 76193d7c 2003-09-30 devnull t = _threadmalloc(sizeof(Thread), 1);
71 76193d7c 2003-09-30 devnull s = stackalloc();
72 76193d7c 2003-09-30 devnull s->thr = t;
73 76193d7c 2003-09-30 devnull t->stk = (char*)s;
74 76193d7c 2003-09-30 devnull t->stksize = STKSIZE;
75 76193d7c 2003-09-30 devnull _threaddebugmemset(s->buf, 0xFE, sizeof s->buf);
76 76193d7c 2003-09-30 devnull _threadinitstack(t, f, arg);
77 76193d7c 2003-09-30 devnull t->proc = p;
78 76193d7c 2003-09-30 devnull t->grp = grp;
79 76193d7c 2003-09-30 devnull if(name)
80 76193d7c 2003-09-30 devnull t->cmdname = strdup(name);
81 76193d7c 2003-09-30 devnull t->id = nextID();
82 76193d7c 2003-09-30 devnull id = t->id;
83 76193d7c 2003-09-30 devnull t->next = (Thread*)~0;
84 76193d7c 2003-09-30 devnull _threaddebug(DBGSCHED, "create thread %d.%d name %s", p->pid, t->id, name);
85 76193d7c 2003-09-30 devnull lock(&p->lock);
86 76193d7c 2003-09-30 devnull p->nthreads++;
87 76193d7c 2003-09-30 devnull if(p->threads.head == nil)
88 76193d7c 2003-09-30 devnull p->threads.head = t;
89 76193d7c 2003-09-30 devnull else{
90 76193d7c 2003-09-30 devnull t->prevt = p->threads.tail;
91 76193d7c 2003-09-30 devnull t->prevt->nextt = t;
92 76193d7c 2003-09-30 devnull }
93 76193d7c 2003-09-30 devnull p->threads.tail = t;
94 76193d7c 2003-09-30 devnull t->state = Ready;
95 76193d7c 2003-09-30 devnull _threadready(t);
96 76193d7c 2003-09-30 devnull unlock(&p->lock);
97 76193d7c 2003-09-30 devnull return id;
98 76193d7c 2003-09-30 devnull }
99 76193d7c 2003-09-30 devnull
100 76193d7c 2003-09-30 devnull static int
101 76193d7c 2003-09-30 devnull nextID(void)
102 76193d7c 2003-09-30 devnull {
103 76193d7c 2003-09-30 devnull static Lock l;
104 76193d7c 2003-09-30 devnull static int id;
105 76193d7c 2003-09-30 devnull int i;
106 76193d7c 2003-09-30 devnull
107 76193d7c 2003-09-30 devnull lock(&l);
108 76193d7c 2003-09-30 devnull i = ++id;
109 76193d7c 2003-09-30 devnull unlock(&l);
110 76193d7c 2003-09-30 devnull return i;
111 76193d7c 2003-09-30 devnull }
112 76193d7c 2003-09-30 devnull
113 76193d7c 2003-09-30 devnull int
114 76193d7c 2003-09-30 devnull procrfork(void (*f)(void *), void *arg, uint stacksize, int rforkflag)
115 76193d7c 2003-09-30 devnull {
116 76193d7c 2003-09-30 devnull Proc *p;
117 76193d7c 2003-09-30 devnull int id;
118 76193d7c 2003-09-30 devnull
119 76193d7c 2003-09-30 devnull p = _threadgetproc();
120 76193d7c 2003-09-30 devnull assert(p->newproc == nil);
121 76193d7c 2003-09-30 devnull p->newproc = _newproc(f, arg, stacksize, nil, p->thread->grp, rforkflag);
122 76193d7c 2003-09-30 devnull id = p->newproc->threads.head->id;
123 76193d7c 2003-09-30 devnull _sched();
124 76193d7c 2003-09-30 devnull return id;
125 76193d7c 2003-09-30 devnull }
126 76193d7c 2003-09-30 devnull
127 76193d7c 2003-09-30 devnull int
128 76193d7c 2003-09-30 devnull proccreate(void (*f)(void*), void *arg, uint stacksize)
129 76193d7c 2003-09-30 devnull {
130 76193d7c 2003-09-30 devnull return procrfork(f, arg, stacksize, 0);
131 76193d7c 2003-09-30 devnull }
132 76193d7c 2003-09-30 devnull
133 76193d7c 2003-09-30 devnull void
134 76193d7c 2003-09-30 devnull _freeproc(Proc *p)
135 76193d7c 2003-09-30 devnull {
136 76193d7c 2003-09-30 devnull Thread *t, *nextt;
137 76193d7c 2003-09-30 devnull
138 76193d7c 2003-09-30 devnull for(t = p->threads.head; t; t = nextt){
139 76193d7c 2003-09-30 devnull if(t->cmdname)
140 76193d7c 2003-09-30 devnull free(t->cmdname);
141 76193d7c 2003-09-30 devnull assert(t->stk != nil);
142 76193d7c 2003-09-30 devnull _stackfree((Stack*)t->stk);
143 76193d7c 2003-09-30 devnull nextt = t->nextt;
144 76193d7c 2003-09-30 devnull free(t);
145 76193d7c 2003-09-30 devnull }
146 76193d7c 2003-09-30 devnull free(p);
147 76193d7c 2003-09-30 devnull }
148 76193d7c 2003-09-30 devnull
149 76193d7c 2003-09-30 devnull /*
150 76193d7c 2003-09-30 devnull * Create a new thread and schedule it to run.
151 76193d7c 2003-09-30 devnull * The thread grp is inherited from the currently running thread.
152 76193d7c 2003-09-30 devnull */
153 76193d7c 2003-09-30 devnull int
154 76193d7c 2003-09-30 devnull threadcreate(void (*f)(void *arg), void *arg, uint stacksize)
155 76193d7c 2003-09-30 devnull {
156 76193d7c 2003-09-30 devnull return newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
157 76193d7c 2003-09-30 devnull }
158 76193d7c 2003-09-30 devnull
159 76193d7c 2003-09-30 devnull /*
160 76193d7c 2003-09-30 devnull * Create and initialize a new Proc structure with a single Thread
161 76193d7c 2003-09-30 devnull * running inside it. Add the Proc to the global process list.
162 76193d7c 2003-09-30 devnull */
163 76193d7c 2003-09-30 devnull Proc*
164 76193d7c 2003-09-30 devnull _newproc(void (*f)(void *arg), void *arg, uint stacksize, char *name, int grp, int rforkflag)
165 76193d7c 2003-09-30 devnull {
166 76193d7c 2003-09-30 devnull Proc *p;
167 76193d7c 2003-09-30 devnull
168 76193d7c 2003-09-30 devnull p = _threadmalloc(sizeof *p, 1);
169 76193d7c 2003-09-30 devnull p->pid = -1;
170 76193d7c 2003-09-30 devnull p->rforkflag = rforkflag;
171 76193d7c 2003-09-30 devnull newthread(p, f, arg, stacksize, name, grp);
172 76193d7c 2003-09-30 devnull
173 76193d7c 2003-09-30 devnull lock(&_threadpq.lock);
174 76193d7c 2003-09-30 devnull if(_threadpq.head == nil)
175 76193d7c 2003-09-30 devnull _threadpq.head = p;
176 76193d7c 2003-09-30 devnull else
177 76193d7c 2003-09-30 devnull *_threadpq.tail = p;
178 76193d7c 2003-09-30 devnull _threadpq.tail = &p->next;
179 76193d7c 2003-09-30 devnull unlock(&_threadpq.lock);
180 76193d7c 2003-09-30 devnull return p;
181 76193d7c 2003-09-30 devnull }
182 76193d7c 2003-09-30 devnull