diff --git a/repos/os/recipes/pkg/black_hole/README b/repos/os/recipes/pkg/black_hole/README new file mode 100644 index 0000000000..3c837fc190 --- /dev/null +++ b/repos/os/recipes/pkg/black_hole/README @@ -0,0 +1,2 @@ + + Runtime for deploying the black hole component from the depot diff --git a/repos/os/recipes/pkg/black_hole/archives b/repos/os/recipes/pkg/black_hole/archives new file mode 100644 index 0000000000..e331bb0e35 --- /dev/null +++ b/repos/os/recipes/pkg/black_hole/archives @@ -0,0 +1 @@ +_/src/black_hole diff --git a/repos/os/recipes/pkg/black_hole/hash b/repos/os/recipes/pkg/black_hole/hash new file mode 100644 index 0000000000..009aeec759 --- /dev/null +++ b/repos/os/recipes/pkg/black_hole/hash @@ -0,0 +1 @@ +2021-08-24 3200fb247859dffd0825d7ed21be65932cc6c752 diff --git a/repos/os/recipes/pkg/black_hole/runtime b/repos/os/recipes/pkg/black_hole/runtime new file mode 100644 index 0000000000..813a43eb41 --- /dev/null +++ b/repos/os/recipes/pkg/black_hole/runtime @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/repos/os/recipes/src/black_hole/content.mk b/repos/os/recipes/src/black_hole/content.mk new file mode 100644 index 0000000000..a0cef1ba23 --- /dev/null +++ b/repos/os/recipes/src/black_hole/content.mk @@ -0,0 +1,2 @@ +SRC_DIR = src/server/black_hole +include $(GENODE_DIR)/repos/base/recipes/src/content.inc diff --git a/repos/os/recipes/src/black_hole/hash b/repos/os/recipes/src/black_hole/hash new file mode 100644 index 0000000000..77c3556475 --- /dev/null +++ b/repos/os/recipes/src/black_hole/hash @@ -0,0 +1 @@ +2021-08-24 0dd5287293a6c95313cd5f82c56a14e174e8bf35 diff --git a/repos/os/recipes/src/black_hole/used_apis b/repos/os/recipes/src/black_hole/used_apis new file mode 100644 index 0000000000..56a415c335 --- /dev/null +++ b/repos/os/recipes/src/black_hole/used_apis @@ -0,0 +1,2 @@ +base +audio_out_session diff --git a/repos/os/src/server/black_hole/README b/repos/os/src/server/black_hole/README new file mode 100644 index 0000000000..4eff4fc987 --- /dev/null +++ b/repos/os/src/server/black_hole/README @@ -0,0 +1,9 @@ +The 'black_hole' component provides dummy implementations of common +session interfaces. + +At this time, only the 'Audio_out' session is provided if enabled +in the configuration of the component: + + + + diff --git a/repos/os/src/server/black_hole/audio_out.h b/repos/os/src/server/black_hole/audio_out.h new file mode 100644 index 0000000000..0c105987cd --- /dev/null +++ b/repos/os/src/server/black_hole/audio_out.h @@ -0,0 +1,162 @@ +/* + * \brief 'Audio_out' part of black hole component + * \author Christian Prochaska + * \date 2021-07-07 + * + */ + +/* + * Copyright (C) 2021 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 _AUDIO_OUT_H_ +#define _AUDIO_OUT_H_ + +/* Genode includes */ +#include +#include + + +namespace Audio_out +{ + class Session_component_base; + class Session_component; + class Root; +} + + +/** + * This base struct is needed to get the 'Signal_handler' constructed + * before the 'Session_rpc_object' constructor is called with the handler + * as argument. + */ + +struct Audio_out::Session_component_base +{ + Genode::Signal_handler _data_available_handler; + Timer::One_shot_timeout _timeout; + + virtual void _handle_data_available() = 0; + virtual void _handle_timeout(Genode::Duration) = 0; + + Session_component_base(Genode::Env &env, Timer::Connection &timer) + : _data_available_handler(env.ep(), + *this, + &Session_component_base::_handle_data_available), + _timeout(timer, *this, &Session_component_base::_handle_timeout) + { } + + virtual ~Session_component_base() { } +}; + + +class Audio_out::Session_component : Audio_out::Session_component_base, + public Audio_out::Session_rpc_object +{ + private: + + /* subtract 200ms for overhead */ + Genode::Microseconds _delay { + ((Audio_out::PERIOD * 1000 * 1000) / Audio_out::SAMPLE_RATE) - 200 }; + + void _handle_data_available() override + { + _timeout.schedule(_delay); + } + + void _handle_timeout(Genode::Duration) override + { + if (stream()->empty()) + return; + + bool const full = stream()->full(); + + Packet *p = stream()->get(stream()->pos()); + p->invalidate(); + p->mark_as_played(); + stream()->increment_position(); + progress_submit(); + + if (full) alloc_submit(); + + if (!stream()->empty()) + _timeout.schedule(_delay); + } + + public: + + Session_component(Genode::Env &env, Timer::Connection &timer) + : Session_component_base(env, timer), + Session_rpc_object(env, _data_available_handler) + { } + + ~Session_component() + { + if (Session_rpc_object::active()) stop(); + } + + void start() override + { + Session_rpc_object::start(); + stream()->pos(0); + } + + void stop() override + { + Session_rpc_object::stop(); + } +}; + + +namespace Audio_out { + typedef Genode::Root_component Root_component; +} + + +class Audio_out::Root : public Audio_out::Root_component +{ + private: + + Genode::Env &_env; + Timer::Connection _timer; + + Session_component *_create_session(const char *args) override + { + using namespace Genode; + + size_t ram_quota = + Arg_string::find_arg(args, "ram_quota").ulong_value(0); + + size_t session_size = align_addr(sizeof(Session_component), 12); + + if ((ram_quota < session_size) || + (sizeof(Stream) > ram_quota - session_size)) { + Genode::error("insufficient 'ram_quota', got ", ram_quota, ", " + "need ", sizeof(Stream) + session_size); + throw Insufficient_ram_quota(); + } + + Session_component *session = new (md_alloc()) + Session_component(_env, _timer); + + return session; + + } + + void _destroy_session(Session_component *session) override + { + Genode::destroy(md_alloc(), session); + } + + public: + + Root(Genode::Env &env, + Genode::Allocator &md_alloc) + : Root_component(env.ep(), md_alloc), + _env(env), _timer(env) { } +}; + +#endif /* _AUDIO_OUT_H_ */ diff --git a/repos/os/src/server/black_hole/main.cc b/repos/os/src/server/black_hole/main.cc new file mode 100644 index 0000000000..0a33c5b442 --- /dev/null +++ b/repos/os/src/server/black_hole/main.cc @@ -0,0 +1,54 @@ +/* + * \brief Black hole component + * \author Christian Prochaska + * \date 2021-07-07 + * + */ + +/* + * Copyright (C) 2021 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 +#include +#include +#include +#include + +/* local includes */ +#include "audio_out.h" + + +/*************** + ** Component ** + ***************/ + +namespace Black_hole { struct Main; } + +struct Black_hole::Main +{ + Genode::Env &env; + + Genode::Sliced_heap heap { env.ram(), env.rm() }; + + Genode::Constructible audio_out_root { }; + + Main(Genode::Env &env) : env(env) + { + Genode::Attached_rom_dataspace _config_rom { env, "config" }; + + if (_config_rom.xml().has_sub_node("audio_out")) { + audio_out_root.construct(env, heap); + env.parent().announce(env.ep().manage(*audio_out_root)); + } + } +}; + + +void Component::construct(Genode::Env &env) +{ static Black_hole::Main inst(env); } diff --git a/repos/os/src/server/black_hole/target.mk b/repos/os/src/server/black_hole/target.mk new file mode 100644 index 0000000000..a79e1e4981 --- /dev/null +++ b/repos/os/src/server/black_hole/target.mk @@ -0,0 +1,3 @@ +TARGET = black_hole +SRC_CC = main.cc +LIBS = base