genode/repos/base-foc/src/lib/base/signal_source_client.cc

82 lines
2.0 KiB
C++

/*
* \brief Fiasco.OC-specific signal-source client interface
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2010-02-03
*/
/*
* Copyright (C) 2011-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <signal_source/client.h>
#include <base/thread.h>
#include <base/env.h>
#include <base/log.h>
/* base-internal includes */
#include <base/internal/capability_data.h>
#include <base/internal/native_thread.h>
/* Fiasco includes */
#include <foc_native_cpu/client.h>
namespace Fiasco {
#include <l4/sys/irq.h>
}
using namespace Genode;
Signal_source_client::Signal_source_client(Capability<Signal_source> cap)
:
Rpc_client<Foc_signal_source>(static_cap_cast<Foc_signal_source>(cap)),
/* request mapping of semaphore capability selector */
_sem(call<Rpc_request_semaphore>())
{
using namespace Fiasco;
Foc_native_cpu_client cpu_client(env_deprecated()->cpu_session()->native_cpu());
Native_capability thread_cap = cpu_client.native_cap(Thread::myself()->cap());
l4_msgtag_t tag = l4_rcv_ep_bind_thread(_sem.data()->kcap(), thread_cap.data()->kcap(), 0);
if (l4_error(tag))
Genode::raw("l4_rcv_ep_bind_thread failed with ", l4_error(tag));
}
Signal_source_client::~Signal_source_client()
{
Fiasco::l4_irq_detach(_sem.data()->kcap());
}
__attribute__((optimize("-fno-omit-frame-pointer")))
__attribute__((noinline))
Signal_source_client::Signal Signal_source_client::wait_for_signal()
{
using namespace Fiasco;
Signal signal;
do {
/* block on semaphore until signal context was submitted */
l4_irq_receive(_sem.data()->kcap(), L4_IPC_NEVER);
/*
* The following request will return immediately and either
* return a valid or a null signal. The latter may happen in
* the case a submitted signal context was destroyed (by the
* submitter) before we have a chance to raise our request.
*/
signal = call<Rpc_wait_for_signal>();
} while (!signal.imprint());
return signal;
}