Arene Base provides facilities for atomic operations across threads that do not depend on the C++ standard library.
The public header is
Public export header for the atomic subpackage.
The Bazel target is
Introduction
The atomic subpackage provides atomic operations and types. It is intended as an alternative to the C++ standard libarary <atomic> header, for environments where the standard library implementation is not available.
Types
atomic_counter
The atomic_counter class provides a thread-safe counter implementation using compiler intrinsics rather than standard library facilities.
arene::base::atomic_counter counter;
API Reference
Constructors
constexpr atomic_counter() noexcept;
constexpr explicit atomic_counter(uint64_t initial_value) noexcept;
Operations
auto operator++() noexcept -> uint64_t;
auto operator++(int) noexcept -> uint64_t;
auto operator--() noexcept -> uint64_t;
auto operator--(int) noexcept -> uint64_t;
auto operator+=(uint64_t val) noexcept -> uint64_t;
auto operator-=(uint64_t val) noexcept -> uint64_t;
Value Access
auto load() const noexcept -> uint64_t;
operator uint64_t() const noexcept;
Thread Safety
All operations on atomic_counter are atomic and thread-safe. The implementation uses compiler intrinsics with sequential consistency memory ordering to ensure proper behavior in multi-threaded environments.
Examples
Basic Usage
auto basic_usage() -> void {
atomic_monotonic_counter counter;
std::cout << "New value: " << new_value << std::endl;
std::cout << "Previous value: " << prev_value << std::endl;
std::cout << "Value: " << value << std::endl;
std::cout << "Same value: " << same_value << std::endl;
}
Thread-Safe Counting
auto concurrent_updates() -> void {
atomic_monotonic_counter shared_counter;
constexpr int num_threads = 4;
constexpr int iterations = 1000;
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
threads.emplace_back([&shared_counter]() {
for (int j = 0; j < iterations; ++j) {
++shared_counter;
}
});
}
for (auto& t : threads) {
t.join();
}
printf("Final counter value: %lu (expected: %d)\n", final_value, num_threads * iterations);
}
Using Counter for Event Tracking
auto counter_as_event_tracker() -> void {
atomic_monotonic_counter requests(0);
atomic_monotonic_counter completed(0);
atomic_monotonic_counter errors(0);
auto process_request = [&](int id) -> void {
++requests;
bool success = (id % 10 != 0);
if (success) {
++completed;
} else {
++errors;
}
};
for (int i = 0; i < 100; ++i) {
process_request(i);
}
printf("Requests: %lu\n", requests.load());
printf("Completed: %lu\n", completed.load());
printf("Errors: %lu\n", errors.load());
}