1/**
2 * hdr_atomic.h
3 * Written by Philip Orwig and released to the public domain,
4 * as explained at http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7#ifndef HDR_ATOMIC_H__
8#define HDR_ATOMIC_H__
9
10
11#if defined(_MSC_VER)
12
13#include <stdint.h>
14#include <intrin.h>
15
16static void __inline * hdr_atomic_load_pointer(void** pointer)
17{
18	_ReadBarrier();
19	return *pointer;
20}
21
22static void hdr_atomic_store_pointer(void** pointer, void* value)
23{
24	_WriteBarrier();
25	*pointer = value;
26}
27
28static int64_t __inline hdr_atomic_load_64(int64_t* field)
29{
30	_ReadBarrier();
31	return *field;
32}
33
34static void __inline hdr_atomic_store_64(int64_t* field, int64_t value)
35{
36	_WriteBarrier();
37	*field = value;
38}
39
40static int64_t __inline hdr_atomic_exchange_64(volatile int64_t* field, int64_t initial)
41{
42	return _InterlockedExchange64(field, initial);
43}
44
45static int64_t __inline hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t value)
46{
47	return _InterlockedExchangeAdd64(field, value) + value;
48}
49
50#elif defined(__ATOMIC_SEQ_CST)
51
52#define hdr_atomic_load_pointer(x) __atomic_load_n(x, __ATOMIC_SEQ_CST)
53#define hdr_atomic_store_pointer(f,v) __atomic_store_n(f,v, __ATOMIC_SEQ_CST)
54#define hdr_atomic_load_64(x) __atomic_load_n(x, __ATOMIC_SEQ_CST)
55#define hdr_atomic_store_64(f,v) __atomic_store_n(f,v, __ATOMIC_SEQ_CST)
56#define hdr_atomic_exchange_64(f,i) __atomic_exchange_n(f,i, __ATOMIC_SEQ_CST)
57#define hdr_atomic_add_fetch_64(field, value) __atomic_add_fetch(field, value, __ATOMIC_SEQ_CST)
58
59#elif defined(__x86_64__)
60
61#include <stdint.h>
62
63static inline void* hdr_atomic_load_pointer(void** pointer)
64{
65   void* p =  *pointer;
66	asm volatile ("" ::: "memory");
67	return p;
68}
69
70static inline void hdr_atomic_store_pointer(void** pointer, void* value)
71{
72    asm volatile ("lock; xchgq %0, %1" : "+q" (value), "+m" (*pointer));
73}
74
75static inline int64_t hdr_atomic_load_64(int64_t* field)
76{
77    int64_t i = *field;
78	asm volatile ("" ::: "memory");
79	return i;
80}
81
82static inline void hdr_atomic_store_64(int64_t* field, int64_t value)
83{
84    asm volatile ("lock; xchgq %0, %1" : "+q" (value), "+m" (*field));
85}
86
87static inline int64_t hdr_atomic_exchange_64(volatile int64_t* field, int64_t value)
88{
89    int64_t result = 0;
90    asm volatile ("lock; xchgq %1, %2" : "=r" (result), "+q" (value), "+m" (*field));
91    return result;
92}
93
94static inline int64_t hdr_atomic_add_fetch_64(volatile int64_t* field, int64_t value)
95{
96    return __sync_add_and_fetch(field, value);
97}
98
99#else
100
101#error "Unable to determine atomic operations for your platform"
102
103#endif
104
105#endif /* HDR_ATOMIC_H__ */
106