#include #include #include #include #ifdef _WIN32 #include #endif extern "C" void TouchHostThreadLocal(); extern "C" unsigned DestroyedHostThreadLocals(); int main() { for (unsigned i = 0; i < 64; ++i) { std::thread worker([] { TouchHostThreadLocal(); TouchHostThreadLocal(); }); worker.join(); if (DestroyedHostThreadLocals() != (i + 1) * 2) std::abort(); } #ifdef _WIN32 for (unsigned i = 0; i < 64; ++i) { const auto worker = CreateThread(nullptr, 0, +[](void*) -> DWORD { TouchHostThreadLocal(); return 0; }, nullptr, 0, nullptr); if (!worker || WaitForSingleObject(worker, 5000) != WAIT_OBJECT_0) std::abort(); CloseHandle(worker); if (DestroyedHostThreadLocals() != 128 + (i + 1) * 2) std::abort(); } #endif for (unsigned i = 0; i < 16; ++i) { const auto before = DestroyedHostThreadLocals(); std::array, 4> workers; for (auto& worker : workers) { worker = std::async(std::launch::async, [] { TouchHostThreadLocal(); TouchHostThreadLocal(); }); } for (auto& worker : workers) worker.get(); if (DestroyedHostThreadLocals() != before + 8) std::abort(); } }