Shared Persistent Heap Data Environment Manual  1.1.0
sasatom.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1995-2014 IBM Corporation.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation, Steven Munroe - initial API and implementation
10  */
11 
12 #ifndef _SASATOMIC_H
13 #define _SASATOMIC_H
14 
15 #include <sched.h> // for sched_yield
16 
28 #define GCC_VERSION \
30  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
31 
34 typedef unsigned int sas_spin_lock_t;
36 typedef void* sas_lock_ptr_t;
37 
38 #if defined(__powerpc64__) || defined (__powerpc__)
39 #include "sasatom_powerpc.h"
40 #elif defined(__x86_64__)
41 #include "sasatom_x86_64.h"
42 #elif defined(__i386__)
43 #include "sasatom_i386.h"
44 #else
45 #include "sasatom_generic.h"
46 #endif
47 
51 #define sas_write_barrier() __arch_sas_write_barrier()
52 
56 #define sas_read_barrier() __arch_sas_read_barrier()
57 
61 #define sas_full_barrier() __arch_sas_full_barrier()
62 
66 #define sas_code_barrier() __asm ("" ::: "memory")
67 
76 static inline void *
77 sas_fetch_and_add_ptr(void **pointer, long int delta)
78 {
79  return __arch_fetch_and_add_ptr(pointer, delta);
80 }
81 
90 static inline long int
91 sas_fetch_and_add(long *pointer, long int delta)
92 {
93  return __arch_fetch_and_add(pointer, delta);
94 }
95 
104 static inline long int
105 sas_fetch_and_and(unsigned int *pointer, int delta)
106 {
107 #if GCC_VERSION >= 40700
108  return __atomic_fetch_and(pointer, delta, __ATOMIC_ACQ_REL);
109 #else
110  return __sync_fetch_and_and(pointer, delta);
111 #endif
112 }
113 
122 static inline long int
123 sas_fetch_and_and_long(unsigned long *pointer, long int delta)
124 {
125 #if GCC_VERSION >= 40700
126  return __atomic_fetch_and(pointer, delta, __ATOMIC_ACQ_REL);
127 #else
128  return __sync_fetch_and_and(pointer, delta);
129 #endif
130 }
131 
140 static inline long int
141 sas_fetch_and_or(unsigned int *pointer, int delta)
142 {
143 #if GCC_VERSION >= 40700
144  return __atomic_fetch_or(pointer, delta, __ATOMIC_ACQ_REL);
145 #else
146  return __sync_fetch_and_or(pointer, delta);
147 #endif
148 }
149 
158 static inline long int
159 sas_fetch_and_or_long(unsigned long *pointer, long int delta)
160 {
161 #if GCC_VERSION >= 40700
162  return __atomic_fetch_or(pointer, delta, __ATOMIC_ACQ_REL);
163 #else
164  return __sync_fetch_and_or(pointer, delta);
165 #endif
166 }
175 static inline int
176 sas_compare_and_swap (volatile long int *p, long int oldval, long int newval)
177 {
178  return __arch_compare_and_swap(p, oldval, newval);
179 }
180 
187 static inline long int
188 sas_atomic_swap (long int *p, long int replace)
189 {
190  return __arch_atomic_swap(p, replace);
191 }
192 
196 static inline void
197 sas_atomic_inc(long int *p)
198 {
199  __arch_atomic_inc(p);
200 }
201 
205 static inline void
206 sas_atomic_dec(long int *p)
207 {
208  __arch_atomic_dec(p);
209 }
210 
215 static inline void
217 {
219  *lock = 0;
220 }
221 
228 static inline void
230 {
231  __arch_sas_spin_lock(lock);
232 }
233 
241 static inline int
243 {
244  return __arch_sas_spin_trylock(lock);
245 }
246 
250 static inline void
252 {
254  *lock = 0;
255 }
256 
261 static inline void
263 {
265  *lock = NULL;
266 }
267 
271 static inline void*
272 sas_lock_ptr (volatile sas_lock_ptr_t *lock)
273 {
274  int rc;
275  long unlocked, locked;
276  do {
277  unlocked = (long)(*lock) & -2L;
278  locked = unlocked | 1;
279  rc = sas_compare_and_swap ((long int *)lock, unlocked, locked);
280  } while (!rc);
282 
283  return (void*)unlocked;
284 }
285 
290 static inline void
292 {
293  int rc;
294  do {
295  long unlocked= (long)(*lock) & -2L;
296  long newlocked= (long)newptr | 1;
297  rc = sas_compare_and_swap ((long int *)lock, unlocked, newlocked);
298  } while (!rc);
300 }
301 
306 static inline void
308 {
309  int rc;
310  do {
311  long locked= (long)(*lock) | 1;
312  long newlocked= (long)newptr | 1;
313  rc = sas_compare_and_swap ((long int *)lock, locked, newlocked);
314  } while (!rc);
315 }
316 
321 static inline int
323 {
324  int rc;
325  {
326  long unlocked= (long)(*lock) & -2L;
327  long locked= unlocked | 1;
328  rc = sas_compare_and_swap ((long int *)lock, unlocked, locked);
329  }
331 
332  return !rc;
333 }
334 
338 static inline void
340 {
341  int rc;
342 
344  do {
345  long unlocked= (long)(*lock) & -2L;
346  long locked= unlocked | 1;
347  rc = sas_compare_and_swap ((long int *)lock, locked, unlocked);
348  } while (!rc);
349 }
350 
355 static inline void
357 {
358  int rc;
359 
360  if (sas_spin_trylock(lock) == 0)
361  return;
362  if (sas_spin_trylock(lock) == 0)
363  return;
364  if (sas_spin_trylock(lock) == 0)
365  return;
366  if (sas_spin_trylock(lock) == 0)
367  return;
368 
369  do
370  {
371  sched_yield();
372  rc = sas_spin_trylock(lock);
373  }
374  while (rc);
375 }
376 
381 static inline void
383 {
384  int rc;
385 
386  if (sas_trylock_ptr(lock) == 0)
387  return;
388  if (sas_trylock_ptr(lock) == 0)
389  return;
390  if (sas_trylock_ptr(lock) == 0)
391  return;
392  if (sas_trylock_ptr(lock) == 0)
393  return;
394 
395  do
396  {
397  sched_yield();
398  rc = sas_trylock_ptr(lock);
399  }
400  while (rc);
401 
402  return;
403 }
404 #if 1
405 
408 static inline long
409 sas_atomic_inc_long (volatile long *value)
410 {
411  long result;
412  long delta = 1;
413 
414 #if GCC_VERSION >= 40700
415  result = __atomic_fetch_add(value, delta, __ATOMIC_ACQUIRE);
416 #else
417  result = __sync_fetch_and_add(value, delta);
418 #endif
419 
420  return result;
421 }
422 
426 static inline long
427 sas_atomic_dec_long (volatile long *value)
428 {
429  long result;
430  long delta = -1;
431 
432 #if GCC_VERSION >= 40700
433  result = __atomic_fetch_add(value, delta, __ATOMIC_ACQUIRE);
434 #else
435  result = __sync_fetch_and_add(value, delta);
436 #endif
437 
438  return result;
439 }
440 #endif
441 #endif /*_SASATOMIC_H */
442 
static long int sas_fetch_and_or_long(unsigned long *pointer, long int delta)
Definition: sasatom.h:159
static void sas_set_unlocked_ptr(volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
Definition: sasatom.h:291
static void * sas_lock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:272
static long int sas_fetch_and_and_long(unsigned long *pointer, long int delta)
Definition: sasatom.h:123
static long sas_atomic_inc_long(volatile long *value)
Definition: sasatom.h:409
static void sas_spin_lock_init(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:216
static void sas_spin_lock_with_yield(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:356
#define sas_write_barrier()
Definition: sasatom.h:51
static long sas_atomic_dec_long(volatile long *value)
Definition: sasatom.h:427
static void sas_lock_ptr_init(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:262
static void sas_atomic_dec(long int *p)
Definition: sasatom.h:206
static long int sas_fetch_and_add(long *pointer, long int delta)
Definition: sasatom.h:91
static void sas_spin_lock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:229
static void sas_lock_ptr_with_yield(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:382
static int sas_spin_trylock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:242
unsigned int sas_spin_lock_t
Definition: sasatom.h:34
static void * sas_fetch_and_add_ptr(void **pointer, long int delta)
Definition: sasatom.h:77
#define sas_read_barrier()
Definition: sasatom.h:56
static void sas_atomic_inc(long int *p)
Definition: sasatom.h:197
void * sas_lock_ptr_t
Definition: sasatom.h:36
static void sas_set_locked_ptr(volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
Definition: sasatom.h:307
static void sas_unlock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:339
static int sas_compare_and_swap(volatile long int *p, long int oldval, long int newval)
Definition: sasatom.h:176
static long int sas_fetch_and_or(unsigned int *pointer, int delta)
Definition: sasatom.h:141
static void sas_spin_unlock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:251
static long int sas_fetch_and_and(unsigned int *pointer, int delta)
Definition: sasatom.h:105
static int sas_trylock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:322
static long int sas_atomic_swap(long int *p, long int replace)
Definition: sasatom.h:188