summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/miscellaneous/InterlockedCompareExchange64/test1/test.cpp
blob: 56430e60cf07184845bd74ad1c6e463fe1819972 (plain)
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; 
}