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. */
12 #include <afs/param.h>
22 #define main_NITERS 10000 /* bops between the two */
24 osi_rwlock_t trylock_first;
25 osi_mutex_t trylock_second;
26 osi_rwlock_t trylock_third;
28 /* counters are not shared */
29 static long neonCount;
30 static long salmonCount;
31 static long interestingEvents;
33 /* set under trylock_first rwlock */
36 /* neon tetras swim normally, i.e. downstream down the locking hierarchy */
37 long main_Neon(long parm)
41 lock_ObtainRead(&trylock_first);
43 lock_ObtainMutex(&trylock_second);
45 lock_ObtainWrite(&trylock_third);
47 lock_ReleaseWrite(&trylock_third);
48 lock_ReleaseMutex(&trylock_second);
49 lock_ReleaseRead(&trylock_first);
51 if (neonCount++ >= main_NITERS) break;
54 /* bump done counter under lock */
55 lock_ObtainMutex(&trylock_second);
57 lock_ReleaseMutex(&trylock_second);
62 /* go upstream against the locking hierarchy */
63 long main_Salmon(long parm)
67 code = lock_TryRead(&trylock_third);
69 /* failed, release others, wait for this, and continue */
70 lock_ObtainRead(&trylock_third);
71 lock_ReleaseRead(&trylock_third);
75 code = lock_TryMutex(&trylock_second);
78 lock_ReleaseRead(&trylock_third);
79 lock_ObtainMutex(&trylock_second);
80 lock_ReleaseMutex(&trylock_second);
84 code = lock_TryWrite(&trylock_first);
86 lock_ReleaseRead(&trylock_third);
87 lock_ReleaseMutex(&trylock_second);
88 lock_ObtainWrite(&trylock_first);
89 lock_ReleaseWrite(&trylock_first);
94 lock_ReleaseRead(&trylock_third);
95 lock_ReleaseMutex(&trylock_second);
96 lock_ReleaseWrite(&trylock_first);
99 if (salmonCount++ >= main_NITERS) break;
104 lock_ObtainMutex(&trylock_second);
106 lock_ReleaseMutex(&trylock_second);
110 main_TryLockTest(HANDLE hWnd)
122 interestingEvents = 0;
124 /* create three processes, two modifiers and one scanner. The scanner
125 * checks that the basic invariants are being maintained, while the
126 * modifiers modify the global variables, maintaining certain invariants
131 main_ForceDisplay(hWnd);
133 lock_InitializeRWLock(&trylock_first, "first lock");
134 lock_InitializeRWLock(&trylock_third, "third lock");
135 lock_InitializeMutex(&trylock_second, "second mutex");
137 mod1Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
138 (LPTHREAD_START_ROUTINE) main_Neon, 0, 0, &mod1ID);
139 if (mod1Handle == NULL) return -1;
141 mod2Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
142 (LPTHREAD_START_ROUTINE) main_Salmon, 0, 0, &mod2ID);
143 if (mod2Handle == NULL) return -2;
145 /* start running check daemon */
148 wsprintf(main_screenText[1], "Neon tetra iteration %d", neonCount);
149 wsprintf(main_screenText[2], "Salmon iteration %d", salmonCount);
150 wsprintf(main_screenText[3], "Interesting events: %d", interestingEvents);
151 main_ForceDisplay(hWnd);
153 /* copy out count of # of dudes finished */
154 lock_ObtainMutex(&trylock_second);
156 lock_ReleaseMutex(&trylock_second);
158 /* right now, we're waiting for 2 threads */
159 if (localDone == 2) break;
162 /* done, release and finalize all locks */
163 lock_FinalizeRWLock(&trylock_first);
164 lock_FinalizeRWLock(&trylock_third);
165 lock_FinalizeMutex(&trylock_second);
167 /* finally clean up thread handles */
168 CloseHandle(mod1Handle);
169 CloseHandle(mod2Handle);