@@ -29,6 +29,60 @@ namespace dart {
2929
3030DECLARE_FLAG (bool , trace_thread_interrupter);
3131
32+ class SignalState : public AllStatic {
33+ public:
34+ static bool Start () {
35+ uword expected = state_.load (std::memory_order_relaxed);
36+ uword desired;
37+ do {
38+ if (!Enabled::decode (expected)) return false ;
39+ desired = Pending::update (Pending::decode (expected) + 1 , expected);
40+ } while (!state_.compare_exchange_weak (expected, desired,
41+ std::memory_order_relaxed));
42+ return true ;
43+ }
44+
45+ static void End () {
46+ uword expected = state_.load (std::memory_order_relaxed);
47+ uword desired;
48+ do {
49+ intptr_t pending = Pending::decode (expected);
50+ ASSERT (pending > 0 );
51+ desired = Pending::update (pending - 1 , expected);
52+ } while (!state_.compare_exchange_weak (expected, desired,
53+ std::memory_order_relaxed));
54+ }
55+
56+ static void Enable () {
57+ uword expected = state_.load (std::memory_order_relaxed);
58+ ASSERT (expected == (Enabled::encode (false ) | Pending::encode (0 )));
59+ uword desired = Enabled::encode (true ) | Pending::encode (0 );
60+ bool success = state_.compare_exchange_strong (expected, desired,
61+ std::memory_order_relaxed);
62+ ASSERT (success);
63+ }
64+
65+ static void Disable () {
66+ ASSERT (Enabled::decode (state_.load (std::memory_order_relaxed)));
67+ uword expected;
68+ uword desired = Enabled::encode (false ) | Pending::encode (0 );
69+ do {
70+ // Failed CAS updates [expected], recompute.
71+ expected = Enabled::encode (true ) | Pending::encode (0 );
72+ } while (!state_.compare_exchange_weak (expected, desired,
73+ std::memory_order_relaxed));
74+ }
75+
76+ private:
77+ using Enabled = BitField<uword, bool , 0 , 1 >;
78+ using Pending =
79+ BitField<uword, intptr_t , Enabled::kNextBit , kBitsPerWord - 1 >;
80+ static std::atomic<uword> state_;
81+ };
82+
83+ std::atomic<uword> SignalState::state_ = {Enabled::encode (false ) |
84+ Pending::encode (0 )};
85+
3286namespace {
3387#if defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
3488extern " C" {
@@ -41,6 +95,9 @@ void ThreadInterruptSignalHandler(int signal, siginfo_t* info, void* context_) {
4195 if (thread == nullptr ) {
4296 return ;
4397 }
98+ if (!SignalState::Start ()) {
99+ return ;
100+ }
44101 ThreadInterruptScope signal_handler_scope;
45102 // Extract thread state.
46103 ucontext_t * context = reinterpret_cast <ucontext_t *>(context_);
@@ -52,6 +109,7 @@ void ThreadInterruptSignalHandler(int signal, siginfo_t* info, void* context_) {
52109 its.dsp = SignalHandler::GetDartStackPointer (mcontext);
53110 its.lr = SignalHandler::GetLinkRegister (mcontext);
54111 Profiler::SampleThread (thread, its);
112+ SignalState::End ();
55113}
56114#if defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
57115} // extern "C"
@@ -81,9 +139,11 @@ void ThreadInterrupter::InstallSignalHandler() {
81139#else
82140 SignalHandler::Install (&ThreadInterruptSignalHandler);
83141#endif
142+ SignalState::Enable ();
84143}
85144
86145void ThreadInterrupter::RemoveSignalHandler () {
146+ SignalState::Disable ();
87147 SignalHandler::Remove ();
88148}
89149
0 commit comments