diff --git a/repos/base-nova/src/core/include/pager.h b/repos/base-nova/src/core/include/pager.h index d7a40ab5e..4ab1d8f03 100644 --- a/repos/base-nova/src/core/include/pager.h +++ b/repos/base-nova/src/core/include/pager.h @@ -85,20 +85,24 @@ namespace Genode { struct Thread_state thread; addr_t sel_client_ec; enum { - BLOCKED = 0x1U, - DEAD = 0x2U, - SINGLESTEP = 0x4U, - SIGNAL_SM = 0x8U, - DISSOLVED = 0x10U, - SUBMIT_SIGNAL = 0x20U, + BLOCKED = 0x1U, + DEAD = 0x2U, + SINGLESTEP = 0x4U, + SIGNAL_SM = 0x8U, + DISSOLVED = 0x10U, + SUBMIT_SIGNAL = 0x20U, + BLOCKED_PAUSE_SM = 0x40U, }; uint8_t _status; bool modified; /* convenience function to access pause/recall state */ - inline bool blocked() { return _status & BLOCKED;} - inline void block() { _status |= BLOCKED; } - inline void unblock() { _status &= ~BLOCKED; } + inline bool blocked() { return _status & BLOCKED;} + inline void block() { _status |= BLOCKED; } + inline void unblock() { _status &= ~BLOCKED; } + inline bool blocked_pause_sm() { return _status & BLOCKED_PAUSE_SM;} + inline void block_pause_sm() { _status |= BLOCKED_PAUSE_SM; } + inline void unblock_pause_sm() { _status &= ~BLOCKED_PAUSE_SM; } inline void mark_dead() { _status |= DEAD; } inline bool is_dead() { return _status & DEAD; } diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index a30f88ca3..f1fbba128 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -156,6 +156,7 @@ void Pager_object::_page_fault_handler(addr_t pager_obj) obj->_state.thread.trapno = PT_SEL_PAGE_FAULT; obj->_state.block(); + obj->_state.block_pause_sm(); obj->_state_lock.unlock(); @@ -261,7 +262,12 @@ void Pager_object::_recall_handler(addr_t pager_obj) /* block until cpu_session()->resume() respectively wake_up() call */ - unsigned long sm = obj->_state.blocked() ? obj->sel_sm_block_pause() : 0; + unsigned long sm = 0; + + if (obj->_state.blocked()) { + sm = obj->sel_sm_block_pause(); + obj->_state.block_pause_sm(); + } obj->_state_lock.unlock(); @@ -405,9 +411,15 @@ void Pager_object::wake_up() _state.unblock(); - uint8_t res = sm_ctrl(sel_sm_block_pause(), SEMAPHORE_UP); - if (res != NOVA_OK) - warning("canceling blocked client failed (thread sm)"); + if (_state.blocked_pause_sm()) { + + uint8_t res = sm_ctrl(sel_sm_block_pause(), SEMAPHORE_UP); + + if (res == NOVA_OK) + _state.unblock_pause_sm(); + else + warning("canceling blocked client failed (thread sm)"); + } }