diff --git a/os/include/os/synced_interface.h b/os/include/os/synced_interface.h new file mode 100644 index 000000000..0c290c43f --- /dev/null +++ b/os/include/os/synced_interface.h @@ -0,0 +1,66 @@ +/* + * \brief Utility for synchronizing the access of interface functions + * \author Norman Feske + * \date 2013-05-16 + * + * The 'Synced_interface' utility makes the serialization of interface + * function calls easy. The 'Synced_interface' is a functor that takes a lock + * and a pointer to an interface as arguments. When called, the functor + * returns a smart pointer to the interface. When this smart pointer gets + * dereferenced, the smart pointer takes care of acquiring and releasing + * the lock while the interface function is executed. + */ + +#ifndef _INCLUDE__OS__SYNCED_INTERFACE_H_ +#define _INCLUDE__OS__SYNCED_INTERFACE_H_ + +/* Genode includes */ +#include + +namespace Genode { + + template + class Synced_interface + { + public: + + class Guard + { + private: + + LOCK &_lock; + IF *_interface; + + Guard(LOCK &lock, IF *interface) + : _lock(lock), _interface(interface) + { + _lock.lock(); + } + + friend class Synced_interface; + + public: + + ~Guard() { _lock.unlock(); } + + IF *operator -> () { return _interface; } + }; + + private: + + LOCK &_lock; + IF *_interface; + + public: + + Synced_interface(LOCK &lock, IF *interface) + : _lock(lock), _interface(interface) { } + + Guard operator () () + { + return Guard(_lock, _interface); + } + }; +} + +#endif /* _INCLUDE__OS__SYNCED_INTERFACE_H_ */ diff --git a/os/run/synced_interface.run b/os/run/synced_interface.run new file mode 100644 index 000000000..1da54b32e --- /dev/null +++ b/os/run/synced_interface.run @@ -0,0 +1,40 @@ +build "core init test/synced_interface" + +create_boot_directory + +install_config { + + + + + + + + + + + + + + + + + + +} + +build_boot_image "core init test-synced_interface" + +append qemu_args "-nographic -m 64" + +run_genode_until {child exited with exit value 0} 10 + +grep_output {-> test-synced_interface} + +compare_output_to { +[init -> test-synced_interface] lock +[init -> test-synced_interface] adding 13 + 14 +[init -> test-synced_interface] unlock +[init -> test-synced_interface] result is 27 +} + diff --git a/os/src/test/synced_interface/main.cc b/os/src/test/synced_interface/main.cc new file mode 100644 index 000000000..bef798732 --- /dev/null +++ b/os/src/test/synced_interface/main.cc @@ -0,0 +1,49 @@ +/* + * \brief Test for 'Synced_interface' + * \author Norman Feske + * \date 2013-05-16 + */ + +/* + * Copyright (C) 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 + + +struct Adder +{ + int add(int a, int b) + { + PLOG("adding %d + %d", a, b); + return a + b; + } +}; + + +struct Pseudo_lock +{ + void lock() { PLOG("lock"); } + void unlock() { PLOG("unlock"); } +}; + + +int main(int, char **) +{ + using namespace Genode; + + Pseudo_lock lock; + Adder adder; + + Synced_interface synced_adder(lock, &adder); + + int const res = synced_adder()->add(13, 14); + + PLOG("result is %d", res); + return 0; +} diff --git a/os/src/test/synced_interface/target.mk b/os/src/test/synced_interface/target.mk new file mode 100644 index 000000000..7ab11f409 --- /dev/null +++ b/os/src/test/synced_interface/target.mk @@ -0,0 +1,3 @@ +TARGET = test-synced_interface +SRC_CC = main.cc +LIBS = base