OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc4/] [libstdc++-v3/] [include/] [bits/] [atomic_2.h] - Blame information for rev 424

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 424 jeremybenn
// -*- C++ -*- header.
2
 
3
// Copyright (C) 2008, 2009
4
// Free Software Foundation, Inc.
5
//
6
// This file is part of the GNU ISO C++ Library.  This library is free
7
// software; you can redistribute it and/or modify it under the
8
// terms of the GNU General Public License as published by the
9
// Free Software Foundation; either version 3, or (at your option)
10
// any later version.
11
 
12
// This library is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
// GNU General Public License for more details.
16
 
17
// Under Section 7 of GPL version 3, you are granted additional
18
// permissions described in the GCC Runtime Library Exception, version
19
// 3.1, as published by the Free Software Foundation.
20
 
21
// You should have received a copy of the GNU General Public License and
22
// a copy of the GCC Runtime Library Exception along with this program;
23
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
// <http://www.gnu.org/licenses/>.
25
 
26
/** @file bits/atomic_2.h
27
 *  This is an internal header file, included by other library headers.
28
 *  You should not attempt to use it directly.
29
 */
30
 
31
#ifndef _GLIBCXX_ATOMIC_2_H
32
#define _GLIBCXX_ATOMIC_2_H 1
33
 
34
#pragma GCC system_header
35
 
36
// _GLIBCXX_BEGIN_NAMESPACE(std)
37
 
