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