windows-more-updates-20030315
[openafs.git] / src / WINNT / client_osi / trylock.c
1 /* 
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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  */
9
10 /* Copyright (C) 1994 Cazamar Systems, Inc. */
11
12 #include <afs/param.h>
13 #include <afs/stds.h>
14
15 #include "windows.h"
16 #include <string.h>
17 #include "main.h"
18 #include "trylock.h"
19 #include "osi.h"
20 #include <assert.h>
21
22 #define main_NITERS     10000   /* bops between the two */
23
24 osi_rwlock_t trylock_first;
25 osi_mutex_t trylock_second;
26 osi_rwlock_t trylock_third;
27
28 /* counters are not shared */
29 static long neonCount;
30 static long salmonCount;
31 static long interestingEvents;
32
33 /* set under trylock_first rwlock */
34 static int done;
35
36 /* neon tetras swim normally, i.e. downstream down the locking hierarchy */
37 long main_Neon(long parm)
38 {
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);
50
51                 if (neonCount++ >= main_NITERS) break;
52         }
53
54         /* bump done counter under lock */
55         lock_ObtainMutex(&trylock_second);
56         done++;
57         lock_ReleaseMutex(&trylock_second);
58
59         return 0;
60 }
61
62 /* go upstream against the locking hierarchy */
63 long main_Salmon(long parm)
64 {
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;
74                 }
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;
83                 }
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;
92                 }
93                 /* done */
94                 lock_ReleaseRead(&trylock_third);
95                 lock_ReleaseMutex(&trylock_second);
96                 lock_ReleaseWrite(&trylock_first);
97
98                 /* check for done */
99                 if (salmonCount++ >= main_NITERS) break;
100
101                 Sleep(0);
102         }
103
104         lock_ObtainMutex(&trylock_second);
105         done++;
106         lock_ReleaseMutex(&trylock_second);
107         return 0;
108 }
109
110 main_TryLockTest(HANDLE hWnd)
111 {
112         long mod1ID;
113         long mod2ID;
114         HANDLE mod1Handle;
115         HANDLE mod2Handle;
116         long localDone;
117
118         osi_Init();
119
120         salmonCount = 0;
121         neonCount = 0;
122         interestingEvents = 0;
123         
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.
128          */
129         done = 0;
130         
131         main_ForceDisplay(hWnd);
132
133         lock_InitializeRWLock(&trylock_first, "first lock");
134         lock_InitializeRWLock(&trylock_third, "third lock");
135         lock_InitializeMutex(&trylock_second, "second mutex");
136
137         mod1Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
138                 (LPTHREAD_START_ROUTINE) main_Neon, 0, 0, &mod1ID);
139         if (mod1Handle == NULL) return -1;
140
141         mod2Handle = CreateThread((SECURITY_ATTRIBUTES *) 0, 0,
142                 (LPTHREAD_START_ROUTINE) main_Salmon, 0, 0, &mod2ID);
143         if (mod2Handle == NULL) return -2;
144
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);
152
153                 /* copy out count of # of dudes finished */
154                 lock_ObtainMutex(&trylock_second);
155                 localDone = done;
156                 lock_ReleaseMutex(&trylock_second);
157
158                 /* right now, we're waiting for 2 threads */
159                 if (localDone == 2) break;
160         }
161         
162         /* done, release and finalize all locks */
163         lock_FinalizeRWLock(&trylock_first);
164         lock_FinalizeRWLock(&trylock_third);
165         lock_FinalizeMutex(&trylock_second);
166
167         /* finally clean up thread handles */
168         CloseHandle(mod1Handle);
169         CloseHandle(mod2Handle);
170         return 0;
171 }