diff --git a/repos/base-fiasco/src/core/include/rpc_cap_factory.h b/repos/base-fiasco/src/core/include/rpc_cap_factory.h index eb5d68a8f0..f28c36414d 100644 --- a/repos/base-fiasco/src/core/include/rpc_cap_factory.h +++ b/repos/base-fiasco/src/core/include/rpc_cap_factory.h @@ -15,7 +15,6 @@ #define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ #include -#include #include namespace Genode { class Rpc_cap_factory; } diff --git a/repos/base-fiasco/src/lib/base/lock.cc b/repos/base-fiasco/src/lib/base/lock.cc index 7deedd31f8..053120c570 100644 --- a/repos/base-fiasco/src/lib/base/lock.cc +++ b/repos/base-fiasco/src/lib/base/lock.cc @@ -12,7 +12,6 @@ */ /* Genode includes */ -#include #include #include #include @@ -25,7 +24,7 @@ namespace Fiasco { using namespace Genode; -Cancelable_lock::Cancelable_lock(Cancelable_lock::State initial) +Lock::Lock(Lock::State initial) : _state(UNLOCKED), _owner(nullptr) { if (initial == LOCKED) @@ -33,28 +32,27 @@ Cancelable_lock::Cancelable_lock(Cancelable_lock::State initial) } -void Cancelable_lock::lock() +void Lock::lock() { Applicant myself(Thread::myself()); lock(myself); } -void Cancelable_lock::lock(Applicant &myself) +void Lock::lock(Applicant &myself) { /* * XXX: How to notice cancel-blocking signals issued when being outside the * 'l4_ipc_sleep' system call? */ while (!Genode::cmpxchg(&_state, UNLOCKED, LOCKED)) - if (Fiasco::l4_ipc_sleep(Fiasco::l4_ipc_timeout(0, 0, 500, 0)) != L4_IPC_RETIMEOUT) - throw Genode::Blocking_canceled(); + Fiasco::l4_ipc_sleep(Fiasco::l4_ipc_timeout(0, 0, 500, 0)); _owner = myself; } -void Cancelable_lock::unlock() +void Lock::unlock() { _owner = Applicant(nullptr); Genode::memory_barrier(); diff --git a/repos/base-fiasco/src/lib/base/sleep.cc b/repos/base-fiasco/src/lib/base/sleep.cc index effd68a5cf..0576dc26b0 100644 --- a/repos/base-fiasco/src/lib/base/sleep.cc +++ b/repos/base-fiasco/src/lib/base/sleep.cc @@ -14,7 +14,6 @@ /* Genode includes */ #include -#include /* L4/Fiasco includes */ namespace Fiasco { diff --git a/repos/base-hw/src/bootstrap/lock.cc b/repos/base-hw/src/bootstrap/lock.cc index 41b5167757..763e6e8df3 100644 --- a/repos/base-hw/src/bootstrap/lock.cc +++ b/repos/base-hw/src/bootstrap/lock.cc @@ -15,18 +15,18 @@ #include #include -Genode::Cancelable_lock::Cancelable_lock(Genode::Cancelable_lock::State state) +Genode::Lock::Lock(Genode::Lock::State state) : _state(state), _owner(nullptr) { } -void Genode::Cancelable_lock::unlock() +void Genode::Lock::unlock() { assert(_state == LOCKED); _state = UNLOCKED; } -void Genode::Cancelable_lock::lock() +void Genode::Lock::lock() { assert(_state == UNLOCKED); _state = LOCKED; diff --git a/repos/base-linux/src/lib/syscall/linux_syscalls.h b/repos/base-linux/src/lib/syscall/linux_syscalls.h index 08f9eacfe2..6df2159903 100644 --- a/repos/base-linux/src/lib/syscall/linux_syscalls.h +++ b/repos/base-linux/src/lib/syscall/linux_syscalls.h @@ -352,6 +352,11 @@ inline int lx_sigaction(int signum, void (*handler)(int), bool altstack) struct kernel_sigaction act; act.handler = handler; + /* + * System calls should be restarted on signal occurrence and not return + * with EINTR. We therefore set the SA_RESTART flag in signal handlers. + */ + #ifdef _LP64 /* * The SA_RESTORER flag is not officially documented, but used internally @@ -360,10 +365,10 @@ inline int lx_sigaction(int signum, void (*handler)(int), bool altstack) * when leaving the signal handler and it should call the rt_sigreturn syscall. */ enum { SA_RESTORER = 0x04000000 }; - act.flags = SA_RESTORER; + act.flags = SA_RESTORER | SA_RESTART; act.restorer = lx_restore_rt; #else - act.flags = 0; + act.flags = SA_RESTART; act.restorer = 0; #endif diff --git a/repos/base-nova/src/lib/base/sleep.cc b/repos/base-nova/src/lib/base/sleep.cc index 15f78b49bb..3c183522d9 100644 --- a/repos/base-nova/src/lib/base/sleep.cc +++ b/repos/base-nova/src/lib/base/sleep.cc @@ -14,7 +14,6 @@ /* Genode includes */ #include -#include /* base-internal includes */ #include diff --git a/repos/base-okl4/src/core/include/rpc_cap_factory.h b/repos/base-okl4/src/core/include/rpc_cap_factory.h index eb5d68a8f0..f28c36414d 100644 --- a/repos/base-okl4/src/core/include/rpc_cap_factory.h +++ b/repos/base-okl4/src/core/include/rpc_cap_factory.h @@ -15,7 +15,6 @@ #define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ #include -#include #include namespace Genode { class Rpc_cap_factory; } diff --git a/repos/base-pistachio/src/core/include/rpc_cap_factory.h b/repos/base-pistachio/src/core/include/rpc_cap_factory.h index eb5d68a8f0..f28c36414d 100644 --- a/repos/base-pistachio/src/core/include/rpc_cap_factory.h +++ b/repos/base-pistachio/src/core/include/rpc_cap_factory.h @@ -15,7 +15,6 @@ #define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ #include -#include #include namespace Genode { class Rpc_cap_factory; } diff --git a/repos/base-sel4/src/core/include/rpc_cap_factory.h b/repos/base-sel4/src/core/include/rpc_cap_factory.h index 9b6000c008..fa0b91035d 100644 --- a/repos/base-sel4/src/core/include/rpc_cap_factory.h +++ b/repos/base-sel4/src/core/include/rpc_cap_factory.h @@ -15,7 +15,6 @@ #define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ #include -#include #include namespace Genode { class Rpc_cap_factory; } diff --git a/repos/base/include/base/cancelable_lock.h b/repos/base/include/base/cancelable_lock.h deleted file mode 100644 index 5c956de94d..0000000000 --- a/repos/base/include/base/cancelable_lock.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * \brief Basic locking primitive - * \author Norman Feske - * \date 2006-07-26 - */ - -/* - * Copyright (C) 2006-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. - */ - -#ifndef _INCLUDE__BASE__CANCELABLE_LOCK_H_ -#define _INCLUDE__BASE__CANCELABLE_LOCK_H_ - -#include -#include - -namespace Genode { - - class Thread; - class Cancelable_lock; - class Mutex; -} - - -class Genode::Cancelable_lock -{ - friend class Mutex; - - private: - - class Applicant - { - private: - - Thread *_thread_base; - Applicant *_to_wake_up; - - public: - - explicit Applicant(Thread *thread_base) - : _thread_base(thread_base), _to_wake_up(0) { } - - void applicant_to_wake_up(Applicant *to_wake_up) { - _to_wake_up = to_wake_up; } - - Applicant *applicant_to_wake_up() { return _to_wake_up; } - - Thread *thread_base() { return _thread_base; } - - /** - * Called from previous lock owner - */ - void wake_up(); - - bool operator == (Applicant &a) { return _thread_base == a.thread_base(); } - bool operator != (Applicant &a) { return _thread_base != a.thread_base(); } - }; - - /* - * Note that modifications of the applicants queue must be performed - * atomically. Hence, we use the additional spinlock here. - */ - - volatile int _spinlock_state = 0; - volatile int _state = 0; - - Applicant * volatile _last_applicant = nullptr; - - Applicant _owner; - - bool lock_owner(Applicant &myself) { - return (_state == LOCKED) && (_owner == myself); } - - void lock(Applicant &); - - public: - - enum State { LOCKED, UNLOCKED }; - - /** - * Constructor - */ - explicit Cancelable_lock(State initial = UNLOCKED); - - /** - * Try to aquire the lock and block while the lock is not free - * - * \throw Genode::Blocking_canceled - */ - void lock(); - - /** - * Release lock - */ - void unlock(); - - /** - * Lock guard - */ - typedef Genode::Lock_guard Guard; -}; - -#endif /* _INCLUDE__BASE__CANCELABLE_LOCK_H_ */ diff --git a/repos/base/include/base/lock.h b/repos/base/include/base/lock.h index 191d32e3a5..dedc334669 100644 --- a/repos/base/include/base/lock.h +++ b/repos/base/include/base/lock.h @@ -1,11 +1,11 @@ /* - * \brief Locking primitives + * \brief Basic locking primitive * \author Norman Feske * \date 2006-07-26 */ /* - * Copyright (C) 2006-2017 Genode Labs GmbH + * Copyright (C) 2006-2020 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. @@ -14,31 +14,84 @@ #ifndef _INCLUDE__BASE__LOCK_H_ #define _INCLUDE__BASE__LOCK_H_ -#include +#include +#include -namespace Genode { class Lock; } +namespace Genode { + class Lock; + class Thread; + class Mutex; +} -struct Genode::Lock : Cancelable_lock +class Genode::Lock { - /** - * Constructor - */ - explicit Lock(State initial = UNLOCKED) : Cancelable_lock(initial) { } + friend class Blockade; + friend class Mutex; - void lock() - { - while (1) - try { - Cancelable_lock::lock(); - return; - } catch (Blocking_canceled) { } - } + private: - /** - * Lock guard - */ - typedef Lock_guard Guard; + class Applicant + { + private: + + Thread *_thread_base; + Applicant *_to_wake_up; + + public: + + explicit Applicant(Thread *thread_base) + : _thread_base(thread_base), _to_wake_up(0) { } + + void applicant_to_wake_up(Applicant *to_wake_up) { + _to_wake_up = to_wake_up; } + + Applicant *applicant_to_wake_up() { return _to_wake_up; } + + Thread *thread_base() { return _thread_base; } + + /** + * Called from previous lock owner + */ + void wake_up(); + + bool operator == (Applicant &a) { return _thread_base == a.thread_base(); } + bool operator != (Applicant &a) { return _thread_base != a.thread_base(); } + }; + + /* + * Note that modifications of the applicants queue must be performed + * atomically. Hence, we use the additional spinlock here. + */ + + volatile int _spinlock_state = 0; + volatile int _state = 0; + + Applicant * volatile _last_applicant = nullptr; + + Applicant _owner; + + bool lock_owner(Applicant &myself) { + return (_state == LOCKED) && (_owner == myself); } + + void lock(Applicant &); + + enum State { LOCKED, UNLOCKED }; + + /** + * Constructor + */ + explicit Lock(State); + + /** + * Try to acquire the lock and block while the lock is not free. + */ + void lock(); + + /** + * Release lock + */ + void unlock(); }; #endif /* _INCLUDE__BASE__LOCK_H_ */ diff --git a/repos/base/include/base/mutex.h b/repos/base/include/base/mutex.h index e1f89d11b7..01cefaaa49 100644 --- a/repos/base/include/base/mutex.h +++ b/repos/base/include/base/mutex.h @@ -42,7 +42,7 @@ class Genode::Mutex : Noncopyable { private: - Lock _lock { }; + Lock _lock { Lock::UNLOCKED }; public: diff --git a/repos/base/include/deprecated/env.h b/repos/base/include/deprecated/env.h index e63eac8236..0d77e74a96 100644 --- a/repos/base/include/deprecated/env.h +++ b/repos/base/include/deprecated/env.h @@ -25,7 +25,6 @@ #include #include #include -#include namespace Genode { diff --git a/repos/base/lib/symbols/ld b/repos/base/lib/symbols/ld index 8c85178f2e..0fd4ffda59 100644 --- a/repos/base/lib/symbols/ld +++ b/repos/base/lib/symbols/ld @@ -139,11 +139,6 @@ _ZN6Genode15Alarm_scheduler7discardEPNS_5AlarmE T _ZN6Genode15Alarm_scheduler8scheduleEPNS_5AlarmEm T _ZN6Genode15Alarm_schedulerD1Ev T _ZN6Genode15Alarm_schedulerD2Ev T -_ZN6Genode15Cancelable_lock4lockEv T -_ZN6Genode15Cancelable_lock6unlockEv T -_ZN6Genode15Cancelable_lock9Applicant7wake_upEv T -_ZN6Genode15Cancelable_lockC1ENS0_5StateE T -_ZN6Genode15Cancelable_lockC2ENS0_5StateE T _ZN6Genode15Connection_baseC1Ev T _ZN6Genode15Connection_baseC2Ev T _ZN6Genode15Signal_receiver12local_submitENS_6Signal4DataE T @@ -225,6 +220,9 @@ _ZN6Genode4HeapC2EPNS_13Ram_allocatorEPNS_10Region_mapEmPvm T _ZN6Genode4HeapD0Ev T _ZN6Genode4HeapD1Ev T _ZN6Genode4HeapD2Ev T +_ZN6Genode4Lock4lockEv T +_ZN6Genode4Lock6unlockEv T +_ZN6Genode4LockC1ENS0_5StateE T _ZN6Genode4Slab13any_used_elemEv T _ZN6Genode4Slab5Block11_slab_entryEi T _ZN6Genode4Slab5Block14any_used_entryEv T diff --git a/repos/base/src/core/include/irq_session_component.h b/repos/base/src/core/include/irq_session_component.h index 6871c09f65..085825f03c 100644 --- a/repos/base/src/core/include/irq_session_component.h +++ b/repos/base/src/core/include/irq_session_component.h @@ -14,7 +14,6 @@ #ifndef _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_ #define _CORE__INCLUDE__IRQ_SESSION_COMPONENT_H_ -#include #include #include #include diff --git a/repos/base/src/core/include/signal_source_component.h b/repos/base/src/core/include/signal_source_component.h index 6a7dd0de56..bd03fcaeb5 100644 --- a/repos/base/src/core/include/signal_source_component.h +++ b/repos/base/src/core/include/signal_source_component.h @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/repos/base/src/lib/base/heap.cc b/repos/base/src/lib/base/heap.cc index a068576ec5..f0a468135b 100644 --- a/repos/base/src/lib/base/heap.cc +++ b/repos/base/src/lib/base/heap.cc @@ -15,7 +15,6 @@ #include #include #include -#include using namespace Genode; diff --git a/repos/base/src/lib/base/lock.cc b/repos/base/src/lib/base/lock.cc index 268b1edd1a..6927c10e72 100644 --- a/repos/base/src/lib/base/lock.cc +++ b/repos/base/src/lib/base/lock.cc @@ -12,7 +12,7 @@ */ /* Genode includes */ -#include +#include #include /* base-internal includes */ @@ -37,7 +37,7 @@ static inline bool thread_base_valid(Genode::Thread *thread_base) ** Lock applicant ** ********************/ -void Cancelable_lock::Applicant::wake_up() +void Lock::Applicant::wake_up() { if (!thread_base_valid(_thread_base)) return; @@ -56,17 +56,17 @@ void Cancelable_lock::Applicant::wake_up() } -/********************* - ** Cancelable lock ** - *********************/ +/*************** + ** Lock lock ** + ***************/ -void Cancelable_lock::lock() +void Lock::lock() { Applicant myself(Thread::myself()); lock(myself); } -void Cancelable_lock::lock(Applicant &myself) +void Lock::lock(Applicant &myself) { spinlock_lock(&_spinlock_state); @@ -126,38 +126,10 @@ void Cancelable_lock::lock(Applicant &myself) * ! thread_yield(); */ thread_stop_myself(myself.thread_base()); - - /* - * We expect to be the lock owner when woken up. If this is not - * the case, the blocking was canceled via core's cancel-blocking - * mechanism. We have to dequeue ourself from the list of applicants - * and reflect this condition as a C++ exception. - */ - spinlock_lock(&_spinlock_state); - if (_owner != myself) { - /* - * Check if we are the applicant to be waken up next, - * otherwise, go through the list of remaining applicants - */ - for (Applicant *a = &_owner; a; a = a->applicant_to_wake_up()) { - /* remove reference to ourself from the applicants list */ - if (a->applicant_to_wake_up() == &myself) { - a->applicant_to_wake_up(myself.applicant_to_wake_up()); - if (_last_applicant == &myself) - _last_applicant = a; - break; - } - } - - spinlock_unlock(&_spinlock_state); - - throw Blocking_canceled(); - } - spinlock_unlock(&_spinlock_state); } -void Cancelable_lock::unlock() +void Lock::unlock() { spinlock_lock(&_spinlock_state); @@ -190,7 +162,7 @@ void Cancelable_lock::unlock() } -Cancelable_lock::Cancelable_lock(Cancelable_lock::State initial) +Lock::Lock(Lock::State initial) : _spinlock_state(SPINLOCK_UNLOCKED), _state(UNLOCKED), diff --git a/repos/base/src/lib/base/mutex.cc b/repos/base/src/lib/base/mutex.cc index 3c82e9de9e..f7bcfd8357 100644 --- a/repos/base/src/lib/base/mutex.cc +++ b/repos/base/src/lib/base/mutex.cc @@ -17,17 +17,12 @@ void Genode::Mutex::acquire() { - while (1) { - try { - Lock::Applicant myself(Thread::myself()); - if (_lock.lock_owner(myself)) - Genode::error("deadlock ahead, mutex=", this, ", return ip=", - __builtin_return_address(0)); + Lock::Applicant myself(Thread::myself()); + if (_lock.lock_owner(myself)) + Genode::error("deadlock ahead, mutex=", this, ", return ip=", + __builtin_return_address(0)); - _lock.Cancelable_lock::lock(myself); - return; - } catch (Blocking_canceled) { } - } + _lock.lock(myself); } void Genode::Mutex::release() @@ -35,8 +30,7 @@ void Genode::Mutex::release() Lock::Applicant myself(Thread::myself()); if (!_lock.lock_owner(myself)) { Genode::error("denied non mutex owner the release, mutex=", - this, ", return ip=", - __builtin_return_address(0)); + this, ", return ip=", __builtin_return_address(0)); return; } _lock.unlock(); diff --git a/repos/os/include/file_system/node.h b/repos/os/include/file_system/node.h index 87459b86a2..6779bea785 100644 --- a/repos/os/include/file_system/node.h +++ b/repos/os/include/file_system/node.h @@ -17,7 +17,6 @@ /* Genode includes */ #include #include -#include namespace File_system { diff --git a/repos/os/include/usb/packet_handler.h b/repos/os/include/usb/packet_handler.h index dff37be012..98ff826843 100644 --- a/repos/os/include/usb/packet_handler.h +++ b/repos/os/include/usb/packet_handler.h @@ -13,7 +13,6 @@ #ifndef _INCLUDE__USB__PACKET_HANDLER_ #define _INCLUDE__USB__PACKET_HANDLER_ -#include #include namespace Usb { class Packet_handler; } diff --git a/repos/os/src/server/vmm/cpu_base.cc b/repos/os/src/server/vmm/cpu_base.cc index dbf2a265d2..4ca063caaa 100644 --- a/repos/os/src/server/vmm/cpu_base.cc +++ b/repos/os/src/server/vmm/cpu_base.cc @@ -18,8 +18,6 @@ using Vmm::Cpu_base; using Vmm::Cpu; using Vmm::Gic; -Genode::Lock & Vmm::lock() { static Genode::Lock l {}; return l; } - Cpu_base::System_register::System_register(unsigned op0, unsigned crn, diff --git a/repos/os/src/server/vmm/cpu_base.h b/repos/os/src/server/vmm/cpu_base.h index 13b73207e8..1a4411dd8e 100644 --- a/repos/os/src/server/vmm/cpu_base.h +++ b/repos/os/src/server/vmm/cpu_base.h @@ -26,7 +26,6 @@ namespace Vmm { class Vm; class Cpu_base; - Genode::Lock & lock(); } class Vmm::Cpu_base