summaryrefslogtreecommitdiff
path: root/include/my_atomic.h
blob: a1347d264016052f5fe9c36c74cb3d6c16f4723e (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
/* 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
#include "atomic/nolock.h"
#endif

#ifndef make_atomic_cas_body
#include "atomic/rwlock.h"
#endif

#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

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

#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