std::atomic is, for the most part, just a thin veneer on top of compiler builtins. Hence, it should be available even when threads are not available on the system, and in fact there has been requests for such support. This patch: - Moves __libcpp_thread_poll_with_backoff to its own header so it can be used in <atomic> when threads are disabled. - Adds a dummy backoff policy for atomic polling that doesn't know about threads. - Adjusts the <atomic> feature-test macros so they are provided even when threads are disabled. - Runs the <atomic> tests when threads are disabled. rdar://77873569 Differential Revision: https://reviews.llvm.org/D114109
110 lines
3.1 KiB
C++
110 lines
3.1 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// <atomic>
|
|
|
|
// struct atomic_flag
|
|
|
|
// bool test_and_set(memory_order = memory_order_seq_cst);
|
|
// bool test_and_set(memory_order = memory_order_seq_cst) volatile;
|
|
|
|
#include <atomic>
|
|
#include <cassert>
|
|
|
|
#include "test_macros.h"
|
|
|
|
int main(int, char**)
|
|
{
|
|
{
|
|
std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set() == 0);
|
|
assert(f.test_and_set() == 1);
|
|
}
|
|
{
|
|
std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_relaxed) == 0);
|
|
assert(f.test_and_set(std::memory_order_relaxed) == 1);
|
|
}
|
|
{
|
|
std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_consume) == 0);
|
|
assert(f.test_and_set(std::memory_order_consume) == 1);
|
|
}
|
|
{
|
|
std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_acquire) == 0);
|
|
assert(f.test_and_set(std::memory_order_acquire) == 1);
|
|
}
|
|
{
|
|
std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_release) == 0);
|
|
assert(f.test_and_set(std::memory_order_release) == 1);
|
|
}
|
|
{
|
|
std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_acq_rel) == 0);
|
|
assert(f.test_and_set(std::memory_order_acq_rel) == 1);
|
|
}
|
|
{
|
|
std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_seq_cst) == 0);
|
|
assert(f.test_and_set(std::memory_order_seq_cst) == 1);
|
|
}
|
|
{
|
|
volatile std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set() == 0);
|
|
assert(f.test_and_set() == 1);
|
|
}
|
|
{
|
|
volatile std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_relaxed) == 0);
|
|
assert(f.test_and_set(std::memory_order_relaxed) == 1);
|
|
}
|
|
{
|
|
volatile std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_consume) == 0);
|
|
assert(f.test_and_set(std::memory_order_consume) == 1);
|
|
}
|
|
{
|
|
volatile std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_acquire) == 0);
|
|
assert(f.test_and_set(std::memory_order_acquire) == 1);
|
|
}
|
|
{
|
|
volatile std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_release) == 0);
|
|
assert(f.test_and_set(std::memory_order_release) == 1);
|
|
}
|
|
{
|
|
volatile std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_acq_rel) == 0);
|
|
assert(f.test_and_set(std::memory_order_acq_rel) == 1);
|
|
}
|
|
{
|
|
volatile std::atomic_flag f;
|
|
f.clear();
|
|
assert(f.test_and_set(std::memory_order_seq_cst) == 0);
|
|
assert(f.test_and_set(std::memory_order_seq_cst) == 1);
|
|
}
|
|
|
|
return 0;
|
|
}
|