231 lines
9.8 KiB
C++
231 lines
9.8 KiB
C++
// Copyright (C) 2018-2019 Free Software Foundation, Inc.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library 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; either version 3, or (at your option)
|
|
// any later version.
|
|
|
|
// This library 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 library; see the file COPYING3. If not see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
// { dg-do compile { target c++11 } }
|
|
// { dg-require-atomic-builtins "" }
|
|
|
|
#include <atomic>
|
|
|
|
void
|
|
test01()
|
|
{
|
|
struct X { };
|
|
struct Y { };
|
|
// Primary template
|
|
volatile std::atomic<X> v;
|
|
std::atomic<Y> a;
|
|
const std::memory_order mo = std::memory_order_seq_cst;
|
|
X x;
|
|
Y y;
|
|
auto r1 = atomic_is_lock_free(&v);
|
|
static_assert( std::is_same<decltype(r1), bool>::value, "" );
|
|
auto r2 = atomic_is_lock_free(&a);
|
|
static_assert( std::is_same<decltype(r2), bool>::value, "" );
|
|
atomic_init(&v, x);
|
|
atomic_init(&a, y);
|
|
atomic_store(&v, x);
|
|
atomic_store(&a, y);
|
|
atomic_store_explicit(&v, x, mo);
|
|
atomic_store_explicit(&a, y, mo);
|
|
auto r3 = atomic_load(&v);
|
|
static_assert( std::is_same<decltype(r3), X>::value, "" );
|
|
auto r4 = atomic_load(&a);
|
|
static_assert( std::is_same<decltype(r4), Y>::value, "" );
|
|
auto r5 = atomic_load_explicit(&v, mo);
|
|
static_assert( std::is_same<decltype(r5), X>::value, "" );
|
|
auto r6 = atomic_load_explicit(&a, mo);
|
|
static_assert( std::is_same<decltype(r6), Y>::value, "" );
|
|
auto r7 = atomic_exchange(&v, x);
|
|
static_assert( std::is_same<decltype(r7), X>::value, "" );
|
|
auto r8 = atomic_exchange(&a, y);
|
|
static_assert( std::is_same<decltype(r8), Y>::value, "" );
|
|
auto r9 = atomic_exchange_explicit(&v, x, mo);
|
|
static_assert( std::is_same<decltype(r9), X>::value, "" );
|
|
auto r10 = atomic_exchange_explicit(&a, y, mo);
|
|
static_assert( std::is_same<decltype(r10), Y>::value, "" );
|
|
auto r11 = atomic_compare_exchange_weak(&v, &x, x);
|
|
static_assert( std::is_same<decltype(r11), bool>::value, "" );
|
|
auto r12 = atomic_compare_exchange_weak(&a, &y, y);
|
|
static_assert( std::is_same<decltype(r12), bool>::value, "" );
|
|
auto r13 = atomic_compare_exchange_strong(&v, &x, x);
|
|
static_assert( std::is_same<decltype(r13), bool>::value, "" );
|
|
auto r14 = atomic_compare_exchange_strong(&a, &y, y);
|
|
static_assert( std::is_same<decltype(r14), bool>::value, "" );
|
|
auto r15 = atomic_compare_exchange_weak_explicit(&v, &x, x, mo, mo);
|
|
static_assert( std::is_same<decltype(r15), bool>::value, "" );
|
|
auto r16 = atomic_compare_exchange_weak_explicit(&a, &y, y, mo, mo);
|
|
static_assert( std::is_same<decltype(r16), bool>::value, "" );
|
|
auto r17 = atomic_compare_exchange_strong_explicit(&v, &x, x, mo, mo);
|
|
static_assert( std::is_same<decltype(r17), bool>::value, "" );
|
|
auto r18 = atomic_compare_exchange_strong_explicit(&a, &y, y, mo, mo);
|
|
static_assert( std::is_same<decltype(r18), bool>::value, "" );
|
|
}
|
|
|
|
void
|
|
test02()
|
|
{
|
|
// Specialization for bool
|
|
volatile std::atomic<bool> v;
|
|
std::atomic<bool> a;
|
|
const std::memory_order mo = std::memory_order_seq_cst;
|
|
bool b = false;
|
|
auto r1 = atomic_is_lock_free(&v);
|
|
static_assert( std::is_same<decltype(r1), bool>::value, "" );
|
|
auto r2 = atomic_is_lock_free(&a);
|
|
static_assert( std::is_same<decltype(r2), bool>::value, "" );
|
|
atomic_init(&v, b);
|
|
atomic_init(&a, b);
|
|
atomic_store(&v, b);
|
|
atomic_store(&a, b);
|
|
atomic_store_explicit(&v, b, mo);
|
|
atomic_store_explicit(&a, b, mo);
|
|
auto r3 = atomic_load(&v);
|
|
static_assert( std::is_same<decltype(r3), bool>::value, "" );
|
|
auto r4 = atomic_load(&a);
|
|
static_assert( std::is_same<decltype(r4), bool>::value, "" );
|
|
auto r5 = atomic_load_explicit(&v, mo);
|
|
static_assert( std::is_same<decltype(r5), bool>::value, "" );
|
|
auto r6 = atomic_load_explicit(&a, mo);
|
|
static_assert( std::is_same<decltype(r6), bool>::value, "" );
|
|
auto r7 = atomic_exchange(&v, b);
|
|
static_assert( std::is_same<decltype(r7), bool>::value, "" );
|
|
auto r8 = atomic_exchange(&a, b);
|
|
static_assert( std::is_same<decltype(r8), bool>::value, "" );
|
|
auto r9 = atomic_exchange_explicit(&v, b, mo);
|
|
static_assert( std::is_same<decltype(r9), bool>::value, "" );
|
|
auto r10 = atomic_exchange_explicit(&a, b, mo);
|
|
static_assert( std::is_same<decltype(r10), bool>::value, "" );
|
|
auto r11 = atomic_compare_exchange_weak(&v, &b, b);
|
|
static_assert( std::is_same<decltype(r11), bool>::value, "" );
|
|
auto r12 = atomic_compare_exchange_weak(&a, &b, b);
|
|
static_assert( std::is_same<decltype(r12), bool>::value, "" );
|
|
auto r13 = atomic_compare_exchange_strong(&v, &b, b);
|
|
static_assert( std::is_same<decltype(r13), bool>::value, "" );
|
|
auto r14 = atomic_compare_exchange_strong(&a, &b, b);
|
|
static_assert( std::is_same<decltype(r14), bool>::value, "" );
|
|
auto r15 = atomic_compare_exchange_weak_explicit(&v, &b, b, mo, mo);
|
|
static_assert( std::is_same<decltype(r15), bool>::value, "" );
|
|
auto r16 = atomic_compare_exchange_weak_explicit(&a, &b, b, mo, mo);
|
|
static_assert( std::is_same<decltype(r16), bool>::value, "" );
|
|
auto r17 = atomic_compare_exchange_strong_explicit(&v, &b, b, mo, mo);
|
|
static_assert( std::is_same<decltype(r17), bool>::value, "" );
|
|
auto r18 = atomic_compare_exchange_strong_explicit(&a, &b, b, mo, mo);
|
|
static_assert( std::is_same<decltype(r18), bool>::value, "" );
|
|
}
|
|
|
|
void
|
|
test03()
|
|
{
|
|
// Partial specialization for pointers
|
|
volatile std::atomic<int*> v;
|
|
std::atomic<long*> a;
|
|
const std::memory_order mo = std::memory_order_seq_cst;
|
|
int* i = nullptr;
|
|
long* l = nullptr;
|
|
auto r1 = atomic_is_lock_free(&v);
|
|
static_assert( std::is_same<decltype(r1), bool>::value, "" );
|
|
auto r2 = atomic_is_lock_free(&a);
|
|
static_assert( std::is_same<decltype(r2), bool>::value, "" );
|
|
atomic_init(&v, i);
|
|
atomic_init(&a, l);
|
|
atomic_store(&v, i);
|
|
atomic_store(&a, l);
|
|
atomic_store_explicit(&v, i, mo);
|
|
atomic_store_explicit(&a, l, mo);
|
|
auto r3 = atomic_load(&v);
|
|
static_assert( std::is_same<decltype(r3), int*>::value, "" );
|
|
auto r4 = atomic_load(&a);
|
|
static_assert( std::is_same<decltype(r4), long*>::value, "" );
|
|
auto r5 = atomic_load_explicit(&v, mo);
|
|
static_assert( std::is_same<decltype(r5), int*>::value, "" );
|
|
auto r6 = atomic_load_explicit(&a, mo);
|
|
static_assert( std::is_same<decltype(r6), long*>::value, "" );
|
|
auto r7 = atomic_exchange(&v, i);
|
|
static_assert( std::is_same<decltype(r7), int*>::value, "" );
|
|
auto r8 = atomic_exchange(&a, l);
|
|
static_assert( std::is_same<decltype(r8), long*>::value, "" );
|
|
auto r9 = atomic_exchange_explicit(&v, i, mo);
|
|
static_assert( std::is_same<decltype(r9), int*>::value, "" );
|
|
auto r10 = atomic_exchange_explicit(&a, l, mo);
|
|
static_assert( std::is_same<decltype(r10), long*>::value, "" );
|
|
auto r11 = atomic_compare_exchange_weak(&v, &i, i);
|
|
static_assert( std::is_same<decltype(r11), bool>::value, "" );
|
|
auto r12 = atomic_compare_exchange_weak(&a, &l, l);
|
|
static_assert( std::is_same<decltype(r12), bool>::value, "" );
|
|
auto r13 = atomic_compare_exchange_strong(&v, &i, i);
|
|
static_assert( std::is_same<decltype(r13), bool>::value, "" );
|
|
auto r14 = atomic_compare_exchange_strong(&a, &l, l);
|
|
static_assert( std::is_same<decltype(r14), bool>::value, "" );
|
|
auto r15 = atomic_compare_exchange_weak_explicit(&v, &i, i, mo, mo);
|
|
static_assert( std::is_same<decltype(r15), bool>::value, "" );
|
|
auto r16 = atomic_compare_exchange_weak_explicit(&a, &l, l, mo, mo);
|
|
static_assert( std::is_same<decltype(r16), bool>::value, "" );
|
|
auto r17 = atomic_compare_exchange_strong_explicit(&v, &i, i, mo, mo);
|
|
static_assert( std::is_same<decltype(r17), bool>::value, "" );
|
|
auto r18 = atomic_compare_exchange_strong_explicit(&a, &l, l, mo, mo);
|
|
static_assert( std::is_same<decltype(r18), bool>::value, "" );
|
|
|
|
auto r19 = atomic_fetch_add(&v, 1);
|
|
static_assert( std::is_same<decltype(r19), int*>::value, "" );
|
|
auto r20 = atomic_fetch_add(&a, 1);
|
|
static_assert( std::is_same<decltype(r20), long*>::value, "" );
|
|
auto r21 = atomic_fetch_add_explicit(&v, 1, mo);
|
|
static_assert( std::is_same<decltype(r21), int*>::value, "" );
|
|
auto r22 = atomic_fetch_add_explicit(&a, 1, mo);
|
|
static_assert( std::is_same<decltype(r22), long*>::value, "" );
|
|
auto r23 = atomic_fetch_sub(&v, 1);
|
|
static_assert( std::is_same<decltype(r23), int*>::value, "" );
|
|
auto r24 = atomic_fetch_sub(&a, 1);
|
|
static_assert( std::is_same<decltype(r24), long*>::value, "" );
|
|
auto r25 = atomic_fetch_sub_explicit(&v, 1, mo);
|
|
static_assert( std::is_same<decltype(r25), int*>::value, "" );
|
|
auto r26 = atomic_fetch_sub_explicit(&a, 1, mo);
|
|
static_assert( std::is_same<decltype(r26), long*>::value, "" );
|
|
}
|
|
|
|
void
|
|
test04()
|
|
{
|
|
struct base { };
|
|
struct derived : base { };
|
|
// Partial specialization for pointers
|
|
volatile std::atomic<base*> v;
|
|
std::atomic<base*> a;
|
|
const std::memory_order mo = std::memory_order_seq_cst;
|
|
// Repeat tests with arguments of type different to value_type.
|
|
derived* const p = nullptr;
|
|
base* b = nullptr;
|
|
atomic_init(&v, p);
|
|
atomic_init(&a, p);
|
|
atomic_store(&v, p);
|
|
atomic_store(&a, p);
|
|
atomic_store_explicit(&v, p, mo);
|
|
atomic_store_explicit(&a, p, mo);
|
|
atomic_exchange(&v, p);
|
|
atomic_exchange(&a, p);
|
|
atomic_exchange_explicit(&v, p, mo);
|
|
atomic_exchange_explicit(&a, p, mo);
|
|
atomic_compare_exchange_weak(&v, &b, p);
|
|
atomic_compare_exchange_weak(&a, &b, p);
|
|
atomic_compare_exchange_strong(&v, &b, p);
|
|
atomic_compare_exchange_strong(&a, &b, p);
|
|
atomic_compare_exchange_weak_explicit(&v, &b, p, mo, mo);
|
|
atomic_compare_exchange_weak_explicit(&a, &b, p, mo, mo);
|
|
atomic_compare_exchange_strong_explicit(&v, &b, p, mo, mo);
|
|
atomic_compare_exchange_strong_explicit(&a, &b, p, mo, mo);
|
|
}
|