You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
concurrentqueue/tests/relacy/relacy_shims.h

111 lines
2.0 KiB
C++

#pragma once
// Use relacy assertions
#undef assert
#ifdef NDEBUG
#define assert(x)
#else
#define assert(x) RL_ASSERT(x)
#endif
struct RelacyThreadExitListener
{
typedef void (*callback_t)(void*);
callback_t callback;
void* userData;
RelacyThreadExitListener* next;
};
class RelacyThreadExitNotifier
{
public:
static void subscribe(RelacyThreadExitListener* listener)
{
auto& tlsInst = instance();
listener->next = tlsInst.tail;
tlsInst.tail = listener;
}
static void unsubscribe(RelacyThreadExitListener* listener)
{
auto& tlsInst = instance();
RelacyThreadExitListener** prev = &tlsInst.tail;
for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) {
if (ptr == listener) {
*prev = ptr->next;
break;
}
prev = &ptr->next;
}
}
static void notify_relacy_thread_start()
{
instance().tail = nullptr;
}
static void notify_relacy_thread_exit()
{
for (auto ptr = instance().tail; ptr != nullptr; ptr = ptr->next) {
ptr->callback(ptr->userData);
}
}
private:
RelacyThreadExitNotifier() : tail(nullptr) { }
static RelacyThreadExitNotifier& instance()
{
static RelacyThreadExitNotifier instances[1024];
auto tid = rl::thread_index();
assert(tid < 1024);
return instances[tid];
}
private:
RelacyThreadExitListener* tail;
};
namespace std
{
// Relacy doesn't wrap std::atomic_flag
struct atomic_flag {
private:
atomic_flag(atomic_flag const&);
atomic_flag(atomic_flag&&);
atomic_flag& operator=(atomic_flag const&);
atomic_flag& operator=(atomic_flag&&);
public:
atomic_flag() { }
atomic_flag(bool initialValue) : val(initialValue ? 1 : 0) { }
void clear()
{
clear(std::memory_order_seq_cst);
}
void clear(rl::memory_order order, rl::debug_info_param d)
{
val.store(0, order, d);
}
bool test_and_set()
{
return test_and_set(std::memory_order_seq_cst);
}
bool test_and_set(rl::memory_order order, rl::debug_info_param d)
{
return val.fetch_or(1, order, d) != 0;
}
private:
std::atomic<int> val;
};
}