1 /* atomic.h
2  * Copyright (C) 2006-2015, Parrot Foundation.
3  *
4  * This header implements portable atomic operations.
5  */
6 
7 
8 #ifndef PARROT_ATOMIC_H_GUARD
9 #define PARROT_ATOMIC_H_GUARD
10 
11 #  include "parrot/has_header.h"
12 
13 #ifdef PARROT_HAS_THREADS
14 #  if defined(PARROT_HAS_I386_GCC_CMPXCHG)
15 #    include "parrot/atomic/gcc_x86.h"
16 #  elif defined(PARROT_HAS_PPC_GCC_CMPSET)
17 #    include "parrot/atomic/gcc_ppc.h"
18 #  elif defined(PARROT_HAS_SPARC_ATOMIC)
19 #    include "parrot/atomic/sparc.h"
20 #  else
21 #    include "parrot/atomic/fallback.h"
22 #  endif
23 #else
24 
25 typedef struct Parrot_atomic_pointer {
26     void *val;
27 } Parrot_atomic_pointer;
28 
29 typedef struct Parrot_atomic_integer {
30     INTVAL val;
31 } Parrot_atomic_integer;
32 
33 #  define PARROT_ATOMIC_PTR_INIT(a)
34 #  define PARROT_ATOMIC_PTR_GET(result, a) (result) = (a).val
35 #  define PARROT_ATOMIC_PTR_SET(a, b) (a).val = (b)
36 
37 /* a is the Parrot_atomic.
38  * expect is the value we expect the atomic to be holding,
39  * update is the new value for the atomic
40  * result will be 1 if the value was as expected (and thus
41  * the update was performed) and 0 otherwise
42  */
43 #  define PARROT_ATOMIC_PTR_CAS(result, a, expect, update) \
44       do { \
45           void * orig; \
46           PARROT_ATOMIC_PTR_GET(orig, (a)); \
47           if ((expect) == (orig)) { \
48               PARROT_ATOMIC_PTR_SET((a), (update)); \
49               (result) = 1; \
50           } \
51           else { \
52               (result) = 0; \
53           } \
54       } while (0)
55 #  define PARROT_ATOMIC_PTR_DESTROY(a)
56 #  define PARROT_ATOMIC_INT_INIT(a)
57 #  define PARROT_ATOMIC_INT_DESTROY(a)
58 #  define PARROT_ATOMIC_INT_GET(result, a) (result) = (a).val
59 #  define PARROT_ATOMIC_INT_SET(a, value)  (a).val = (value)
60 #  define PARROT_ATOMIC_INT_CAS(result, a, expect, update) \
61       do { \
62           INTVAL orig; \
63           PARROT_ATOMIC_INT_GET(orig, (a)); \
64           if ((expect) == (orig)) { \
65               PARROT_ATOMIC_INT_SET((a), (update)); \
66               (result) = 1; \
67           } \
68           else { \
69               (result) = 0; \
70           } \
71       } while (0)
72 #  define PARROT_ATOMIC_INT_INC(result, a) ((result) = ++(a).val)
73 #  define PARROT_ATOMIC_INT_DEC(result, a) ((result) = --(a).val)
74 
75 #endif /* PARROT_HAS_THREADS */
76 
77 #endif /* PARROT_ATOMIC_H_GUARD */
78 
79 /*
80  * Local variables:
81  *   c-file-style: "parrot"
82  * End:
83  * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
84  */
85