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: InterlockedDecrement64() 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 | LONG TotalOperations=0; |
28 | int i=0; |
29 | DWORD dwThreadID = 0; |
30 | HANDLE hThread[MAX_THREADS]; |
31 | TotalOperations = MAX_THREADS * REPEAT_COUNT; |
32 | GlobalCounter = TotalOperations; |
33 | |
34 | /* |
35 | * Initialize the PAL and return FAILURE if this fails |
36 | */ |
37 | |
38 | if(0 != (PAL_Initialize(argc, argv))) |
39 | { |
40 | return FAIL; |
41 | } |
42 | |
43 | #if defined(BIT64) |
44 | |
45 | //Create MAX_THREADS threads that will operate on the global counter |
46 | for (i=0;i<MAX_THREADS;i++) |
47 | { |
48 | hThread[i] = CreateThread( |
49 | NULL, // default security attributes |
50 | 0, // use default stack size |
51 | (LPTHREAD_START_ROUTINE) DecrementCounter, // thread function |
52 | NULL, // argument to thread function |
53 | 0, // use default creation flags |
54 | &dwThreadID); // returns the thread identifier |
55 | |
56 | // Check the return value for success. |
57 | if (hThread[i] == NULL) |
58 | { |
59 | Fail("ERROR: Was not able to create thread\n" |
60 | "GetLastError returned %d\n" , GetLastError()); |
61 | } |
62 | } |
63 | |
64 | //Wait for all threads to finish |
65 | for (i=0;i<MAX_THREADS;i++) |
66 | { |
67 | |
68 | if (WAIT_OBJECT_0 != WaitForSingleObject (hThread[i], INFINITE)) |
69 | { |
70 | Fail ("Main: Wait for Single Object failed. Failing test.\n" |
71 | "GetLastError returned %d\n" , GetLastError()); |
72 | } |
73 | } |
74 | |
75 | /* Compare the value of global counter with zero. |
76 | */ |
77 | if (0!=GlobalCounter) |
78 | { |
79 | Fail("Test Case Failed: InterlockedDecrement \n" ); |
80 | } |
81 | |
82 | #endif //defined(BIT64) |
83 | |
84 | PAL_Terminate(); |
85 | return PASS; |
86 | } |
87 | |
88 | void DecrementCounter(void) |
89 | { |
90 | int i=0; |
91 | |
92 | for (i=0; i<REPEAT_COUNT;i++) |
93 | { |
94 | InterlockedDecrement(&GlobalCounter); |
95 | } |
96 | } |
97 | |
98 | |
99 | |
100 | |