1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | /*============================================================ |
6 | ** |
7 | ** Source : test.c |
8 | ** |
9 | ** Purpose: InterlockedDecrement() function |
10 | ** |
11 | ** The test case spawns MAX_THREADS Threads, and each thread call InterlockedDecrement Function to decrement a |
12 | ** global counter REPEAT_COUNT Times. The Test case sets the global counter to MAX_THREADS * REPEAT_COUNT |
13 | ** at the begining of the test. The test cases passes if at the end the test the value of the global counter is Zero. |
14 | ** |
15 | ** |
16 | **=========================================================*/ |
17 | |
18 | #include <palsuite.h> |
19 | #define MAX_THREADS 64 |
20 | #define REPEAT_COUNT 10000 |
21 | |
22 | LONG GlobalCounter = 0; |
23 | void DecrementCounter(void); |
24 | |
25 | int __cdecl main(int argc, char *argv[]) |
26 | { |
27 | |
28 | LONG TotalOperations=0; |
29 | int i=0; |
30 | DWORD dwThreadID = 0; |
31 | HANDLE hThread[MAX_THREADS]; |
32 | TotalOperations = MAX_THREADS * REPEAT_COUNT; |
33 | GlobalCounter = TotalOperations; |
34 | |
35 | /* |
36 | * Initialize the PAL and return FAILURE if this fails |
37 | */ |
38 | if(0 != (PAL_Initialize(argc, argv))) |
39 | { |
40 | return FAIL; |
41 | } |
42 | |
43 | //Create MAX_THREADS threads that will operate on the global counter |
44 | for (i=0;i<MAX_THREADS;i++) |
45 | { |
46 | hThread[i] = CreateThread( |
47 | NULL, // default security attributes |
48 | 0, // use default stack size |
49 | (LPTHREAD_START_ROUTINE) DecrementCounter, // thread function |
50 | NULL, // argument to thread function |
51 | 0, // use default creation flags |
52 | &dwThreadID); // returns the thread identifier |
53 | |
54 | // Check the return value for success. |
55 | |
56 | if (hThread[i] == NULL) |
57 | { |
58 | Fail("ERROR: Was not able to create thread\n" |
59 | "GetLastError returned %d\n" , GetLastError()); |
60 | } |
61 | } |
62 | |
63 | //Wait for all threads to finish |
64 | for (i=0;i<MAX_THREADS;i++) |
65 | { |
66 | if (WAIT_OBJECT_0 != WaitForSingleObject (hThread[i], INFINITE)) |
67 | { |
68 | Fail ("Main: Wait for Single Object failed. Failing test.\n" |
69 | "GetLastError returned %d\n" , GetLastError()); |
70 | } |
71 | } |
72 | |
73 | /* Compare the value of global counter with zero. |
74 | */ |
75 | if (0!=GlobalCounter) |
76 | { |
77 | Fail("Test Case Failed: InterlockedDecrement \n" ); |
78 | } |
79 | |
80 | PAL_Terminate(); |
81 | return PASS; |
82 | } |
83 | |
84 | void DecrementCounter(void) |
85 | { |
86 | int i=0; |
87 | for (i=0; i<REPEAT_COUNT;i++) |
88 | { |
89 | InterlockedDecrement(&GlobalCounter); |
90 | } |
91 | } |
92 | |
93 | |
94 | |
95 | |