~clint-fewbar/ubuntu/precise/erlang/merge-15b

« back to all changes in this revision

Viewing changes to erts/include/internal/gcc/ethr_atomic.h

  • Committer: Package Import Robot
  • Author(s): Sergei Golovan
  • Date: 2011-12-15 19:20:10 UTC
  • mfrom: (1.1.18) (3.5.15 sid)
  • mto: (3.5.16 sid)
  • mto: This revision was merged to the branch mainline in revision 33.
  • Revision ID: package-import@ubuntu.com-20111215192010-jnxcfe3tbrpp0big
Tags: 1:15.b-dfsg-1
* New upstream release.
* Upload to experimental because this release breaks external drivers
  API along with ABI, so several applications are to be fixed.
* Removed SSL patch because the old SSL implementation is removed from
  the upstream distribution.
* Removed never used patch which added native code to erlang beam files.
* Removed the erlang-docbuilder binary package because the docbuilder
  application was dropped by upstream.
* Documented dropping ${erlang-docbuilder:Depends} substvar in
  erlang-depends(1) manpage.
* Made erlang-base and erlang-base-hipe provide virtual package
  erlang-abi-15.b (the number means the first erlang version, which
  provides current ABI).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * %CopyrightBegin%
3
3
 *
4
 
 * Copyright Ericsson AB 2010. All Rights Reserved.
 
4
 * Copyright Ericsson AB 2010-2011. All Rights Reserved.
5
5
 *
6
6
 * The contents of this file are subject to the Erlang Public License,
7
7
 * Version 1.1, (the "License"); you may not use this file except in
22
22
 * Author: Rickard Green
23
23
 */
24
24
 
25
 
#ifndef ETHR_GCC_ATOMIC_H__
26
 
#define ETHR_GCC_ATOMIC_H__
27
 
 
28
 
#if !defined(ETHR_HAVE_NATIVE_ATOMICS) && defined(ETHR_HAVE_GCC_ATOMIC_OPS)
29
 
#define ETHR_HAVE_NATIVE_ATOMICS 1
30
 
 
31
 
#define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 0
32
 
/* Enable immediate read/write on platforms where we know it is safe */
 
25
#undef ETHR_INCLUDE_ATOMIC_IMPL__
 
26
#if !defined(ETHR_GCC_ATOMIC32_H__) && defined(ETHR_ATOMIC_WANT_32BIT_IMPL__)
 
27
#define ETHR_GCC_ATOMIC32_H__
 
28
#if defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP32)
 
29
#  define ETHR_INCLUDE_ATOMIC_IMPL__ 4
 
30
#endif
 
31
#undef ETHR_ATOMIC_WANT_32BIT_IMPL__
 
32
#elif !defined(ETHR_GCC_ATOMIC64_H__) && defined(ETHR_ATOMIC_WANT_64BIT_IMPL__)
 
33
#define ETHR_GCC_ATOMIC64_H__
 
34
#if defined(ETHR_HAVE___SYNC_VAL_COMPARE_AND_SWAP64)
 
35
#  define ETHR_INCLUDE_ATOMIC_IMPL__ 8
 
36
#endif
 
37
#undef ETHR_ATOMIC_WANT_64BIT_IMPL__
 
38
#endif
 
39
 
 
40
#ifdef ETHR_INCLUDE_ATOMIC_IMPL__
 
41
 
 
42
#ifndef ETHR_GCC_ATOMIC_COMMON__
 
43
#define ETHR_GCC_ATOMIC_COMMON__
 
44
 
 
45
#define ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ 0
33
46
#if defined(__i386__) || defined(__x86_64__) || defined(__sparc__) \
34
47
    || defined(__powerpc__) || defined(__ppc__) || defined(__mips__)
35
 
#  undef ETHR_IMMED_ATOMIC_SET_GET_SAFE__
36
 
#  define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 1
 
48
#  undef ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
 
49
#  define ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ 1
 
50
#endif
 
51
 
 
52
#endif /* ETHR_GCC_ATOMIC_COMMON__ */
 
