Open
Description
Consider the code
static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \
++LOG_OCCURRENCES; \
if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
if (LOG_OCCURRENCES_MOD_N == 1)
Although every statement here is an atomic operation, other threads may fall into the first if
condition even though LOG_OCCURRENCES_MOD_N
already subtracts n
Simple test
#include <glog/logging.h>
#include <thread>
#include <atomic>
void bar() {
static std::atomic<int> n(0);
LOG_EVERY_N(INFO, 2) << ++n;
}
int main() {
std::vector<std::thread> threads;
for (size_t i = 0; i < 4000; ++i) {
std::thread t(&bar);
threads.emplace_back(std::move(t));
}
for (auto& thread : threads) {
thread.join();
}
}
Sometimes the output will not be equal to 2000.
I have no idea if it is thread-safe in the older compilers.