summaryrefslogtreecommitdiff
path: root/include/my_atomic.h
blob: f5da6e6a0d976d2bd1de7375a0e0d34ee600f28c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#ifndef MY_ATOMIC_INCLUDED
#define MY_ATOMIC_INCLUDED

/* Copyright (C) 2006 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef my_atomic_rwlock_init

#define intptr         void *

#ifndef MY_ATOMIC_MODE_RWLOCKS
/*
 * Attempt to do atomic ops without locks
 */
#include "atomic/nolock.h"
#endif

#ifndef MY_ATOMIC_NOLOCK
/*
 * Have to use rw-locks for atomic ops
 */
#include "atomic/rwlock.h"
#endif

#ifndef MY_ATOMICS_MADE

#ifndef make_atomic_add_body
#define make_atomic_add_body(S)					\
  int ## S tmp=*a;                                              \
  while (!my_atomic_cas ## S(a, &tmp, tmp+v));                  \
  v=tmp;
#endif

#ifdef HAVE_INLINE

#define make_atomic_add(S)					\
STATIC_INLINE int ## S my_atomic_add ## S(			\
                        int ## S volatile *a, int ## S v)	\
{								\
  make_atomic_add_body(S);					\
  return v;							\
}

#define make_atomic_swap(S)					\
STATIC_INLINE int ## S my_atomic_swap ## S(			\
                         int ## S volatile *a, int ## S v)	\
{								\
  make_atomic_swap_body(S);					\
  return v;							\
}

#define make_atomic_cas(S)					\
STATIC_INLINE int my_atomic_cas ## S(int ## S volatile *a,	\
                            int ## S *cmp, int ## S set)	\
{								\
  int8 ret;							\
  make_atomic_cas_body(S);					\
  return ret;							\
}

#define make_atomic_load(S)					\
STATIC_INLINE int ## S my_atomic_load ## S(int ## S volatile *a) \
{								\
  int ## S ret;						\
  make_atomic_load_body(S);					\
  return ret;							\
}

#define make_atomic_store(S)					\
STATIC_INLINE void my_atomic_store ## S(			\
                     int ## S volatile *a, int ## S v)	\
{								\
  make_atomic_store_body(S);					\
}

#else /* no inline functions */

#define make_atomic_add(S)					\
extern int ## S my_atomic_add ## S(int ## S volatile *a, int ## S v);

#define make_atomic_swap(S)					\
extern int ## S my_atomic_swap ## S(int ## S volatile *a, int ## S v);

#define make_atomic_cas(S)					\
extern int my_atomic_cas ## S(int ## S volatile *a, int ## S *cmp, int ## S set);

#define make_atomic_load(S)					\
extern int ## S my_atomic_load ## S(int ## S volatile *a);

#define make_atomic_store(S)					\
extern void my_atomic_store ## S(int ## S volatile *a, int ## S v);

#endif /* HAVE_INLINE */

make_atomic_cas( 8)
make_atomic_cas(16)
make_atomic_cas(32)
make_atomic_cas(ptr)

make_atomic_add( 8)
make_atomic_add(16)
make_atomic_add(32)

make_atomic_load( 8)
make_atomic_load(16)
make_atomic_load(32)
make_atomic_load(ptr)

make_atomic_store( 8)
make_atomic_store(16)
make_atomic_store(32)
make_atomic_store(ptr)

make_atomic_swap( 8)
make_atomic_swap(16)
make_atomic_swap(32)
make_atomic_swap(ptr)

#undef make_atomic_add
#undef make_atomic_cas
#undef make_atomic_load
#undef make_atomic_store
#undef make_atomic_swap
#undef make_atomic_add_body
#undef make_atomic_cas_body
#undef make_atomic_load_body
#undef make_atomic_store_body
#undef make_atomic_swap_body
#undef intptr

#endif /* MY_ATOMICS_MADE */

#ifdef _atomic_h_cleanup_
#include _atomic_h_cleanup_
#undef _atomic_h_cleanup_
#endif

#define MY_ATOMIC_OK       0
#define MY_ATOMIC_NOT_1CPU 1
extern int my_atomic_initialize();

#endif

#endif /* MY_ATOMIC_INCLUDED */