:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / apps / tests / tests / Mutex / fivemutex.c
1 /* fivemutex.c: hungry philosophers problem
2  *
3  * (c) Copyright D.W.Howells 2000.
4  *     All rights reserved
5  */
6 #include <windows.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #define ERR(X,Y) do { if (X) { perror(""Y""); return 1; } } while(0)
11 #define RUNLENGTH 4
12
13 int count[5];
14
15 const char *names[] = {
16         "five/1", "five/2", "five/3", "five/4", "five/5"
17 };
18
19 DWORD WINAPI child(LPVOID tparam)
20 {
21         HANDLE left, right, first, second;
22         const char *lname, *rname;
23         int pid = (int) tparam;
24         int wt;
25
26         lname = names[pid%5];
27         rname = names[(pid+1)%5];
28
29         /* create a mutex */
30         left = CreateMutex(NULL,0,lname);       ERR(!left,"create left");
31         right = CreateMutex(NULL,0,rname);      ERR(!left,"create right");
32
33         printf("[%d] left: %p [%s]\n",pid,left,lname);
34         printf("[%d] right: %p [%s]\n",pid,right,rname);
35
36         /* pick the forks up in numerical order, else risk starvation */
37         if (pid%5 < (pid+1)%5) {
38                 first = left;
39                 second = right;
40         }
41         else {
42                 first = right;
43                 second = left;
44         }
45
46         for (;;) {
47                 /* grab the left mutex */
48                 wt = WaitForMultipleObjects(1,&first,0,INFINITE);
49                 if (wt!=WAIT_OBJECT_0)
50                         goto wait_failed;
51
52                 /* grab the right mutex */
53                 wt = WaitForMultipleObjects(1,&second,0,INFINITE);
54                 if (wt!=WAIT_OBJECT_0)
55                         goto wait_failed;
56
57                 /* got it */
58                 count[pid]++;
59
60                 /* pass the mutexes */
61                 ERR(!ReleaseMutex(left),"release left");
62                 ERR(!ReleaseMutex(right),"release right");
63                 continue;
64
65             wait_failed:
66                 switch (wt) {
67                 case WAIT_OBJECT_0+1:
68                         printf("[%d] obtained mutex __1__\n",pid);
69                         exit(1);
70                 case WAIT_ABANDONED_0:
71                 case WAIT_ABANDONED_0+1:
72                         printf("[%d] abandoned wait\n",pid);
73                         continue;
74                 case WAIT_TIMEOUT:
75                         printf("[%d] wait timed out\n",pid);
76                         exit(1);
77                 default:
78                         ERR(1,"WaitForMultipleObjects");
79                 }
80
81                 return 1;
82         }
83
84         /* close the handles */
85         ERR(!CloseHandle(left),"close left");
86         ERR(!CloseHandle(right),"close right");
87
88         return 0;
89
90 }
91
92 int main()
93 {
94         HANDLE hThread[5];
95         DWORD tid;
96         int loop;
97
98         for (loop=0; loop<5; loop++) {
99
100                 hThread[loop] = CreateThread(NULL,                                      /* thread attributes */
101                                                                          0,                                     /* stack size */
102                                                                          child,                         /* start address */
103                                                                          (void*)loop,                   /* parameter */
104                                                                          0,                                     /* creation flags */
105                                                                          &tid                                   /* thread ID */
106                                                                          );
107                 if (!hThread[loop])
108                 {
109                                 ERR(1,"CreateThread");
110                 }
111         }
112
113         WaitForMultipleObjects(5,hThread,0,RUNLENGTH*1000);
114
115         for (loop=0; loop<5; loop++)
116                 TerminateThread(hThread[loop],0);
117
118         for (loop=0; loop<5; loop++)
119                 printf("[%d] ate %d times (%d times per second)\n",
120                        loop,count[loop],count[loop]/RUNLENGTH
121                            );
122
123         return 0;
124 }