Initial revision
[reactos.git] / reactos / 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 }