blob: afeb9cb710451b5c07aa813183a81646991a3e53 [file] [log] [blame]
Jason Evans92d32842011-03-18 18:15:37 -07001/******************************************************************************/
2#ifdef JEMALLOC_H_TYPES
3
4#endif /* JEMALLOC_H_TYPES */
5/******************************************************************************/
6#ifdef JEMALLOC_H_STRUCTS
7
8#endif /* JEMALLOC_H_STRUCTS */
9/******************************************************************************/
10#ifdef JEMALLOC_H_EXTERNS
11
12#define atomic_read_uint64(p) atomic_add_uint64(p, 0)
13#define atomic_read_uint32(p) atomic_add_uint32(p, 0)
Jason Evans06304a92012-03-23 16:09:56 -070014#define atomic_read_z(p) atomic_add_z(p, 0)
Jason Evans92d32842011-03-18 18:15:37 -070015
16#endif /* JEMALLOC_H_EXTERNS */
17/******************************************************************************/
18#ifdef JEMALLOC_H_INLINES
19
20#ifndef JEMALLOC_ENABLE_INLINE
21uint64_t atomic_add_uint64(uint64_t *p, uint64_t x);
22uint64_t atomic_sub_uint64(uint64_t *p, uint64_t x);
23uint32_t atomic_add_uint32(uint32_t *p, uint32_t x);
24uint32_t atomic_sub_uint32(uint32_t *p, uint32_t x);
Jason Evans06304a92012-03-23 16:09:56 -070025size_t atomic_add_z(size_t *p, size_t x);
26size_t atomic_sub_z(size_t *p, size_t x);
Jason Evans92d32842011-03-18 18:15:37 -070027#endif
28
29#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ATOMIC_C_))
Jason Evans3e292472011-03-24 16:48:11 -070030/******************************************************************************/
Jason Evans92d32842011-03-18 18:15:37 -070031/* 64-bit operations. */
32#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
33JEMALLOC_INLINE uint64_t
34atomic_add_uint64(uint64_t *p, uint64_t x)
35{
36
37 return (__sync_add_and_fetch(p, x));
38}
39
40JEMALLOC_INLINE uint64_t
41atomic_sub_uint64(uint64_t *p, uint64_t x)
42{
43
44 return (__sync_sub_and_fetch(p, x));
45}
Jason Evans763baa62011-03-18 19:10:31 -070046#elif (defined(JEMALLOC_OSATOMIC))
47JEMALLOC_INLINE uint64_t
48atomic_add_uint64(uint64_t *p, uint64_t x)
49{
50
51 return (OSAtomicAdd64((int64_t)x, (int64_t *)p));
52}
53
54JEMALLOC_INLINE uint64_t
55atomic_sub_uint64(uint64_t *p, uint64_t x)
56{
57
58 return (OSAtomicAdd64(-((int64_t)x), (int64_t *)p));
59}
Jason Evansb1726102012-02-28 16:50:47 -080060#elif (defined(__amd64__) || defined(__x86_64__))
Jason Evans3e292472011-03-24 16:48:11 -070061JEMALLOC_INLINE uint64_t
62atomic_add_uint64(uint64_t *p, uint64_t x)
63{
64
65 asm volatile (
66 "lock; xaddq %0, %1;"
67 : "+r" (x), "=m" (*p) /* Outputs. */
68 : "m" (*p) /* Inputs. */
69 );
70
71 return (x);
72}
73
74JEMALLOC_INLINE uint64_t
75atomic_sub_uint64(uint64_t *p, uint64_t x)
76{
77
78 x = (uint64_t)(-(int64_t)x);
79 asm volatile (
80 "lock; xaddq %0, %1;"
81 : "+r" (x), "=m" (*p) /* Outputs. */
82 : "m" (*p) /* Inputs. */
83 );
84
85 return (x);
86}
Jason Evans92d32842011-03-18 18:15:37 -070087#else
Jason Evans47e57f92011-03-22 09:00:56 -070088# if (LG_SIZEOF_PTR == 3)
89# error "Missing implementation for 64-bit atomic operations"
90# endif
Jason Evans92d32842011-03-18 18:15:37 -070091#endif
92
Jason Evans3e292472011-03-24 16:48:11 -070093/******************************************************************************/
Jason Evans92d32842011-03-18 18:15:37 -070094/* 32-bit operations. */
95#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
96JEMALLOC_INLINE uint32_t
97atomic_add_uint32(uint32_t *p, uint32_t x)
98{
99
100 return (__sync_add_and_fetch(p, x));
101}
102
103JEMALLOC_INLINE uint32_t
104atomic_sub_uint32(uint32_t *p, uint32_t x)
105{
106
107 return (__sync_sub_and_fetch(p, x));
108}
Jason Evans763baa62011-03-18 19:10:31 -0700109#elif (defined(JEMALLOC_OSATOMIC))
110JEMALLOC_INLINE uint32_t
111atomic_add_uint32(uint32_t *p, uint32_t x)
112{
113
114 return (OSAtomicAdd32((int32_t)x, (int32_t *)p));
115}
116
117JEMALLOC_INLINE uint32_t
118atomic_sub_uint32(uint32_t *p, uint32_t x)
119{
120
121 return (OSAtomicAdd32(-((int32_t)x), (int32_t *)p));
122}
Jason Evansb1726102012-02-28 16:50:47 -0800123#elif (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
Jason Evans3e292472011-03-24 16:48:11 -0700124JEMALLOC_INLINE uint32_t
125atomic_add_uint32(uint32_t *p, uint32_t x)
126{
127
128 asm volatile (
129 "lock; xaddl %0, %1;"
130 : "+r" (x), "=m" (*p) /* Outputs. */
131 : "m" (*p) /* Inputs. */
132 );
133
134 return (x);
135}
136
137JEMALLOC_INLINE uint32_t
138atomic_sub_uint32(uint32_t *p, uint32_t x)
139{
140
141 x = (uint32_t)(-(int32_t)x);
142 asm volatile (
143 "lock; xaddl %0, %1;"
144 : "+r" (x), "=m" (*p) /* Outputs. */
145 : "m" (*p) /* Inputs. */
146 );
147
148 return (x);
149}
Jason Evans3492daf2012-03-05 12:16:57 -0800150#elif (defined __SH4__ || defined __mips__) && (__GNUC__ > 4 || \
151 (__GNUC__ == 4 && (__GNUC_MINOR__ > 1 || (__GNUC_MINOR__ == 1 && \
152 __GNUC_PATCHLEVEL__ > 1))))
153JEMALLOC_INLINE uint32_t
154atomic_add_uint32(uint32_t *p, uint32_t x)
155{
156
157 return (__sync_add_and_fetch(p, x));
158}
159
160JEMALLOC_INLINE uint32_t
161atomic_sub_uint32(uint32_t *p, uint32_t x)
162{
163
164 return (__sync_sub_and_fetch(p, x));
165}
Jason Evans92d32842011-03-18 18:15:37 -0700166#else
167# error "Missing implementation for 32-bit atomic operations"
168#endif
Jason Evans06304a92012-03-23 16:09:56 -0700169
170/******************************************************************************/
171/* size_t operations. */
172JEMALLOC_INLINE size_t
173atomic_add_z(size_t *p, size_t x)
174{
175
176#if (LG_SIZEOF_PTR == 3)
177 return ((size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x));
178#elif (LG_SIZEOF_PTR == 2)
179 return ((size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x));
180#endif
181}
182
183JEMALLOC_INLINE size_t
184atomic_sub_z(size_t *p, size_t x)
185{
186
187#if (LG_SIZEOF_PTR == 3)
188 return ((size_t)atomic_add_uint64((uint64_t *)p,
189 (uint64_t)-((int64_t)x)));
190#elif (LG_SIZEOF_PTR == 2)
191 return ((size_t)atomic_add_uint32((uint32_t *)p,
192 (uint32_t)-((int32_t)x)));
193#endif
194}
Jason Evans92d32842011-03-18 18:15:37 -0700195#endif
196
197#endif /* JEMALLOC_H_INLINES */
198/******************************************************************************/