2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* Copyright (C) 1994 Cazamar Systems, Inc. */
13 #include <afs/param.h>
22 #define OSI_MOD1LOOPS 15000
23 #define OSI_MOD2LOOPS 10000
25 /* global variables for the test */
26 osi_mutex_t main_aMutex; /* mutex controlling access to a */
27 long a; /* variable a */
29 osi_rwlock_t main_bRWLock; /* rwlock controlling access to b */
30 long b; /* variable b itself */
32 osi_rwlock_t main_doneRWLock; /* lock for done */
33 int done; /* count of done dudes */
35 osi_log_t *main_logp; /* global log */
37 /* unlocked stat counters */
44 unsigned long main_Mod1(void *parm)
47 for(i=0; i<OSI_MOD1LOOPS; i++) {
48 lock_ObtainMutex(&main_aMutex);
49 osi_Log0(main_logp, "mod1");
50 lock_ObtainWrite(&main_bRWLock);
54 osi_assert(a+b == 100);
56 lock_ReleaseWrite(&main_bRWLock);
58 lock_ReleaseMutex(&main_aMutex);
61 osi_Log1(main_logp, "mod1 done, %d", m1Loops);
63 lock_ObtainWrite(&main_doneRWLock);
66 lock_ReleaseWrite(&main_doneRWLock);
70 unsigned long main_Mod2(void *parm)
73 for(i=0; i<OSI_MOD2LOOPS; i++) {
74 osi_Log0(main_logp, "mod2");
75 lock_ObtainMutex(&main_aMutex);
76 lock_ObtainWrite(&main_bRWLock);
80 osi_assert(a+b == 100);
82 lock_ReleaseWrite(&main_bRWLock);
84 lock_ReleaseMutex(&main_aMutex);
87 osi_Log4(main_logp, "mod2 done, %d %d %d %d", m2Loops, 2, 3, 4);
89 lock_ObtainWrite(&main_doneRWLock);
92 lock_ReleaseWrite(&main_doneRWLock);
96 unsigned long main_Scan1(unsigned long parm)
99 osi_Log0(main_logp, "scan1");
100 /* check to see if we're done */
101 lock_ObtainRead(&main_doneRWLock);
102 lock_AssertRead(&main_doneRWLock);
103 if (done >= 2) break;
104 lock_ReleaseRead(&main_doneRWLock);
106 /* check state for consistency */
107 lock_ObtainMutex(&main_aMutex);
108 lock_AssertMutex(&main_aMutex);
110 lock_ObtainRead(&main_bRWLock);
112 osi_assert(a+b == 100);
113 lock_ReleaseRead(&main_bRWLock);
115 lock_ReleaseMutex(&main_aMutex);
117 /* get a read lock here to test people getting stuck on RW lock alone */
118 lock_ObtainRead(&main_bRWLock);
120 lock_ReleaseRead(&main_bRWLock);
124 osi_Log2(main_logp, "scan1 done %d %d", s1Loops, 2);
126 lock_ReleaseRead(&main_doneRWLock);
127 lock_ObtainWrite(&main_doneRWLock);
128 lock_AssertWrite(&main_doneRWLock);
130 lock_ReleaseWrite(&main_doneRWLock);
134 unsigned long main_Scan2(unsigned long parm)
137 osi_Log0(main_logp, "scan2");
138 /* check to see if we're done */
139 lock_ObtainRead(&main_doneRWLock);
140 lock_AssertAny(&main_doneRWLock);
141 if (done >= 2) break;
142 lock_ReleaseRead(&main_doneRWLock);
144 /* check state for consistency without locks */
145 if (a+b != 100) s2Events++;
147 /* and record that we went around again */
150 /* give others a chance */
152 osi_Log3(main_logp, "scan2 done %d %d %d", s2Loops, 2, 3);
154 lock_ReleaseRead(&main_doneRWLock);
155 lock_ObtainWrite(&main_doneRWLock);
156 lock_AssertAny(&main_doneRWLock);
158 lock_ReleaseWrite(&main_doneRWLock);
162 main_BasicTest(HANDLE hWnd)
176 if (main_logp == NULL) {
177 main_logp = osi_LogCreate("basic", 0);
178 osi_LogEnable(main_logp);
179 osi_SetStatLog(main_logp);
182 /* create three processes, two modifiers and one scanner. The scanner
183 * checks that the basic invariants are being maintained, while the
184 * modifiers modify the global variables, maintaining certain invariants
187 * The invariant is that global variables a and b total 100.
193 lock_InitializeRWLock(&main_doneRWLock, "done lock");
194 lock_InitializeRWLock(&main_bRWLock, "b lock");
195 lock_InitializeMutex(&main_aMutex, "a mutex");
197 mod1Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
198 (LPTHREAD_START_ROUTINE) main_Mod1, 0, 0, &mod1ID);
199 if (mod1Handle == NULL) return -1;
201 mod2Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
202 (LPTHREAD_START_ROUTINE) main_Mod2, 0, 0, &mod2ID);
203 if (mod2Handle == NULL) return -2;
205 scan1Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
206 (LPTHREAD_START_ROUTINE) main_Scan1, 0, 0, &scan1ID);
207 if (scan1Handle== NULL) return -2;
209 scan2Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
210 (LPTHREAD_START_ROUTINE) main_Scan2, 0, 0, &scan2ID);
211 if (scan2Handle== NULL) return -2;
213 /* start running check daemon */
216 wsprintf(main_screenText[1], "Mod1 iteration %d", m1Loops);
217 wsprintf(main_screenText[2], "Mod2 iteration %d", m2Loops);
218 wsprintf(main_screenText[3], "Scan1 iteration %d", s1Loops);
219 wsprintf(main_screenText[4], "Scan2 iteration %d, %d opportunites seen",
221 main_ForceDisplay(hWnd);
223 /* copy out count of # of dudes finished */
224 lock_ObtainRead(&main_doneRWLock);
226 lock_ReleaseRead(&main_doneRWLock);
228 /* right now, we're waiting for 4 threads */
229 if (localDone == 4) break;
232 wsprintf(main_screenText[0], "Test done.");
233 main_ForceDisplay(hWnd);
235 /* done, release and finalize all locks */
236 lock_FinalizeRWLock(&main_doneRWLock);
237 lock_FinalizeRWLock(&main_bRWLock);
238 lock_FinalizeMutex(&main_aMutex);
240 /* finally clean up thread handles */
241 CloseHandle(mod1Handle);
242 CloseHandle(mod2Handle);
243 CloseHandle(scan1Handle);
244 CloseHandle(scan2Handle);