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
);