Blame


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