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:
Norman Feske
2024-06-17 18:19:07 +02:00
parent e7f564cd3b
commit d866b6b053
58 changed files with 562 additions and 371 deletions

View File

@ -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;
}

View File

@ -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
*

View File

@ -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;

View File

@ -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 **

View File

@ -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_ */

View File

@ -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,