mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
base-nova: increment 'pause' semaphore only when recall handler uses it in reply
Fixes #2796
This commit is contained in:
parent
e005d966b4
commit
f78d856b37
@ -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; }
|
||||
|
@ -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)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user