]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.1.1/liblfds611/src/lfds611_abstraction/lfds611_abstraction_cas.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.1.1 / liblfds611 / src / lfds611_abstraction / lfds611_abstraction_cas.c
1 #include "lfds611_abstraction_internal_body.h"
2
3
4
5
6
7 /****************************************************************************/
8 #if (defined _WIN32 && defined _MSC_VER)
9
10   /* TRD : 64 bit and 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
11
12            _WIN32    indicates 64-bit or 32-bit Windows
13            _MSC_VER  indicates Microsoft C compiler
14   */
15
16   static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_cas( volatile lfds611_atom_t *destination, lfds611_atom_t exchange, lfds611_atom_t compare )
17   {
18     lfds611_atom_t
19       rv;
20
21     assert( destination != NULL );
22     // TRD : exchange can be any value in its range
23     // TRD : compare can be any value in its range
24
25     LFDS611_BARRIER_COMPILER_FULL;
26
27     rv = (lfds611_atom_t) _InterlockedCompareExchangePointer( (void * volatile *) destination, (void *) exchange, (void *) compare );
28
29     LFDS611_BARRIER_COMPILER_FULL;
30
31     return( rv );
32   }
33
34 #endif
35
36
37
38
39
40 /****************************************************************************/
41 #if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && __GNUC_PATCHLEVEL__ >= 0)
42
43   /* TRD : any OS on any CPU with GCC 4.1.0 or better
44
45            GCC 4.1.0 introduced the __sync_*() atomic intrinsics
46
47            __GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__  indicates GCC and which version
48   */
49
50   static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_cas( volatile lfds611_atom_t *destination, lfds611_atom_t exchange, lfds611_atom_t compare )
51   {
52     lfds611_atom_t
53       rv;
54
55     assert( destination != NULL );
56     // TRD : exchange can be any value in its range
57     // TRD : compare can be any value in its range
58
59     // TRD : note the different argument order for the GCC instrinsic to the MSVC instrinsic
60
61     LFDS611_BARRIER_COMPILER_FULL;
62
63     rv = (lfds611_atom_t) __sync_val_compare_and_swap( destination, compare, exchange );
64
65     LFDS611_BARRIER_COMPILER_FULL;
66
67     return( rv );
68   }
69
70 #endif
71