-
Notifications
You must be signed in to change notification settings - Fork 4.9k
/
Copy pathPalRedhawkInline.h
129 lines (104 loc) · 3.84 KB
/
PalRedhawkInline.h
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
123
124
125
126
127
128
129
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// Implementation of Redhawk PAL inline functions
#include <errno.h>
FORCEINLINE int32_t PalInterlockedIncrement(_Inout_ int32_t volatile *pDst)
{
return __sync_add_and_fetch(pDst, 1);
}
FORCEINLINE int32_t PalInterlockedDecrement(_Inout_ int32_t volatile *pDst)
{
return __sync_sub_and_fetch(pDst, 1);
}
FORCEINLINE uint32_t PalInterlockedOr(_Inout_ uint32_t volatile *pDst, uint32_t iValue)
{
return __sync_or_and_fetch(pDst, iValue);
}
FORCEINLINE uint32_t PalInterlockedAnd(_Inout_ uint32_t volatile *pDst, uint32_t iValue)
{
return __sync_and_and_fetch(pDst, iValue);
}
FORCEINLINE int32_t PalInterlockedExchange(_Inout_ int32_t volatile *pDst, int32_t iValue)
{
#ifdef __clang__
return __sync_swap(pDst, iValue);
#else
return __atomic_exchange_n(pDst, iValue, __ATOMIC_ACQ_REL);
#endif
}
FORCEINLINE int64_t PalInterlockedExchange64(_Inout_ int64_t volatile *pDst, int64_t iValue)
{
#ifdef __clang__
return __sync_swap(pDst, iValue);
#else
return __atomic_exchange_n(pDst, iValue, __ATOMIC_ACQ_REL);
#endif
}
FORCEINLINE int32_t PalInterlockedCompareExchange(_Inout_ int32_t volatile *pDst, int32_t iValue, int32_t iComparand)
{
return __sync_val_compare_and_swap(pDst, iComparand, iValue);
}
FORCEINLINE int64_t PalInterlockedCompareExchange64(_Inout_ int64_t volatile *pDst, int64_t iValue, int64_t iComparand)
{
return __sync_val_compare_and_swap(pDst, iComparand, iValue);
}
#if defined(HOST_AMD64) || defined(HOST_ARM64)
FORCEINLINE uint8_t PalInterlockedCompareExchange128(_Inout_ int64_t volatile *pDst, int64_t iValueHigh, int64_t iValueLow, int64_t *pComparandAndResult)
{
__int128_t iComparand = ((__int128_t)pComparandAndResult[1] << 64) + (uint64_t)pComparandAndResult[0];
__int128_t iResult = __sync_val_compare_and_swap((__int128_t volatile*)pDst, iComparand, ((__int128_t)iValueHigh << 64) + (uint64_t)iValueLow);
pComparandAndResult[0] = (int64_t)iResult; pComparandAndResult[1] = (int64_t)(iResult >> 64);
return iComparand == iResult;
}
#endif // HOST_AMD64
#ifdef HOST_64BIT
#define PalInterlockedExchangePointer(_pDst, _pValue) \
((void *)PalInterlockedExchange64((int64_t volatile *)(_pDst), (int64_t)(size_t)(_pValue)))
#define PalInterlockedCompareExchangePointer(_pDst, _pValue, _pComparand) \
((void *)PalInterlockedCompareExchange64((int64_t volatile *)(_pDst), (int64_t)(size_t)(_pValue), (int64_t)(size_t)(_pComparand)))
#else // HOST_64BIT
#define PalInterlockedExchangePointer(_pDst, _pValue) \
((void *)PalInterlockedExchange((int32_t volatile *)(_pDst), (int32_t)(size_t)(_pValue)))
#define PalInterlockedCompareExchangePointer(_pDst, _pValue, _pComparand) \
((void *)PalInterlockedCompareExchange((int32_t volatile *)(_pDst), (int32_t)(size_t)(_pValue), (int32_t)(size_t)(_pComparand)))
#endif // HOST_64BIT
FORCEINLINE void PalYieldProcessor()
{
#if defined(HOST_X86) || defined(HOST_AMD64)
__asm__ __volatile__(
"rep\n"
"nop"
);
#elif defined(HOST_ARM64)
__asm__ __volatile__(
"dmb ishst\n"
"yield"
);
#endif
}
FORCEINLINE void PalMemoryBarrier()
{
__sync_synchronize();
}
#define PalDebugBreak() abort()
FORCEINLINE int32_t PalGetLastError()
{
return errno;
}
FORCEINLINE void PalSetLastError(int32_t error)
{
errno = error;
}
FORCEINLINE int32_t PalOsPageSize()
{
#if defined(HOST_AMD64)
// all supported platforms use 4K pages on x64, including emulated environments
return 0x1000;
#elif defined(HOST_APPLE)
// OSX and related OS expose 16-kilobyte pages to the 64-bit userspace
// https://developer.apple.com/library/archive/documentation/Performance/Conceptual/ManagingMemory/Articles/AboutMemory.html
return 0x4000;
#else
return PalGetOsPageSize();
#endif
}