void BasicThread::ForceCoreThreadReidentify(void) { for(const auto& ctxt : ContextEnumerator(AutoGlobalContext())) { auto threadListCpy = ctxt->CopyBasicThreadList(); for(auto q = threadListCpy.begin(); q != threadListCpy.end(); q++) (**q).SetCurrentThreadName(); } }
Benchmark ContextTrackingBm::ContextEnum(void) { return { { "single", [](Stopwatch& sw) { auto all = create(); // Now enumerate sw.Start(); AutoCurrentContext ctxt; for (auto cur : ContextEnumerator(ctxt)) ; sw.Stop(n); } }, { "parallel", do_parallel_enum<1> }, { "parallel x10", do_parallel_enum<1> } }; }
TEST_F(ContextEnumeratorTest, DegenerateEnumeration) { size_t ct = 0; for(const auto& cur : ContextEnumerator(std::shared_ptr<CoreContext>(nullptr))) { ASSERT_TRUE(!!cur.get()) << "Context enumerator incorrectly enumerated a null context pointer"; ct++; } ASSERT_EQ(0UL, ct) << "An empty enumerator unexpectedly enumerated one or more entries"; }
TEST_F(ContextEnumeratorTest, TrivialEnumeration) { size_t ct = 0; for(const auto& cur : ContextEnumerator(AutoCurrentContext())) { (void) cur; ct++; } ASSERT_EQ(1UL, ct) << "Context enumerator failed to enumerate a context with no children"; }
TEST_F(ContextEnumeratorTest, TwoContextEnumerationTest) { AutoCreateContext ctxt1; AutoCreateContext ctxt2; size_t ct = 0; for(const auto& cur : ContextEnumerator(ctxt1)) { (void) cur; ct++; } ASSERT_EQ(1UL, ct) << "An attempt to enumerate a context with a sibling did not correctly enumerate one context"; }
static void do_parallel_enum(Stopwatch& sw) { AutoCurrentContext ctxt; auto all = create(); // Create threads which will cause contention: auto proceed = std::make_shared<bool>(true); for (size_t nParallel = N; nParallel--;) { std::thread([proceed, all, ctxt] { while (*proceed) for (auto cur : ContextEnumerator(ctxt)) ; }).detach(); } auto cleanup = MakeAtExit([&] { *proceed = false; }); std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Perform parallel enumeration sw.Start(); for (auto cur : ContextEnumerator(ctxt)) ; sw.Stop(n); }