53
 
 
54
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
55
#define ETHR_HAVE_NATIVE_ATOMIC32 1
 
56
#define ETHR_NATIVE_ATOMIC32_IMPL "gcc"
 
57
#define ETHR_NATMC_FUNC__(X) ethr_native_atomic32_ ## X
 
58
#define ETHR_ATMC_T__ ethr_native_atomic32_t
 
59
#define ETHR_AINT_T__ ethr_sint32_t
 
60
#if defined(ETHR_HAVE___SYNC_ADD_AND_FETCH32)
 
61
#  define ETHR_HAVE___SYNC_ADD_AND_FETCH
 
62
#endif
 
63
#if defined(ETHR_HAVE___SYNC_FETCH_AND_AND32)
 
64
#  define ETHR_HAVE___SYNC_FETCH_AND_AND
 
65
#endif 
 
66
#if defined(ETHR_HAVE___SYNC_FETCH_AND_OR32)
 
67
#  define ETHR_HAVE___SYNC_FETCH_AND_OR
 
68
#endif
 
69
#elif ETHR_INCLUDE_ATOMIC_IMPL__ == 8
 
70
#define ETHR_HAVE_NATIVE_ATOMIC64 1
 
71
#define ETHR_NATIVE_ATOMIC64_IMPL "gcc"
 
72
#define ETHR_NATMC_FUNC__(X) ethr_native_atomic64_ ## X
 
73
#define ETHR_ATMC_T__ ethr_native_atomic64_t
 
74
#define ETHR_AINT_T__ ethr_sint64_t
 
75
#if defined(ETHR_HAVE___SYNC_ADD_AND_FETCH64)
 
76
#  define ETHR_HAVE___SYNC_ADD_AND_FETCH
 
77
#endif
 
78
#if defined(ETHR_HAVE___SYNC_FETCH_AND_AND64)
 
79
#  define ETHR_HAVE___SYNC_FETCH_AND_AND
 
80
#endif 
 
81
#if defined(ETHR_HAVE___SYNC_FETCH_AND_OR64)
 
82
#  define ETHR_HAVE___SYNC_FETCH_AND_OR
 
83
#endif
 
84
#else
 
85
#error "Unsupported integer size"
37
86
#endif
38
87
 
39
88
typedef struct {
40
 
    volatile long counter;
41
 
} ethr_native_atomic_t;
42
 
 
43
 
 
44
 
/*
45
 
 * According to the documentation this is what we want:
46
 
 *   #define ETHR_MEMORY_BARRIER __sync_synchronize()
47
 
 * However, __sync_synchronize() is known to erroneously be
48
 
 * a noop on at least some platforms with some gcc versions.
49
 
 * This has suposedly been fixed in some gcc version, but we
50
 
 * don't know from which version. Therefore, we use the
51
 
 * workaround implemented below on all gcc versions except
52
 
 * for gcc 4.2 or above for MIPS, where it's been verified.
53
 
 */
54
 
#if defined(__mips__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
55
 
#define ETHR_MEMORY_BARRIER __sync_synchronize()
56
 
#else
57
 
#define ETHR_MEMORY_BARRIER \
58
 
do { \
59
 
    volatile long x___ = 0; \
60
 
    (void) __sync_val_compare_and_swap(&x___, (long) 0, (long) 1); \
61
 
} while (0)
62
 
#endif
63
 
#define ETHR_READ_DEPEND_MEMORY_BARRIER ETHR_MEMORY_BARRIER
64
 
 
65
 
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
 
89
    volatile ETHR_AINT_T__ counter;
 
90
} ETHR_ATMC_T__;
 
91
 
 
92
 
 
93
#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_ATOMIC_IMPL__)
 
94
 
 
95
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
96
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADDR 1
 
97
#else
 
98
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADDR 1
 
99
#endif
 
100
 
 
101
static ETHR_INLINE ETHR_AINT_T__ *
 
102
ETHR_NATMC_FUNC__(addr)(ETHR_ATMC_T__ *var)
 
