mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-23 04:25:21 +00:00
nova: don't wait for workers in cpu_session::pause
If a local thread is attempted to be 'pause'd via cpu_session, don't wait until it gets into the recalled state. If the caller is lucky it is, if not return only the stack pointer. Avoids deadlocking of the gdb when attached to a process running a server. Issue #478
This commit is contained in:
parent
d8cf17687e
commit
73cff5c996
@ -135,6 +135,7 @@ namespace Genode {
|
||||
/**
|
||||
* Set initial stack pointer used by the startup handler
|
||||
*/
|
||||
addr_t initial_esp() { return _initial_esp; }
|
||||
void initial_esp(addr_t esp) { _initial_esp = esp; }
|
||||
|
||||
/**
|
||||
@ -183,14 +184,14 @@ namespace Genode {
|
||||
/**
|
||||
* Copy thread state of recalled thread.
|
||||
*/
|
||||
int copy_thread_state(Thread_state * state_dst)
|
||||
bool copy_thread_state(Thread_state * state_dst)
|
||||
{
|
||||
if (!state_dst || !_state.is_valid())
|
||||
return -1;
|
||||
return false;
|
||||
|
||||
*state_dst = _state.thread;
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,13 +37,24 @@ namespace Genode {
|
||||
addr_t _id_base;
|
||||
addr_t _sel_exc_base;
|
||||
Affinity::Location _location;
|
||||
bool _is_main_thread;
|
||||
bool _is_vcpu;
|
||||
|
||||
enum {
|
||||
MAIN_THREAD = 0x1U,
|
||||
VCPU = 0x2U,
|
||||
WORKER = 0x4U,
|
||||
};
|
||||
uint8_t _features;
|
||||
|
||||
char _name[Thread_base::Context::NAME_LEN];
|
||||
|
||||
addr_t _sel_ec() const { return _id_base; }
|
||||
addr_t _sel_sc() const { return _id_base + 1; }
|
||||
|
||||
/* convenience function to access _feature variable */
|
||||
inline bool is_main_thread() { return _features & MAIN_THREAD; }
|
||||
inline bool is_vcpu() { return _features & VCPU; }
|
||||
inline bool is_worker() { return _features & WORKER; }
|
||||
|
||||
public:
|
||||
|
||||
/* invalid thread number */
|
||||
@ -144,9 +155,11 @@ namespace Genode {
|
||||
/**
|
||||
* Associate thread with protection domain
|
||||
*/
|
||||
void bind_to_pd(Platform_pd *pd, bool is_main_thread)
|
||||
void bind_to_pd(Platform_pd *pd, bool main_thread)
|
||||
{
|
||||
_pd = pd, _is_main_thread = is_main_thread;
|
||||
_pd = pd;
|
||||
|
||||
if (main_thread) _features |= MAIN_THREAD;
|
||||
}
|
||||
|
||||
void single_step(bool on);
|
||||
|
@ -63,9 +63,9 @@ int Platform_thread::start(void *ip, void *sp)
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (!_is_main_thread) {
|
||||
if (!is_main_thread()) {
|
||||
addr_t initial_sp = reinterpret_cast<addr_t>(sp);
|
||||
addr_t utcb = _is_vcpu ? 0 : round_page(initial_sp);
|
||||
addr_t utcb = is_vcpu() ? 0 : round_page(initial_sp);
|
||||
|
||||
if (_sel_exc_base == Native_thread::INVALID_INDEX) {
|
||||
PERR("exception base not specified");
|
||||
@ -82,6 +82,13 @@ int Platform_thread::start(void *ip, void *sp)
|
||||
return -4;
|
||||
}
|
||||
|
||||
if (!thread_global) {
|
||||
_features |= WORKER;
|
||||
|
||||
/* local/worker threads do not require a startup portal */
|
||||
revoke(Obj_crd(_pager->exc_pt_sel_client() + PT_SEL_STARTUP, 0));
|
||||
}
|
||||
|
||||
_pager->initial_eip((addr_t)ip);
|
||||
_pager->initial_esp(initial_sp);
|
||||
_pager->client_set_ec(_sel_ec());
|
||||
@ -181,18 +188,20 @@ int Platform_thread::start(void *ip, void *sp)
|
||||
|
||||
Native_capability Platform_thread::pause()
|
||||
{
|
||||
if (!_pager)
|
||||
return Native_capability::invalid_cap();
|
||||
if (!_pager) return Native_capability();
|
||||
|
||||
Native_capability notify_sm = _pager->notify_sm();
|
||||
if (!notify_sm.valid()) return notify_sm;
|
||||
|
||||
if (_pager->client_recall() != Nova::NOVA_OK)
|
||||
return Native_capability::invalid_cap();
|
||||
if (_pager->client_recall() != Nova::NOVA_OK)
|
||||
return Native_capability();
|
||||
|
||||
/* If the thread is blocked in the its own SM, get him out */
|
||||
/* If the thread is blocked in its own SM, get him out */
|
||||
cancel_blocking();
|
||||
|
||||
/* local thread may never get be canceled if it doesn't receive an IPC */
|
||||
if (is_worker()) return Native_capability();
|
||||
|
||||
return notify_sm;
|
||||
}
|
||||
|
||||
@ -201,8 +210,10 @@ void Platform_thread::resume()
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
uint8_t res = create_sc(_sel_sc(), _pd->pd_sel(), _sel_ec(), Qpd());
|
||||
if (res == NOVA_OK) return;
|
||||
if (!is_worker()) {
|
||||
uint8_t res = create_sc(_sel_sc(), _pd->pd_sel(), _sel_ec(), Qpd());
|
||||
if (res == NOVA_OK) return;
|
||||
}
|
||||
|
||||
if (!_pager) return;
|
||||
|
||||
@ -213,9 +224,15 @@ void Platform_thread::resume()
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
Thread_state s;
|
||||
if (!_pager) throw Cpu_session::State_access_failed();
|
||||
_pager->copy_thread_state(&s);
|
||||
|
||||
Thread_state s;
|
||||
if (_pager->copy_thread_state(&s))
|
||||
return s;
|
||||
|
||||
if (is_worker())
|
||||
s.sp = _pager->initial_esp();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -223,20 +240,20 @@ Thread_state Platform_thread::state()
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
/* not permitted for main thread */
|
||||
if (_is_main_thread) throw Cpu_session::State_access_failed();
|
||||
if (is_main_thread()) throw Cpu_session::State_access_failed();
|
||||
|
||||
/* you can do it only once */
|
||||
if (_sel_exc_base != Native_thread::INVALID_INDEX)
|
||||
throw Cpu_session::State_access_failed();
|
||||
|
||||
/*
|
||||
* _sel_exc_base exception base of thread in caller
|
||||
* s.sel_exc_base exception base of thread in caller
|
||||
* protection domain - not in Core !
|
||||
* _is_vcpu If true it will run as vCPU,
|
||||
* otherwise it will be a thread.
|
||||
* s.is_vcpu If true it will run as vCPU,
|
||||
* otherwise it will be a thread.
|
||||
*/
|
||||
_sel_exc_base = s.sel_exc_base;
|
||||
_is_vcpu = s.is_vcpu;
|
||||
if (s.is_vcpu) _features |= VCPU;
|
||||
}
|
||||
|
||||
|
||||
@ -272,7 +289,7 @@ Platform_thread::Platform_thread(const char *name, unsigned, int thread_id)
|
||||
:
|
||||
_pd(0), _pager(0), _id_base(cap_selector_allocator()->alloc(1)),
|
||||
_sel_exc_base(Native_thread::INVALID_INDEX), _location(boot_cpu(), 0),
|
||||
_is_main_thread(false), _is_vcpu(false)
|
||||
_features(0)
|
||||
{
|
||||
strncpy(_name, name, sizeof(_name));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user