xref: /plan9/sys/src/cmd/fossil/9proc.c (revision 5e96a66c77eb9140492ca53f857cbbf108e128ed)
1*5e96a66cSDavid du Colombier #include "stdinc.h"
2*5e96a66cSDavid du Colombier 
3*5e96a66cSDavid du Colombier #include "9.h"
4*5e96a66cSDavid du Colombier #include "dat.h"
5*5e96a66cSDavid du Colombier #include "fns.h"
6*5e96a66cSDavid du Colombier 
7*5e96a66cSDavid du Colombier enum {
8*5e96a66cSDavid du Colombier 	NConInit	= 128,
9*5e96a66cSDavid du Colombier 	NMsgInit	= 20,
10*5e96a66cSDavid du Colombier 	NMsgProcInit	= 4,
11*5e96a66cSDavid du Colombier 	NMsizeInit	= 8192+IOHDRSZ,
12*5e96a66cSDavid du Colombier };
13*5e96a66cSDavid du Colombier 
14*5e96a66cSDavid du Colombier static struct {
15*5e96a66cSDavid du Colombier 	VtLock*	lock;
16*5e96a66cSDavid du Colombier 	Con**	con;			/* arena */
17*5e96a66cSDavid du Colombier 	int	ncon;			/* how many in arena */
18*5e96a66cSDavid du Colombier 	int	hi;			/* high watermark */
19*5e96a66cSDavid du Colombier 	int	cur;			/* hint for allocation */
20*5e96a66cSDavid du Colombier 
21*5e96a66cSDavid du Colombier 	u32int	msize;
22*5e96a66cSDavid du Colombier } cbox;
23*5e96a66cSDavid du Colombier 
24*5e96a66cSDavid du Colombier static struct {
25*5e96a66cSDavid du Colombier 	VtLock*	lock;
26*5e96a66cSDavid du Colombier 
27*5e96a66cSDavid du Colombier 	Msg*	free;
28*5e96a66cSDavid du Colombier 	VtRendez* alloc;
29*5e96a66cSDavid du Colombier 
30*5e96a66cSDavid du Colombier 	Msg*	head;
31*5e96a66cSDavid du Colombier 	Msg*	tail;
32*5e96a66cSDavid du Colombier 	VtRendez* work;
33*5e96a66cSDavid du Colombier 
34*5e96a66cSDavid du Colombier 	int	maxmsg;
35*5e96a66cSDavid du Colombier 	int	nmsg;
36*5e96a66cSDavid du Colombier 	int	maxproc;
37*5e96a66cSDavid du Colombier 	int	nproc;
38*5e96a66cSDavid du Colombier 
39*5e96a66cSDavid du Colombier 	u32int	msize;			/* immutable */
40*5e96a66cSDavid du Colombier } mbox;
41*5e96a66cSDavid du Colombier 
42*5e96a66cSDavid du Colombier static void
43*5e96a66cSDavid du Colombier msgFree(Msg* m)
44*5e96a66cSDavid du Colombier {
45*5e96a66cSDavid du Colombier 	vtLock(mbox.lock);
46*5e96a66cSDavid du Colombier 	if(mbox.nmsg > mbox.maxmsg){
47*5e96a66cSDavid du Colombier 		vtMemFree(m->data);
48*5e96a66cSDavid du Colombier 		vtMemFree(m);
49*5e96a66cSDavid du Colombier 		mbox.nmsg--;
50*5e96a66cSDavid du Colombier 		vtUnlock(mbox.lock);
51*5e96a66cSDavid du Colombier 		return;
52*5e96a66cSDavid du Colombier 	}
53*5e96a66cSDavid du Colombier 	m->next = mbox.free;
54*5e96a66cSDavid du Colombier 	mbox.free = m;
55*5e96a66cSDavid du Colombier 	if(m->next == nil)
56*5e96a66cSDavid du Colombier 		vtWakeup(mbox.alloc);
57*5e96a66cSDavid du Colombier 	vtUnlock(mbox.lock);
58*5e96a66cSDavid du Colombier }
59*5e96a66cSDavid du Colombier 
60*5e96a66cSDavid du Colombier static void
61*5e96a66cSDavid du Colombier conFree(Con* con)
62*5e96a66cSDavid du Colombier {
63*5e96a66cSDavid du Colombier 	if(con->fd >= 0){
64*5e96a66cSDavid du Colombier 		close(con->fd);
65*5e96a66cSDavid du Colombier 		con->fd = -1;
66*5e96a66cSDavid du Colombier 	}
67*5e96a66cSDavid du Colombier 
68*5e96a66cSDavid du Colombier 	assert(con->version == nil);
69*5e96a66cSDavid du Colombier 	assert(con->mhead == nil);
70*5e96a66cSDavid du Colombier 	assert(con->nmsg == 0);
71*5e96a66cSDavid du Colombier 	assert(con->nfid == 0);
72*5e96a66cSDavid du Colombier 	assert(con->state == CsMoribund);
73*5e96a66cSDavid du Colombier 
74*5e96a66cSDavid du Colombier 	con->state = CsDead;
75*5e96a66cSDavid du Colombier }
76*5e96a66cSDavid du Colombier 
77*5e96a66cSDavid du Colombier static void
78*5e96a66cSDavid du Colombier msgProc(void*)
79*5e96a66cSDavid du Colombier {
80*5e96a66cSDavid du Colombier 	int n;
81*5e96a66cSDavid du Colombier 	Msg *m;
82*5e96a66cSDavid du Colombier 	char *e;
83*5e96a66cSDavid du Colombier 	Con *con;
84*5e96a66cSDavid du Colombier 
85*5e96a66cSDavid du Colombier 	vtThreadSetName("msg");
86*5e96a66cSDavid du Colombier 
87*5e96a66cSDavid du Colombier 	vtLock(mbox.lock);
88*5e96a66cSDavid du Colombier 	while(mbox.nproc <= mbox.maxproc){
89*5e96a66cSDavid du Colombier 		while(mbox.head == nil)
90*5e96a66cSDavid du Colombier 			vtSleep(mbox.work);
91*5e96a66cSDavid du Colombier 		m = mbox.head;
92*5e96a66cSDavid du Colombier 		mbox.head = m->next;
93*5e96a66cSDavid du Colombier 		m->next = nil;
94*5e96a66cSDavid du Colombier 
95*5e96a66cSDavid du Colombier 		e = nil;
96*5e96a66cSDavid du Colombier 
97*5e96a66cSDavid du Colombier 		con = m->con;
98*5e96a66cSDavid du Colombier 		vtLock(con->lock);
99*5e96a66cSDavid du Colombier 		assert(con->state != CsDead);
100*5e96a66cSDavid du Colombier 		con->nmsg++;
101*5e96a66cSDavid du Colombier 
102*5e96a66cSDavid du Colombier 		if(m->t.type == Tversion){
103*5e96a66cSDavid du Colombier 			con->version = m;
104*5e96a66cSDavid du Colombier 			con->state = CsDown;
105*5e96a66cSDavid du Colombier 			while(con->mhead != nil)
106*5e96a66cSDavid du Colombier 				vtSleep(con->active);
107*5e96a66cSDavid du Colombier 			assert(con->state == CsDown);
108*5e96a66cSDavid du Colombier 			if(con->version == m){
109*5e96a66cSDavid du Colombier 				con->version = nil;
110*5e96a66cSDavid du Colombier 				con->state = CsInit;
111*5e96a66cSDavid du Colombier 			}
112*5e96a66cSDavid du Colombier 			else
113*5e96a66cSDavid du Colombier 				e = "Tversion aborted";
114*5e96a66cSDavid du Colombier 		}
115*5e96a66cSDavid du Colombier 		else if(con->state != CsUp)
116*5e96a66cSDavid du Colombier 			e = "connection not ready";
117*5e96a66cSDavid du Colombier 
118*5e96a66cSDavid du Colombier 		/*
119*5e96a66cSDavid du Colombier 		 * Add Msg to end of active list.
120*5e96a66cSDavid du Colombier 		 */
121*5e96a66cSDavid du Colombier 		if(con->mtail != nil){
122*5e96a66cSDavid du Colombier 			m->prev = con->mtail;
123*5e96a66cSDavid du Colombier 			con->mtail->next = m;
124*5e96a66cSDavid du Colombier 		}
125*5e96a66cSDavid du Colombier 		else{
126*5e96a66cSDavid du Colombier 			con->mhead = m;
127*5e96a66cSDavid du Colombier 			m->prev = nil;
128*5e96a66cSDavid du Colombier 		}
129*5e96a66cSDavid du Colombier 		con->mtail = m;
130*5e96a66cSDavid du Colombier 		m->next = nil;
131*5e96a66cSDavid du Colombier 
132*5e96a66cSDavid du Colombier 		vtUnlock(con->lock);
133*5e96a66cSDavid du Colombier 		vtUnlock(mbox.lock);
134*5e96a66cSDavid du Colombier 
135*5e96a66cSDavid du Colombier 		/*
136*5e96a66cSDavid du Colombier 		 * Dispatch if not error already.
137*5e96a66cSDavid du Colombier 		 */
138*5e96a66cSDavid du Colombier 		m->r.tag = m->t.tag;
139*5e96a66cSDavid du Colombier 		if(e == nil && !(*rFcall[m->t.type])(m))
140*5e96a66cSDavid du Colombier 			e = vtGetError();
141*5e96a66cSDavid du Colombier 		if(e != nil){
142*5e96a66cSDavid du Colombier 			m->r.type = Rerror;
143*5e96a66cSDavid du Colombier 			m->r.ename = e;
144*5e96a66cSDavid du Colombier 		}
145*5e96a66cSDavid du Colombier 		else
146*5e96a66cSDavid du Colombier 			m->r.type = m->t.type+1;
147*5e96a66cSDavid du Colombier 
148*5e96a66cSDavid du Colombier 		vtLock(con->lock);
149*5e96a66cSDavid du Colombier 		/*
150*5e96a66cSDavid du Colombier 		 * Remove Msg from active list.
151*5e96a66cSDavid du Colombier 		 */
152*5e96a66cSDavid du Colombier 		if(m->prev != nil)
153*5e96a66cSDavid du Colombier 			m->prev->next = m->next;
154*5e96a66cSDavid du Colombier 		else
155*5e96a66cSDavid du Colombier 			con->mhead = m->next;
156*5e96a66cSDavid du Colombier 		if(m->next != nil)
157*5e96a66cSDavid du Colombier 			m->next->prev = m->prev;
158*5e96a66cSDavid du Colombier 		else
159*5e96a66cSDavid du Colombier 			con->mtail = m->prev;
160*5e96a66cSDavid du Colombier 		m->prev = m->next = nil;
161*5e96a66cSDavid du Colombier 		if(con->mhead == nil)
162*5e96a66cSDavid du Colombier 			vtWakeup(con->active);
163*5e96a66cSDavid du Colombier 
164*5e96a66cSDavid du Colombier 		if(Dflag)
165*5e96a66cSDavid du Colombier 			fprint(2, "msgProc: r %F\n", &m->r);
166*5e96a66cSDavid du Colombier 
167*5e96a66cSDavid du Colombier 		if((con->state == CsNew || con->state == CsUp) && !m->flush){
168*5e96a66cSDavid du Colombier 			/*
169*5e96a66cSDavid du Colombier 			 * TODO: optimise this copy away somehow for
170*5e96a66cSDavid du Colombier 			 * read, stat, etc.
171*5e96a66cSDavid du Colombier 			 */
172*5e96a66cSDavid du Colombier 			assert(n = convS2M(&m->r, con->data, con->msize));
173*5e96a66cSDavid du Colombier 			if(write(con->fd, con->data, n) != n){
174*5e96a66cSDavid du Colombier 				if(con->fd >= 0){
175*5e96a66cSDavid du Colombier 					close(con->fd);
176*5e96a66cSDavid du Colombier 					con->fd = -1;
177*5e96a66cSDavid du Colombier 				}
178*5e96a66cSDavid du Colombier 			}
179*5e96a66cSDavid du Colombier 		}
180*5e96a66cSDavid du Colombier 
181*5e96a66cSDavid du Colombier 		con->nmsg--;
182*5e96a66cSDavid du Colombier 		if(con->state == CsMoribund && con->nmsg == 0){
183*5e96a66cSDavid du Colombier 			vtUnlock(con->lock);
184*5e96a66cSDavid du Colombier 			conFree(con);
185*5e96a66cSDavid du Colombier 		}
186*5e96a66cSDavid du Colombier 		else
187*5e96a66cSDavid du Colombier 			vtUnlock(con->lock);
188*5e96a66cSDavid du Colombier 
189*5e96a66cSDavid du Colombier 		vtLock(mbox.lock);
190*5e96a66cSDavid du Colombier 		m->next = mbox.free;
191*5e96a66cSDavid du Colombier 		mbox.free = m;
192*5e96a66cSDavid du Colombier 		if(m->next == nil)
193*5e96a66cSDavid du Colombier 			vtWakeup(mbox.alloc);
194*5e96a66cSDavid du Colombier 	}
195*5e96a66cSDavid du Colombier 	mbox.nproc--;
196*5e96a66cSDavid du Colombier 	vtUnlock(mbox.lock);
197*5e96a66cSDavid du Colombier }
198*5e96a66cSDavid du Colombier 
199*5e96a66cSDavid du Colombier static void
200*5e96a66cSDavid du Colombier conProc(void* v)
201*5e96a66cSDavid du Colombier {
202*5e96a66cSDavid du Colombier 	Msg *m;
203*5e96a66cSDavid du Colombier 	Con *con;
204*5e96a66cSDavid du Colombier 	int eof, fd, n;
205*5e96a66cSDavid du Colombier 
206*5e96a66cSDavid du Colombier 	vtThreadSetName("con");
207*5e96a66cSDavid du Colombier 
208*5e96a66cSDavid du Colombier 	con = v;
209*5e96a66cSDavid du Colombier 	if(Dflag)
210*5e96a66cSDavid du Colombier 		fprint(2, "conProc: con->fd %d\n", con->fd);
211*5e96a66cSDavid du Colombier 	fd = con->fd;
212*5e96a66cSDavid du Colombier 	eof = 0;
213*5e96a66cSDavid du Colombier 
214*5e96a66cSDavid du Colombier 	vtLock(mbox.lock);
215*5e96a66cSDavid du Colombier 	while(!eof){
216*5e96a66cSDavid du Colombier 		while(mbox.free == nil){
217*5e96a66cSDavid du Colombier 			if(mbox.nmsg >= mbox.maxmsg){
218*5e96a66cSDavid du Colombier 				vtSleep(mbox.alloc);
219*5e96a66cSDavid du Colombier 				continue;
220*5e96a66cSDavid du Colombier 			}
221*5e96a66cSDavid du Colombier 			m = vtMemAllocZ(sizeof(Msg));
222*5e96a66cSDavid du Colombier 			m->data = vtMemAlloc(mbox.msize);
223*5e96a66cSDavid du Colombier 			m->msize = mbox.msize;
224*5e96a66cSDavid du Colombier 			mbox.nmsg++;
225*5e96a66cSDavid du Colombier 			mbox.free = m;
226*5e96a66cSDavid du Colombier 			break;
227*5e96a66cSDavid du Colombier 		}
228*5e96a66cSDavid du Colombier 		m = mbox.free;
229*5e96a66cSDavid du Colombier 		mbox.free = m->next;
230*5e96a66cSDavid du Colombier 		m->next = nil;
231*5e96a66cSDavid du Colombier 		vtUnlock(mbox.lock);
232*5e96a66cSDavid du Colombier 
233*5e96a66cSDavid du Colombier 		m->con = con;
234*5e96a66cSDavid du Colombier 		m->flush = 0;
235*5e96a66cSDavid du Colombier 
236*5e96a66cSDavid du Colombier 		while((n = read9pmsg(fd, m->data, con->msize)) == 0)
237*5e96a66cSDavid du Colombier 			;
238*5e96a66cSDavid du Colombier 		if(n < 0){
239*5e96a66cSDavid du Colombier 			m->t.type = Tversion;
240*5e96a66cSDavid du Colombier 			m->t.fid = NOFID;
241*5e96a66cSDavid du Colombier 			m->t.tag = NOTAG;
242*5e96a66cSDavid du Colombier 			m->t.msize = con->msize;
243*5e96a66cSDavid du Colombier 			m->t.version = "9PEoF";
244*5e96a66cSDavid du Colombier 			eof = 1;
245*5e96a66cSDavid du Colombier 		}
246*5e96a66cSDavid du Colombier 		else if(convM2S(m->data, n, &m->t) != n){
247*5e96a66cSDavid du Colombier 			if(Dflag)
248*5e96a66cSDavid du Colombier 				fprint(2, "conProc: convM2S error: %s\n",
249*5e96a66cSDavid du Colombier 					con->name);
250*5e96a66cSDavid du Colombier 			msgFree(m);
251*5e96a66cSDavid du Colombier 			vtLock(mbox.lock);
252*5e96a66cSDavid du Colombier 			continue;
253*5e96a66cSDavid du Colombier 		}
254*5e96a66cSDavid du Colombier 		if(Dflag)
255*5e96a66cSDavid du Colombier 			fprint(2, "conProc: t %F\n", &m->t);
256*5e96a66cSDavid du Colombier 
257*5e96a66cSDavid du Colombier 		vtLock(mbox.lock);
258*5e96a66cSDavid du Colombier 		if(mbox.head == nil){
259*5e96a66cSDavid du Colombier 			mbox.head = m;
260*5e96a66cSDavid du Colombier 			if(!vtWakeup(mbox.work) && mbox.nproc < mbox.maxproc){
261*5e96a66cSDavid du Colombier 				if(vtThread(msgProc, nil) > 0)
262*5e96a66cSDavid du Colombier 					mbox.nproc++;
263*5e96a66cSDavid du Colombier 			}
264*5e96a66cSDavid du Colombier 			vtWakeup(mbox.work);
265*5e96a66cSDavid du Colombier 		}
266*5e96a66cSDavid du Colombier 		else
267*5e96a66cSDavid du Colombier 			mbox.tail->next = m;
268*5e96a66cSDavid du Colombier 		mbox.tail = m;
269*5e96a66cSDavid du Colombier 	}
270*5e96a66cSDavid du Colombier 	vtUnlock(mbox.lock);
271*5e96a66cSDavid du Colombier }
272*5e96a66cSDavid du Colombier 
273*5e96a66cSDavid du Colombier Con*
274*5e96a66cSDavid du Colombier conAlloc(int fd, char* name)
275*5e96a66cSDavid du Colombier {
276*5e96a66cSDavid du Colombier 	Con *con;
277*5e96a66cSDavid du Colombier 	int cur, i;
278*5e96a66cSDavid du Colombier 
279*5e96a66cSDavid du Colombier 	vtLock(cbox.lock);
280*5e96a66cSDavid du Colombier 	cur = cbox.cur;
281*5e96a66cSDavid du Colombier 	for(i = 0; i < cbox.hi; i++){
282*5e96a66cSDavid du Colombier 		/*
283*5e96a66cSDavid du Colombier 		 * Look for any unallocated or CsDead up to the
284*5e96a66cSDavid du Colombier 		 * high watermark; cur is a hint where to start.
285*5e96a66cSDavid du Colombier 		 * Wrap around the whole arena.
286*5e96a66cSDavid du Colombier 		 */
287*5e96a66cSDavid du Colombier 		if(cbox.con[cur] == nil || cbox.con[cur]->state == CsDead)
288*5e96a66cSDavid du Colombier 			break;
289*5e96a66cSDavid du Colombier 		if(++cur >= cbox.hi)
290*5e96a66cSDavid du Colombier 			cur = 0;
291*5e96a66cSDavid du Colombier 	}
292*5e96a66cSDavid du Colombier 	if(i >= cbox.hi){
293*5e96a66cSDavid du Colombier 		/*
294*5e96a66cSDavid du Colombier 		 * None found.
295*5e96a66cSDavid du Colombier 		 * If the high watermark is up to the limit of those
296*5e96a66cSDavid du Colombier 		 * allocated, increase the size of the arena.
297*5e96a66cSDavid du Colombier 		 * Bump up the watermark and take the next.
298*5e96a66cSDavid du Colombier 		 */
299*5e96a66cSDavid du Colombier 		if(cbox.hi >= cbox.ncon){
300*5e96a66cSDavid du Colombier 			cbox.con = vtMemRealloc(cbox.con,
301*5e96a66cSDavid du Colombier 					(cbox.ncon+NConInit)*sizeof(Con*));
302*5e96a66cSDavid du Colombier 			memset(&cbox.con[cbox.ncon], 0, NConInit*sizeof(Con*));
303*5e96a66cSDavid du Colombier 			cbox.ncon += NConInit;
304*5e96a66cSDavid du Colombier 		}
305*5e96a66cSDavid du Colombier 		cur = cbox.hi++;
306*5e96a66cSDavid du Colombier 	}
307*5e96a66cSDavid du Colombier 
308*5e96a66cSDavid du Colombier 	/*
309*5e96a66cSDavid du Colombier 	 * Do one-time initialisation if necessary.
310*5e96a66cSDavid du Colombier 	 * Put back a new hint.
311*5e96a66cSDavid du Colombier 	 * Do specific initialisation and start the proc.
312*5e96a66cSDavid du Colombier 	 */
313*5e96a66cSDavid du Colombier 	con = cbox.con[cur];
314*5e96a66cSDavid du Colombier 	if(con == nil){
315*5e96a66cSDavid du Colombier 		con = vtMemAllocZ(sizeof(Con));
316*5e96a66cSDavid du Colombier 		con->lock = vtLockAlloc();
317*5e96a66cSDavid du Colombier 		con->data = vtMemAlloc(cbox.msize);
318*5e96a66cSDavid du Colombier 		con->msize = cbox.msize;
319*5e96a66cSDavid du Colombier 		con->active = vtRendezAlloc(con->lock);
320*5e96a66cSDavid du Colombier 		con->fidlock = vtLockAlloc();
321*5e96a66cSDavid du Colombier 		cbox.con[cur] = con;
322*5e96a66cSDavid du Colombier 	}
323*5e96a66cSDavid du Colombier 	assert(con->mhead == nil);
324*5e96a66cSDavid du Colombier 	assert(con->nmsg == 0);
325*5e96a66cSDavid du Colombier 	assert(con->fhead == nil);
326*5e96a66cSDavid du Colombier 	assert(con->nfid == 0);
327*5e96a66cSDavid du Colombier 
328*5e96a66cSDavid du Colombier 	con->state = CsNew;
329*5e96a66cSDavid du Colombier 
330*5e96a66cSDavid du Colombier 	if(++cur >= cbox.hi)
331*5e96a66cSDavid du Colombier 		cur = 0;
332*5e96a66cSDavid du Colombier 	cbox.cur = cur;
333*5e96a66cSDavid du Colombier 
334*5e96a66cSDavid du Colombier 	con->fd = fd;
335*5e96a66cSDavid du Colombier 	if(con->name != nil){
336*5e96a66cSDavid du Colombier 		vtMemFree(con->name);
337*5e96a66cSDavid du Colombier 		con->name = nil;
338*5e96a66cSDavid du Colombier 	}
339*5e96a66cSDavid du Colombier 	if(name != nil)
340*5e96a66cSDavid du Colombier 		con->name = vtStrDup(name);
341*5e96a66cSDavid du Colombier 	con->aok = 0;
342*5e96a66cSDavid du Colombier 	vtUnlock(cbox.lock);
343*5e96a66cSDavid du Colombier 
344*5e96a66cSDavid du Colombier 	if(vtThread(conProc, con) < 0){
345*5e96a66cSDavid du Colombier 		conFree(con);
346*5e96a66cSDavid du Colombier 		return nil;
347*5e96a66cSDavid du Colombier 	}
348*5e96a66cSDavid du Colombier 
349*5e96a66cSDavid du Colombier 	return con;
350*5e96a66cSDavid du Colombier }
351*5e96a66cSDavid du Colombier 
352*5e96a66cSDavid du Colombier static int
353*5e96a66cSDavid du Colombier cmdMsg(int argc, char* argv[])
354*5e96a66cSDavid du Colombier {
355*5e96a66cSDavid du Colombier 	char *p;
356*5e96a66cSDavid du Colombier 	int maxmsg, maxproc;
357*5e96a66cSDavid du Colombier 	char *usage = "usage: msg [-m nmsg] [-p nproc]";
358*5e96a66cSDavid du Colombier 
359*5e96a66cSDavid du Colombier 	maxmsg = maxproc = 0;
360*5e96a66cSDavid du Colombier 
361*5e96a66cSDavid du Colombier 	ARGBEGIN{
362*5e96a66cSDavid du Colombier 	default:
363*5e96a66cSDavid du Colombier 		return cliError(usage);
364*5e96a66cSDavid du Colombier 	case 'm':
365*5e96a66cSDavid du Colombier 		p = ARGF();
366*5e96a66cSDavid du Colombier 		if(p == nil)
367*5e96a66cSDavid du Colombier 			return cliError(usage);
368*5e96a66cSDavid du Colombier 		maxmsg = strtol(argv[0], &p, 0);
369*5e96a66cSDavid du Colombier 		if(maxmsg <= 0 || p == argv[0] || *p != '\0')
370*5e96a66cSDavid du Colombier 			return cliError(usage);
371*5e96a66cSDavid du Colombier 		break;
372*5e96a66cSDavid du Colombier 	case 'p':
373*5e96a66cSDavid du Colombier 		p = ARGF();
374*5e96a66cSDavid du Colombier 		if(p == nil)
375*5e96a66cSDavid du Colombier 			return cliError(usage);
376*5e96a66cSDavid du Colombier 		maxproc = strtol(argv[0], &p, 0);
377*5e96a66cSDavid du Colombier 		if(maxproc <= 0 || p == argv[0] || *p != '\0')
378*5e96a66cSDavid du Colombier 			return cliError(usage);
379*5e96a66cSDavid du Colombier 		break;
380*5e96a66cSDavid du Colombier 	}ARGEND
381*5e96a66cSDavid du Colombier 	if(argc)
382*5e96a66cSDavid du Colombier 		return cliError(usage);
383*5e96a66cSDavid du Colombier 
384*5e96a66cSDavid du Colombier 	vtLock(mbox.lock);
385*5e96a66cSDavid du Colombier 	if(maxmsg)
386*5e96a66cSDavid du Colombier 		mbox.maxmsg = maxmsg;
387*5e96a66cSDavid du Colombier 	maxmsg = mbox.maxmsg;
388*5e96a66cSDavid du Colombier 	if(maxproc)
389*5e96a66cSDavid du Colombier 		mbox.maxproc = maxproc;
390*5e96a66cSDavid du Colombier 	maxproc = mbox.maxproc;
391*5e96a66cSDavid du Colombier 	vtUnlock(mbox.lock);
392*5e96a66cSDavid du Colombier 
393*5e96a66cSDavid du Colombier 	consPrint("\tmsg -m %d -p %d\n", maxmsg, maxproc);
394*5e96a66cSDavid du Colombier 
395*5e96a66cSDavid du Colombier 	return 1;
396*5e96a66cSDavid du Colombier }
397*5e96a66cSDavid du Colombier 
398*5e96a66cSDavid du Colombier void
399*5e96a66cSDavid du Colombier procInit(void)
400*5e96a66cSDavid du Colombier {
401*5e96a66cSDavid du Colombier 	mbox.lock = vtLockAlloc();
402*5e96a66cSDavid du Colombier 	mbox.alloc = vtRendezAlloc(mbox.lock);
403*5e96a66cSDavid du Colombier 	mbox.work = vtRendezAlloc(mbox.lock);
404*5e96a66cSDavid du Colombier 
405*5e96a66cSDavid du Colombier 	mbox.maxmsg = NMsgInit;
406*5e96a66cSDavid du Colombier 	mbox.maxproc = NMsgProcInit;
407*5e96a66cSDavid du Colombier 	mbox.msize = NMsizeInit;
408*5e96a66cSDavid du Colombier 
409*5e96a66cSDavid du Colombier 	cliAddCmd("msg", cmdMsg);
410*5e96a66cSDavid du Colombier 
411*5e96a66cSDavid du Colombier 	cbox.lock = vtLockAlloc();
412*5e96a66cSDavid du Colombier 	cbox.con = nil;
413*5e96a66cSDavid du Colombier 	cbox.ncon = 0;
414*5e96a66cSDavid du Colombier 	cbox.msize = NMsizeInit;
415*5e96a66cSDavid du Colombier }
416