mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 22:47:50 +00:00
parent
d1be1281bc
commit
c55a499009
@ -64,7 +64,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup_call(Rpc_object_base *obj, Nova::Utcb * ep_utcb,
|
static void cleanup_call(Rpc_object_base *obj, Nova::Utcb * ep_utcb,
|
||||||
Native_capability &cap, Genode::Blockade &delay_start)
|
Native_capability &cap)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* effectively invalidate the capability used before */
|
/* effectively invalidate the capability used before */
|
||||||
@ -84,9 +84,6 @@ static void cleanup_call(Rpc_object_base *obj, Nova::Utcb * ep_utcb,
|
|||||||
if (utcb == ep_utcb)
|
if (utcb == ep_utcb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* activate entrypoint now - otherwise cleanup call will block forever */
|
|
||||||
delay_start.wakeup();
|
|
||||||
|
|
||||||
/* make a IPC to ensure that cap() identifier is not used anymore */
|
/* make a IPC to ensure that cap() identifier is not used anymore */
|
||||||
utcb->msg()[0] = 0xdead;
|
utcb->msg()[0] = 0xdead;
|
||||||
utcb->set_msg_word(1);
|
utcb->set_msg_word(1);
|
||||||
@ -109,8 +106,7 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
|||||||
/* make sure nobody is able to find this object */
|
/* make sure nobody is able to find this object */
|
||||||
remove(obj);
|
remove(obj);
|
||||||
|
|
||||||
cleanup_call(obj, reinterpret_cast<Nova::Utcb *>(this->utcb()), _cap,
|
cleanup_call(obj, reinterpret_cast<Nova::Utcb *>(this->utcb()), _cap);
|
||||||
_delay_start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reply(Nova::Utcb &utcb, Rpc_exception_code exc, Msgbuf_base &snd_msg)
|
static void reply(Nova::Utcb &utcb, Rpc_exception_code exc, Msgbuf_base &snd_msg)
|
||||||
@ -160,11 +156,6 @@ void Rpc_entrypoint::_activation_entry()
|
|||||||
reply(utcb, exc, ep._snd_buf);
|
reply(utcb, exc, ep._snd_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delay start */
|
|
||||||
ep._delay_start.block();
|
|
||||||
/* XXX inadequate usage of Blockade here is planned to be removed, see #3612 */
|
|
||||||
ep._delay_start.wakeup();
|
|
||||||
|
|
||||||
/* atomically lookup and lock referenced object */
|
/* atomically lookup and lock referenced object */
|
||||||
auto lambda = [&] (Rpc_object_base *obj) {
|
auto lambda = [&] (Rpc_object_base *obj) {
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
@ -198,20 +189,6 @@ void Rpc_entrypoint::entry()
|
|||||||
void Rpc_entrypoint::_block_until_cap_valid() { }
|
void Rpc_entrypoint::_block_until_cap_valid() { }
|
||||||
|
|
||||||
|
|
||||||
void Rpc_entrypoint::activate()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* In contrast to a normal thread, a server activation is created at
|
|
||||||
* construction time. However, it executes no code because processing
|
|
||||||
* time is always provided by the caller of the server activation. To
|
|
||||||
* delay the processing of requests until the 'activate' function is
|
|
||||||
* called, we grab the '_delay_start' lock on construction and release it
|
|
||||||
* here.
|
|
||||||
*/
|
|
||||||
_delay_start.wakeup();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Rpc_entrypoint::is_myself() const
|
bool Rpc_entrypoint::is_myself() const
|
||||||
{
|
{
|
||||||
return (Thread::myself() == this);
|
return (Thread::myself() == this);
|
||||||
@ -219,8 +196,7 @@ bool Rpc_entrypoint::is_myself() const
|
|||||||
|
|
||||||
|
|
||||||
Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
||||||
const char *name, bool start_on_construction,
|
const char *name, Affinity::Location location)
|
||||||
Affinity::Location location)
|
|
||||||
:
|
:
|
||||||
Thread(Cpu_session::Weight::DEFAULT_WEIGHT, name, stack_size, location),
|
Thread(Cpu_session::Weight::DEFAULT_WEIGHT, name, stack_size, location),
|
||||||
_pd_session(*pd_session)
|
_pd_session(*pd_session)
|
||||||
@ -246,9 +222,6 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
|||||||
/* prepare portal receive window of new thread */
|
/* prepare portal receive window of new thread */
|
||||||
if (!rcv_window.prepare_rcv_window(*(Nova::Utcb *)&_stack->utcb()))
|
if (!rcv_window.prepare_rcv_window(*(Nova::Utcb *)&_stack->utcb()))
|
||||||
throw Cpu_session::Thread_creation_failed();
|
throw Cpu_session::Thread_creation_failed();
|
||||||
|
|
||||||
if (start_on_construction)
|
|
||||||
activate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -269,8 +242,7 @@ Rpc_entrypoint::~Rpc_entrypoint()
|
|||||||
/* avoid any incoming IPC */
|
/* avoid any incoming IPC */
|
||||||
Nova::revoke(Nova::Obj_crd(obj->cap().local_name(), 0), true);
|
Nova::revoke(Nova::Obj_crd(obj->cap().local_name(), 0), true);
|
||||||
|
|
||||||
cleanup_call(obj, reinterpret_cast<Nova::Utcb *>(this->utcb()), _cap,
|
cleanup_call(obj, reinterpret_cast<Nova::Utcb *>(this->utcb()), _cap);
|
||||||
_delay_start);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!_cap.valid())
|
if (!_cap.valid())
|
||||||
|
@ -41,7 +41,8 @@ using namespace Genode;
|
|||||||
void test_translate(Genode::Env &env)
|
void test_translate(Genode::Env &env)
|
||||||
{
|
{
|
||||||
enum { STACK_SIZE = 4096 };
|
enum { STACK_SIZE = 4096 };
|
||||||
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_translate");
|
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_translate",
|
||||||
|
Affinity::Location());
|
||||||
|
|
||||||
Test::Component component;
|
Test::Component component;
|
||||||
Test::Capability session_cap = ep.manage(&component);
|
Test::Capability session_cap = ep.manage(&component);
|
||||||
@ -136,7 +137,8 @@ void test_translate(Genode::Env &env)
|
|||||||
void test_revoke(Genode::Env &env)
|
void test_revoke(Genode::Env &env)
|
||||||
{
|
{
|
||||||
enum { STACK_SIZE = 4096 };
|
enum { STACK_SIZE = 4096 };
|
||||||
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_revoke");
|
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_revoke",
|
||||||
|
Affinity::Location());
|
||||||
|
|
||||||
Test::Component component;
|
Test::Component component;
|
||||||
Test::Capability session_cap = ep.manage(&component);
|
Test::Capability session_cap = ep.manage(&component);
|
||||||
@ -304,7 +306,8 @@ void test_pat(Genode::Env &env)
|
|||||||
|
|
||||||
enum { STACK_SIZE = 4096 };
|
enum { STACK_SIZE = 4096 };
|
||||||
|
|
||||||
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_pat");
|
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_pat",
|
||||||
|
Affinity::Location());
|
||||||
|
|
||||||
Genode::Rm_connection rm(env);
|
Genode::Rm_connection rm(env);
|
||||||
Genode::Region_map_client rm_free_area(rm.create(1 << (DS_ORDER + PAGE_4K)));
|
Genode::Region_map_client rm_free_area(rm.create(1 << (DS_ORDER + PAGE_4K)));
|
||||||
@ -381,7 +384,8 @@ void test_server_oom(Genode::Env &env)
|
|||||||
|
|
||||||
enum { STACK_SIZE = 4096 };
|
enum { STACK_SIZE = 4096 };
|
||||||
|
|
||||||
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_oom");
|
static Rpc_entrypoint ep(&env.pd(), STACK_SIZE, "rpc_ep_oom",
|
||||||
|
Affinity::Location());
|
||||||
|
|
||||||
Test::Component component;
|
Test::Component component;
|
||||||
Test::Capability session_cap = ep.manage(&component);
|
Test::Capability session_cap = ep.manage(&component);
|
||||||
|
@ -283,13 +283,9 @@ struct Genode::Rpc_object : Rpc_object_base, Rpc_dispatcher<RPC_INTERFACE, SERVE
|
|||||||
* RPC entrypoint serving RPC objects
|
* RPC entrypoint serving RPC objects
|
||||||
*
|
*
|
||||||
* The entrypoint's thread will initialize its capability but will not
|
* The entrypoint's thread will initialize its capability but will not
|
||||||
* immediately enable the processing of requests. This way, the
|
* immediately enable the processing of requests. The server's capability must
|
||||||
* activation-using server can ensure that it gets initialized completely
|
* be handed over to other parties _after_ the server is completely
|
||||||
* before the first capability invocations come in. Once the server is
|
* initialized.
|
||||||
* ready, it must enable the entrypoint explicitly by calling the
|
|
||||||
* 'activate()' method. The 'start_on_construction' argument is a
|
|
||||||
* shortcut for the common case where the server's capability is handed
|
|
||||||
* over to other parties _after_ the server is completely initialized.
|
|
||||||
*/
|
*/
|
||||||
class Genode::Rpc_entrypoint : Thread, public Object_pool<Rpc_object_base>
|
class Genode::Rpc_entrypoint : Thread, public Object_pool<Rpc_object_base>
|
||||||
{
|
{
|
||||||
@ -339,7 +335,6 @@ class Genode::Rpc_entrypoint : Thread, public Object_pool<Rpc_object_base>
|
|||||||
|
|
||||||
Native_capability _caller { };
|
Native_capability _caller { };
|
||||||
Blockade _cap_valid { }; /* thread startup synchronization */
|
Blockade _cap_valid { }; /* thread startup synchronization */
|
||||||
Blockade _delay_start { }; /* delay start of request dispatching */
|
|
||||||
Blockade _delay_exit { }; /* delay destructor until server settled */
|
Blockade _delay_exit { }; /* delay destructor until server settled */
|
||||||
Pd_session &_pd_session; /* for creating capabilities */
|
Pd_session &_pd_session; /* for creating capabilities */
|
||||||
Exit_handler _exit_handler { };
|
Exit_handler _exit_handler { };
|
||||||
@ -412,8 +407,7 @@ class Genode::Rpc_entrypoint : Thread, public Object_pool<Rpc_object_base>
|
|||||||
* \param location CPU affinity
|
* \param location CPU affinity
|
||||||
*/
|
*/
|
||||||
Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
||||||
char const *name, bool start_on_construction = true,
|
char const *name, Affinity::Location location);
|
||||||
Affinity::Location location = Affinity::Location());
|
|
||||||
|
|
||||||
~Rpc_entrypoint();
|
~Rpc_entrypoint();
|
||||||
|
|
||||||
@ -436,11 +430,6 @@ class Genode::Rpc_entrypoint : Thread, public Object_pool<Rpc_object_base>
|
|||||||
_dissolve(obj);
|
_dissolve(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Activate entrypoint, start processing RPC requests
|
|
||||||
*/
|
|
||||||
void activate();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request reply capability for current call
|
* Request reply capability for current call
|
||||||
*
|
*
|
||||||
|
@ -115,10 +115,8 @@ _ZN6Genode14Rpc_entrypoint17reply_signal_infoENS_17Native_capabilityEmm T
|
|||||||
_ZN6Genode14Rpc_entrypoint22_block_until_cap_validEv T
|
_ZN6Genode14Rpc_entrypoint22_block_until_cap_validEv T
|
||||||
_ZN6Genode14Rpc_entrypoint5entryEv T
|
_ZN6Genode14Rpc_entrypoint5entryEv T
|
||||||
_ZN6Genode14Rpc_entrypoint7_manageEPNS_15Rpc_object_baseE T
|
_ZN6Genode14Rpc_entrypoint7_manageEPNS_15Rpc_object_baseE T
|
||||||
_ZN6Genode14Rpc_entrypoint8activateEv T
|
|
||||||
_ZN6Genode14Rpc_entrypoint9_dissolveEPNS_15Rpc_object_baseE T
|
_ZN6Genode14Rpc_entrypoint9_dissolveEPNS_15Rpc_object_baseE T
|
||||||
_ZN6Genode14Rpc_entrypointC1EPNS_10Pd_sessionEmPKcbNS_8Affinity8LocationE T
|
_ZN6Genode14Rpc_entrypointC1EPNS_10Pd_sessionEmPKcNS_8Affinity8LocationE T
|
||||||
_ZN6Genode14Rpc_entrypointC2EPNS_10Pd_sessionEmPKcbNS_8Affinity8LocationE T
|
|
||||||
_ZN6Genode14Rpc_entrypointD0Ev T
|
_ZN6Genode14Rpc_entrypointD0Ev T
|
||||||
_ZN6Genode14Rpc_entrypointD1Ev T
|
_ZN6Genode14Rpc_entrypointD1Ev T
|
||||||
_ZN6Genode14Rpc_entrypointD2Ev T
|
_ZN6Genode14Rpc_entrypointD2Ev T
|
||||||
|
@ -58,7 +58,8 @@ class Genode::Core_env : public Env_deprecated, Noncopyable
|
|||||||
|
|
||||||
Core_env()
|
Core_env()
|
||||||
:
|
:
|
||||||
_entrypoint(nullptr, ENTRYPOINT_STACK_SIZE, "entrypoint"),
|
_entrypoint(nullptr, ENTRYPOINT_STACK_SIZE, "entrypoint",
|
||||||
|
Affinity::Location()),
|
||||||
_region_map(_entrypoint),
|
_region_map(_entrypoint),
|
||||||
_pd_session(_entrypoint,
|
_pd_session(_entrypoint,
|
||||||
_entrypoint,
|
_entrypoint,
|
||||||
|
@ -30,7 +30,7 @@ namespace Genode {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Io_port_handler(Pd_session &pd_session) :
|
Io_port_handler(Pd_session &pd_session) :
|
||||||
_ep(&pd_session, STACK_SIZE, "ioport")
|
_ep(&pd_session, STACK_SIZE, "ioport", Affinity::Location())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Rpc_entrypoint &entrypoint() { return _ep; }
|
Rpc_entrypoint &entrypoint() { return _ep; }
|
||||||
|
@ -55,7 +55,7 @@ class Genode::Irq_root : public Root_component<Irq_session_component>
|
|||||||
Range_allocator &irq_alloc, Allocator &md_alloc)
|
Range_allocator &irq_alloc, Allocator &md_alloc)
|
||||||
:
|
:
|
||||||
Root_component<Irq_session_component>(&_session_ep, &md_alloc),
|
Root_component<Irq_session_component>(&_session_ep, &md_alloc),
|
||||||
_session_ep(&pd_session, STACK_SIZE, "irq"),
|
_session_ep(&pd_session, STACK_SIZE, "irq", Affinity::Location()),
|
||||||
_irq_alloc(irq_alloc)
|
_irq_alloc(irq_alloc)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
@ -58,6 +58,6 @@ void Signal_transmitter::submit(unsigned cnt)
|
|||||||
Rpc_entrypoint &Core_env::signal_ep()
|
Rpc_entrypoint &Core_env::signal_ep()
|
||||||
{
|
{
|
||||||
static Rpc_entrypoint ep(nullptr, ENTRYPOINT_STACK_SIZE,
|
static Rpc_entrypoint ep(nullptr, ENTRYPOINT_STACK_SIZE,
|
||||||
"signal_entrypoint");
|
"signal_entrypoint", Affinity::Location());
|
||||||
return ep;
|
return ep;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ void Entrypoint::_process_incoming_signals()
|
|||||||
|
|
||||||
init_signal_thread(_env);
|
init_signal_thread(_env);
|
||||||
|
|
||||||
_rpc_ep.construct(&_env.pd(), Component::stack_size(), initial_ep_name());
|
_rpc_ep.construct(&_env.pd(), Component::stack_size(), initial_ep_name(), Affinity::Location());
|
||||||
init_heartbeat_monitoring(_env);
|
init_heartbeat_monitoring(_env);
|
||||||
_signal_proxy_cap = manage(_signal_proxy);
|
_signal_proxy_cap = manage(_signal_proxy);
|
||||||
_sig_rec.construct();
|
_sig_rec.construct();
|
||||||
@ -330,7 +330,7 @@ namespace {
|
|||||||
Entrypoint::Entrypoint(Env &env)
|
Entrypoint::Entrypoint(Env &env)
|
||||||
:
|
:
|
||||||
_env(env),
|
_env(env),
|
||||||
_rpc_ep(&env.pd(), Component::stack_size(), initial_ep_name()),
|
_rpc_ep(&env.pd(), Component::stack_size(), initial_ep_name(), Affinity::Location()),
|
||||||
|
|
||||||
/* initialize signalling before creating the first signal receiver */
|
/* initialize signalling before creating the first signal receiver */
|
||||||
_signalling_initialized((init_signal_thread(env), true))
|
_signalling_initialized((init_signal_thread(env), true))
|
||||||
@ -365,7 +365,7 @@ Entrypoint::Entrypoint(Env &env, size_t stack_size, char const *name,
|
|||||||
Affinity::Location location)
|
Affinity::Location location)
|
||||||
:
|
:
|
||||||
_env(env),
|
_env(env),
|
||||||
_rpc_ep(&env.pd(), stack_size, name, true, location),
|
_rpc_ep(&env.pd(), stack_size, name, location),
|
||||||
_signalling_initialized(true)
|
_signalling_initialized(true)
|
||||||
{
|
{
|
||||||
_signal_proxy_thread.construct(env, *this, location,
|
_signal_proxy_thread.construct(env, *this, location,
|
||||||
|
@ -50,15 +50,6 @@ void Rpc_entrypoint::entry()
|
|||||||
_cap = srv;
|
_cap = srv;
|
||||||
_cap_valid.wakeup();
|
_cap_valid.wakeup();
|
||||||
|
|
||||||
/*
|
|
||||||
* Now, the capability of the server activation is initialized
|
|
||||||
* an can be passed around. However, the processing of capability
|
|
||||||
* invocations should not happen until activation-using server
|
|
||||||
* is completely initialized. Thus, we wait until the activation
|
|
||||||
* gets explicitly unblocked by calling 'Rpc_entrypoint::activate()'.
|
|
||||||
*/
|
|
||||||
_delay_start.block();
|
|
||||||
|
|
||||||
Rpc_exception_code exc = Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT);
|
Rpc_exception_code exc = Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT);
|
||||||
|
|
||||||
while (!_exit_handler.exit) {
|
while (!_exit_handler.exit) {
|
||||||
|
@ -57,12 +57,6 @@ void Rpc_entrypoint::reply_signal_info(Untyped_capability reply_cap,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Rpc_entrypoint::activate()
|
|
||||||
{
|
|
||||||
_delay_start.wakeup();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Rpc_entrypoint::is_myself() const
|
bool Rpc_entrypoint::is_myself() const
|
||||||
{
|
{
|
||||||
return (Thread::myself() == this);
|
return (Thread::myself() == this);
|
||||||
@ -70,8 +64,7 @@ bool Rpc_entrypoint::is_myself() const
|
|||||||
|
|
||||||
|
|
||||||
Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
||||||
char const *name, bool start_on_construction,
|
char const *name, Affinity::Location location)
|
||||||
Affinity::Location location)
|
|
||||||
:
|
:
|
||||||
Thread(Cpu_session::Weight::DEFAULT_WEIGHT, name, stack_size, location),
|
Thread(Cpu_session::Weight::DEFAULT_WEIGHT, name, stack_size, location),
|
||||||
_cap(Untyped_capability()),
|
_cap(Untyped_capability()),
|
||||||
@ -80,21 +73,12 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
|||||||
Thread::start();
|
Thread::start();
|
||||||
_block_until_cap_valid();
|
_block_until_cap_valid();
|
||||||
|
|
||||||
if (start_on_construction)
|
|
||||||
activate();
|
|
||||||
|
|
||||||
_exit_cap = manage(&_exit_handler);
|
_exit_cap = manage(&_exit_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rpc_entrypoint::~Rpc_entrypoint()
|
Rpc_entrypoint::~Rpc_entrypoint()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* We have to make sure the server loop is running which is only the case
|
|
||||||
* if the Rpc_entrypoint was activated before we execute the RPC call.
|
|
||||||
*/
|
|
||||||
_delay_start.wakeup();
|
|
||||||
|
|
||||||
/* leave server loop */
|
/* leave server loop */
|
||||||
_exit_cap.call<Exit::Rpc_exit>();
|
_exit_cap.call<Exit::Rpc_exit>();
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ namespace Mp_server_test {
|
|||||||
Client cli { cap };
|
Client cli { cap };
|
||||||
|
|
||||||
Cpu_compound(Genode::Affinity::Location l, Genode::Env &env)
|
Cpu_compound(Genode::Affinity::Location l, Genode::Env &env)
|
||||||
: rpc(&env.pd(), STACK_SIZE, "rpc en", true, l) {}
|
: rpc(&env.pd(), STACK_SIZE, "rpc en", l) {}
|
||||||
~Cpu_compound() { rpc.dissolve(&comp); }
|
~Cpu_compound() { rpc.dissolve(&comp); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user