103
{
 
104
    return (ETHR_AINT_T__ *) &var->counter;
 
105
}
 
106
 
 
107
#if ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
 
108
 
 
109
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
110
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_SET 1
 
111
#else
 
112
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_SET 1
 
113
#endif
66
114
 
67
115
static ETHR_INLINE void
68
 
ethr_native_atomic_set(ethr_native_atomic_t *var, long value)
 
116
ETHR_NATMC_FUNC__(set)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ value)
69
117
{
70
 
#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
71
118
    var->counter = value;
 
119
}
 
120
 
 
121
#endif /* ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ */
 
122
 
 
123
#if ETHR_READ_AND_SET_WITHOUT_SYNC_OP__
 
124
 
 
125
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
126
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_READ 1
72
127
#else
73
 
    /*
74
 
     * Unfortunately no __sync_store() or similar exist in the gcc atomic
75
 
     * op interface. We therefore have to simulate it this way...
76
 
     */
77
 
    long act = 0, exp;
78
 
    do {
79
 
        exp = act;
80
 
        act = __sync_val_compare_and_swap(&var->counter, exp, value);
81
 
    } while (act != exp);
 
128
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_READ 1
82
129
#endif
83
 
}
84
 
 
85
 
#define ethr_native_atomic_init ethr_native_atomic_set
86
 
 
87
 
static ETHR_INLINE long
88
 
ethr_native_atomic_read(ethr_native_atomic_t *var)
 
130
 
 
131
static ETHR_INLINE ETHR_AINT_T__
 
132
ETHR_NATMC_FUNC__(read)(ETHR_ATMC_T__ *var)
89
133
{
90
 
#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
91
134
    return var->counter;
 
135
}
 
136
 
 
137
#endif /* ETHR_READ_AND_SET_WITHOUT_SYNC_OP__ */
 
138
 
 
139
#if defined(ETHR_HAVE___SYNC_ADD_AND_FETCH)
 
140
 
 
141
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
142
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_ADD_RETURN_MB 1
92
143
#else
93
 
    /*
94
 
     * Unfortunately no __sync_fetch() or similar exist in the gcc atomic
95
 
     * op interface. We therefore have to simulate it this way...
96
 
     */
97
 
    return __sync_add_and_fetch(&var->counter, (long) 0);
 
144
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_ADD_RETURN_MB 1
98
145
#endif
99
 
}
100
 
 
101
 
static ETHR_INLINE void
102
 
ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
103
 
{
104
 
    (void) __sync_add_and_fetch(&var->counter, incr);
105
 
}
106
 
 
107
 
static ETHR_INLINE long
108
 
ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
 
146
 
 
147
static ETHR_INLINE ETHR_AINT_T__
 
148
ETHR_NATMC_FUNC__(add_return_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ incr)
109
149
{
110
150
    return __sync_add_and_fetch(&var->counter, incr);
111
151
}
112
152
 
113
 
static ETHR_INLINE void
114
 
ethr_native_atomic_inc(ethr_native_atomic_t *var)
115
 
{
116
 
    (void) __sync_add_and_fetch(&var->counter, (long) 1);
117
 
}
118
 
 
119
 
static ETHR_INLINE void
120
 
ethr_native_atomic_dec(ethr_native_atomic_t *var)
121
 
{
122
 
    (void) __sync_sub_and_fetch(&var->counter, (long) 1);
123
 
}
124
 
 
125
 
static ETHR_INLINE long
126
 
ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
127
 
{
128
 
    return __sync_add_and_fetch(&var->counter, (long) 1);
129
 
}
130
 
 
131
 
static ETHR_INLINE long
132
 
ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
133
 
{
134
 
    return __sync_sub_and_fetch(&var->counter, (long) 1);
135
 
}
136
 
 
137
 
static ETHR_INLINE long
138
 
ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
 
153
#endif
 
154
 
 
155
#if defined(ETHR_HAVE___SYNC_FETCH_AND_AND)
 
156
 
 
157
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
158
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_AND_RETOLD_MB 1
 
