clean up headers, obsd socket.h needs types.h
[arla.git] / lwp / rw.c
blobd5ee206cb7ade22e60499e5f1d75f7fe173a5610
1 /*
2 ****************************************************************************
3 * Copyright IBM Corporation 1988, 1989 - All Rights Reserved *
4 * *
5 * Permission to use, copy, modify, and distribute this software and its *
6 * documentation for any purpose and without fee is hereby granted, *
7 * provided that the above copyright notice appear in all copies and *
8 * that both that copyright notice and this permission notice appear in *
9 * supporting documentation, and that the name of IBM not be used in *
10 * advertising or publicity pertaining to distribution of the software *
11 * without specific, written prior permission. *
12 * *
13 * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL *
14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM *
15 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY *
16 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER *
17 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING *
18 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
19 ****************************************************************************
23 (Multiple) readers & writers test of LWP stuff.
25 Created: 11/1/83, J. Rosenberg
29 #include <sys/time.h>
30 #include <stdio.h>
31 #include <stdlib.h>
33 #include <lwp.h>
34 #include "lock.h"
35 #include "preempt.h"
37 #define DEFAULT_READERS 5
39 #define STACK_SIZE (16*1024)
41 /* The shared queue */
42 typedef struct QUEUE {
43 struct QUEUE *prev, *next;
44 char *data;
45 struct Lock lock;
46 } queue;
48 static queue *init()
50 queue *q;
52 q = (queue *) malloc(sizeof(queue));
53 q -> prev = q -> next = q;
54 return(q);
57 static char empty(queue *q)
59 return (q->prev == q && q->next == q);
62 static void insert(queue *q, char *s)
64 queue *new;
66 new = (queue *) malloc(sizeof(queue));
67 new -> data = s;
68 new -> prev = q -> prev;
69 q -> prev -> next = new;
70 q -> prev = new;
71 new -> next = q;
74 static char *Remove(queue *q)
76 queue *old;
77 char *s;
79 if (empty(q)) {
80 printf("Remove from empty queue");
81 abort();
84 old = q -> next;
85 q -> next = old -> next;
86 q -> next -> prev = q;
87 s = old -> data;
88 free(old);
89 return(s);
92 queue *q;
94 int asleep; /* Number of processes sleeping -- used for
95 clean termination */
97 static void
98 read_process(char *id)
100 printf("\t[Reader %d]\n", *(int *)id);
101 LWP_NewRock(1, id);
102 LWP_DispatchProcess(); /* Just relinquish control for now */
104 PRE_PreemptMe();
105 for (;;) {
106 int i;
107 char *tmp;
109 /* Wait until there is something in the queue */
110 asleep++;
111 ObtainReadLock(&q->lock);
112 while (empty(q)) {
113 ReleaseReadLock(&q->lock);
114 LWP_WaitProcess((void *)q);
115 ObtainReadLock(&q->lock);
117 asleep--;
118 for (i=0; i<10000; i++) ;
119 PRE_BeginCritical();
120 LWP_GetRock(1, &tmp);
121 printf("[%d: %s]\n", *(int *)tmp, Remove(q));
122 PRE_EndCritical();
123 ReleaseReadLock(&q->lock);
124 LWP_DispatchProcess();
128 static void write_process()
130 static char *messages[] =
132 "Mary had a little lamb,",
133 "Its fleece was white as snow,",
134 "And everywhere that Mary went,",
135 "The lamb was sure to go",
136 "Mary had a little lamb,",
137 "Its fleece was white as snow,",
138 "And everywhere that Mary went,",
139 "The lamb was sure to go",
140 "Mary had a little lamb,",
141 "Its fleece was white as snow,",
142 "And everywhere that Mary went,",
143 "The lamb was sure to go",
144 "Mary had a little lamb,",
145 "Its fleece was white as snow,",
146 "And everywhere that Mary went,",
147 "The lamb was sure to go",
148 "Mary had a little lamb,",
149 "Its fleece was white as snow,",
150 "And everywhere that Mary went,",
151 "The lamb was sure to go",
152 "Mary had a little lamb,",
153 "Its fleece was white as snow,",
154 "And everywhere that Mary went,",
155 "The lamb was sure to go",
156 "Mary had a little lamb,",
157 "Its fleece was white as snow,",
158 "And everywhere that Mary went,",
159 "The lamb was sure to go",
160 "Mary had a little lamb,",
161 "Its fleece was white as snow,",
162 "And everywhere that Mary went,",
163 "The lamb was sure to go",
164 "Mary had a little lamb,",
165 "Its fleece was white as snow,",
166 "And everywhere that Mary went,",
167 "The lamb was sure to go",
168 "Mary had a little lamb,",
169 "Its fleece was white as snow,",
170 "And everywhere that Mary went,",
171 "The lamb was sure to go",
174 char **mesg;
176 printf("\t[Writer]\n");
177 PRE_PreemptMe();
179 /* Now loop & write data */
180 for (mesg=messages; *mesg!=0; mesg++) {
181 ObtainWriteLock(&q->lock);
182 insert(q, *mesg);
183 ReleaseWriteLock(&q->lock);
184 LWP_SignalProcess(q);
187 asleep++;
191 Arguments:
192 0: Unix junk, ignore
193 1: Number of readers to create (default is DEFAULT_READERS)
194 2: # msecs for interrupt (to satisfy Larry)
195 3: Present if lwp_debug to be set
200 main(int argc, char **argv)
202 int nreaders, i;
203 long interval; /* To satisfy Brad */
204 PROCESS *readers;
205 int *readersid;
206 PROCESS writer, master;
207 struct timeval tv;
208 char rname[9];
210 printf("\n*Readers & Writers*\n\n");
212 /* Determine # readers */
213 if (argc == 1)
214 nreaders = DEFAULT_READERS;
215 else
216 sscanf(*++argv, "%d", &nreaders);
217 printf("[There will be %d readers]\n", nreaders);
219 interval = (argc >= 3 ? atoi(*++argv)*1000 : 50000);
221 if (argc == 4) lwp_debug = 1;
222 LWP_InitializeProcessSupport(0, &master);
223 printf("[Support initialized]\n");
224 tv.tv_sec = 0;
225 tv.tv_usec = interval;
226 PRE_InitPreempt(&tv);
228 /* Initialize queue */
229 q = init();
231 /* Initialize lock */
232 Lock_Init(&q->lock);
234 asleep = 0;
235 /* Now create readers */
236 printf("[Creating Readers...\n");
237 readers = (PROCESS *) calloc(nreaders, sizeof(PROCESS));
238 readersid = (int *) calloc(nreaders, sizeof(int));
239 for (i=0; i<nreaders; i++) {
240 snprintf(rname, sizeof(rname), "Reader %d", i);
241 readersid[i] = i;
242 LWP_CreateProcess(read_process,
243 STACK_SIZE, 0, (char *)&readersid[i],
244 rname, &readers[i]);
246 printf("done]\n");
248 printf("\t[Creating Writer...\n");
249 LWP_CreateProcess(write_process, STACK_SIZE, 1, 0, "Writer", &writer);
250 printf("done]\n");
252 /* Now loop until everyone's done */
253 while (asleep != nreaders+1) LWP_DispatchProcess();
254 /* Destroy the readers */
255 for (i=nreaders-1; i>=0; i--) LWP_DestroyProcess(readers[i]);
256 printf("\n*Exiting*\n");
257 return 0;