Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / client_osi / trylock.c
blob6daabd46b29a770dbced7facf95591137dde50e3
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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
8 */
10 /* Copyright (C) 1994 Cazamar Systems, Inc. */
12 #include <afs/param.h>
13 #include <afs/stds.h>
15 #include "windows.h"
16 #include <string.h>
17 #include "main.h"
18 #include "trylock.h"
19 #include "osi.h"
20 #include <assert.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 */
34 static int done;
36 /* neon tetras swim normally, i.e. downstream down the locking hierarchy */
37 long main_Neon(long parm)
39 while (1) {
40 Sleep(0);
41 lock_ObtainRead(&trylock_first);
42 Sleep(0);
43 lock_ObtainMutex(&trylock_second);
44 Sleep(0);
45 lock_ObtainWrite(&trylock_third);
46 Sleep(0);
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);
56 done++;
57 lock_ReleaseMutex(&trylock_second);
59 return 0;
62 /* go upstream against the locking hierarchy */
63 long main_Salmon(long parm)
65 long code;
66 while (1) {
67 code = lock_TryRead(&trylock_third);
68 if (code == 0) {
69 /* failed, release others, wait for this, and continue */
70 lock_ObtainRead(&trylock_third);
71 lock_ReleaseRead(&trylock_third);
72 interestingEvents++;
73 continue;
75 code = lock_TryMutex(&trylock_second);
76 if (!code) {
77 /* failed */
78 lock_ReleaseRead(&trylock_third);
79 lock_ObtainMutex(&trylock_second);
80 lock_ReleaseMutex(&trylock_second);
81 interestingEvents++;
82 continue;
84 code = lock_TryWrite(&trylock_first);
85 if (!code) {
86 lock_ReleaseRead(&trylock_third);
87 lock_ReleaseMutex(&trylock_second);
88 lock_ObtainWrite(&trylock_first);
89 lock_ReleaseWrite(&trylock_first);
90 interestingEvents++;
91 continue;
93 /* done */
94 lock_ReleaseRead(&trylock_third);
95 lock_ReleaseMutex(&trylock_second);
96 lock_ReleaseWrite(&trylock_first);
98 /* check for done */
99 if (salmonCount++ >= main_NITERS) break;
101 Sleep(0);
104 lock_ObtainMutex(&trylock_second);
105 done++;
106 lock_ReleaseMutex(&trylock_second);
107 return 0;
110 main_TryLockTest(HANDLE hWnd)
112 long mod1ID;
113 long mod2ID;
114 HANDLE mod1Handle;
115 HANDLE mod2Handle;
116 long localDone;
118 osi_Init();
120 salmonCount = 0;
121 neonCount = 0;
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
127 * by using locks.
129 done = 0;
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 */
146 while (1) {
147 Sleep(1000);
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);
155 localDone = done;
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);
170 return 0;