38
// 2 == __atomic2 == Always lock-free
39
// Assumed:
40
// _GLIBCXX_ATOMIC_BUILTINS_1
41
// _GLIBCXX_ATOMIC_BUILTINS_2
42
// _GLIBCXX_ATOMIC_BUILTINS_4
43
// _GLIBCXX_ATOMIC_BUILTINS_8
44
namespace __atomic2
45
{
46
  /// atomic_flag
47
  struct atomic_flag : public __atomic_flag_base
48
  {
49
    atomic_flag() = default;
50
    ~atomic_flag() = default;
51
    atomic_flag(const atomic_flag&) = delete;
52
    atomic_flag& operator=(const atomic_flag&) volatile = delete;
53
 
54
    // Conversion to ATOMIC_FLAG_INIT.
55
    atomic_flag(bool __i): __atomic_flag_base({ __i }) { }
56
 
57
    bool
58
    test_and_set(memory_order __m = memory_order_seq_cst)
59
    {
60
      // Redundant synchronize if built-in for lock is a full barrier.
61
      if (__m != memory_order_acquire && __m != memory_order_acq_rel)
62
        __sync_synchronize();
63
      return __sync_lock_test_and_set(&_M_i, 1);
64
    }
65
 
66
    void
67
    clear(memory_order __m = memory_order_seq_cst)
68
    {
69
      __glibcxx_assert(__m != memory_order_consume);
70
      __glibcxx_assert(__m != memory_order_acquire);
71
      __glibcxx_assert(__m != memory_order_acq_rel);
72
 
73
      __sync_lock_release(&_M_i);
74
      if (__m != memory_order_acquire && __m != memory_order_acq_rel)
75
        __sync_synchronize();
76
    }
77
  };
78
 
79
 
80
  /// 29.4.2, address types
81
  struct atomic_address
82
  {
83
  private:
84
    void* _M_i;
85
 
86
  public:
87
    atomic_address() = default;
88
    ~atomic_address() = default;
89
    atomic_address(const atomic_address&) = delete;
90
    atomic_address& operator=(const atomic_address&) volatile = delete;
91
 
92
    atomic_address(void* __v) { _M_i = __v; }
93
 
94
    bool
95
    is_lock_free() const
96
    { return true; }
97
 
98
    void
99
    store(void* __v, memory_order __m = memory_order_seq_cst)
100
    {
101
      __glibcxx_assert(__m != memory_order_acquire);
102
      __glibcxx_assert(__m != memory_order_acq_rel);
103
      __glibcxx_assert(__m != memory_order_consume);
104
 
105
      if (__m == memory_order_relaxed)
106
        _M_i = __v;
107
      else
108
        {
109
          // write_mem_barrier();
110
          _M_i = __v;
111
          if (__m == memory_order_seq_cst)
112
            __sync_synchronize();
113
        }
114
    }
115
 
116
    void*
117
    load(memory_order __m = memory_order_seq_cst) const
118
    {
119
      __glibcxx_assert(__m != memory_order_release);
120
      __glibcxx_assert(__m != memory_order_acq_rel);
121
 
122
      __sync_synchronize();
123
      void* __ret = _M_i;
124
      __sync_synchronize();
125
      return __ret;
126
    }
127
 
128
    void*
129
    exchange(void* __v, memory_order __m = memory_order_seq_cst)
130
    {
131
      // XXX built-in assumes memory_order_acquire.
132
      return __sync_lock_test_and_set(&_M_i, __v);
133
    }
134
 
135
    bool
136
    compare_exchange_weak(void*& __v1, void* __v2, memory_order __m1,
137
                          memory_order __m2)
138
    { return compare_exchange_strong(__v1, __v2, __m1, __m2); }
139
 
140
    bool
141
    compare_exchange_weak(void*& __v1, void* __v2,
142
                          memory_order __m = memory_order_seq_cst)
143
    {
144
      return compare_exchange_weak(__v1, __v2, __m,
145
                                   __calculate_memory_order(__m));
146
    }
147
 
148
    bool
149
    compare_exchange_strong(void*& __v1, void* __v2, memory_order __m1,
150
                            memory_order __m2)
151
    {
152
      __glibcxx_assert(__m2 != memory_order_release);
153
      __glibcxx_assert(__m2 != memory_order_acq_rel);
154
      __glibcxx_assert(__m2 <= __m1);
155
 
156
      void* __v1o = __v1;
157
      void* __v1n = __sync_val_compare_and_swap(&_M_i, __v1o, __v2);
158
 
159
      // Assume extra stores (of same value) allowed in true case.
160
      __v1 = __v1n;
161
      return __v1o == __v1n;
162
    }
163
 
164
    bool
165
    compare_exchange_strong(void*& __v1, void* __v2,
166
                          memory_order __m = memory_order_seq_cst)
167
    {
168
      return compare_exchange_strong(__v1, __v2, __m,
169
                                     __calculate_memory_order(__m));
170
    }
171
 
172
    void*
173
    fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
174
    { return __sync_fetch_and_add(&_M_i, __d); }
175
 
176
    void*
177
    fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
178
    { return __sync_fetch_and_sub(&_M_i, __d); }
179
 
180
    operator void*() const
181
    { return load(); }
182
 
183
    void*
184
    operator=(void* __v)
185
    {
186
      store(__v);
187
      return __v;
188
    }
189
 
190
    void*
191
    operator+=(ptrdiff_t __d)
192
    { return __sync_add_and_fetch(&_M_i, __d); }
193
 
194
    void*
195
    operator-=(ptrdiff_t __d)
196
    { return __sync_sub_and_fetch(&_M_i, __d); }
197
  };
198
 
199
  // 29.3.1 atomic integral types
200
  // For each of the integral types, define atomic_[integral type] struct
201
  //
202
  // atomic_bool     bool
203
  // atomic_char     char
204
  // atomic_schar    signed char
205
  // atomic_uchar    unsigned char
206
  // atomic_short    short
207
  // atomic_ushort   unsigned short
208
  // atomic_int      int
209
  // atomic_uint     unsigned int
210
  // atomic_long     long
211
  // atomic_ulong    unsigned long
212
  // atomic_llong    long long
213
  // atomic_ullong   unsigned long long
214
  // atomic_char16_t char16_t
215
  // atomic_char32_t char32_t
216
  // atomic_wchar_t  wchar_t
217
 
218
  // Base type.
219
  // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or 8 bytes,
220
  // since that is what GCC built-in functions for atomic memory access work on.
221
  template<typename _ITp>
222
    struct __atomic_base
223
    {
224
    private:
225
      typedef _ITp      __integral_type;
226
 
227
      __integral_type   _M_i;
228
 
229
    public:
230
      __atomic_base() = default;
231
      ~__atomic_base() = default;
232
      __atomic_base(const __atomic_base&) = delete;
233
      __atomic_base& operator=(const __atomic_base&) volatile = delete;
234
 
235
      // Requires __integral_type convertible to _M_base._M_i.
236
      __atomic_base(__integral_type __i) { _M_i = __i; }
237
 
238
      operator __integral_type() const
239
      { return load(); }
240
 
241
      __integral_type
242
      operator=(__integral_type __i)
243
      {
244
        store(__i);
245
        return __i;
246
      }
247
 
248
      __integral_type
249
      operator++(int)
250
      { return fetch_add(1); }
251
 
252
      __integral_type
253
      operator--(int)
254
      { return fetch_sub(1); }
255
 
256
      __integral_type
257
      operator++()
258
      { return __sync_add_and_fetch(&_M_i, 1); }
259
 
260
      __integral_type
261
      operator--()
262
      { return __sync_sub_and_fetch(&_M_i, 1); }
263
 
264
      __integral_type
265
      operator+=(__integral_type __i)
266
      { return __sync_add_and_fetch(&_M_i, __i); }
267
 
268
      __integral_type
269
      operator-=(__integral_type __i)
270
      { return __sync_sub_and_fetch(&_M_i, __i); }
271
 
272
      __integral_type
273
      operator&=(__integral_type __i)
274
      { return __sync_and_and_fetch(&_M_i, __i); }
275
 
276
      __integral_type
277
      operator|=(__integral_type __i)
278
      { return __sync_or_and_fetch(&_M_i, __i); }
279
 
280
      __integral_type
281
      operator^=(__integral_type __i)
282
      { return __sync_xor_and_fetch(&_M_i, __i); }
283
 
284
      bool
285
      is_lock_free() const
286
      { return true; }
287
 
288
      void
289
      store(__integral_type __i, memory_order __m = memory_order_seq_cst)
290
      {
291
        __glibcxx_assert(__m != memory_order_acquire);
292
        __glibcxx_assert(__m != memory_order_acq_rel);
293
        __glibcxx_assert(__m != memory_order_consume);
294
 
295
        if (__m == memory_order_relaxed)
296
          _M_i = __i;
297
        else
298
          {
299
            // write_mem_barrier();
300
            _M_i = __i;
301
            if (__m == memory_order_seq_cst)
302
              __sync_synchronize();
303
          }
304
      }
305
 
306
      __integral_type
307
      load(memory_order __m = memory_order_seq_cst) const
308
      {
309
        __glibcxx_assert(__m != memory_order_release);
310
        __glibcxx_assert(__m != memory_order_acq_rel);
311
 
312
        __sync_synchronize();
313
        __integral_type __ret = _M_i;
314
        __sync_synchronize();
315
        return __ret;
316
      }
317
 
318
      __integral_type
319
      exchange(__integral_type __i, memory_order __m = memory_order_seq_cst)
320
      {
321
        // XXX built-in assumes memory_order_acquire.
322
        return __sync_lock_test_and_set(&_M_i, __i);
323
      }
324
 
325
      bool
326
      compare_exchange_weak(__integral_type& __i1, __integral_type __i2,
327
                            memory_order __m1, memory_order __m2)
328
      { return compare_exchange_strong(__i1, __i2, __m1, __m2); }
329
 
330
      bool
331
      compare_exchange_weak(__integral_type& __i1, __integral_type __i2,
332
                            memory_order __m = memory_order_seq_cst)
333
      {
334
        return compare_exchange_weak(__i1, __i2, __m,
335
                                     __calculate_memory_order(__m));
336
      }
337
 
338
      bool
339
      compare_exchange_strong(__integral_type& __i1, __integral_type __i2,
340
                              memory_order __m1, memory_order __m2)
341
      {
342
        __glibcxx_assert(__m2 != memory_order_release);
343
        __glibcxx_assert(__m2 != memory_order_acq_rel);
344
        __glibcxx_assert(__m2 <= __m1);
345
 
346
        __integral_type __i1o = __i1;
347
        __integral_type __i1n = __sync_val_compare_and_swap(&_M_i, __i1o, __i2);
348
 
349
        // Assume extra stores (of same value) allowed in true case.
350
        __i1 = __i1n;
351
        return __i1o == __i1n;
352
      }
353
 
354
      bool
355
      compare_exchange_strong(__integral_type& __i1, __integral_type __i2,
356
                              memory_order __m = memory_order_seq_cst)
357
      {
358
        return compare_exchange_strong(__i1, __i2, __m,
359
                                       __calculate_memory_order(__m));
360
      }
361
 
362
      __integral_type
363
      fetch_add(__integral_type __i,
364
                memory_order __m = memory_order_seq_cst)
365
      { return __sync_fetch_and_add(&_M_i, __i); }
366
 
367
      __integral_type
368
      fetch_sub(__integral_type __i,
369
                memory_order __m = memory_order_seq_cst)
370
      { return __sync_fetch_and_sub(&_M_i, __i); }
371
 
372
      __integral_type
373
      fetch_and(__integral_type __i,
374
                memory_order __m = memory_order_seq_cst)
375
      { return __sync_fetch_and_and(&_M_i, __i); }
376
 
377
      __integral_type
378
      fetch_or(__integral_type __i,
379
               memory_order __m = memory_order_seq_cst)
380
      { return __sync_fetch_and_or(&_M_i, __i); }
381
 
382
      __integral_type
383
      fetch_xor(__integral_type __i,
384
                memory_order __m = memory_order_seq_cst)
385
      { return __sync_fetch_and_xor(&_M_i, __i); }
386
    };
387
 
388
 
389
  /// atomic_bool
390
  // NB: No operators or fetch-operations for this type.
391
  struct atomic_bool
392
  {
393
  private:
394
    __atomic_base<bool> _M_base;
395
 
396
  public:
397
    atomic_bool() = default;
398
    ~atomic_bool() = default;
399
    atomic_bool(const atomic_bool&) = delete;
400
    atomic_bool& operator=(const atomic_bool&) volatile = delete;
401
 
402
    atomic_bool(bool __i) : _M_base(__i) { }
403
 
404
    bool
405
    operator=(bool __i)
406
    { return _M_base.operator=(__i); }
407
 
408
    operator bool() const
409
    { return _M_base.load(); }
410
 
411
    bool
412
    is_lock_free() const
413
    { return _M_base.is_lock_free(); }
414
 
415
    void
416
    store(bool __i, memory_order __m = memory_order_seq_cst)
417
    { _M_base.store(__i, __m); }
418
 
419
    bool
420
    load(memory_order __m = memory_order_seq_cst) const
421
    { return _M_base.load(__m); }
422
 
423
    bool
424
    exchange(bool __i, memory_order __m = memory_order_seq_cst)
425
    { return _M_base.exchange(__i, __m); }
426
 
427
    bool
428
    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
429
                          memory_order __m2)
430
    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
431
 
432
    bool
433
    compare_exchange_weak(bool& __i1, bool __i2,
434
                          memory_order __m = memory_order_seq_cst)
435
    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
436
 
437
    bool
438
    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
439
                            memory_order __m2)
440
    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
441
 
442
 
443
    bool
444
    compare_exchange_strong(bool& __i1, bool __i2,
445
                            memory_order __m = memory_order_seq_cst)
446
    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
447
  };
448
} // namespace __atomic2
449
 
450
// _GLIBCXX_END_NAMESPACE
451
 
452
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.