aboutsummaryrefslogtreecommitdiffstats
path: root/util/system/atomic_win.h
blob: 65c290e6ccc9b2dede3dc699c94b8c340911f20f (plain) (blame)
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
#pragma once

#include <intrin.h>

#define USE_GENERIC_SETGET

#if defined(_i386_)

    #pragma intrinsic(_InterlockedIncrement)
    #pragma intrinsic(_InterlockedDecrement)
    #pragma intrinsic(_InterlockedExchangeAdd)
    #pragma intrinsic(_InterlockedExchange)
    #pragma intrinsic(_InterlockedCompareExchange)

static inline intptr_t AtomicIncrement(TAtomic& a) {
    return _InterlockedIncrement((volatile long*)&a);
}

static inline intptr_t AtomicGetAndIncrement(TAtomic& a) {
    return _InterlockedIncrement((volatile long*)&a) - 1;
}

static inline intptr_t AtomicDecrement(TAtomic& a) {
    return _InterlockedDecrement((volatile long*)&a);
}

static inline intptr_t AtomicGetAndDecrement(TAtomic& a) {
    return _InterlockedDecrement((volatile long*)&a) + 1;
}

static inline intptr_t AtomicAdd(TAtomic& a, intptr_t b) {
    return _InterlockedExchangeAdd((volatile long*)&a, b) + b;
}

static inline intptr_t AtomicGetAndAdd(TAtomic& a, intptr_t b) {
    return _InterlockedExchangeAdd((volatile long*)&a, b);
}

static inline intptr_t AtomicSwap(TAtomic* a, intptr_t b) {
    return _InterlockedExchange((volatile long*)a, b);
}

static inline bool AtomicCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
    return _InterlockedCompareExchange((volatile long*)a, exchange, compare) == compare;
}

static inline intptr_t AtomicGetAndCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
    return _InterlockedCompareExchange((volatile long*)a, exchange, compare);
}

#else // _x86_64_

    #pragma intrinsic(_InterlockedIncrement64)
    #pragma intrinsic(_InterlockedDecrement64)
    #pragma intrinsic(_InterlockedExchangeAdd64)
    #pragma intrinsic(_InterlockedExchange64)
    #pragma intrinsic(_InterlockedCompareExchange64)

static inline intptr_t AtomicIncrement(TAtomic& a) {
    return _InterlockedIncrement64((volatile __int64*)&a);
}

static inline intptr_t AtomicGetAndIncrement(TAtomic& a) {
    return _InterlockedIncrement64((volatile __int64*)&a) - 1;
}

static inline intptr_t AtomicDecrement(TAtomic& a) {
    return _InterlockedDecrement64((volatile __int64*)&a);
}

static inline intptr_t AtomicGetAndDecrement(TAtomic& a) {
    return _InterlockedDecrement64((volatile __int64*)&a) + 1;
}

static inline intptr_t AtomicAdd(TAtomic& a, intptr_t b) {
    return _InterlockedExchangeAdd64((volatile __int64*)&a, b) + b;
}

static inline intptr_t AtomicGetAndAdd(TAtomic& a, intptr_t b) {
    return _InterlockedExchangeAdd64((volatile __int64*)&a, b);
}

static inline intptr_t AtomicSwap(TAtomic* a, intptr_t b) {
    return _InterlockedExchange64((volatile __int64*)a, b);
}

static inline bool AtomicCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
    return _InterlockedCompareExchange64((volatile __int64*)a, exchange, compare) == compare;
}

static inline intptr_t AtomicGetAndCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
    return _InterlockedCompareExchange64((volatile __int64*)a, exchange, compare);
}

static inline intptr_t AtomicOr(TAtomic& a, intptr_t b) {
    return _InterlockedOr64(&a, b) | b;
}

static inline intptr_t AtomicAnd(TAtomic& a, intptr_t b) {
    return _InterlockedAnd64(&a, b) & b;
}

static inline intptr_t AtomicXor(TAtomic& a, intptr_t b) {
    return _InterlockedXor64(&a, b) ^ b;
}

#endif // _x86_

//TODO
static inline void AtomicBarrier() {
    TAtomic val = 0;

    AtomicSwap(&val, 0);
}