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 
29 typedef unsigned int sas_spin_lock_t;
31 typedef void* sas_lock_ptr_t;
32 
33 #if defined(__powerpc64__) || defined (__powerpc__)
34 #include "sasatom_powerpc.h"
35 #elif defined(__x86_64__)
36 #include "sasatom_x86_64.h"
37 #elif defined(__i386__)
38 #include "sasatom_i386.h"
39 #else
40 #include "sasatom_generic.h"
41 #endif
42 
46 #define sas_write_barrier() __arch_sas_write_barrier()
47 
51 #define sas_read_barrier() __arch_sas_read_barrier()
52 
56 #define sas_full_barrier() __arch_sas_full_barrier()
57 
61 #define sas_code_barrier() __asm ("" ::: "memory")
62 
71 static inline void *
72 fetch_and_add_ptr(void **pointer, long int delta)
73 {
74  return __arch_fetch_and_add_ptr(pointer, delta);
75 }
76 
85 static inline long int
86 fetch_and_add(void *pointer, long int delta)
87 {
88  return __arch_fetch_and_add(pointer, delta);
89 }
90 
99 static inline int
100 compare_and_swap (volatile long int *p, long int oldval, long int newval)
101 {
102  return __arch_compare_and_swap(p, oldval, newval);
103 }
104 
111 static inline long int
112 atomic_swap (long int *p, long int replace)
113 {
114  return __arch_atomic_swap(p, replace);
115 }
116 
120 static inline void
121 atomic_inc(long int *p)
122 {
123  __arch_atomic_inc(p);
124 }
125 
129 static inline void
130 atomic_dec(long int *p)
131 {
132  __arch_atomic_dec(p);
133 }
134 
139 static inline void
141 {
143  *lock = 0;
144 }
145 
152 static inline void
154 {
155  __arch_sas_spin_lock(lock);
156 }
157 
165 static inline int
167 {
168  return __arch_sas_spin_trylock(lock);
169 }
170 
174 static inline void
176 {
178  *lock = 0;
179 }
180 
185 static inline void
187 {
189  *lock = NULL;
190 }
191 
195 static inline void*
196 sas_lock_ptr (volatile sas_lock_ptr_t *lock)
197 {
198  int rc;
199  long unlocked, locked;
200  do {
201  unlocked = (long)(*lock) & -2L;
202  locked = unlocked | 1;
203  rc = compare_and_swap ((long int *)lock, unlocked, locked);
204  } while (!rc);
206 
207  return (void*)unlocked;
208 }
209 
214 static inline void
216 {
217  int rc;
218  do {
219  long unlocked= (long)(*lock) & -2L;
220  long newlocked= (long)newptr | 1;
221  rc = compare_and_swap ((long int *)lock, unlocked, newlocked);
222  } while (!rc);
224 }
225 
230 static inline void
232 {
233  int rc;
234  do {
235  long locked= (long)(*lock) | 1;
236  long newlocked= (long)newptr | 1;
237  rc = compare_and_swap ((long int *)lock, locked, newlocked);
238  } while (!rc);
239 }
240 
245 static inline int
247 {
248  int rc;
249  {
250  long unlocked= (long)(*lock) & -2L;
251  long locked= unlocked | 1;
252  rc = compare_and_swap ((long int *)lock, unlocked, locked);
253  }
255 
256  return !rc;
257 }
258 
262 static inline void
264 {
265  int rc;
266 
268  do {
269  long unlocked= (long)(*lock) & -2L;
270  long locked= unlocked | 1;
271  rc = compare_and_swap ((long int *)lock, locked, unlocked);
272  } while (!rc);
273 }
274 
279 static inline void
281 {
282  int rc;
283 
284  if (sas_spin_trylock(lock) == 0)
285  return;
286  if (sas_spin_trylock(lock) == 0)
287  return;
288  if (sas_spin_trylock(lock) == 0)
289  return;
290  if (sas_spin_trylock(lock) == 0)
291  return;
292 
293  do
294  {
295  sched_yield();
296  rc = sas_spin_trylock(lock);
297  }
298  while (rc);
299 }
300 
305 static inline void
307 {
308  int rc;
309 
310  if (sas_trylock_ptr(lock) == 0)
311  return;
312  if (sas_trylock_ptr(lock) == 0)
313  return;
314  if (sas_trylock_ptr(lock) == 0)
315  return;
316  if (sas_trylock_ptr(lock) == 0)
317  return;
318 
319  do
320  {
321  sched_yield();
322  rc = sas_trylock_ptr(lock);
323  }
324  while (rc);
325 
326  return;
327 }
328 
332 static inline long
333 sas_atomic_inc_long (volatile long *value)
334 {
335  long result, update;
336  int rc;
337 
338  do {
339  result = *value;
340  update = result + 1;
341  rc = compare_and_swap ((long int *)value, result, update);
342  } while (!rc);
344 
345  return result;
346 }
347 
351 static inline long
352 sas_atomic_dec_long (volatile long *value)
353 {
354  long result, update;
355  int rc;
356 
357  do {
358  result = *value;
359  update = result - 1;
360  rc = compare_and_swap ((long int *)value, result, update);
361  } while (!rc);
363 
364  return result;
365 }
366 
367 #endif /*_SASATOMIC_H */
368 
static void sas_set_unlocked_ptr(volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
Definition: sasatom.h:215
static void * sas_lock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:196
static long sas_atomic_inc_long(volatile long *value)
Definition: sasatom.h:333
static void sas_spin_lock_init(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:140
static void sas_spin_lock_with_yield(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:280
#define sas_write_barrier()
Definition: sasatom.h:46
static long sas_atomic_dec_long(volatile long *value)
Definition: sasatom.h:352
static long int fetch_and_add(void *pointer, long int delta)
Definition: sasatom.h:86
static void sas_lock_ptr_init(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:186
static void sas_spin_lock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:153
static void sas_lock_ptr_with_yield(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:306
static int sas_spin_trylock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:166
static long int atomic_swap(long int *p, long int replace)
Definition: sasatom.h:112
unsigned int sas_spin_lock_t
Definition: sasatom.h:29
static void * fetch_and_add_ptr(void **pointer, long int delta)
Definition: sasatom.h:72
static void atomic_dec(long int *p)
Definition: sasatom.h:130
#define sas_read_barrier()
Definition: sasatom.h:51
void * sas_lock_ptr_t
Definition: sasatom.h:31
static void sas_set_locked_ptr(volatile sas_lock_ptr_t *lock, sas_lock_ptr_t newptr)
Definition: sasatom.h:231
static void sas_unlock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:263
static void sas_spin_unlock(volatile sas_spin_lock_t *lock)
Definition: sasatom.h:175
static void atomic_inc(long int *p)
Definition: sasatom.h:121
static int sas_trylock_ptr(volatile sas_lock_ptr_t *lock)
Definition: sasatom.h:246
static int compare_and_swap(volatile long int *p, long int oldval, long int newval)
Definition: sasatom.h:100