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