History

Fix race condition between scheduler and debugger during all thread suspension.

arr committed 9 years ago

Commit bd141a71 parent a6da1dc5 files · +20 −33Browse files

Showing the changes to src/vm/tool_dispatch.cpp (1 of 5 files). Show all

Unified · Split

src/vm/tool_dispatch.cpp+9−10
@@ -332,23 +332,22 @@ void vm_tool_dispatch_t::suspend_all_threads() · 331 unmodified lines
332332
333333 const auto &sched = _vm.get_scheduler_control();
334334
335− auto current = _threads_suspended_count.load();
336− auto max = static_cast<uint32_t>(sched.get_runnable_threads().size());
335+ const auto sys_thread_count = static_cast<int32_t>(sched.get_system_thread_count());
336+ assert(sys_thread_count != 0);
337337
338− // Sleep and check until we determine all threads have been suspended
339− // Minus 1 to exclude the current thread.
340− while (max != 0 && current < (max - 1))
338+ // Sleep and check until we account for all system threads associated with the VM.
339+ auto suspended = _threads_suspended_count.load();
340+ while ((suspended + 1) < sys_thread_count)
341341 {
342342 std::this_thread::sleep_for(std::chrono::milliseconds{ 20 });
343− current = _threads_suspended_count.load();
344− max = static_cast<uint32_t>(sched.get_runnable_threads().size());
343+ suspended = _threads_suspended_count.load();
345344 }
346345
347− // If the current count is ever equal to the max, then a non vm thread is
348− // inside the tool dispatcher which may be okay, but it indicates a type of
346+ // If the suspended count is ever equal to the system thread count, then a non-vm thread
347+ // is inside the tool dispatcher which may be okay, but it indicates a type of
349348 // non-invasive debugging that was not originally incorporated into this
350349 // dispatcher design.
351− assert(max == 0 || current < max);
350+ assert(suspended < sys_thread_count);
352351 }
353352
354353 void vm_tool_dispatch_t::resume_all_threads()