mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
os: add black hole component
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: <config> <audio_out/> </config> Issue #3653
This commit is contained in:
parent
2b0bb6dda0
commit
eedbcf88ec
2
repos/os/recipes/pkg/black_hole/README
Normal file
2
repos/os/recipes/pkg/black_hole/README
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
Runtime for deploying the black hole component from the depot
|
1
repos/os/recipes/pkg/black_hole/archives
Normal file
1
repos/os/recipes/pkg/black_hole/archives
Normal file
@ -0,0 +1 @@
|
||||
_/src/black_hole
|
1
repos/os/recipes/pkg/black_hole/hash
Normal file
1
repos/os/recipes/pkg/black_hole/hash
Normal file
@ -0,0 +1 @@
|
||||
2021-08-24 3200fb247859dffd0825d7ed21be65932cc6c752
|
16
repos/os/recipes/pkg/black_hole/runtime
Normal file
16
repos/os/recipes/pkg/black_hole/runtime
Normal file
@ -0,0 +1,16 @@
|
||||
<runtime ram="8M" caps="100" binary="black_hole">
|
||||
|
||||
<provides>
|
||||
<audio_out/>
|
||||
</provides>
|
||||
|
||||
<config>
|
||||
<audio_out/>
|
||||
</config>
|
||||
|
||||
<content>
|
||||
<rom label="ld.lib.so"/>
|
||||
<rom label="black_hole"/>
|
||||
</content>
|
||||
|
||||
</runtime>
|
2
repos/os/recipes/src/black_hole/content.mk
Normal file
2
repos/os/recipes/src/black_hole/content.mk
Normal file
@ -0,0 +1,2 @@
|
||||
SRC_DIR = src/server/black_hole
|
||||
include $(GENODE_DIR)/repos/base/recipes/src/content.inc
|
1
repos/os/recipes/src/black_hole/hash
Normal file
1
repos/os/recipes/src/black_hole/hash
Normal file
@ -0,0 +1 @@
|
||||
2021-08-24 0dd5287293a6c95313cd5f82c56a14e174e8bf35
|
2
repos/os/recipes/src/black_hole/used_apis
Normal file
2
repos/os/recipes/src/black_hole/used_apis
Normal file
@ -0,0 +1,2 @@
|
||||
base
|
||||
audio_out_session
|
9
repos/os/src/server/black_hole/README
Normal file
9
repos/os/src/server/black_hole/README
Normal file
@ -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:
|
||||
|
||||
<config>
|
||||
<audio_out/>
|
||||
</config>
|
162
repos/os/src/server/black_hole/audio_out.h
Normal file
162
repos/os/src/server/black_hole/audio_out.h
Normal file
@ -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 <audio_out_session/rpc_object.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
|
||||
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<Session_component_base> _data_available_handler;
|
||||
Timer::One_shot_timeout<Session_component_base> _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<Session_component, Genode::Multiple_clients> 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_ */
|
54
repos/os/src/server/black_hole/main.cc
Normal file
54
repos/os/src/server/black_hole/main.cc
Normal file
@ -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 <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/log.h>
|
||||
#include <root/component.h>
|
||||
|
||||
/* 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> 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); }
|
3
repos/os/src/server/black_hole/target.mk
Normal file
3
repos/os/src/server/black_hole/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET = black_hole
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
Loading…
x
Reference in New Issue
Block a user