1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/*============================================================
**
** Source : test.c
**
** Purpose: Test for InterlockedCompareExchange() function
**
**
**=========================================================*/
/* This test is FINISHED. Note: The biggest feature of this function is that
it locks the value before it increments it -- in order to make it so only
one thread can access it. But, I really don't have a great test to make
sure it's thread safe. Any ideas?
*/
#include <palsuite.h>
#define START_VALUE 0
#define SECOND_VALUE 5
#define THIRD_VALUE 10
int __cdecl main(int argc, char *argv[]) {
LONGLONG BaseVariableToManipulate = START_VALUE;
LONGLONG ValueToExchange = SECOND_VALUE;
LONGLONG TempValue;
LONGLONG TheReturn;
/*
* Initialize the PAL and return FAILURE if this fails
*/
if(0 != (PAL_Initialize(argc, argv)))
{
return FAIL;
}
/*
** Run only on 64 bit platforms
*/
#if defined(BIT64) && defined(PLATFORM_UNIX)
/* Compare START_VALUE with BaseVariableToManipulate, they're equal,
so exchange
*/
TheReturn = InterlockedCompareExchange64(
&BaseVariableToManipulate, /* Destination */
ValueToExchange, /* Exchange value */
START_VALUE); /* Compare value */
/* Exchanged, these should be equal now */
if(BaseVariableToManipulate != ValueToExchange)
{
#ifdef PLATFORM_UNIX
Fail("ERROR: A successful compare and exchange should have occurred, "
"making the variable have the value of %ll, as opposed to the "
"current value of %ll.",
ValueToExchange,BaseVariableToManipulate);
#else
Fail("ERROR: A successful compare and exchange should have occurred, "
"making the variable have the value of %I64, as opposed to the "
"current value of %d.",
ValueToExchange,BaseVariableToManipulate);
#endif
}
/* Check to make sure it returns the original number which
'BaseVariableToManipulate' was set to.
*/
if(TheReturn != START_VALUE)
{
#ifdef PLATFORM_UNIX
Fail("ERROR: The return value after the first exchange should be the "
"former value of the variable, which was %ll, but it is now %ll.",
START_VALUE,TheReturn);
#else
Fail("ERROR: The return value after the first exchange should be the "
"former value of the variable, which was %I64, but it is now %I64.",
START_VALUE,TheReturn);
#endif
}
ValueToExchange = THIRD_VALUE; /* Give this a new value */
TempValue = BaseVariableToManipulate; /* Note value of Base */
/*
Do an exchange where 'BaseVariableToManipulate' doesn't
match -- therefore the exchange shouldn't happen.
So, it should end up the same as the 'TempValue' we saved.
*/
InterlockedCompareExchange64(&BaseVariableToManipulate,
ValueToExchange,
START_VALUE);
if(BaseVariableToManipulate != TempValue)
{
#ifdef PLATFORM_UNIX
Fail("ERROR: An attempted exchange should have failed due to "
"the compare failing. But, it seems to have succeeded. The "
"value should be %ll but is %ll in this case.",
TempValue,BaseVariableToManipulate);
#else
Fail("ERROR: An attempted exchange should have failed due to "
"the compare failing. But, it seems to have succeeded. The "
"value should be %I64 but is %I64 in this case.",
TempValue,BaseVariableToManipulate);
#endif
}
#endif //if defined(BIT64) && defined(PLATFORM_UNIX)
PAL_Terminate();
return PASS;
}
|