mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-21 16:39:39 +00:00
Remove exceptions from Cpu_session interface
The 'Thread_creation_failed' error is now reflected as 'Thread::Start_result' return value. This change also removes the use of 'Invalid_thread' within core as this exception is an alias of Cpu_session::Thread_creation_failed. Issue #5245
This commit is contained in:
@ -25,73 +25,66 @@
|
||||
using namespace Core;
|
||||
|
||||
|
||||
Thread_capability Cpu_session_component::create_thread(Capability<Pd_session> pd_cap,
|
||||
Name const &name,
|
||||
Affinity::Location affinity,
|
||||
Weight weight,
|
||||
addr_t utcb)
|
||||
Cpu_session::Create_thread_result
|
||||
Cpu_session_component::create_thread(Capability<Pd_session> pd_cap,
|
||||
Name const &name, Affinity::Location affinity,
|
||||
Weight weight, addr_t utcb)
|
||||
{
|
||||
Trace::Thread_name thread_name(name.string());
|
||||
if (!try_withdraw(Ram_quota{_utcb_quota_size()}))
|
||||
return Create_thread_error::OUT_OF_RAM;
|
||||
|
||||
withdraw(Ram_quota{_utcb_quota_size()});
|
||||
if (weight.value == 0) {
|
||||
warning("Thread ", name, ": Bad weight 0, using default weight instead.");
|
||||
weight = Weight();
|
||||
}
|
||||
if (weight.value > QUOTA_LIMIT) {
|
||||
warning("Thread ", name, ": Oversized weight ", weight.value, ", using limit instead.");
|
||||
weight = Weight(QUOTA_LIMIT);
|
||||
}
|
||||
|
||||
try {
|
||||
Mutex::Guard thread_list_lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = 0;
|
||||
Create_thread_result result = Create_thread_error::DENIED;
|
||||
|
||||
if (weight.value == 0) {
|
||||
warning("Thread ", name, ": Bad weight 0, using default weight instead.");
|
||||
weight = Weight();
|
||||
}
|
||||
if (weight.value > QUOTA_LIMIT) {
|
||||
warning("Thread ", name, ": Oversized weight ", weight.value, ", using limit instead.");
|
||||
weight = Weight(QUOTA_LIMIT);
|
||||
_incr_weight(weight.value);
|
||||
|
||||
_thread_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
|
||||
|
||||
if (!pd) {
|
||||
error("create_thread: invalid PD argument");
|
||||
return;
|
||||
}
|
||||
|
||||
Mutex::Guard thread_list_lock_guard(_thread_list_lock);
|
||||
Mutex::Guard slab_lock_guard(_thread_alloc_lock);
|
||||
|
||||
/*
|
||||
* Create thread associated with its protection domain
|
||||
*/
|
||||
auto create_thread_lambda = [&] (Pd_session_component *pd) {
|
||||
if (!pd) {
|
||||
error("create_thread: invalid PD argument");
|
||||
throw Thread_creation_failed();
|
||||
}
|
||||
|
||||
Mutex::Guard slab_lock_guard(_thread_alloc_lock);
|
||||
thread = new (&_thread_alloc)
|
||||
try {
|
||||
Cpu_thread_component &thread = *new (&_thread_alloc)
|
||||
Cpu_thread_component(
|
||||
cap(), _thread_ep, _pager_ep, *pd, _trace_control_area,
|
||||
_trace_sources, weight, _weight_to_quota(weight.value),
|
||||
_thread_affinity(affinity), _label, thread_name,
|
||||
_thread_affinity(affinity), _label, name,
|
||||
_priority, utcb);
|
||||
};
|
||||
|
||||
try {
|
||||
_incr_weight(weight.value);
|
||||
_thread_ep.apply(pd_cap, create_thread_lambda);
|
||||
} catch (Allocator::Out_of_memory) {
|
||||
_decr_weight(weight.value);
|
||||
throw Out_of_ram();
|
||||
} catch (Native_capability::Reference_count_overflow) {
|
||||
_decr_weight(weight.value);
|
||||
throw Thread_creation_failed();
|
||||
} catch (...) {
|
||||
_decr_weight(weight.value);
|
||||
throw;
|
||||
if (!thread.valid()) {
|
||||
destroy(_thread_alloc, &thread);
|
||||
return;
|
||||
}
|
||||
|
||||
thread.session_exception_sigh(_exception_sigh);
|
||||
|
||||
_thread_list.insert(&thread);
|
||||
result = thread.cap();
|
||||
}
|
||||
catch (Out_of_ram) { result = Create_thread_error::OUT_OF_RAM; }
|
||||
catch (Out_of_caps) { result = Create_thread_error::OUT_OF_CAPS; }
|
||||
catch (...) { result = Create_thread_error::DENIED; }
|
||||
});
|
||||
|
||||
thread->session_exception_sigh(_exception_sigh);
|
||||
|
||||
_thread_list.insert(thread);
|
||||
|
||||
return thread->cap();
|
||||
|
||||
} catch (...) {
|
||||
if (result.failed()) {
|
||||
_decr_weight(weight.value);
|
||||
replenish(Ram_quota{_utcb_quota_size()});
|
||||
throw;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,6 +192,17 @@ class Core::Account
|
||||
_quota_guard.withdraw(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraw quota from account
|
||||
*
|
||||
* \return true if withdrawal of 'amount' succeeded
|
||||
*/
|
||||
[[nodiscard]] bool try_withdraw(UNIT amount)
|
||||
{
|
||||
Mutex::Guard guard(_mutex);
|
||||
return _quota_guard.try_withdraw(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replenish quota to account
|
||||
*
|
||||
|
@ -166,8 +166,8 @@ class Core::Cpu_session_component : public Session_object<Cpu_session>,
|
||||
** CPU session interface **
|
||||
***************************/
|
||||
|
||||
Thread_capability create_thread(Capability<Pd_session>, Name const &,
|
||||
Affinity::Location, Weight, addr_t) override;
|
||||
Create_thread_result create_thread(Capability<Pd_session>, Name const &,
|
||||
Affinity::Location, Weight, addr_t) override;
|
||||
void kill_thread(Thread_capability) override;
|
||||
void exception_sigh(Signal_context_capability) override;
|
||||
Affinity::Space affinity_space() const override;
|
||||
|
@ -55,9 +55,7 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
|
||||
bool _bind_to_pd(Pd_session_component &pd)
|
||||
{
|
||||
if (!pd.bind_thread(_platform_thread))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
return true;
|
||||
return pd.bind_thread(_platform_thread);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,6 +181,8 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
_address_space_region_map.remove_client(_rm_client);
|
||||
}
|
||||
|
||||
bool valid() const { return _bound_to_pd; };
|
||||
|
||||
|
||||
/********************************************
|
||||
** Trace::Source::Info_accessor interface **
|
||||
|
@ -43,7 +43,7 @@ class Core::Irq_object : public Thread
|
||||
void sigh(Signal_context_capability cap) { _sig_cap = cap; }
|
||||
void ack_irq() { _sync_ack.wakeup(); }
|
||||
|
||||
void start() override;
|
||||
Start_result start() override;
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__IRQ_OBJECT_H_ */
|
||||
|
@ -30,8 +30,6 @@
|
||||
|
||||
namespace Core {
|
||||
|
||||
typedef Cpu_session::Thread_creation_failed Invalid_thread;
|
||||
|
||||
/**
|
||||
* Special server object for paging
|
||||
*
|
||||
@ -84,8 +82,6 @@ class Core::Pager_object : public Object_pool<Pager_object>::Entry
|
||||
* Constructor
|
||||
*
|
||||
* \param location affinity of paged thread to physical CPU
|
||||
*
|
||||
* \throw Invalid_thread
|
||||
*/
|
||||
Pager_object(Cpu_session_capability cpu_sesion,
|
||||
Thread_capability thread,
|
||||
|
Reference in New Issue
Block a user