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