From 4f4738427dd8b673ec46ffb2b31e708aca4daa35 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Wed, 18 Sep 2013 12:57:01 +0200 Subject: [PATCH] hw: release pagers from faulting threads ref #589 --- base-hw/include/kernel/syscalls.h | 19 ++++++++----------- base-hw/src/core/kernel.cc | 23 ++++++++++++++--------- base-hw/src/core/platform_thread.cc | 13 ++++++++----- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/base-hw/include/kernel/syscalls.h b/base-hw/include/kernel/syscalls.h index 928279a2c1..123da1bc8b 100644 --- a/base-hw/include/kernel/syscalls.h +++ b/base-hw/include/kernel/syscalls.h @@ -351,21 +351,18 @@ namespace Kernel /** - * Set a thread that gets informed about pagefaults of another thread + * Set or unset an IPC destination for pagefaults reports of a thread * - * \param pager_id ID of the thread that shall get informed. - * Subsequently this thread gets an IPC message, - * wich contains an according 'Pagefault' object for - * every pagefault the faulter throws. - * \param faulter_id ID of the thread that throws the pagefaults - * wich shall be notified. After every pagefault this - * thread remains paused to be reactivated by - * 'resume_thread'. + * \param pager_id kernel name of the pager thread or 0 for "unset" + * \param faulter_id kernel name of the thread that throws the pagefaults * * Restricted to core threads. */ - inline void set_pager(unsigned const pager_id, unsigned const faulter_id) { - syscall(SET_PAGER, pager_id, faulter_id); } + inline void set_pager(unsigned const pager_id, unsigned const faulter_id) + { + syscall(SET_PAGER, pager_id, faulter_id); + } + /** * Print a char 'c' to the kernels serial ouput diff --git a/base-hw/src/core/kernel.cc b/base-hw/src/core/kernel.cc index 9a3a10c66b..5be3915ae8 100644 --- a/base-hw/src/core/kernel.cc +++ b/base-hw/src/core/kernel.cc @@ -468,16 +468,21 @@ namespace Kernel */ void do_set_pager(Thread * const user) { - /* assert preconditions */ - assert(user->pd_id() == core_id()); - - /* get faulter and pager thread */ - Thread * const p = Thread::pool()->object(user->user_arg_1()); - Thread * const f = Thread::pool()->object(user->user_arg_2()); - assert(p && f); - + /* check permissions */ + if (user->pd_id() != core_id()) { + PERR("not entitled to set pager"); + return; + } + /* lookup faulter and pager thread */ + unsigned const pager_id = user->user_arg_1(); + Thread * const pager = Thread::pool()->object(pager_id); + Thread * const faulter = Thread::pool()->object(user->user_arg_2()); + if ((pager_id && !pager) || !faulter) { + PERR("failed to set pager"); + return; + } /* assign pager */ - f->pager(p); + faulter->pager(pager); } diff --git a/base-hw/src/core/platform_thread.cc b/base-hw/src/core/platform_thread.cc index a147c4cc42..2750f55e98 100644 --- a/base-hw/src/core/platform_thread.cc +++ b/base-hw/src/core/platform_thread.cc @@ -181,11 +181,14 @@ int Platform_thread::start(void * ip, void * sp, unsigned int cpu_no) void Platform_thread::pager(Pager_object * const pager) { - /* announce pager thread to kernel */ - Kernel::set_pager(pager->cap().dst(), _id); - - /* get RM client from pager pointer */ - _rm_client = dynamic_cast(pager); + if (pager) { + Kernel::set_pager(pager->cap().dst(), _id); + _rm_client = dynamic_cast(pager); + return; + } + Kernel::set_pager(0, _id); + _rm_client = 0; + return; }