From 41b99a6b51615651f18c0c216d3d137ed23602b8 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 7 May 2015 14:22:42 +0200 Subject: [PATCH] sel4: use yielding spinlock for 'Genode::Lock' --- .../base-sel4/include/base/cancelable_lock.h | 56 +++++++++++++++++++ repos/base-sel4/lib/mk/base-common.inc | 1 - repos/base-sel4/src/base/lock/lock.cc | 44 +++++++++++++++ repos/base-sel4/src/base/lock/lock_helper.h | 26 +++------ 4 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 repos/base-sel4/include/base/cancelable_lock.h create mode 100644 repos/base-sel4/src/base/lock/lock.cc diff --git a/repos/base-sel4/include/base/cancelable_lock.h b/repos/base-sel4/include/base/cancelable_lock.h new file mode 100644 index 0000000000..c684501dab --- /dev/null +++ b/repos/base-sel4/include/base/cancelable_lock.h @@ -0,0 +1,56 @@ +/* + * \brief Basic locking primitive + * \author Norman Feske + * \date 2006-07-26 + */ + +/* + * Copyright (C) 2006-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__BASE__CANCELABLE_LOCK_H_ +#define _INCLUDE__BASE__CANCELABLE_LOCK_H_ + +#include +#include + +namespace Genode { + + class Cancelable_lock + { + private: + + int volatile _lock; + + public: + + enum State { LOCKED, UNLOCKED }; + + /** + * Constructor + */ + explicit Cancelable_lock(State initial = UNLOCKED); + + /** + * Try to aquire lock an block while lock is not free + * + * This function may throw a Genode::Blocking_canceled exception. + */ + void lock(); + + /** + * Release lock + */ + void unlock(); + + /** + * Lock guard + */ + typedef Genode::Lock_guard Guard; + }; +} + +#endif /* _INCLUDE__BASE__CANCELABLE_LOCK_H_ */ diff --git a/repos/base-sel4/lib/mk/base-common.inc b/repos/base-sel4/lib/mk/base-common.inc index 5a71e30220..449ff80647 100644 --- a/repos/base-sel4/lib/mk/base-common.inc +++ b/repos/base-sel4/lib/mk/base-common.inc @@ -27,7 +27,6 @@ SRC_CC += thread/thread_bootstrap.cc #SRC_CC += env/cap_map.cc INC_DIR += $(REP_DIR)/src/base/lock -INC_DIR += $(BASE_DIR)/src/base/lock INC_DIR += $(BASE_DIR)/src/base/thread vpath %.cc $(REP_DIR)/src/base diff --git a/repos/base-sel4/src/base/lock/lock.cc b/repos/base-sel4/src/base/lock/lock.cc new file mode 100644 index 0000000000..f123f7bd6d --- /dev/null +++ b/repos/base-sel4/src/base/lock/lock.cc @@ -0,0 +1,44 @@ +/* + * \brief Lock implementation + * \author Norman Feske + * \date 2007-10-15 + */ + +/* + * Copyright (C) 2007-2013 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#include +#include +#include + +/* seL4 includes */ +#include + +using namespace Genode; + + +Cancelable_lock::Cancelable_lock(Cancelable_lock::State initial) +: _lock(UNLOCKED) +{ + if (initial == LOCKED) + lock(); +} + + +void Cancelable_lock::lock() +{ + while (!Genode::cmpxchg(&_lock, UNLOCKED, LOCKED)) + seL4_Yield(); +} + + +void Cancelable_lock::unlock() +{ + Genode::memory_barrier(); + _lock = UNLOCKED; +} diff --git a/repos/base-sel4/src/base/lock/lock_helper.h b/repos/base-sel4/src/base/lock/lock_helper.h index 4d09ef2f81..bc357ea92a 100644 --- a/repos/base-sel4/src/base/lock/lock_helper.h +++ b/repos/base-sel4/src/base/lock/lock_helper.h @@ -1,31 +1,21 @@ + /* * \brief seL4-specific helper functions for the Lock implementation * \author Norman Feske - * \date 2014-10-14 + * \date 2015-05-07 + * + * Based on the lock implementation of base-fiasco/src/base/lock/. */ /* - * Copyright (C) 2014 Genode Labs GmbH + * Copyright (C) 2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ -/* Genode includes */ -#include -#include +/* seL4 includes */ +#include -static inline void thread_yield() { } - - -static inline bool thread_check_stopped_and_restart(Genode::Thread_base *) -{ - return false; -} - - -static inline void thread_switch_to(Genode::Thread_base *thread_base) { } - - -static inline void thread_stop_myself() { } +static inline void thread_yield() { seL4_Yield(); }