159
#else
 
160
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_AND_RETOLD_MB 1
 
161
#endif
 
162
 
 
163
static ETHR_INLINE ETHR_AINT_T__
 
164
ETHR_NATMC_FUNC__(and_retold_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
139
165
{
140
166
    return __sync_fetch_and_and(&var->counter, mask);
141
167
}
142
168
 
143
 
static ETHR_INLINE long
144
 
ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
 
169
#endif
 
170
 
 
171
#if defined(ETHR_HAVE___SYNC_FETCH_AND_OR)
 
172
 
 
173
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
174
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_OR_RETOLD_MB 1
 
175
#else
 
176
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_OR_RETOLD_MB 1
 
177
#endif
 
178
 
 
179
static ETHR_INLINE ETHR_AINT_T__
 
180
ETHR_NATMC_FUNC__(or_retold_mb)(ETHR_ATMC_T__ *var, ETHR_AINT_T__ mask)
145
181
{
146
 
    return (long) __sync_fetch_and_or(&var->counter, mask);
 
182
    return (ETHR_AINT_T__) __sync_fetch_and_or(&var->counter, mask);
147
183
}
148
184
 
149
 
static ETHR_INLINE long
150
 
ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long old)
 
185
#endif
 
186
 
 
187
#if ETHR_INCLUDE_ATOMIC_IMPL__ == 4
 
188
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC32_CMPXCHG_MB 1
 
189
#else
 
190
#  define ETHR_HAVE_ETHR_NATIVE_ATOMIC64_CMPXCHG_MB 1
 
191
#endif
 
192
 
 
193
static ETHR_INLINE ETHR_AINT_T__
 
194
ETHR_NATMC_FUNC__(cmpxchg_mb)(ETHR_ATMC_T__ *var,
 
195
                              ETHR_AINT_T__ new,
 
196
                              ETHR_AINT_T__ old)
151
197
{
152
198
    return __sync_val_compare_and_swap(&var->counter, old, new);
153
199
}
154
200
 
155
 
static ETHR_INLINE long
156
 
ethr_native_atomic_xchg(ethr_native_atomic_t *var, long new)
157
 
{
158
 
    long exp, act = 0;
159
 
    do {
160
 
        exp = act;
161
 
        act = __sync_val_compare_and_swap(&var->counter, exp, new);
162
 
    } while (act != exp);
163
 
    return act;
164
 
}
165
 
 
166
 
/*
167
 
 * Atomic ops with at least specified barriers.
168
 
 */
169
 
 
170
 
static ETHR_INLINE long
171
 
ethr_native_atomic_read_acqb(ethr_native_atomic_t *var)
172
 
{
173
 
    return __sync_add_and_fetch(&var->counter, (long) 0);
174
 
}
175
 
 
176
 
#define ethr_native_atomic_inc_return_acqb ethr_native_atomic_inc_return
177
 
#define ethr_native_atomic_set_relb ethr_native_atomic_xchg
178
 
#define ethr_native_atomic_dec_relb ethr_native_atomic_dec_return
179
 
#define ethr_native_atomic_dec_return_relb ethr_native_atomic_dec_return
180
 
 
181
 
#define ethr_native_atomic_cmpxchg_acqb ethr_native_atomic_cmpxchg
182
 
#define ethr_native_atomic_cmpxchg_relb ethr_native_atomic_cmpxchg
183
 
 
184
 
#endif
185
 
 
186
 
#endif
 
201
#endif /* ETHR_TRY_INLINE_FUNCS */
 
202
 
 
203
#undef ETHR_NATMC_FUNC__
 
204
#undef ETHR_ATMC_T__
 
205
#undef ETHR_AINT_T__
 
206
#undef ETHR_AINT_SUFFIX__
 
207
#undef ETHR_HAVE___SYNC_ADD_AND_FETCH
 
208
#undef ETHR_HAVE___SYNC_FETCH_AND_AND
 
209
#undef ETHR_HAVE___SYNC_FETCH_AND_OR
187
210
 
188
211
#endif