Adapt high-level components to new parent API

This patch adjusts the various users of the 'Child' API to the changes
on the account of the new non-blocking parent interface. It also removes
the use of the no-longer-available 'Connection::KEEP_OPEN' feature.

With the adjustment, we took the opportunity to redesign several
components to fit the non-blocking execution model much better, in
particular the demo applications.

Issue #2120
This commit is contained in:
Norman Feske 2016-11-23 17:07:49 +01:00 committed by Christian Helmuth
parent 8bafb9d41b
commit b44f0554bd
146 changed files with 3026 additions and 3484 deletions

View File

@ -26,65 +26,138 @@
#include <cap_session/connection.h>
#include <timer_session/timer_session.h>
#include <pd_session/client.h>
#include <init/child.h>
class Launchpad_child_policy : public Genode::Child_policy,
public Genode::Client
class Launchpad;
class Launchpad_child : public Genode::Child_policy,
public Genode::List<Launchpad_child>::Element,
public Genode::Child_service::Wakeup
{
public:
typedef Genode::Child_policy::Name Name;
typedef Genode::Registered<Genode::Child_service> Child_service;
typedef Genode::Registered<Genode::Parent_service> Parent_service;
typedef Genode::Registry<Child_service> Child_services;
typedef Genode::Registry<Parent_service> Parent_services;
private:
typedef Genode::String<64> Name;
Name const _name;
Genode::Server *_server;
Genode::Service_registry *_parent_services;
Genode::Service_registry *_child_services;
Genode::Dataspace_capability _config_ds;
Genode::Rpc_entrypoint *_parent_entrypoint;
Init::Child_policy_enforce_labeling _labeling_policy;
Init::Child_policy_provide_rom_file _config_policy;
Init::Child_policy_provide_rom_file _binary_policy;
Genode::Env &_env;
Genode::Ram_session_capability _ref_ram_cap;
Genode::Ram_session_client _ref_ram { _ref_ram_cap };
Genode::size_t const _ram_quota;
Parent_services &_parent_services;
Child_services &_child_services;
Genode::Dataspace_capability _config_ds;
Genode::Session_requester _session_requester;
Init::Child_policy_enforce_labeling _labeling_policy { _name.string() };
Init::Child_policy_provide_rom_file _config_policy;
Genode::Child _child;
/**
* Child_service::Wakeup callback
*/
void wakeup_child_service() override
{
_session_requester.trigger_update();
}
template <typename T>
static Genode::Service *_find_service(Genode::Registry<T> &services,
Genode::Service::Name const &name)
{
Genode::Service *service = nullptr;
services.for_each([&] (T &s) {
if (!service && (s.name() == name))
service = &s; });
return service;
}
public:
Launchpad_child_policy(const char *name,
Genode::Server *server,
Genode::Service_registry *parent_services,
Genode::Service_registry *child_services,
Genode::Dataspace_capability config_ds,
Genode::Dataspace_capability binary_ds,
Genode::Rpc_entrypoint *parent_entrypoint)
Launchpad_child(Genode::Env &env,
Genode::Session_label const &label,
Name const &elf_name,
Genode::size_t ram_quota,
Parent_services &parent_services,
Child_services &child_services,
Genode::Dataspace_capability config_ds)
:
_name(name),
_server(server),
_name(label),
_env(env), _ref_ram_cap(env.ram_session_cap()), _ram_quota(ram_quota),
_parent_services(parent_services),
_child_services(child_services),
_config_ds(config_ds),
_parent_entrypoint(parent_entrypoint),
_labeling_policy(_name.string()),
_config_policy("config", config_ds, _parent_entrypoint),
_binary_policy("binary", binary_ds, _parent_entrypoint)
_session_requester(env.ep().rpc_ep(), _env.ram(), _env.rm()),
_config_policy("config", config_ds, &_env.ep().rpc_ep()),
_child(_env.rm(), _env.ep().rpc_ep(), *this)
{ }
const char *name() const { return _name.string(); }
Genode::Service *resolve_session_request(const char *service_name,
const char *args)
~Launchpad_child()
{
Genode::Service *service;
using namespace Genode;
/* unregister services */
_child_services.for_each(
[&] (Child_service &service) {
if (service.has_id_space(_session_requester.id_space()))
Genode::destroy(_child.heap(), &service); });
}
Genode::Allocator &heap() { return _child.heap(); }
/****************************
** Child_policy interface **
****************************/
Name name() const override { return _name; }
Genode::Ram_session &ref_ram() override { return _ref_ram; }
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
void init(Genode::Ram_session &session,
Genode::Ram_session_capability cap) override
{
session.ref_account(_ref_ram_cap);
_ref_ram.transfer_quota(cap, _ram_quota);
}
Genode::Id_space<Genode::Parent::Server> &server_id_space() override {
return _session_requester.id_space(); }
Genode::Service &resolve_session_request(Genode::Service::Name const &service_name,
Genode::Session_state::Args const &args) override
{
Genode::Service *service = nullptr;
/* check for config file request */
if ((service = _config_policy.resolve_session_request(service_name, args)))
return service;
if ((service = _config_policy
.resolve_session_request(service_name.string(), args.string())))
return *service;
/* check for binary file request */
if ((service = _binary_policy.resolve_session_request(service_name, args)))
return service;
/* check for "session_requests" ROM request */
Genode::Session_label const label(Genode::label_from_args(args.string()));
if (service_name == Genode::Rom_session::service_name()
&& label.last_element() == Genode::Session_requester::rom_name())
return _session_requester.service();
/* if service is provided by one of our children, use it */
if ((service = _child_services->find(service_name)))
return service;
if ((service = _find_service(_child_services, service_name)))
return *service;
/*
* Handle special case of the demo scenario when the user uses
@ -100,130 +173,33 @@ class Launchpad_child_policy : public Genode::Child_policy,
* interacted, however, would block at the parent interface
* until this condition gets satisfied.
*/
if (Genode::strcmp(service_name, "Input") != 0
&& Genode::strcmp(service_name, "Framebuffer") != 0
&& (service = _parent_services->find(service_name)))
return service;
if (service_name != "Input"
&& service_name != "Framebuffer"
&& ((service = _find_service(_parent_services, service_name))))
return *service;
/* wait for the service to become available */
Genode::Client client;
return _child_services->wait_for_service(service_name,
&client, name());
Genode::warning(name(), ": service ", service_name, " not available");
throw Genode::Parent::Service_denied();
}
void filter_session_args(const char *service, char *args,
Genode::size_t args_len)
void filter_session_args(Genode::Service::Name const &service,
char *args, Genode::size_t args_len) override
{
_labeling_policy.filter_session_args(service, args, args_len);
_labeling_policy.filter_session_args(service.string(), args, args_len);
}
bool announce_service(const char *service_name,
Genode::Root_capability root,
Genode::Allocator *alloc,
Genode::Server * /*server*/)
void announce_service(Genode::Service::Name const &service_name) override
{
if (_child_services->find(service_name)) {
PWRN("%s: service %s is already registered",
name(), service_name);
return false;
if (_find_service(_child_services, service_name)) {
Genode::warning(name(), ": service ", service_name, " is already registered");
return;
}
/* XXX remove potential race between checking for and inserting service */
_child_services->insert(new (alloc)
Genode::Child_service(service_name, root, _server));
Genode::printf("%s registered service %s\n", name(), service_name);
return true;
new (_child.heap())
Child_service(_child_services, _session_requester.id_space(),
_child.session_factory(), service_name,
_child.ram_session_cap(), *this);
}
void unregister_services()
{
Genode::Service *rs;
while ((rs = _child_services->find_by_server(_server)))
_child_services->remove(rs);
}
};
class Launchpad;
class Launchpad_child : public Genode::List<Launchpad_child>::Element
{
private:
static Genode::Dataspace_capability _ldso_ds();
Launchpad *_launchpad;
/*
* Entry point used for serving the parent interface and the
* locally provided ROM sessions for the 'config' and 'binary'
* files.
*/
enum { ENTRYPOINT_STACK_SIZE = 12*1024 };
Genode::Rpc_entrypoint _entrypoint;
Genode::Region_map_client _address_space;
Genode::Rom_session_client _rom;
Genode::Pd_session_client _pd;
Genode::Ram_session_client _ram;
Genode::Cpu_session_client _cpu;
Genode::Child::Initial_thread _initial_thread;
Genode::Server _server;
Launchpad_child_policy _policy;
Genode::Child _child;
public:
Launchpad_child(const char *name,
Genode::Dataspace_capability elf_ds,
Genode::Pd_session_capability pd,
Genode::Ram_session_capability ram,
Genode::Cpu_session_capability cpu,
Genode::Rom_session_capability rom,
Genode::Cap_session *cap_session,
Genode::Service_registry *parent_services,
Genode::Service_registry *child_services,
Genode::Dataspace_capability config_ds,
Launchpad *launchpad)
:
_launchpad(launchpad),
_entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, name, false),
_address_space(Genode::Pd_session_client(pd).address_space()),
_rom(rom), _pd(pd), _ram(ram), _cpu(cpu),
_initial_thread(_cpu, _pd, name), _server(_ram),
_policy(name, &_server, parent_services, child_services,
config_ds, elf_ds, &_entrypoint),
_child(elf_ds, _ldso_ds(), _pd, _pd, _ram, _ram, _cpu,
_initial_thread, *Genode::env()->rm_session(),
_address_space, _entrypoint, _policy)
{
_entrypoint.activate();
}
/**
* Required to forcefully kill client which blocks on a session
* opening quest where the service is not up yet.
*/
void cancel_blocking() { _entrypoint.cancel_blocking(); }
Genode::Rom_session_capability rom_session_cap() { return _rom; }
Genode::Ram_session_capability ram_session_cap() { return _ram; }
Genode::Cpu_session_capability cpu_session_cap() { return _cpu; }
const char *name() const { return _policy.name(); }
const Genode::Server *server() const { return &_server; }
Genode::Allocator *heap() { return _child.heap(); }
void revoke_server(const Genode::Server *server) {
_child.revoke_server(server); }
};
@ -231,31 +207,31 @@ class Launchpad
{
private:
Genode::Env &_env;
Genode::Heap _heap { _env.ram(), _env.rm() };
unsigned long _initial_quota;
Genode::Service_registry _parent_services;
Genode::Service_registry _child_services;
Launchpad_child::Parent_services _parent_services;
Launchpad_child::Child_services _child_services;
Genode::Lock _children_lock;
Genode::List<Launchpad_child> _children;
bool _child_name_exists(const char *name);
void _get_unique_child_name(const char *filename, char *dst, int dst_len);
bool _child_name_exists(Launchpad_child::Name const &);
Launchpad_child::Name _get_unique_child_name(Launchpad_child::Name const &);
Genode::Sliced_heap _sliced_heap;
/* cap session for allocating capabilities for parent interfaces */
Genode::Cap_connection _cap_session;
protected:
int _ypos;
public:
Genode::Lock gui_lock;
Launchpad(unsigned long initial_quota);
Launchpad(Genode::Env &env, unsigned long initial_quota);
unsigned long initial_quota() { return _initial_quota; }
@ -273,36 +249,26 @@ class Launchpad
virtual void quota(unsigned long quota) { }
virtual void add_launcher(const char *filename,
virtual void add_launcher(Launchpad_child::Name const &binary_name,
unsigned long default_quota,
Genode::Dataspace_capability config_ds) { }
virtual void add_child(const char *unique_name,
virtual void add_child(Launchpad_child::Name const &,
unsigned long quota,
Launchpad_child *launchpad_child,
Genode::Allocator *alloc) { }
Launchpad_child &,
Genode::Allocator &) { }
virtual void remove_child(const char *name,
Genode::Allocator *alloc) { }
virtual void remove_child(Launchpad_child::Name const &,
Genode::Allocator &) { }
Launchpad_child *start_child(const char *prg_name, unsigned long quota,
Launchpad_child *start_child(Launchpad_child::Name const &binary_name,
unsigned long quota,
Genode::Dataspace_capability config_ds);
/**
* Exit child and close all its sessions
*
* \param timer Timer session to use for watchdog
* mechanism. When using the default
* value, a new timer session gets
* created during the 'exit_child'
* call.
* \param session_close_timeout_ms Timeout in milliseconds until a an
* unresponsive service->close call
* gets canceled.
*/
void exit_child(Launchpad_child *child,
Timer::Session *timer = 0,
int session_close_timeout_ms = 2000);
void exit_child(Launchpad_child &child);
};
#endif /* _INCLUDE__LAUNCHPAD__LAUNCHPAD_H_ */

View File

@ -181,7 +181,7 @@ class Scout::Element
/**
* Handle user input or timer event
*/
void handle_event(Event &ev) { if (_evh) _evh->handle(ev); }
void handle_event(Event const &ev) { if (_evh) _evh->handle_event(ev); }
/**
* Request the chapter in which the element lives

View File

@ -76,7 +76,7 @@ class Scout::Event_handler
/**
* Handle event
*/
virtual void handle(Event &e) = 0;
virtual void handle_event(Event const &e) = 0;
};
#endif /* _INCLUDE__SCOUT__EVENT_H_ */

View File

@ -17,6 +17,7 @@
#define _INCLUDE__SCOUT__PLATFORM_H_
#include <base/env.h>
#include <base/attached_dataspace.h>
#include <base/semaphore.h>
#include <timer_session/connection.h>
#include <input_session/input_session.h>
@ -51,150 +52,108 @@ class Scout::Platform
{
private:
/*****************
** Event queue **
*****************/
class Event_queue
Genode::Env &_env;
Event_handler *_event_handler = nullptr;
int _mx = 0, _my = 0;
void _handle_event(Event const &ev)
{
private:
if (_event_handler)
_event_handler->handle_event(ev);
}
static const int queue_size = 1024;
int _head;
int _tail;
Genode::Semaphore _sem;
Genode::Lock _head_lock; /* synchronize add */
/****************************
** Timer event processing **
****************************/
Event _queue[queue_size];
Timer::Connection _timer { _env };
public:
unsigned long _ticks = 0;
/**
* Constructor
*/
Event_queue(): _head(0), _tail(0)
{
Genode::memset(_queue, 0, sizeof(_queue));
}
void add(Event ev)
{
Genode::Lock::Guard lock_guard(_head_lock);
if ((_head + 1)%queue_size != _tail) {
_queue[_head] = ev;
_head = (_head + 1)%queue_size;
_sem.up();
}
}
Event get()
{
_sem.down();
Event ev = _queue[_tail];
_tail = (_tail + 1)%queue_size;
return ev;
}
int pending() const { return _head != _tail; }
} _event_queue;
/******************
** Timer thread **
******************/
class Timer_thread : public Genode::Thread_deprecated<4096>
void _handle_timer()
{
private:
_ticks = _timer.elapsed_ms();
Timer::Connection _timer;
Input::Session &_input;
Input::Event *_ev_buf = { Genode::env()->rm_session()->attach(_input.dataspace()) };
Event_queue &_event_queue;
int _mx, _my;
unsigned long _ticks = { 0 };
Event ev;
ev.assign(Event::TIMER, _mx, _my, 0);
void _import_events()
{
if (_input.pending() == false) return;
_handle_event(ev);
}
for (int i = 0, num = _input.flush(); i < num; i++)
{
Event ev;
Input::Event e = _ev_buf[i];
Genode::Signal_handler<Platform> _timer_handler {
_env.ep(), *this, &Platform::_handle_timer };
if (e.type() == Input::Event::RELEASE
|| e.type() == Input::Event::PRESS) {
_mx = e.ax();
_my = e.ay();
ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE,
e.ax(), e.ay(), e.code());
_event_queue.add(ev);
}
if (e.type() == Input::Event::MOTION) {
_mx = e.ax();
_my = e.ay();
ev.assign(Event::MOTION, e.ax(), e.ay(), e.code());
_event_queue.add(ev);
}
}
/****************************
** Input event processing **
****************************/
Input::Session &_input;
Genode::Attached_dataspace _input_ds { _env.rm(), _input.dataspace() };
Input::Event * const _ev_buf = _input_ds.local_addr<Input::Event>();
bool _event_pending = 0;
void _handle_input()
{
if (_input.pending() == false) return;
for (int i = 0, num = _input.flush(); i < num; i++)
{
Event ev;
Input::Event e = _ev_buf[i];
_event_pending = i + 1 < num;
if (e.type() == Input::Event::RELEASE
|| e.type() == Input::Event::PRESS) {
_mx = e.ax();
_my = e.ay();
ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE,
e.ax(), e.ay(), e.code());
_handle_event(ev);
}
public:
/**
* Constructor
*
* Start thread immediately on construction.
*/
Timer_thread(Input::Session &input, Event_queue &event_queue)
: Thread_deprecated("timer"), _input(input), _event_queue(event_queue)
{ start(); }
void entry()
{
while (1) {
Event ev;
ev.assign(Event::TIMER, _mx, _my, 0);
_event_queue.add(ev);
_import_events();
_timer.msleep(10);
_ticks += 10;
}
if (e.type() == Input::Event::MOTION) {
_mx = e.ax();
_my = e.ay();
ev.assign(Event::MOTION, e.ax(), e.ay(), e.code());
_handle_event(ev);
}
}
}
unsigned long ticks() const { return _ticks; }
} _timer_thread;
Genode::Signal_handler<Platform> _input_handler {
_env.ep(), *this, &Platform::_handle_input};
public:
Platform(Input::Session &input) : _timer_thread(input, _event_queue) { }
Platform(Genode::Env &env, Input::Session &input)
: _env(env), _input(input) { }
/**
* Get timer ticks in miilliseconds
*/
unsigned long timer_ticks() const { return _timer_thread.ticks(); }
unsigned long timer_ticks() const { return _ticks; }
/**
* Return true if an event is pending
* Register event handler
*/
bool event_pending() const { return _event_queue.pending(); }
void event_handler(Event_handler &handler)
{
_event_handler = &handler;
/**
* Request event
*
* \param e destination where to store event information.
*
* If there is no event pending, this function blocks
* until there is an event to deliver.
*/
Event get_event() { return _event_queue.get(); }
_timer.sigh(_timer_handler);
_timer.trigger_periodic(40*1000);
_input.sigh(_input_handler);
}
bool event_pending() const { return _event_pending; }
};
#endif /* _INCLUDE__SCOUT__PLATFORM_H_ */

View File

@ -78,7 +78,7 @@ class Scout::User_state : public Parent_element
/**
* Apply input event to mouse focus state
*/
void handle_event(Event &ev)
void handle_event(Event const &ev)
{
_key_cnt += ev.type == Event::PRESS ? 1 : 0;
_key_cnt -= ev.type == Event::RELEASE ? 1 : 0;

View File

@ -34,21 +34,34 @@ class Scout::Window : public Parent_element
Graphics_backend &_gfx_backend;
Rect _dirty;
Area _max_size;
Point _view_position;
int _request_cnt; /* nb of requests since last process */
bool const _scout_quirk; /* enable redraw quirk for scout */
/*
* We limit the rate of (expensive) view-position updates to the rate
* of 'process_redraw' calls instead of eagerly responding to
* individual input events (which trigger calls of 'vpos').
*/
Point _view_position, _next_view_position = _view_position;
void _update_view_position()
{
if (_view_position == _next_view_position) return;
_view_position = _next_view_position;
_gfx_backend.position(_view_position);
}
public:
Window(Graphics_backend &gfx_backend, Point position, Area size,
Area max_size, bool scout_quirk)
:
_gfx_backend(gfx_backend), _max_size(max_size), _request_cnt(0),
_scout_quirk(scout_quirk)
_scout_quirk(scout_quirk), _view_position(position)
{
/* init element attributes */
_view_position = position;
_size = size;
_size = size;
}
virtual ~Window() { }
@ -56,8 +69,8 @@ class Scout::Window : public Parent_element
/**
* Return current window position
*/
int view_x() const { return _view_position.x(); }
int view_y() const { return _view_position.y(); }
int view_x() const { return _next_view_position.x(); }
int view_y() const { return _next_view_position.y(); }
int view_w() const { return _size.w(); }
int view_h() const { return _size.h(); }
@ -71,11 +84,7 @@ class Scout::Window : public Parent_element
/**
* Move window to new position
*/
virtual void vpos(int x, int y)
{
_view_position = Point(x, y);
_gfx_backend.position(_view_position);
}
virtual void vpos(int x, int y) { _next_view_position = Point(x, y); }
/**
* Define vertical scroll offset
@ -133,6 +142,8 @@ class Scout::Window : public Parent_element
*/
void process_redraw()
{
_update_view_position();
if (_request_cnt == 0) return;
/* get actual drawing area (clipped against canvas dimensions) */
@ -198,7 +209,7 @@ class Scout::Drag_event_handler : public Event_handler
/**
* Event handler interface
*/
void handle(Event &ev)
void handle_event(Event const &ev) override
{
if (ev.type == Event::PRESS) _key_cnt++;
if (ev.type == Event::RELEASE) _key_cnt--;

View File

@ -32,18 +32,18 @@ class Kill_event_handler : public Scout::Event_handler
{
private:
Launchpad *_launchpad;
Launchpad_child *_launchpad_child;
Launchpad &_launchpad;
Launchpad_child &_launchpad_child;
public:
Kill_event_handler(Launchpad *launchpad, Launchpad_child *launchpad_child):
Kill_event_handler(Launchpad &launchpad, Launchpad_child &launchpad_child):
_launchpad(launchpad), _launchpad_child(launchpad_child) { }
/**
* Event handler interface
*/
void handle(Scout::Event &ev)
void handle_event(Scout::Event const &ev) override
{
static int key_cnt;
@ -53,7 +53,7 @@ class Kill_event_handler : public Scout::Event_handler
if (ev.type == Event::RELEASE) key_cnt--;
if (ev.type == Event::RELEASE && key_cnt == 0)
_launchpad->exit_child(_launchpad_child);
_launchpad.exit_child(_launchpad_child);
}
};
@ -73,7 +73,7 @@ class Child_entry : public Scout::Parent_element,
Scout::Block _block;
Kbyte_loadbar<PT> _loadbar;
char _name[_NAME_LEN];
Launchpad_child::Name const _name;
Scout::Fade_icon<PT, _IW, _IH> _kill_icon;
Scout::Fade_icon<PT, _IW, _IH> _fold_icon;
@ -85,14 +85,14 @@ class Child_entry : public Scout::Parent_element,
/**
* Constructor
*/
Child_entry(const char *name, int quota_kb, int max_quota_kb,
Launchpad *launchpad, Launchpad_child *launchpad_child)
Child_entry(Launchpad_child::Name const &name, int quota_kb, int max_quota_kb,
Launchpad &launchpad, Launchpad_child &launchpad_child)
:
_block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font),
_name(name),
_kill_event_handler(launchpad, launchpad_child)
{
Genode::strncpy(_name, name, sizeof(_name));
_block.append_plaintext(_name, &Scout::plain_style);
_block.append_plaintext(_name.string(), &Scout::plain_style);
_loadbar.max_value(max_quota_kb);
_loadbar.value(quota_kb);
@ -118,7 +118,7 @@ class Child_entry : public Scout::Parent_element,
/**
* Accessors
*/
const char *name() { return _name; }
Launchpad_child::Name name() { return _name; }
/******************************

View File

@ -22,6 +22,7 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener
{
private:
Scout::Launcher::Name _prg_name;
Scout::Block _block;
Kbyte_loadbar<PT> _loadbar;
Scout::Launcher_config _config;
@ -37,15 +38,16 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener
/**
* Constructor
*/
Launch_entry(const char *prg_name, unsigned long initial_quota,
Launch_entry(Scout::Launcher::Name const &prg_name, unsigned long initial_quota,
unsigned long max_quota, Launchpad *launchpad,
Genode::Dataspace_capability config_ds)
:
_prg_name(prg_name),
_block(Scout::Block::RIGHT), _loadbar(this, &Scout::label_font),
_config(config_ds),
_launcher(prg_name, launchpad, initial_quota * 1024UL, &_config)
{
_block.append_launchertext(prg_name, &Scout::link_style, &_launcher);
_block.append_launchertext(_prg_name.string(), &Scout::link_style, &_launcher);
_loadbar.max_value(max_quota);
_loadbar.value(initial_quota);

View File

@ -35,11 +35,12 @@ extern unsigned char TITLEBAR_RGBA[];
********************************/
template <typename PT>
Launchpad_window<PT>::Launchpad_window(Graphics_backend &gfx_backend,
Launchpad_window<PT>::Launchpad_window(Genode::Env &env,
Graphics_backend &gfx_backend,
Point position, Area size, Area max_size,
unsigned long initial_quota)
:
Launchpad(initial_quota),
Launchpad(env, initial_quota),
Window(gfx_backend, position, size, max_size, false),
_docview(0),
_spacer(1, _TH),

View File

@ -14,6 +14,9 @@
#ifndef _LAUNCHPAD_WINDOW_H_
#define _LAUNCHPAD_WINDOW_H_
#include <base/env.h>
#include <dataspace/capability.h>
#include <scout/platform.h>
#include <scout/window.h>
@ -73,7 +76,8 @@ class Launchpad_window : public Scout::Scrollbar_listener,
*
* \param initial_quota maximum value of quota displays
*/
Launchpad_window(Scout::Graphics_backend &gfx_backend,
Launchpad_window(Genode::Env &env,
Scout::Graphics_backend &gfx_backend,
Scout::Point position, Scout::Area size,
Scout::Area max_size, unsigned long inital_quota);
@ -123,39 +127,40 @@ class Launchpad_window : public Scout::Scrollbar_listener,
_status_entry.refresh();
}
void add_launcher(const char *filename,
void add_launcher(Launchpad_child::Name const &name,
unsigned long default_quota,
Genode::Dataspace_capability config_ds = Genode::Dataspace_capability())
Genode::Dataspace_capability config_ds = Genode::Dataspace_capability()) override
{
Launch_entry<PT> *le;
le = new Launch_entry<PT>(filename, default_quota / 1024,
le = new Launch_entry<PT>(name, default_quota / 1024,
initial_quota() / 1024,
this, config_ds);
_launch_section.append(le);
refresh();
}
void add_child(const char *unique_name,
void add_child(Launchpad_child::Name const &name,
unsigned long quota,
Launchpad_child *launchpad_child,
Genode::Allocator *alloc)
Launchpad_child &launchpad_child,
Genode::Allocator &alloc) override
{
Child_entry<PT> *ce;
ce = new (alloc) Child_entry<PT>(unique_name, quota / 1024,
ce = new (alloc) Child_entry<PT>(name, quota / 1024,
initial_quota() / 1024,
this, launchpad_child);
*this, launchpad_child);
_child_entry_list.insert(ce);
_kiddy_section.append(ce);
format(_size);
refresh();
}
void remove_child(const char *name, Genode::Allocator *alloc)
void remove_child(Launchpad_child::Name const &name,
Genode::Allocator &alloc) override
{
/* lookup child entry by its name */
Child_entry<PT> *ce = _child_entry_list.first();
for ( ; ce; ce = ce->Genode::List<Child_entry<PT> >::Element::next())
if (Genode::strcmp(ce->name(), name) == 0)
if (name == ce->name())
break;
if (!ce) {

View File

@ -53,7 +53,7 @@ class Loadbar_event_handler : public Scout::Event_handler
/**
* Event handler interface
*/
void handle(Scout::Event &ev)
void handle_event(Scout::Event const &ev) override
{
static int key_cnt;
using Scout::Event;

View File

@ -11,6 +11,8 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/component.h>
#include <scout/platform.h>
#include <scout/tick.h>
#include <scout/user_state.h>
@ -85,15 +87,52 @@ static long read_int_attr_from_config(const char *attr, long default_value)
}
/**
* Main program
*/
int main(int argc, char **argv)
struct Main : Scout::Event_handler
{
Scout::Platform &_pf;
Scout::Window &_launchpad;
Scout::User_state &_user_state;
unsigned long _old_time = _pf.timer_ticks();
Main(Scout::Platform &pf, Scout::Window &launchpad, Scout::User_state &user_state)
: _pf(pf), _launchpad(launchpad), _user_state(user_state) { }
void handle_event(Scout::Event const &event) override
{
using namespace Scout;
Event ev = event;
if (ev.type != Event::WHEEL)
ev.mouse_position = ev.mouse_position - _user_state.view_position();
_user_state.handle_event(ev);
if (ev.type == Event::TIMER)
Tick::handle(_pf.timer_ticks());
/* perform periodic redraw */
unsigned long const curr_time = _pf.timer_ticks();
if (!_pf.event_pending() && ((curr_time - _old_time > 20)
|| (curr_time < _old_time))) {
_old_time = curr_time;
_launchpad.process_redraw();
}
}
};
/***************
** Component **
***************/
void Component::construct(Genode::Env &env)
{
using namespace Scout;
static Nitpicker::Connection nitpicker;
static Platform pf(*nitpicker.input());
static Nitpicker::Connection nitpicker(env);
static Platform pf(env, *nitpicker.input());
long initial_x = read_int_attr_from_config("xpos", 550);
long initial_y = read_int_attr_from_config("ypos", 150);
@ -109,17 +148,13 @@ int main(int argc, char **argv)
/* create instance of launchpad window */
static Launchpad_window<Pixel_rgb565>
launchpad(
graphics_backend, initial_position, initial_size, max_size,
Genode::env()->ram_session()->avail()
);
launchpad(env, graphics_backend, initial_position, initial_size,
max_size, env.ram().avail());
/* request config file from ROM service */
try {
launchpad.process_config();
} catch (...) { }
try { launchpad.process_config(); } catch (...) { }
Avail_quota_update avail_quota_update(&launchpad);
static Avail_quota_update avail_quota_update(&launchpad);
/* create user state manager */
static User_state user_state(&launchpad, &launchpad,
@ -129,36 +164,6 @@ int main(int argc, char **argv)
launchpad.format(initial_size);
launchpad.ypos(0);
Genode::printf("--- entering main loop ---\n");
/* enter main loop */
unsigned long curr_time, old_time;
curr_time = old_time = pf.timer_ticks();
for (;;) {
Event ev = pf.get_event();
launchpad.gui_lock.lock();
if (ev.type != Event::WHEEL)
ev.mouse_position = ev.mouse_position - user_state.view_position();
user_state.handle_event(ev);
if (ev.type == Event::TIMER)
Tick::handle(pf.timer_ticks());
/* perform periodic redraw */
curr_time = pf.timer_ticks();
if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) {
old_time = curr_time;
launchpad.process_redraw();
}
launchpad.gui_lock.unlock();
if (ev.type == Event::QUIT)
break;
}
return 0;
static Main main(pf, launchpad, user_state);
pf.event_handler(main);
}

View File

@ -136,7 +136,7 @@ class Iconbar_event_handler : public Scout::Event_handler
/**
* Event handler interface
*/
void handle(Event &ev)
void handle_event(Event const &ev) override
{
static int key_cnt;

View File

@ -426,7 +426,7 @@ void Verbatim::format_fixed_width(int w)
** Link_token **
****************/
void Link_token::handle(Event &e)
void Link_token::handle_event(Event const &e)
{
if (e.type != Event::PRESS) return;
@ -444,7 +444,7 @@ void Link_token::handle(Event &e)
** Launcher_link_token **
*************************/
void Launcher_link_token::handle(Event &e)
void Launcher_link_token::handle_event(Event const &e)
{
if (e.type != Event::PRESS) return;

View File

@ -200,7 +200,7 @@ class Scout::Link_token : public Token, public Link, public Event_handler,
/**
* Event handler interface
*/
void handle(Event &e);
void handle_event(Event const &) override;
/**
* Tick interface
@ -221,9 +221,13 @@ class Launchpad;
class Scout::Launcher : public Anchor
{
public:
typedef Genode::String<64> Name;
private:
const char *_prg_name; /* null-terminated name of the program */
Name _prg_name;
int _active;
int _exec_once;
Launchpad *_launchpad;
@ -232,22 +236,24 @@ class Scout::Launcher : public Anchor
public:
static void init(Genode::Env &);
/**
* Constructors
*/
Launcher(const char *prg_name, int exec_once = 0,
Launcher(Name const &prg_name, int exec_once = 0,
unsigned long quota = 0, Launcher_config *config = 0) :
_prg_name(prg_name), _active(1),
_exec_once(exec_once), _quota(quota), _config(config) { }
Launcher(const char *prg_name, Launchpad *launchpad,
Launcher(Name const &prg_name, Launchpad *launchpad,
unsigned long quota, Launcher_config *config = 0) :
_prg_name(prg_name), _launchpad(launchpad), _quota(quota),
_config(config) { }
int active() { return _active; }
const char *prg_name() { return _prg_name; }
Name prg_name() { return _prg_name; }
void quota(unsigned long quota) { _quota = quota; }
@ -280,7 +286,7 @@ class Scout::Launcher_link_token : public Link_token
/**
* Event handler interface
*/
void handle(Event &e);
void handle_event(Event const &) override;
};

View File

@ -18,9 +18,6 @@
#include <base/snprintf.h>
#include "elements.h"
static Launchpad launchpad(Genode::env()->ram_session()->quota());
using namespace Genode;
using namespace Scout;
@ -94,10 +91,32 @@ Dataspace_capability Config_registry::config(char const *name)
** Launcher interface **
************************/
static Launchpad *launchpad_ptr;
static Launchpad &launchpad()
{
if (!launchpad_ptr) {
class Missing_launchpad_init_call { };
throw Missing_launchpad_init_call();
}
return *launchpad_ptr;
}
void Launcher::init(Genode::Env &env)
{
static Launchpad launchpad(env, env.ram().avail());
launchpad_ptr = &launchpad;
}
void Launcher::launch()
{
static Config_registry config_registry;
launchpad.start_child(prg_name(), quota(),
config_registry.config(prg_name()));
launchpad().start_child(prg_name(), quota(),
config_registry.config(prg_name().string()));
}

View File

@ -11,6 +11,8 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/component.h>
#include <scout/platform.h>
#include <scout/tick.h>
#include <scout/user_state.h>
@ -45,20 +47,86 @@ extern unsigned char NAV_PREV_RGBA[];
static unsigned char *navicons_rgba[] = { NAV_NEXT_RGBA, NAV_PREV_RGBA };
static Scout::Generic_icon **navicons[] = { &Scout::Navbar::next_icon,
&Scout::Navbar::prev_icon };
&Scout::Navbar::prev_icon };
extern int native_startup(int, char **);
/**
* Main program
*/
int main(int argc, char **argv)
namespace Scout { struct Main; }
struct Scout::Main : Scout::Event_handler
{
Scout::Platform &_pf;
Scout::Window &_browser;
Scout::User_state &_user_state;
Scout::Element &_mcursor;
Scout::Point _mouse_position;
unsigned long _old_time = _pf.timer_ticks();
Main(Scout::Platform &pf, Scout::Window &browser,
Scout::User_state &user_state, Scout::Element &mcursor)
:
_pf(pf), _browser(browser), _user_state(user_state), _mcursor(mcursor)
{ }
void handle_event(Scout::Event const &event) override
{
using namespace Scout;
Event ev = event;
if (event.type != Event::WHEEL) {
ev.mouse_position = ev.mouse_position - _user_state.view_position();
/* update mouse cursor */
if (Config::mouse_cursor && (ev.mouse_position.x() != _mouse_position.x()
|| ev.mouse_position.y() != _mouse_position.y())) {
int x1 = min(ev.mouse_position.x(), _mouse_position.x());
int y1 = min(ev.mouse_position.y(), _mouse_position.y());
int x2 = max(ev.mouse_position.x() + _mcursor.size().w() - 1,
_mouse_position.x() + _mcursor.size().w() - 1);
int y2 = max(ev.mouse_position.y() + _mcursor.size().h() - 1,
_mouse_position.y() + _mcursor.size().h() - 1);
_mcursor.geometry(Rect(ev.mouse_position, _mcursor.size()));
_browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
_mouse_position = ev.mouse_position;
}
}
_user_state.handle_event(ev);
if (event.type == Event::TIMER)
Tick::handle(_pf.timer_ticks());
/* perform periodic redraw */
unsigned long curr_time = _pf.timer_ticks();
if (!_pf.event_pending() && ((curr_time - _old_time > 20)
|| (curr_time < _old_time))) {
_old_time = curr_time;
_browser.process_redraw();
}
}
};
/***************
** Component **
***************/
void Component::construct(Genode::Env &env)
{
using namespace Scout;
Launcher::init(env);
static Nitpicker::Connection nitpicker;
static Platform pf(*nitpicker.input());
static Platform pf(env, *nitpicker.input());
Area const max_size(530, 620);
Point const initial_position(256, 80);
@ -92,10 +160,9 @@ int main(int argc, char **argv)
);
/* initialize mouse cursor */
Point mouse_position;
static Icon<Pixel_rgb565, 32, 32> mcursor;
if (Config::mouse_cursor) {
mcursor.geometry(Rect(mouse_position, Area(32, 32)));
mcursor.geometry(Rect(Point(0, 0), Area(32, 32)));
mcursor.rgba(POINTER_RGBA);
mcursor.alpha(255);
mcursor.findable(0);
@ -107,47 +174,7 @@ int main(int argc, char **argv)
initial_position.x(), initial_position.y());
browser.ypos(0);
/* enter main loop */
unsigned long curr_time, old_time;
curr_time = old_time = pf.timer_ticks();
for (;;) {
Event ev = pf.get_event();
static Main main(pf, browser, user_state, mcursor);
pf.event_handler(main);
if (ev.type != Event::WHEEL) {
ev.mouse_position = ev.mouse_position - user_state.view_position();
/* update mouse cursor */
if (Config::mouse_cursor && (ev.mouse_position.x() != mouse_position.x()
|| ev.mouse_position.y() != mouse_position.y())) {
int x1 = min(ev.mouse_position.x(), mouse_position.x());
int y1 = min(ev.mouse_position.y(), mouse_position.y());
int x2 = max(ev.mouse_position.x() + mcursor.size().w() - 1,
mouse_position.x() + mcursor.size().w() - 1);
int y2 = max(ev.mouse_position.y() + mcursor.size().h() - 1,
mouse_position.y() + mcursor.size().h() - 1);
mcursor.geometry(Rect(ev.mouse_position, mcursor.size()));
browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
mouse_position = ev.mouse_position;
}
}
user_state.handle_event(ev);
if (ev.type == Event::TIMER)
Tick::handle(pf.timer_ticks());
/* perform periodic redraw */
curr_time = pf.timer_ticks();
if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) {
old_time = curr_time;
browser.process_redraw();
}
if (ev.type == Event::QUIT)
break;
}
return 0;
}

View File

@ -58,7 +58,7 @@ class Linkicon_event_handler : public Event_handler
/**
* Event handler interface
*/
void handle(Event &ev)
void handle_event(Event const &ev) override
{
if (ev.type != Event::PRESS || !_navbar) return;

View File

@ -69,7 +69,7 @@ class Arrow_event_handler : public Event_handler, public Tick
/**
* Event handler interface
*/
void handle(Event &ev)
void handle_event(Event const &ev) override
{
static int key_cnt;
@ -166,7 +166,7 @@ class Slider_event_handler : public Event_handler
/**
* Event handler interface
*/
void handle(Event &ev)
void handle_event(Event const &ev) override
{
static int key_cnt;
static int curr_my, orig_my;

View File

@ -14,16 +14,10 @@
*/
#include <base/env.h>
#include <base/child.h>
#include <base/sleep.h>
#include <base/service.h>
#include <base/snprintf.h>
#include <base/blocking.h>
#include <rom_session/connection.h>
#include <ram_session/connection.h>
#include <cpu_session/connection.h>
#include <base/attached_dataspace.h>
#include <os/config.h>
#include <timer_session/connection.h>
#include <launchpad/launchpad.h>
using namespace Genode;
@ -33,10 +27,11 @@ using namespace Genode;
** Launchpad **
***************/
Launchpad::Launchpad(unsigned long initial_quota)
Launchpad::Launchpad(Env &env, unsigned long initial_quota)
:
_env(env),
_initial_quota(initial_quota),
_sliced_heap(env()->ram_session(), env()->rm_session())
_sliced_heap(_env.ram(), _env.rm())
{
/* names of services provided by the parent */
static const char *names[] = {
@ -45,25 +40,24 @@ Launchpad::Launchpad(unsigned long initial_quota)
"RAM", "RM", "PD", "CPU", "IO_MEM", "IO_PORT", "IRQ", "ROM", "LOG",
/* services expected to got started by init */
"Nitpicker", "Init", "Timer", "PCI", "Block", "Nic", "Rtc",
"Nitpicker", "Init", "Timer", "Block", "Nic", "Rtc",
0 /* null-termination */
};
for (unsigned i = 0; names[i]; i++)
_parent_services.insert(new (env()->heap())
Parent_service(names[i]));
new (_heap) Launchpad_child::Parent_service(_parent_services, names[i]);
}
/**
* Check if a program with the specified name already exists
*/
bool Launchpad::_child_name_exists(const char *name)
bool Launchpad::_child_name_exists(Launchpad_child::Name const &name)
{
Launchpad_child *c = _children.first();
for ( ; c; c = c->List<Launchpad_child>::Element::next())
if (strcmp(c->name(), name) == 0)
if (c->name() == name)
return true;
return false;
@ -73,30 +67,23 @@ bool Launchpad::_child_name_exists(const char *name)
/**
* Create a unique name based on the filename
*
* If a program with the filename as name already exists, we
* add a counting number as suffix.
* If a program with the filename as name already exists, we add a counting
* number as suffix.
*/
void Launchpad::_get_unique_child_name(const char *filename, char *dst, int dst_len)
Launchpad_child::Name
Launchpad::_get_unique_child_name(Launchpad_child::Name const &binary_name)
{
Lock::Guard lock_guard(_children_lock);
char buf[64];
char suffix[8];
suffix[0] = 0;
if (!_child_name_exists(binary_name))
return binary_name;
for (int cnt = 1; true; cnt++) {
/* build program name composed of filename and numeric suffix */
snprintf(buf, sizeof(buf), "%s%s", filename, suffix);
for (unsigned cnt = 1; ; cnt++) {
/* if such a program name does not exist yet, we are happy */
if (!_child_name_exists(buf)) {
strncpy(dst, buf, dst_len);
return;
}
/* increase number of suffix */
snprintf(suffix, sizeof(suffix), ".%d", cnt + 1);
Launchpad_child::Name const unique(binary_name, ".", cnt);
if (!_child_name_exists(unique))
return unique;
}
}
@ -114,370 +101,98 @@ void Launchpad::process_config()
* Iterate through all entries of the config file and create
* launchpad entries as specified.
*/
int launcher_cnt = 0;
for (unsigned i = 0; i < config_node.num_sub_nodes(); i++) {
Xml_node node = config_node.sub_node(i);
if (node.has_type("launcher"))
config_node.for_each_sub_node("launcher", [&] (Xml_node node) {
/* catch XML syntax errors within launcher node */
try {
/* read file name and default quote from launcher node */
Xml_node::Attribute filename_attr = node.attribute("name");
typedef Launchpad_child::Name Name;
Name *name = new (_heap) Name(node.attribute_value("name", Name()));
enum { MAX_NAME_LEN = 128 };
char *filename = (char *)env()->heap()->alloc(MAX_NAME_LEN);
if (!filename) {
Genode::error("out of memory while processing configuration");
return;
}
filename_attr.value(filename, MAX_NAME_LEN);
Xml_node::Attribute ram_quota_attr = node.attribute("ram_quota");
Number_of_bytes default_ram_quota = 0;
ram_quota_attr.value(&default_ram_quota);
Number_of_bytes default_ram_quota =
node.attribute_value("ram_quota", Number_of_bytes(0));
/*
* Obtain configuration for the child
*/
Dataspace_capability config_ds;
/*
* Obtain configuration for the child
*/
Dataspace_capability config_ds;
if (node.has_sub_node("configfile")
&& node.sub_node("configfile").has_attribute("name")) {
typedef String<128> Rom_name;
char name[128];
node.sub_node("configfile").attribute("name").value(name, sizeof(name));
if (node.has_sub_node("configfile")) {
Rom_connection config_rom(name);
config_rom.on_destruction(Rom_connection::KEEP_OPEN);
Rom_name const name =
node.sub_node("configfile").attribute_value("name", Rom_name());
config_ds = config_rom.dataspace();
}
Rom_connection &config_rom = *new (_heap) Rom_connection(name.string());
if (node.has_sub_node("config")) {
Xml_node config_node = node.sub_node("config");
/* allocate dataspace for config */
size_t const config_size = config_node.size();
config_ds = env()->ram_session()->alloc(config_size);
/* copy configuration into new dataspace */
char * const ptr = env()->rm_session()->attach(config_ds);
Genode::memcpy(ptr, config_node.addr(), config_size);
env()->rm_session()->detach(ptr);
}
/* add launchpad entry */
add_launcher(filename, default_ram_quota, config_ds);
launcher_cnt++;
} catch (...) {
Genode::warning("launcher entry ", launcher_cnt + 1, " is malformed");
}
else {
char buf[32];
node.type_name(buf, sizeof(buf));
Genode::warning("ignoring unsupported tag <", Genode::Cstring(buf), ">");
config_ds = config_rom.dataspace();
}
}
if (node.has_sub_node("config")) {
Xml_node config_node = node.sub_node("config");
/* allocate dataspace for config */
size_t const size = config_node.size();
config_ds = env()->ram_session()->alloc(size);
/* copy configuration into new dataspace */
Attached_dataspace attached(config_ds);
memcpy(attached.local_addr<char>(), config_node.addr(), size);
}
/* add launchpad entry */
add_launcher(*name, default_ram_quota, config_ds);
});
}
Launchpad_child *Launchpad::start_child(const char *filename,
Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name,
unsigned long ram_quota,
Genode::Dataspace_capability config_ds)
Dataspace_capability config_ds)
{
Genode::log("starting ", filename, " with quota ", ram_quota);
log("starting ", binary_name, " with quota ", ram_quota);
/* find unique name for new child */
char unique_name[64];
_get_unique_child_name(filename, unique_name, sizeof(unique_name));
Genode::log("using unique child name \"", Cstring(unique_name), "\"");
Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name);
log("using unique child name \"", unique_name, "\"");
if (ram_quota > env()->ram_session()->avail()) {
Genode::error("child's ram quota is higher than our available quota, using available quota");
error("child's ram quota is higher than our available quota, using available quota");
ram_quota = env()->ram_session()->avail() - 256*1000;
}
size_t metadata_size = 4096*16 + sizeof(Launchpad_child);
if (metadata_size > ram_quota) {
Genode::error("too low ram_quota to hold child metadata");
error("too low ram_quota to hold child metadata");
return 0;
}
ram_quota -= metadata_size;
/* lookup executable elf binary */
Dataspace_capability file_cap;
Rom_session_capability rom_cap;
try {
/*
* When creating a ROM connection for a non-existing file, the
* constructor of 'Rom_connection' throws a 'Parent::Service_denied'
* exception.
*/
Rom_connection rom(prefixed_label(Session_label(Cstring(unique_name)),
Session_label(filename)).string());
rom.on_destruction(Rom_connection::KEEP_OPEN);
rom_cap = rom.cap();
file_cap = rom.dataspace();
} catch (...) {
Genode::error("could not access ROM module \"", filename, "\"");
return 0;
}
/* create ram session for child with some of our own quota */
Ram_connection ram;
ram.on_destruction(Ram_connection::KEEP_OPEN);
ram.ref_account(env()->ram_session_cap());
env()->ram_session()->transfer_quota(ram.cap(), ram_quota);
/* create cpu session for child */
Cpu_connection cpu(unique_name);
cpu.on_destruction(Cpu_connection::KEEP_OPEN);
if (!ram.cap().valid() || !cpu.cap().valid()) {
if (ram.cap().valid()) {
Genode::warning("failed to create CPU session");
env()->parent()->close(ram.cap());
}
if (cpu.cap().valid()) {
Genode::warning("failed to create RAM session");
env()->parent()->close(cpu.cap());
}
env()->parent()->close(rom_cap);
Genode::log("our quota is ", env()->ram_session()->quota());
return 0;
}
Pd_connection pd;
pd.on_destruction(Pd_connection::KEEP_OPEN);
if (!pd.cap().valid()) {
Genode::warning("failed to create PD session");
env()->parent()->close(ram.cap());
env()->parent()->close(cpu.cap());
env()->parent()->close(rom_cap);
return 0;
}
try {
Launchpad_child *c = new (&_sliced_heap)
Launchpad_child(unique_name, file_cap, pd.cap(), ram.cap(),
cpu.cap(), rom_cap,
&_cap_session, &_parent_services, &_child_services,
config_ds, this);
Launchpad_child(_env, unique_name, binary_name, ram_quota,
_parent_services, _child_services, config_ds);
Lock::Guard lock_guard(_children_lock);
_children.insert(c);
add_child(unique_name, ram_quota, c, c->heap());
add_child(unique_name, ram_quota, *c, c->heap());
return c;
} catch (Cpu_session::Thread_creation_failed) {
Genode::warning("failed to create child - Cpu_session::Thread_creation_failed");
} catch (...) {
Genode::warning("failed to create child - unknown reason");
}
env()->parent()->close(ram.cap());
env()->parent()->close(cpu.cap());
env()->parent()->close(rom_cap);
} catch (...) {
warning("failed to create child - unknown reason"); }
return 0;
}
/**
* Watchdog-guarded child destruction mechanism
*
* During the destruction of a child, all sessions of the child are getting
* closed. A server, however, may refuse to answer a close call. We detect
* this case using a watchdog mechanism, unblock the 'close' call, and
* proceed with the closing the other remaining sessions.
*/
class Child_destructor_thread : Thread_deprecated<2*4096>
void Launchpad::exit_child(Launchpad_child &child)
{
private:
Launchpad_child *_curr_child; /* currently destructed child */
Allocator *_curr_alloc; /* child object'sallocator */
Lock _submit_lock; /* only one submission at a time */
Lock _activate_lock; /* submission protocol */
bool _ready; /* set if submission is completed */
int _watchdog_cnt; /* watchdog counter in milliseconds */
/**
* Thread entry function
*/
void entry() {
while (true) {
/* wait for next submission */
_activate_lock.lock();
/*
* Eventually long-taking operation that involves the
* closing of all session of the child. This procedure
* may need blocking cancellation to proceed in the
* case servers are unresponsive.
*/
try {
destroy(_curr_alloc, _curr_child);
} catch (Blocking_canceled) {
Genode::error("suspicious cancellation");
}
_ready = true;
}
}
public:
/*
* Watchdog timer granularity in milliseconds. This value defined
* after how many milliseconds the watchdog is activated.
*/
enum { WATCHDOG_GRANULARITY_MS = 10 };
/**
* Constructor
*/
Child_destructor_thread() :
Thread_deprecated("child_destructor"),
_curr_child(0), _curr_alloc(0),
_activate_lock(Lock::LOCKED),
_ready(true)
{
start();
}
/**
* Destruct child, coping with unresponsive servers
*
* \param alloc Child object's allocator
* \param child Child to destruct
* \param timeout_ms Maximum destruction time until the destructing
* thread gets waken up to give up the close call to
* an unreponsive server.
*/
void submit_for_destruction(Allocator *alloc, Launchpad_child *child,
Timer::Session *timer, int timeout_ms)
{
/* block until destructor thread is ready for new submission */
Lock::Guard _lock_guard(_submit_lock);
/* register submission values */
_curr_child = child;
_curr_alloc = alloc;
_ready = false;
_watchdog_cnt = 0;
/* wake up the destruction thread */
_activate_lock.unlock();
/*
* Now, the destruction thread attempts to close all the
* child's sessions. Check '_ready' flag periodically.
*/
while (!_ready) {
/* give the destruction thread some time to proceed */
timer->msleep(WATCHDOG_GRANULARITY_MS);
_watchdog_cnt += WATCHDOG_GRANULARITY_MS;
/* check if we reached the timeout */
if (_watchdog_cnt > timeout_ms) {
/*
* The destruction seems to got stuck, let's shake it a
* bit to proceed and reset the watchdog counter to give
* the next blocking operation a chance to execute.
*/
child->cancel_blocking();
_watchdog_cnt = 0;
}
}
}
};
/**
* Construct a timer session for the watchdog timer on demand
*/
static Timer::Session *timer_session()
{
static Timer::Connection timer;
return &timer;
}
Dataspace_capability Launchpad_child::_ldso_ds()
{
static bool first_attempt_failed = false;
if (!first_attempt_failed) {
try {
static Rom_connection rom("ld.lib.so");
static Dataspace_capability ds = rom.dataspace();
return ds;
} catch (...) { }
}
first_attempt_failed = true;
return Dataspace_capability();
}
/* construct child-destructor thread early - in case we run out of threads */
static Child_destructor_thread child_destructor;
/**
* Destruct Launchpad_child, cope with infinitely blocking server->close calls
*
* The arguments correspond to the 'Child_destructor_thread::submit_for_destruction'
* function.
*/
static void destruct_child(Allocator *alloc, Launchpad_child *child,
Timer::Session *timer, int timeout)
{
/* if no timer session was provided by our caller, we have create one */
if (!timer)
timer = timer_session();
child_destructor.submit_for_destruction(alloc, child, timer, timeout);
}
void Launchpad::exit_child(Launchpad_child *child,
Timer::Session *timer,
int session_close_timeout_ms)
{
remove_child(child->name(), child->heap());
remove_child(child.name(), child.heap());
Lock::Guard lock_guard(_children_lock);
_children.remove(child);
_children.remove(&child);
Ram_session_capability ram_session_cap = child->ram_session_cap();
Cpu_session_capability cpu_session_cap = child->cpu_session_cap();
Rom_session_capability rom_session_cap = child->rom_session_cap();
const Genode::Server *server = child->server();
destruct_child(&_sliced_heap, child, timer, session_close_timeout_ms);
env()->parent()->close(cpu_session_cap);
env()->parent()->close(rom_session_cap);
env()->parent()->close(ram_session_cap);
/*
* The killed child may have provided services to other children.
* Since the server is dead by now, we cannot close its sessions
* in the cooperative way. Instead, we need to instruct each
* other child to forget about session associated with the dead
* server. Note that the 'child' pointer points a a no-more
* existing object. It is only used to identify the corresponding
* session. It must never by de-referenced!
*/
Launchpad_child *c = _children.first();
for ( ; c; c = c->Genode::List<Launchpad_child>::Element::next())
c->revoke_server(server);
destroy(_sliced_heap, &child);
}

View File

@ -11,10 +11,9 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/component.h>
#include <base/rpc_server.h>
#include <base/signal.h>
#include <cap_session/connection.h>
#include <os/config.h>
#include <base/attached_rom_dataspace.h>
#include <scout/user_state.h>
#include <scout/nitpicker_graphics_backend.h>
@ -101,12 +100,10 @@ static bool config_decoration = true;
/**
* Parse configuration
*/
static void read_config()
static void read_config(Genode::Xml_node config_node)
{
using namespace Genode;
Xml_node config_node = config()->xml_node();
try {
char buf[16];
config_node.attribute("animate").value(buf, sizeof(buf));
@ -169,42 +166,71 @@ static void read_config()
struct Input_handler
{
GENODE_RPC(Rpc_handle_input, void, handle, Scout::Event&);
GENODE_RPC(Rpc_handle_input, void, handle_input, Scout::Event const &);
GENODE_RPC_INTERFACE(Rpc_handle_input);
};
class Input_handler_component : public Genode::Rpc_object<Input_handler,
Input_handler_component>
class Main : public Scout::Event_handler
{
private:
Scout::Platform &_pf;
Scout::User_state &_user_state;
Framebuffer_window<Genode::Pixel_rgb565> &_fb_win;
Genode::Signal_receiver &_sig_rec;
Genode::Attached_rom_dataspace &_config;
unsigned long _curr_time, _old_time;
void _handle_config()
{
_config.update();
/* keep the current values by default */
config_fb_x = _fb_win.view_x();
config_fb_y = _fb_win.view_y();
config_fb_width = _fb_win.view_w();
config_fb_height = _fb_win.view_h();
try { read_config(_config.xml()); } catch (...) { }
_fb_win.name(config_title);
_fb_win.config_alpha(config_alpha);
_fb_win.config_resize_handle(config_resize_handle);
_fb_win.config_decoration(config_decoration);
/* must get called after 'config_decoration()' */
_fb_win.content_geometry(config_fb_x, config_fb_y,
config_fb_width, config_fb_height);
_user_state.update_view_offset();
}
Genode::Signal_handler<Main> _config_handler;
public:
Input_handler_component(Scout::Platform &pf,
Scout::User_state &user_state,
Framebuffer_window<Genode::Pixel_rgb565> &fb_win,
Genode::Signal_receiver &sig_rec)
Main(Scout::Platform &pf,
Scout::User_state &user_state,
Framebuffer_window<Genode::Pixel_rgb565> &fb_win,
Genode::Entrypoint &ep,
Genode::Attached_rom_dataspace &config)
:
_pf(pf),
_user_state(user_state),
_fb_win(fb_win),
_sig_rec(sig_rec)
_config(config),
_config_handler(ep, *this, &Main::_handle_config)
{
_curr_time = _old_time = _pf.timer_ticks();
config.sigh(_config_handler);
}
void handle(Scout::Event &ev)
void handle_event(Scout::Event const &event) override
{
using Scout::Event;
Event ev = event;
if (ev.type != Event::WHEEL)
ev.mouse_position = ev.mouse_position - _user_state.view_position();
@ -217,30 +243,11 @@ class Input_handler_component : public Genode::Rpc_object<Input_handler,
if (ev.type == Event::TIMER) {
Scout::Tick::handle(_pf.timer_ticks());
/* check for configuration changes */
if (_sig_rec.pending()) {
_sig_rec.wait_for_signal();
Genode::config()->reload();
/* keep the current values by default */
config_fb_x = _fb_win.view_x();
config_fb_y = _fb_win.view_y();
config_fb_width = _fb_win.view_w();
config_fb_height = _fb_win.view_h();
try { read_config(); } catch (...) { }
_fb_win.name(config_title);
_fb_win.config_alpha(config_alpha);
_fb_win.config_resize_handle(config_resize_handle);
_fb_win.config_decoration(config_decoration);
/* must get called after 'config_decoration()' */
_fb_win.content_geometry(config_fb_x, config_fb_y,
config_fb_width, config_fb_height);
_user_state.update_view_offset();
}
}
/* perform periodic redraw */
_curr_time = _pf.timer_ticks();
if (!_pf.event_pending() && ((_curr_time - _old_time > 20) || (_curr_time < _old_time))) {
if ((_curr_time - _old_time > 20) || (_curr_time < _old_time)) {
_old_time = _curr_time;
_fb_win.process_redraw();
}
@ -248,29 +255,24 @@ class Input_handler_component : public Genode::Rpc_object<Input_handler,
};
/**
* Main program
*/
int main(int argc, char **argv)
/***************
** Component **
***************/
void Component::construct(Genode::Env &env)
{
using namespace Scout;
try { read_config(); } catch (...) { }
static Genode::Attached_rom_dataspace config(env, "config");
/*
* Register signal handler for config changes
*/
static Genode::Signal_receiver sig_rec;
static Genode::Signal_context sig_ctx;
try { Genode::config()->sigh(sig_rec.manage(&sig_ctx)); } catch (...) { }
try { read_config(config.xml()); } catch (...) { }
/* heuristic for allocating the double-buffer backing store */
enum { WINBORDER_WIDTH = 10, WINBORDER_HEIGHT = 40 };
/* init platform */
static Nitpicker::Connection nitpicker;
static Platform pf(*nitpicker.input());
static Nitpicker::Connection nitpicker(env);
static Platform pf(env, *nitpicker.input());
Area const max_size(config_fb_width + WINBORDER_WIDTH,
config_fb_height + WINBORDER_HEIGHT);
@ -301,27 +303,9 @@ int main(int argc, char **argv)
fb_win.content_geometry(config_fb_x, config_fb_y,
config_fb_width, config_fb_height);
/* initialize server entry point */
enum { STACK_SIZE = 2*1024*sizeof(Genode::addr_t) };
static Genode::Cap_connection cap;
static Genode::Rpc_entrypoint ep(&cap, STACK_SIZE, "liquid_fb_ep");
/* initialize public services */
init_services(ep);
init_services(env.ep().rpc_ep());
/* create local input handler service */
static Input_handler_component input_handler(pf, user_state, fb_win,
sig_rec);
Genode::Capability<Input_handler> input_handler_cap = ep.manage(&input_handler);
/* enter main loop */
for (;;) {
Event ev = pf.get_event();
input_handler_cap.call<Input_handler::Rpc_handle_input>(ev);
if (ev.type == Event::QUIT)
break;
}
return 0;
static Main main(pf, user_state, fb_win, env.ep(), config);
pf.event_handler(main);
}

View File

@ -58,7 +58,7 @@ class Window_content : public Scout::Element
:
_input_session(input_session),_element(element) { }
void handle(Scout::Event &ev)
void handle_event(Scout::Event const &ev) override
{
using namespace Scout;

View File

@ -401,7 +401,7 @@ int main(int argc, char **argv)
Framebuffer::Mode::RGB565), false);
/* initialize entry point that serves the root interface */
enum { STACK_SIZE = 4096 };
enum { STACK_SIZE = 4096*sizeof(long) };
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "nitlog_ep");

View File

@ -17,85 +17,53 @@
/* Genode includes */
#include <base/lock.h>
#include <os/slave.h>
#include <report_session/report_session.h>
#include <rom_session/capability.h>
#include <root/client.h>
#include <report_session/connection.h>
#include <rom_session/connection.h>
class Report_rom_slave : public Genode::Noncopyable
{
private:
class Policy : public Genode::Slave_policy
class Policy : public Genode::Slave::Policy
{
private:
Genode::Root_capability _report_root_cap;
Genode::Root_capability _rom_root_cap;
bool _announced;
Genode::Lock mutable _lock; /* used to wait for announcement */
protected:
char const **_permitted_services() const
{
static char const *permitted_services[] = {
"LOG", "RM", 0 };
"CPU", "PD", "RAM", "LOG", 0 };
return permitted_services;
};
static Name _name() { return "report_rom"; }
static Genode::size_t _quota() { return 1024*1024; }
public:
Policy(Genode::Rpc_entrypoint &entrypoint,
Genode::Ram_session &ram,
const char *config)
Policy(Genode::Rpc_entrypoint &ep,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
const char *config)
:
Slave_policy("report_rom", entrypoint, &ram),
_lock(Genode::Lock::LOCKED)
Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota())
{
if (config)
configure(config);
}
bool announce_service(const char *service_name,
Genode::Root_capability root,
Genode::Allocator *,
Genode::Server *)
{
if (Genode::strcmp(service_name, "ROM") == 0)
_rom_root_cap = root;
else if (Genode::strcmp(service_name, "Report") == 0)
_report_root_cap = root;
else
return false;
if (_rom_root_cap.valid() && _report_root_cap.valid())
_lock.unlock();
return true;
}
Genode::Root_capability report_root() const
{
Genode::Lock::Guard guard(_lock);
return _report_root_cap;
}
Genode::Root_capability rom_root() const
{
Genode::Lock::Guard guard(_lock);
return _rom_root_cap;
}
};
Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t);
Genode::Rpc_entrypoint _ep;
Policy _policy;
Genode::size_t const _quota = 1024*1024;
Genode::Slave _slave;
Genode::Root_client _rom_root;
Genode::Root_client _report_root;
Genode::Child _child;
public:
@ -106,64 +74,17 @@ class Report_rom_slave : public Genode::Noncopyable
* \param ram RAM session used to allocate the configuration
* dataspace
*/
Report_rom_slave(Genode::Cap_session &cap, Genode::Ram_session &ram,
char const *config)
Report_rom_slave(Genode::Pd_session &pd,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
char const *config)
:
_ep(&cap, _ep_stack_size, "report_rom"),
_policy(_ep, ram, config),
_slave(_ep, _policy, _quota),
_rom_root(_policy.rom_root()),
_report_root(_policy.report_root())
_ep(&pd, _ep_stack_size, "report_rom"),
_policy(_ep, rm, ram, config),
_child(rm, _ep, _policy)
{ }
Genode::Rom_session_capability rom_session(char const *label)
{
using namespace Genode;
enum { ARGBUF_SIZE = 128 };
char argbuf[ARGBUF_SIZE];
argbuf[0] = 0;
/*
* Declare ram-quota donation
*/
enum { SESSION_METADATA = 4*1024 };
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
/*
* Set session label
*/
Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label);
Session_capability session_cap = _rom_root.session(argbuf, Affinity());
return static_cap_cast<Genode::Rom_session>(session_cap);
}
Genode::Capability<Report::Session> report_session(char const *label)
{
using namespace Genode;
enum { ARGBUF_SIZE = 128 };
char argbuf[ARGBUF_SIZE];
argbuf[0] = 0;
/*
* Declare ram-quota donation
*/
enum { BUFFER_SIZE = 4096, SESSION_METADATA = BUFFER_SIZE + 8*1024 };
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
Arg_string::set_arg(argbuf, sizeof(argbuf), "buffer_size", BUFFER_SIZE);
/*
* Set session label
*/
Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label);
Session_capability session_cap = _report_root.session(argbuf, Affinity());
return static_cap_cast<Report::Session>(session_cap);
}
Genode::Slave::Policy &policy() { return _policy; }
};
#endif /* _INCLUDE__GEMS__REPORT_ROM_SLAVE_H_ */

View File

@ -1,39 +0,0 @@
/*
* \brief Utility for implementing a local service with a single session
* \author Norman Feske
* \date 2014-02-14
*/
/*
* Copyright (C) 2014 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__GEMS__SINGLE_SESSION_SERVICE_H_
#define _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_
#include <base/service.h>
struct Single_session_service : Genode::Service
{
Genode::Session_capability session_cap;
Single_session_service(char const *service_name,
Genode::Session_capability session_cap)
:
Service(service_name), session_cap(session_cap)
{ }
Genode::Session_capability
session(const char *, Genode::Affinity const &) override
{
return session_cap;
}
void upgrade(Genode::Session_capability, const char *) override { }
void close(Genode::Session_capability) override { }
};
#endif /* _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_ */

View File

@ -105,12 +105,11 @@ class Launcher::Context_dialog : Input_event_handler, Dialog_generator,
public:
Context_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
Dataspace_capability ldso_ds,
Context_dialog(Env &env,
Report_rom_slave &report_rom_slave,
Response_handler &response_handler)
:
_dialog(ep, cap, ram, ldso_ds, report_rom_slave,
_dialog(env, report_rom_slave,
"context_dialog", "context_hover",
*this, *this, *this, *this,
Fading_dialog::Position(364, 64)),

View File

@ -20,6 +20,7 @@
/* Genode includes */
#include <util/string.h>
#include <base/entrypoint.h>
#include <os/attached_dataspace.h>
#include <nitpicker_session/nitpicker_session.h>
#include <input_session/client.h>
@ -54,7 +55,7 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session
Input_event_handler &_input_event_handler;
Server::Entrypoint &_ep;
Rpc_entrypoint &_session_ep;
Nitpicker::Session &_nitpicker_session;
@ -62,36 +63,43 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session
Attached_dataspace _nitpicker_input_ds { _nitpicker_input.dataspace() };
Signal_rpc_member<Dialog_nitpicker_session>
_input_dispatcher { _ep, *this, &Dialog_nitpicker_session::_input_handler };
Signal_handler<Dialog_nitpicker_session> _input_handler;
Input::Session_component _input_session;
Capability<Input::Session> _input_session_cap { _ep.manage(_input_session) };
/**
* Constructor
*
* \param input_sigh_ep entrypoint where the input signal handler is
* installed ('env.ep')
* \param service_ep entrypoint providing the nitpicker session
* (slave-specific ep)
*/
Dialog_nitpicker_session(Nitpicker::Session &nitpicker_session,
Server::Entrypoint &ep,
Dialog_nitpicker_session(Nitpicker::Session &nitpicker_session,
Entrypoint &input_sigh_ep,
Rpc_entrypoint &session_ep,
Input_event_handler &input_event_handler)
:
Wrapped_nitpicker_session(nitpicker_session),
_input_event_handler(input_event_handler),
_ep(ep),
_nitpicker_session(nitpicker_session)
_session_ep(session_ep),
_nitpicker_session(nitpicker_session),
_input_handler(input_sigh_ep, *this, &Dialog_nitpicker_session::_handle_input)
{
_nitpicker_input.sigh(_input_dispatcher);
_session_ep.manage(this);
_session_ep.manage(&_input_session);
_nitpicker_input.sigh(_input_handler);
_input_session.event_queue().enabled(true);
}
~Dialog_nitpicker_session()
{
_ep.dissolve(_input_session);
_session_ep.dissolve(&_input_session);
_session_ep.dissolve(this);
}
void _input_handler(unsigned)
void _handle_input()
{
Input::Event const * const events =
_nitpicker_input_ds.local_addr<Input::Event>();
@ -116,7 +124,7 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session
Input::Session_capability input_session() override
{
return _input_session_cap;
return _input_session.cap();
}
};

View File

@ -54,17 +54,17 @@ class Launcher::Fading_dialog : private Input_event_handler
{
private:
Rom_session_capability _dialog_rom;
Slave::Connection<Rom_connection> _dialog_rom;
/* dialog reported locally */
Capability<Report::Session> _dialog_report;
Slave::Connection<Report::Connection> _dialog_report;
Rom_session_client _hover_rom;
Slave::Connection<Rom_connection> _hover_rom;
Lazy_volatile_object<Attached_dataspace> _hover_ds;
/* hovered element reported by menu view */
Capability<Report::Session> _hover_report;
Slave::Connection<Report::Connection> _hover_report;
Local_reporter _dialog_reporter { "dialog", _dialog_report };
@ -100,7 +100,7 @@ class Launcher::Fading_dialog : private Input_event_handler
return forward_event;
}
void _handle_hover_update(unsigned)
void _handle_hover_update()
{
try {
if (!_hover_ds.constructed() || _hover_rom.update() == false) {
@ -129,52 +129,10 @@ class Launcher::Fading_dialog : private Input_event_handler
}
}
Signal_rpc_member<Fading_dialog> _hover_update_dispatcher;
Signal_handler<Fading_dialog> _hover_update_handler;
private:
/**
* Local nitpicker service to be handed out to the menu view slave
*/
struct Nitpicker_service : Genode::Service
{
Server::Entrypoint &ep;
Rpc_entrypoint &child_ep;
/* connection to real nitpicker */
Nitpicker::Connection connection { "menu" };
Dialog_nitpicker_session wrapper_session;
Capability<Nitpicker::Session> session_cap { child_ep.manage(&wrapper_session) };
Nitpicker_service(Server::Entrypoint &ep,
Rpc_entrypoint &child_ep,
Dialog_nitpicker_session::Input_event_handler &ev_handler)
:
Genode::Service(Nitpicker::Session::service_name()),
ep(ep), child_ep(child_ep),
wrapper_session(connection, ep, ev_handler)
{ }
/*******************************
** Genode::Service interface **
*******************************/
Genode::Session_capability
session(const char *, Genode::Affinity const &) override
{
return session_cap;
}
void upgrade(Genode::Session_capability, const char *args) override
{
Genode::log("upgrade called args: '", args, "'");
}
void close(Genode::Session_capability) override { }
};
/*
* Entrypoint for the fader slave
*
@ -188,9 +146,21 @@ class Launcher::Fading_dialog : private Input_event_handler
size_t const _fader_slave_ep_stack_size = 4*1024*sizeof(addr_t);
Rpc_entrypoint _fader_slave_ep;
Nitpicker_service _nitpicker_service;
Nit_fader_slave _nit_fader_slave;
Menu_view_slave _menu_view_slave;
/*
* Provide wrapped nitpicker connection as a service handed out to
* the menu-view slave
*/
typedef Genode::Local_service<Dialog_nitpicker_session> Nitpicker_service;
typedef Nitpicker_service::Single_session_factory Nitpicker_factory;
Nitpicker::Connection _nitpicker_connection;
Dialog_nitpicker_session _nitpicker_session;
Nitpicker_factory _nitpicker_factory { _nitpicker_session };
Nitpicker_service _nitpicker_service { _nitpicker_factory };
Nit_fader_slave _nit_fader_slave;
Slave::Connection<Nitpicker::Connection> _nit_fader_connection;
Menu_view_slave _menu_view_slave;
bool _visible = false;
@ -198,47 +168,38 @@ class Launcher::Fading_dialog : private Input_event_handler
typedef Menu_view_slave::Position Position;
/**
* Constructor
*
* \param ep main entrypoint, used for managing the local input
* session provided (indirectly through the wrapped
* nitpicker session) to the menu view
* \param cap capability session to be used for creating the
* slave entrypoints
* \param ram RAM session where to draw the memory for providing
* configuration data to the slave processes
*/
Fading_dialog(Server::Entrypoint &ep,
Cap_session &cap,
Ram_session &ram,
Dataspace_capability ldso_ds,
Report_rom_slave &report_rom_slave,
char const *dialog_name,
char const *hover_name,
Input_event_handler &input_event_handler,
Hover_handler &hover_handler,
Dialog_generator &dialog_generator,
Dialog_model &dialog_model,
Position initial_position)
Fading_dialog(Env &env,
Report_rom_slave &report_rom_slave,
char const *dialog_name,
char const *hover_name,
Input_event_handler &input_event_handler,
Hover_handler &hover_handler,
Dialog_generator &dialog_generator,
Dialog_model &dialog_model,
Position initial_position)
:
_dialog_rom(report_rom_slave.rom_session(dialog_name)),
_dialog_report(report_rom_slave.report_session(dialog_name)),
_hover_rom(report_rom_slave.rom_session(hover_name)),
_hover_report(report_rom_slave.report_session(hover_name)),
_dialog_rom(report_rom_slave.policy(), Slave::Args("label=", dialog_name)),
_dialog_report(report_rom_slave.policy(),
Slave::Args("label=", dialog_name, ", buffer_size=4096")),
_hover_rom(report_rom_slave.policy(), Slave::Args("label=", hover_name)),
_hover_report(report_rom_slave.policy(),
Slave::Args("label=", hover_name, ", buffer_size=4096")),
_dialog_input_event_handler(input_event_handler),
_hover_handler(hover_handler),
_dialog_generator(dialog_generator),
_dialog_model(dialog_model),
_hover_update_dispatcher(ep, *this, &Fading_dialog::_handle_hover_update),
_fader_slave_ep(&cap, _fader_slave_ep_stack_size, "nit_fader"),
_nitpicker_service(ep, _fader_slave_ep, *this),
_nit_fader_slave(_fader_slave_ep, ram, _nitpicker_service, ldso_ds),
_menu_view_slave(cap, ram, ldso_ds,
_nit_fader_slave.nitpicker_session("menu"),
_hover_update_handler(env.ep(), *this, &Fading_dialog::_handle_hover_update),
_fader_slave_ep(&env.pd(), _fader_slave_ep_stack_size, "nit_fader"),
_nitpicker_connection(env, "menu"),
_nitpicker_session(_nitpicker_connection, env.ep(), _fader_slave_ep, *this),
_nit_fader_slave(_fader_slave_ep, env.rm(), env.ram_session_cap(),
_nitpicker_service),
_nit_fader_connection(_nit_fader_slave.policy(), Slave::Args("label=menu")),
_menu_view_slave(env.pd(), env.rm(), env.ram_session_cap(),
_nit_fader_connection,
_dialog_rom, _hover_report, initial_position)
{
Rom_session_client(_hover_rom).sigh(_hover_update_dispatcher);
Rom_session_client(_hover_rom).sigh(_hover_update_handler);
}
void update()

View File

@ -12,9 +12,7 @@
*/
/* Genode includes */
#include <os/server.h>
#include <os/config.h>
#include <cap_session/connection.h>
#include <base/component.h>
#include <decorator/xml_utils.h>
#include <util/volatile_object.h>
#include <os/attached_rom_dataspace.h>
@ -23,25 +21,16 @@
/* local includes */
#include <panel_dialog.h>
namespace Launcher {
using namespace Genode;
struct Main;
}
namespace Launcher { struct Main; }
struct Launcher::Main
{
Server::Entrypoint &_ep;
Genode::Dataspace_capability _request_ldso_ds()
{
try {
static Genode::Rom_connection rom("ld.lib.so");
return rom.dataspace();
} catch (...) { }
return Genode::Dataspace_capability();
}
Genode::Dataspace_capability _ldso_ds = _request_ldso_ds();
Genode::Cap_connection _cap;
Env &_env;
char const *_report_rom_config =
"<config>"
@ -53,35 +42,54 @@ struct Launcher::Main
" <policy label=\"context_hover\" report=\"context_hover\"/>"
"</config>";
Report_rom_slave _report_rom_slave = { _cap, *env()->ram_session(), _report_rom_config };
Report_rom_slave _report_rom_slave {
_env.pd(), _env.rm(), _env.ram_session_cap(), _report_rom_config };
/**
* Nitpicker session used to perform session-control operations on the
* subsystem's nitpicker sessions and to receive global keyboard
* shortcuts.
*/
Nitpicker::Connection _nitpicker;
Nitpicker::Connection _nitpicker { _env };
Genode::Signal_rpc_member<Main> _input_dispatcher =
{ _ep, *this, &Main::_handle_input };
Signal_handler<Main> _input_handler =
{ _env.ep(), *this, &Main::_handle_input };
void _handle_input(unsigned);
void _handle_input();
unsigned _key_cnt = 0;
Genode::Signal_rpc_member<Main> _exited_child_dispatcher =
{ _ep, *this, &Main::_handle_exited_child };
Signal_handler<Main> _exited_child_handler =
{ _env.ep(), *this, &Main::_handle_exited_child };
Subsystem_manager _subsystem_manager { _ep, _cap, _exited_child_dispatcher,
_ldso_ds };
Attached_rom_dataspace _config { _env, "config" };
Panel_dialog _panel_dialog { _ep, _cap, *env()->ram_session(), _ldso_ds,
*env()->heap(),
_report_rom_slave, _subsystem_manager, _nitpicker };
static size_t _ram_preservation(Xml_node config)
{
char const * const node_name = "preservation";
void _handle_config(unsigned);
if (config.has_sub_node(node_name)) {
void _handle_exited_child(unsigned)
Xml_node const node = config.sub_node(node_name);
if (node.attribute_value("name", Genode::String<16>()) == "RAM")
return node.attribute_value("quantum", Genode::Number_of_bytes());
}
return 0;
}
Subsystem_manager _subsystem_manager { _env.ep(), _env.pd(),
_ram_preservation(_config.xml()),
_exited_child_handler };
Heap _heap { _env.ram(), _env.rm() };
Panel_dialog _panel_dialog { _env, _heap, _report_rom_slave,
_subsystem_manager, _nitpicker };
void _handle_config();
void _handle_exited_child()
{
auto kill_child_fn = [&] (Label const &label) { _panel_dialog.kill(label); };
@ -92,37 +100,40 @@ struct Launcher::Main
Genode::Attached_rom_dataspace _focus_rom { "focus" };
void _handle_focus_update(unsigned);
void _handle_focus_update();
Genode::Signal_rpc_member<Main> _focus_update_dispatcher =
{ _ep, *this, &Main::_handle_focus_update };
Signal_handler<Main> _focus_update_handler =
{ _env.ep(), *this, &Main::_handle_focus_update };
/**
* Constructor
*/
Main(Server::Entrypoint &ep) : _ep(ep)
Main(Env &env) : _env(env)
{
_nitpicker.input()->sigh(_input_dispatcher);
_focus_rom.sigh(_focus_update_dispatcher);
_nitpicker.input()->sigh(_input_handler);
_focus_rom.sigh(_focus_update_handler);
_handle_config(0);
_handle_config();
_panel_dialog.visible(true);
}
};
void Launcher::Main::_handle_config(unsigned)
void Launcher::Main::_handle_config()
{
config()->reload();
_config.update();
_focus_prefix = config()->xml_node().attribute_value("focus_prefix", Label());
_focus_prefix = _config.xml().attribute_value("focus_prefix", Label());
_panel_dialog.update(config()->xml_node());
try {
_panel_dialog.update(_config.xml()); }
catch (Allocator::Out_of_memory) {
error("out of memory while applying configuration"); }
}
void Launcher::Main::_handle_input(unsigned)
void Launcher::Main::_handle_input()
{
_nitpicker.input()->for_each_event([&] (Input::Event const &e) {
if (e.type() == Input::Event::PRESS) _key_cnt++;
@ -143,7 +154,7 @@ void Launcher::Main::_handle_input(unsigned)
}
void Launcher::Main::_handle_focus_update(unsigned)
void Launcher::Main::_handle_focus_update()
{
try {
_focus_rom.update();
@ -176,18 +187,4 @@ void Launcher::Main::_handle_focus_update(unsigned)
}
/************
** Server **
************/
namespace Server {
char const *name() { return "desktop_ep"; }
size_t stack_size() { return 4*1024*sizeof(long); }
void construct(Entrypoint &ep)
{
static Launcher::Main desktop(ep);
}
}
void Component::construct(Genode::Env &env) { static Launcher::Main main(env); }

View File

@ -103,18 +103,14 @@ class Launcher::Menu_dialog : Input_event_handler, Dialog_generator,
public:
Menu_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
Dataspace_capability ldso_ds,
Menu_dialog(Env &env,
Report_rom_slave &report_rom_slave,
Response_handler &response_handler)
:
_response_handler(response_handler),
_dialog(ep, cap, ram, ldso_ds, report_rom_slave,
"menu_dialog", "menu_hover",
*this, *this, *this, *this,
_position)
{
}
_dialog(env, report_rom_slave, "menu_dialog", "menu_hover",
*this, *this, *this, *this, _position)
{ }
/**
* Dialog_generator interface

View File

@ -19,7 +19,7 @@
#include <nitpicker_session/nitpicker_session.h>
/* gems includes */
#include <gems/single_session_service.h>
#include <os/single_session_service.h>
/* local includes */
#include <types.h>
@ -35,16 +35,13 @@ class Launcher::Menu_view_slave
private:
class Policy : public Genode::Slave_policy
class Policy : public Genode::Slave::Policy
{
private:
Lock mutable _nitpicker_root_lock { Lock::LOCKED };
Capability<Root> _nitpicker_root_cap;
Single_session_service _nitpicker_service;
Single_session_service _dialog_rom_service;
Single_session_service _hover_report_service;
Genode::Single_session_service<Nitpicker::Session> _nitpicker;
Genode::Single_session_service<Genode::Rom_session> _dialog_rom;
Genode::Single_session_service<Report::Session> _hover_report;
Position _position;
@ -53,7 +50,7 @@ class Launcher::Menu_view_slave
char const **_permitted_services() const
{
static char const *permitted_services[] = {
"ROM", "LOG", "RM", "Timer", 0 };
"CPU", "PD", "RAM", "ROM", "LOG", "Timer", 0 };
return permitted_services;
};
@ -78,82 +75,70 @@ class Launcher::Menu_view_slave
configure(config);
}
static Name _name() { return "menu_view"; }
static Genode::size_t _quota() { return 6*1024*1024; }
public:
Policy(Genode::Rpc_entrypoint &entrypoint,
Genode::Ram_session &ram,
Policy(Genode::Rpc_entrypoint &ep,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
Capability<Nitpicker::Session> nitpicker_session,
Capability<Rom_session> dialog_rom_session,
Capability<Report::Session> hover_report_session,
Position position)
:
Slave_policy("menu_view", entrypoint, &ram),
_nitpicker_service(Nitpicker::Session::service_name(), nitpicker_session),
_dialog_rom_service(Rom_session::service_name(), dialog_rom_session),
_hover_report_service(Report::Session::service_name(), hover_report_session),
Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota()),
_nitpicker(nitpicker_session),
_dialog_rom(dialog_rom_session),
_hover_report(hover_report_session),
_position(position)
{
_configure(position);
}
void position(Position pos)
void position(Position pos) { _configure(pos); }
Genode::Service &resolve_session_request(Genode::Service::Name const &service,
Genode::Session_state::Args const &args) override
{
_configure(pos);
}
if (service == "Nitpicker")
return _nitpicker.service();
Genode::Service *resolve_session_request(const char *service_name,
const char *args) override
{
using Genode::strcmp;
Genode::Session_label const label(label_from_args(args.string()));
if (strcmp(service_name, "Nitpicker") == 0)
return &_nitpicker_service;
if ((service == "ROM") && (label == "menu_view -> dialog"))
return _dialog_rom.service();
char label[128];
Arg_string::find_arg(args, "label").string(label, sizeof(label), "");
if ((service == "Report") && (label == "menu_view -> hover"))
return _hover_report.service();
if (strcmp(service_name, "ROM") == 0) {
if (strcmp(label, "menu_view -> dialog") == 0)
return &_dialog_rom_service;
}
if (strcmp(service_name, "Report") == 0) {
if (strcmp(label, "menu_view -> hover") == 0)
return &_hover_report_service;
}
return Genode::Slave_policy::resolve_session_request(service_name, args);
return Genode::Slave::Policy::resolve_session_request(service, args);
}
};
Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t);
Genode::Rpc_entrypoint _ep;
Policy _policy;
Genode::size_t const _quota = 6*1024*1024;
Genode::Slave _slave;
Genode::Child _child;
public:
/**
* Constructor
*
* \param ep entrypoint used for child thread
* \param ram RAM session used to allocate the configuration
* dataspace
*/
Menu_view_slave(Genode::Cap_session &cap, Genode::Ram_session &ram,
Genode::Dataspace_capability ldso_ds,
Menu_view_slave(Genode::Pd_session &pd,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
Capability<Nitpicker::Session> nitpicker_session,
Capability<Rom_session> dialog_rom_session,
Capability<Report::Session> hover_report_session,
Position initial_position)
:
_ep(&cap, _ep_stack_size, "nit_fader"),
_policy(_ep, ram, nitpicker_session, dialog_rom_session,
_ep(&pd, _ep_stack_size, "nit_fader"),
_policy(_ep, rm, ram, nitpicker_session, dialog_rom_session,
hover_report_session, initial_position),
_slave(_ep, _policy, _quota, env()->ram_session_cap(), ldso_ds)
_child(rm, _ep, _policy)
{ }
void position(Position position) { _policy.position(position); }

View File

@ -28,31 +28,33 @@ class Launcher::Nit_fader_slave
{
private:
class Policy : public Slave_policy
class Policy : public Slave::Policy
{
private:
Genode::Service &_nitpicker_service;
Lock mutable _nitpicker_root_lock { Lock::LOCKED };
Capability<Root> _nitpicker_root_cap;
protected:
char const **_permitted_services() const
{
static char const *permitted_services[] = {
"LOG", "RM", "Timer", 0 };
"RAM", "CPU", "PD", "LOG", "Timer", 0 };
return permitted_services;
};
static Name _name() { return "nit_fader"; }
static size_t _quota() { return 2*1024*1024; }
public:
Policy(Rpc_entrypoint &entrypoint,
Ram_session &ram,
Genode::Service &nitpicker_service)
Policy(Rpc_entrypoint &ep,
Region_map &rm,
Ram_session_capability ram,
Genode::Service &nitpicker_service)
:
Slave_policy("nit_fader", entrypoint, &ram),
Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota()),
_nitpicker_service(nitpicker_service)
{
visible(false);
@ -66,42 +68,18 @@ class Launcher::Nit_fader_slave
configure(config, strlen(config) + 1);
}
bool announce_service(const char *service_name,
Root_capability root,
Allocator *,
Genode::Server *)
Genode::Service &resolve_session_request(Genode::Service::Name const &service,
Genode::Session_state::Args const &args) override
{
if (strcmp(service_name, "Nitpicker") == 0)
_nitpicker_root_cap = root;
else
return false;
if (service == Nitpicker::Session::service_name())
return _nitpicker_service;
if (_nitpicker_root_cap.valid())
_nitpicker_root_lock.unlock();
return true;
}
Genode::Service *resolve_session_request(const char *service_name,
const char *args) override
{
if (Genode::strcmp(service_name, "Nitpicker") == 0)
return &_nitpicker_service;
return Genode::Slave_policy::resolve_session_request(service_name, args);
}
Root_capability nitpicker_root() const
{
Lock::Guard guard(_nitpicker_root_lock);
return _nitpicker_root_cap;
return Genode::Slave::Policy::resolve_session_request(service, args);
}
};
Policy _policy;
size_t const _quota = 2*1024*1024;
Slave _slave;
Root_client _nitpicker_root;
Policy _policy;
Child _child;
public:
@ -112,38 +90,18 @@ class Launcher::Nit_fader_slave
* \param ram RAM session used to allocate the configuration
* dataspace
*/
Nit_fader_slave(Rpc_entrypoint &ep, Ram_session &ram,
Genode::Service &nitpicker_service,
Genode::Dataspace_capability ldso_ds)
Nit_fader_slave(Rpc_entrypoint &ep,
Genode::Region_map &rm,
Ram_session_capability ram,
Genode::Service &nitpicker_service)
:
_policy(ep, ram, nitpicker_service),
_slave(ep, _policy, _quota, env()->ram_session_cap(), ldso_ds),
_nitpicker_root(_policy.nitpicker_root())
_policy(ep, rm, ram, nitpicker_service),
_child(rm, ep, _policy)
{
visible(false);
}
Capability<Nitpicker::Session> nitpicker_session(char const *label)
{
enum { ARGBUF_SIZE = 128 };
char argbuf[ARGBUF_SIZE];
argbuf[0] = 0;
/*
* Declare ram-quota donation
*/
enum { SESSION_METADATA = 8*1024 };
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA);
/*
* Set session label
*/
Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label);
Session_capability session_cap = _nitpicker_root.session(argbuf, Affinity());
return static_cap_cast<Nitpicker::Session>(session_cap);
}
Genode::Slave::Policy &policy() { return _policy; }
void visible(bool visible)
{

View File

@ -50,6 +50,39 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
Genode::Allocator &_alloc;
struct Buffered_xml
{
Allocator &_alloc;
char const * const _ptr; /* pointer to dynamically allocated buffer */
Xml_node const _xml; /* referring to buffer of '_ptr' */
/**
* \throw Allocator::Out_of_memory
*/
static char const *_init_ptr(Allocator &alloc, Xml_node node)
{
char *ptr = (char *)alloc.alloc(node.size());
Genode::memcpy(ptr, node.addr(), node.size());
return ptr;
}
/**
* Constructor
*
* \throw Allocator::Out_of_memory
*/
Buffered_xml(Allocator &alloc, Xml_node node)
:
_alloc(alloc), _ptr(_init_ptr(alloc, node)), _xml(_ptr, node.size())
{ }
~Buffered_xml() { _alloc.free(const_cast<char *>(_ptr), _xml.size()); }
Xml_node xml() const { return _xml; }
};
Lazy_volatile_object<Buffered_xml> _config;
List<Element> _elements;
Label _focus;
@ -135,7 +168,7 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
Element *_clicked = nullptr;
bool _click_in_progress = false;
Signal_rpc_member<Panel_dialog> _timer_dispatcher;
Signal_handler<Panel_dialog> _timer_handler;
Label _context_subsystem;
Context_dialog _context_dialog;
@ -165,9 +198,13 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
void _start(Label const &label)
{
if (!_config.constructed()) {
warning("attempt to start subsystem without prior configuration");
return;
}
try {
Xml_node subsystem = _subsystem(config()->xml_node(),
label.string());
Xml_node subsystem = _subsystem(_config->xml(), label.string());
_subsystem_manager.start(subsystem);
Title const title = subsystem.attribute_value("title", Title());
@ -232,7 +269,7 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
_context_dialog.visible(true);
}
void _handle_timer(unsigned)
void _handle_timer()
{
if (_click_in_progress && _clicked && _hovered() == _clicked) {
_open_context_dialog(_clicked->label);
@ -250,26 +287,23 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
public:
Panel_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram,
Dataspace_capability ldso_ds,
Genode::Allocator &alloc,
Report_rom_slave &report_rom_slave,
Subsystem_manager &subsystem_manager,
Panel_dialog(Env &env,
Genode::Allocator &alloc,
Report_rom_slave &report_rom_slave,
Subsystem_manager &subsystem_manager,
Nitpicker::Session &nitpicker)
:
_alloc(alloc),
_subsystem_manager(subsystem_manager),
_nitpicker(nitpicker),
_dialog(ep, cap, ram, ldso_ds, report_rom_slave,
"panel_dialog", "panel_hover",
*this, *this, *this, *this,
_position),
_timer_dispatcher(ep, *this, &Panel_dialog::_handle_timer),
_context_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this),
_menu_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this)
_dialog(env, report_rom_slave, "panel_dialog", "panel_hover",
*this, *this, *this, *this, _position),
_timer_handler(env.ep(), *this, &Panel_dialog::_handle_timer),
_context_dialog(env, report_rom_slave, *this),
_menu_dialog(env, report_rom_slave, *this)
{
_elements.insert(&_menu_button);
_timer.sigh(_timer_dispatcher);
_timer.sigh(_timer_handler);
}
/**
@ -514,13 +548,17 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator,
_kill(label);
}
/**
* \throw Allocator::Out_of_memory
*/
void update(Xml_node config)
{
_config.construct(_alloc, config);
/* populate menu dialog with one item per subsystem */
_menu_dialog.update(config);
_menu_dialog.update(_config->xml());
/* evaluate configuration */
_dialog.update();
}

View File

@ -25,28 +25,7 @@ namespace Launcher {
class Subsystem_manager;
using Decorator::string_attribute;
}
/***************
** Utilities **
***************/
/*
* XXX copied from 'cli_monitor/main.cc'
*/
static Genode::size_t ram_preservation_from_config()
{
Genode::Number_of_bytes ram_preservation = 0;
try {
Genode::Xml_node node =
Genode::config()->xml_node().sub_node("preservation");
if (node.attribute("name").has_value("RAM"))
node.attribute("quantum").value(&ram_preservation);
} catch (...) { }
return ram_preservation;
using namespace Genode;
}
@ -61,34 +40,15 @@ class Launcher::Subsystem_manager
private:
Server::Entrypoint &_ep;
Cap_session &_cap;
Dataspace_capability _ldso_ds;
Entrypoint &_ep;
Pd_session &_pd;
size_t const _ram_preservation;
struct Child : Child_base, List<Child>::Element
{
typedef String<128> Binary_name;
Child(Ram &ram,
Label const &label,
Binary_name const &binary,
Cap_session &cap_session,
size_t ram_quota,
size_t ram_limit,
Signal_context_capability yield_response_sig_cap,
Signal_context_capability exit_sig_cap,
Dataspace_capability ldso_ds)
:
Child_base(ram,
label.string(),
binary.string(),
cap_session,
ram_quota,
ram_limit,
yield_response_sig_cap,
exit_sig_cap,
ldso_ds)
{ }
template <typename... ARGS>
Child(ARGS &&... args) : Child_base(args...) { }
};
List<Child> _children;
@ -99,10 +59,10 @@ class Launcher::Subsystem_manager
child->try_response_to_resource_request();
}
Genode::Signal_rpc_member<Subsystem_manager> _yield_broadcast_dispatcher =
Signal_handler<Subsystem_manager> _yield_broadcast_handler =
{ _ep, *this, &Subsystem_manager::_handle_yield_broadcast };
void _handle_yield_broadcast(unsigned)
void _handle_yield_broadcast()
{
_try_response_to_resource_request();
@ -129,27 +89,27 @@ class Launcher::Subsystem_manager
child->yield(amount, true);
}
Genode::Signal_rpc_member<Subsystem_manager> _resource_avail_dispatcher =
Signal_handler<Subsystem_manager> _resource_avail_handler =
{ _ep, *this, &Subsystem_manager::_handle_resource_avail };
void _handle_resource_avail(unsigned)
void _handle_resource_avail()
{
_try_response_to_resource_request();
}
Genode::Signal_rpc_member<Subsystem_manager> _yield_response_dispatcher =
Signal_handler<Subsystem_manager> _yield_response_handler =
{ _ep, *this, &Subsystem_manager::_handle_yield_response };
void _handle_yield_response(unsigned)
void _handle_yield_response()
{
_try_response_to_resource_request();
}
Genode::Signal_context_capability _exited_child_sig_cap;
Ram _ram { ram_preservation_from_config(),
_yield_broadcast_dispatcher,
_resource_avail_dispatcher };
Ram _ram { _ram_preservation,
_yield_broadcast_handler,
_resource_avail_handler };
static Child::Binary_name _binary_name(Xml_node subsystem)
{
@ -187,11 +147,11 @@ class Launcher::Subsystem_manager
public:
Subsystem_manager(Server::Entrypoint &ep, Cap_session &cap,
Genode::Signal_context_capability exited_child_sig_cap,
Dataspace_capability ldso_ds)
Subsystem_manager(Genode::Entrypoint &ep, Pd_session &pd,
size_t ram_preservation,
Genode::Signal_context_capability exited_child_sig_cap)
:
_ep(ep), _cap(cap), _ldso_ds(ldso_ds),
_ep(ep), _pd(pd), _ram_preservation(ram_preservation),
_exited_child_sig_cap(exited_child_sig_cap)
{ }
@ -213,10 +173,14 @@ class Launcher::Subsystem_manager
try {
Child *child = new (env()->heap())
Child(_ram, label, binary_name.string(), _cap,
Child(_ram, label, binary_name.string(),
*Genode::env()->pd_session(),
*Genode::env()->ram_session(),
Genode::env()->ram_session_cap(),
*Genode::env()->rm_session(),
ram_config.quantum, ram_config.limit,
_yield_broadcast_dispatcher,
_exited_child_sig_cap, _ldso_ds);
_yield_broadcast_handler,
_exited_child_sig_cap);
/* configure child */
try {
@ -228,8 +192,8 @@ class Launcher::Subsystem_manager
child->start();
} catch (Rom_connection::Rom_connection_failed) {
Genode::error("binary \"", binary_name, "\" is missing");
} catch (Parent::Service_denied) {
Genode::error("failed to start ", binary_name);
throw Invalid_config();
}
}

View File

@ -1,4 +1,4 @@
TARGET = launcher
SRC_CC = main.cc
LIBS = base server config
LIBS = base
INC_DIR += $(PRG_DIR)

View File

@ -118,7 +118,7 @@ struct Decorator::Main : Window_factory_base
* and view_handle operations. Currently, these exceptions will
* abort the decorator.
*/
Genode::env()->parent()->upgrade(nitpicker, "ram_quota=256K");
nitpicker.upgrade_ram(256*1024);
Genode::config()->sigh(config_dispatcher);
handle_config(0);

View File

@ -499,15 +499,11 @@ namespace Terminal {
}
extern "C" void wait_for_continue();
int main(int, char **)
{
using namespace Genode;
log("--- terminal service started ---");
wait_for_continue();
static Framebuffer::Connection framebuffer;
static Input::Connection input;

View File

@ -737,7 +737,7 @@ int main(int, char **)
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
static Registry registry;
static ::Registry registry;
static Ncurses ncurses;
static Status_window status_window(ncurses);
static Menu menu(ncurses, registry, status_window);

View File

@ -352,7 +352,8 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
void upgrade(const char *args)
{
Genode::env()->parent()->upgrade(_nitpicker_session, args);
size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
_nitpicker_session.upgrade_ram(ram_quota);
}

View File

@ -40,7 +40,8 @@ class Wm::Direct_nitpicker_session : public Genode::Rpc_object<Nitpicker::Sessio
void upgrade(char const *args)
{
Genode::env()->parent()->upgrade(_session, args);
size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
_session.upgrade_ram(ram_quota);
}

View File

@ -737,7 +737,8 @@ class Wm::Nitpicker::Session_component : public Rpc_object<Nitpicker::Session>,
void upgrade(char const *args)
{
Genode::env()->parent()->upgrade(_session, args);
size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
_session.upgrade_ram(ram_quota);
}
void try_to_init_real_child_views()

View File

@ -0,0 +1,24 @@
/*
* \brief Port of ACPICA library
* \author Alexander Boettcher
* \date 2016-11-14
*/
/*
* Copyright (C) 2016 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__ACPICA__ACPICA_H_
#define _INCLUDE__ACPICA__ACPICA_H_
namespace Genode {
struct Env;
struct Allocator;
}
namespace Acpica { void init(Genode::Env &env, Genode::Allocator &heap); }
#endif /* _INCLUDE__ACPICA__ACPICA_H_ */

View File

@ -0,0 +1,2 @@
INC_DIR += $(call select_from_ports,acpica)/src/lib/acpica/source/include
CC_OPT += -DACPI_INLINE=inline -Wno-unused-variable

View File

@ -3,8 +3,6 @@ REQUIRES := x86
ACPICA_DIR := $(call select_from_ports,acpica)/src/lib/acpica
ACPICA_COMP := $(ACPICA_DIR)/source/components
INC_DIR += $(ACPICA_DIR)/source/include
SRC_C += debugger/dbdisply.c debugger/dbobject.c debugger/dbxface.c
SRC_C += $(addprefix disassembler/, $(notdir $(wildcard $(ACPICA_COMP)/disassembler/*.c)))
SRC_C += $(addprefix dispatcher/, $(notdir $(wildcard $(ACPICA_COMP)/dispatcher/*.c)))
@ -17,10 +15,10 @@ SRC_C += $(addprefix resources/, $(notdir $(wildcard $(ACPICA_COMP)/resources/*.
SRC_C += $(addprefix tables/, $(notdir $(wildcard $(ACPICA_COMP)/tables/*.c)))
SRC_C += $(addprefix utilities/, $(notdir $(wildcard $(ACPICA_COMP)/utilities/*.c)))
SRC_CC += osl.cc iomem.cc pci.cc
SRC_CC += scan_root.cc
SRC_CC += osl.cc iomem.cc pci.cc scan_root.cc env.cc
include $(REP_DIR)/lib/import/import-acpica.mk
CC_OPT += -Wno-unused-function -Wno-unused-variable
CC_C_OPT += -DACPI_LIBRARY
vpath %.c $(ACPICA_COMP)

View File

@ -1 +1 @@
a3d820f28b860fdd9fd8c855f0fa2ec0b4beb859
cd8c5b5513ba384e52be2cfc54ee4435439b57d2

View File

@ -103,7 +103,7 @@ append_platform_drv_config
append_if $use_nic_driver config {
<start name="nic_drv">
<resource name="RAM" quantum="4M"/>
<resource name="RAM" quantum="6M"/>
<provides><service name="Nic"/></provides>
</start>}

View File

@ -145,8 +145,9 @@ proc drivers_start_nodes { feature_arg } {
append_if [use_audio_drv feature] start_nodes {
<start name="audio_drv">
<resource name="RAM" quantum="4M"/>
<resource name="RAM" quantum="8M"/>
<provides><service name="Audio_out"/></provides>
<config/>
</start>
}
@ -177,7 +178,7 @@ proc drivers_start_nodes { feature_arg } {
append_if [use_nic_drv feature] start_nodes {
<start name="nic_drv">
<resource name="RAM" quantum="4M"/>
<resource name="RAM" quantum="8M"/>
<provides><service name="Nic"/></provides>
</start>
}

View File

@ -14,16 +14,19 @@
#include <base/component.h>
#include <base/log.h>
#include <base/signal.h>
#include <base/heap.h>
#include <irq_session/connection.h>
#include <io_port_session/connection.h>
#include <os/attached_rom_dataspace.h>
#include <os/config.h>
#include <os/reporter.h>
#include <util/volatile_object.h>
#include <util/xml_node.h>
#include <acpica/acpica.h>
extern "C" {
#include "acpi.h"
#include "accommon.h"
@ -46,7 +49,149 @@ namespace Acpica {
#include "ec.h"
static void init_acpica(Acpica::Reportstate *report) {
struct Acpica::Statechange
{
Genode::Signal_handler<Acpica::Statechange> _dispatcher;
Genode::Attached_rom_dataspace _system_state;
bool _enable_reset;
bool _enable_poweroff;
Statechange(Genode::Entrypoint &ep, bool reset, bool poweroff)
:
_dispatcher(ep, *this, &Statechange::state_changed),
_system_state("system"),
_enable_reset(reset), _enable_poweroff(poweroff)
{
_system_state.sigh(_dispatcher);
state_changed();
}
void state_changed() {
_system_state.update();
if (!_system_state.is_valid()) return;
Genode::Xml_node system(_system_state.local_addr<char>(),
_system_state.size());
Genode::String<32> state;
system.attribute("state").value<32>(&state);
if (_enable_poweroff && state == "poweroff") {
ACPI_STATUS res0 = AcpiEnterSleepStatePrep(5);
ACPI_STATUS res1 = AcpiEnterSleepState(5);
Genode::error("system poweroff failed - "
"res=", Genode::Hex(res0), ",", Genode::Hex(res1));
return;
}
if (_enable_reset && state == "reset") {
ACPI_STATUS res = AE_OK;
try {
res = AcpiReset();
} catch (...) { }
Genode::uint64_t const space_addr = AcpiGbl_FADT.ResetRegister.Address;
Genode::error("system reset failed - "
"err=", res, " "
"reset=", !!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER), " "
"spaceid=", Genode::Hex(AcpiGbl_FADT.ResetRegister.SpaceId), " "
"addr=", Genode::Hex(space_addr));
}
}
};
struct Acpica::Main
{
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
Genode::Attached_rom_dataspace config { env, "config" };
Genode::Signal_handler<Acpica::Main> sci_irq;
Genode::Lazy_volatile_object<Genode::Irq_connection> sci_conn;
Acpica::Reportstate * report = nullptr;
static struct Irq_handler {
UINT32 irq;
ACPI_OSD_HANDLER handler;
void *context;
} irq_handler;
void init_acpica();
Main(Genode::Env &env)
:
env(env),
sci_irq(env.ep(), *this, &Main::acpi_irq)
{
bool const enable_reset = config.xml().attribute_value("reset", false);
bool const enable_poweroff = config.xml().attribute_value("poweroff", false);
bool const enable_report = config.xml().attribute_value("report", false);
bool const enable_ready = config.xml().attribute_value("acpi_ready", false);
if (enable_report)
report = new (heap) Acpica::Reportstate();
init_acpica();
if (enable_report)
report->enable();
if (enable_reset || enable_poweroff)
new (heap) Acpica::Statechange(env.ep(), enable_reset,
enable_poweroff);
/* setup IRQ */
if (!irq_handler.handler) {
Genode::warning("no IRQ handling available");
return;
}
sci_conn.construct(irq_handler.irq);
Genode::log("SCI IRQ: ", irq_handler.irq);
sci_conn->sigh(sci_irq);
sci_conn->ack_irq();
if (!enable_ready)
return;
/* we are ready - signal it via changing system state */
static Genode::Reporter _system_rom { "system", "acpi_ready" };
_system_rom.enabled(true);
Genode::Reporter::Xml_generator xml(_system_rom, [&] () {
xml.attribute("state", "acpi_ready");
});
}
void acpi_irq()
{
if (!irq_handler.handler)
return;
UINT32 res = irq_handler.handler(irq_handler.context);
sci_conn->ack_irq();
AcpiOsWaitEventsComplete();
if (report)
report->generate_report();
if (res == ACPI_INTERRUPT_HANDLED)
return;
}
};
void Acpica::Main::init_acpica()
{
Acpica::init(env, heap);
/* enable debugging: */
/* AcpiDbgLevel |= ACPI_LV_IO | ACPI_LV_INTERRUPTS | ACPI_LV_INIT_NAMES; */
@ -107,7 +252,7 @@ static void init_acpica(Acpica::Reportstate *report) {
}
/* note: ACPI_EVENT_PMTIMER claimed by nova kernel - not usable by us */
Fixed * acpi_fixed = new (Genode::env()->heap()) Fixed(report);
Fixed * acpi_fixed = new (heap) Fixed(report);
status = AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON,
Fixed::handle_power_button,
@ -144,138 +289,6 @@ static void init_acpica(Acpica::Reportstate *report) {
}
}
struct Acpica::Statechange
{
Genode::Signal_handler<Acpica::Statechange> _dispatcher;
Genode::Attached_rom_dataspace _system_state;
bool _enable_reset;
bool _enable_poweroff;
Statechange(Genode::Entrypoint &ep, bool reset, bool poweroff)
:
_dispatcher(ep, *this, &Statechange::state_changed),
_system_state("system"),
_enable_reset(reset), _enable_poweroff(poweroff)
{
_system_state.sigh(_dispatcher);
state_changed();
}
void state_changed() {
_system_state.update();
if (!_system_state.is_valid()) return;
Genode::Xml_node system(_system_state.local_addr<char>(),
_system_state.size());
Genode::String<32> state;
system.attribute("state").value<32>(&state);
if (_enable_poweroff && state == "poweroff") {
ACPI_STATUS res0 = AcpiEnterSleepStatePrep(5);
ACPI_STATUS res1 = AcpiEnterSleepState(5);
Genode::error("system poweroff failed - "
"res=", Genode::Hex(res0), ",", Genode::Hex(res1));
return;
}
if (_enable_reset && state == "reset") {
ACPI_STATUS res = AE_OK;
try {
res = AcpiReset();
} catch (...) { }
Genode::uint64_t const space_addr = AcpiGbl_FADT.ResetRegister.Address;
Genode::error("system reset failed - "
"err=", res, " "
"reset=", !!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER), " "
"spaceid=", Genode::Hex(AcpiGbl_FADT.ResetRegister.SpaceId), " "
"addr=", Genode::Hex(space_addr));
}
}
};
struct Acpica::Main {
Genode::Signal_handler<Acpica::Main> _sci_irq;
Genode::Lazy_volatile_object<Genode::Irq_connection> _sci_conn;
Acpica::Reportstate * _report = nullptr;
static struct Irq_handler {
UINT32 irq;
ACPI_OSD_HANDLER handler;
void *context;
} irq_handler;
Main(Genode::Env &env)
:
_sci_irq(env.ep(), *this, &Main::acpi_irq)
{
bool enable_reset = Genode::config()->xml_node().attribute_value("reset", false);
bool enable_poweroff = Genode::config()->xml_node().attribute_value("poweroff", false);
bool enable_report = Genode::config()->xml_node().attribute_value("report", false);
bool enable_ready = Genode::config()->xml_node().attribute_value("acpi_ready", false);
if (enable_report)
_report = new (Genode::env()->heap()) Acpica::Reportstate();
init_acpica(_report);
if (enable_report)
_report->enable();
if (enable_reset || enable_poweroff)
new (Genode::env()->heap()) Acpica::Statechange(env.ep(), enable_reset,
enable_poweroff);
/* setup IRQ */
if (!irq_handler.handler) {
Genode::warning("no IRQ handling available");
return;
}
_sci_conn.construct(irq_handler.irq);
Genode::log("SCI IRQ: ", irq_handler.irq);
_sci_conn->sigh(_sci_irq);
_sci_conn->ack_irq();
if (!enable_ready)
return;
/* we are ready - signal it via changing system state */
const char * system_file = "system";
static Genode::Reporter _system_rom { "system", "acpi_ready" };
_system_rom.enabled(true);
Genode::Reporter::Xml_generator xml(_system_rom, [&] () {
xml.attribute("state", "acpi_ready");
});
}
void acpi_irq()
{
if (!irq_handler.handler)
return;
UINT32 res = irq_handler.handler(irq_handler.context);
_sci_conn->ack_irq();
AcpiOsWaitEventsComplete();
if (_report)
_report->generate_report();
if (res == ACPI_INTERRUPT_HANDLED)
return;
}
};
struct Acpica::Main::Irq_handler Acpica::Main::irq_handler;

View File

@ -1,8 +1,3 @@
REQUIRES := x86
LIBS += base acpica config
CC_OPT += -Wno-unused-function -Wno-unused-variable
CC_C_OPT += -DACPI_LIBRARY
INC_DIR += $(call select_from_ports,acpica)/src/lib/acpica/source/include
LIBS += base acpica

View File

@ -1,133 +0,0 @@
/*
* \brief Avplay policy
* \author Christian Prochaska
* \date 2012-04-05
*/
/*
* Copyright (C) 2012-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 _AVPLAY_POLICY_H_
#define _AVPLAY_POLICY_H_
/* Qt includes */
#include <QDebug>
#include <QObject>
#include <QDomDocument>
#include <QDomElement>
#include <QDomText>
/* Genode includes */
#include <os/slave.h>
class Avplay_policy : public QObject, public Genode::Slave_policy
{
Q_OBJECT
private:
Genode::Service_registry &_input_in;
Genode::Service_registry &_framebuffer_in;
const char *_mediafile;
int _sdl_audio_volume;
QByteArray _config_byte_array;
const char *_config()
{
QDomDocument config_doc;
QDomElement config_node = config_doc.createElement("config");
config_doc.appendChild(config_node);
QDomElement arg0_node = config_doc.createElement("arg");
arg0_node.setAttribute("value", "avplay");
config_node.appendChild(arg0_node);
QDomElement arg1_node = config_doc.createElement("arg");
arg1_node.setAttribute("value", _mediafile);
config_node.appendChild(arg1_node);
/*
* Configure libc of avplay to direct output to LOG and to obtain
* the mediafile from ROM.
*/
QDomElement libc_node = config_doc.createElement("libc");
libc_node.setAttribute("stdout", "/dev/log");
libc_node.setAttribute("stderr", "/dev/log");
QDomElement libc_vfs_node = config_doc.createElement("vfs");
QDomElement libc_vfs_dev_node = config_doc.createElement("dir");
libc_vfs_dev_node.setAttribute("name", "dev");
QDomElement libc_vfs_dev_log_node = config_doc.createElement("log");
libc_vfs_dev_node.appendChild(libc_vfs_dev_log_node);
libc_vfs_node.appendChild(libc_vfs_dev_node);
QDomElement libc_vfs_mediafile_node = config_doc.createElement("rom");
libc_vfs_mediafile_node.setAttribute("name", "mediafile");
libc_vfs_node.appendChild(libc_vfs_mediafile_node);
libc_node.appendChild(libc_vfs_node);
config_node.appendChild(libc_node);
QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume");
sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume));
config_node.appendChild(sdl_audio_volume_node);
_config_byte_array = config_doc.toByteArray(4);
return _config_byte_array.constData();
}
protected:
const char **_permitted_services() const
{
static const char *permitted_services[] = {
"LOG", "RM", "ROM", "Timer", "Audio_out", 0 };
return permitted_services;
};
public:
Avplay_policy(Genode::Rpc_entrypoint &entrypoint,
Genode::Service_registry &input_in,
Genode::Service_registry &framebuffer_in,
const char *mediafile)
: Genode::Slave_policy("avplay", entrypoint, Genode::env()->ram_session()),
_input_in(input_in),
_framebuffer_in(framebuffer_in),
_mediafile(mediafile),
_sdl_audio_volume(100)
{
configure(_config());
}
Genode::Service *resolve_session_request(const char *service_name,
const char *args)
{
if (strcmp(service_name, "Input") == 0)
return _input_in.find(service_name);
if (strcmp(service_name, "Framebuffer") == 0) {
Genode::Client client;
return _framebuffer_in.wait_for_service(service_name, &client, name());
}
return Slave_policy::resolve_session_request(service_name, args);
}
public Q_SLOTS:
void volume_changed(int value)
{
_sdl_audio_volume = value;
configure(_config());
}
};
#endif /* _AVPLAY_POLICY_H_ */

View File

@ -0,0 +1,175 @@
/*
* \brief Avplay slave
* \author Christian Prochaska
* \date 2012-04-05
*/
/*
* Copyright (C) 2012-2016 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 _AVPLAY_SLAVE_H_
#define _AVPLAY_SLAVE_H_
/* Qt includes */
#include <QDebug>
#include <QObject>
#include <QDomDocument>
#include <QDomElement>
#include <QDomText>
/* Genode includes */
#include <input/component.h>
#include <os/slave.h>
/* local includes */
#include "framebuffer_service_factory.h"
typedef Genode::Local_service<Input::Session_component> Input_service;
class Avplay_slave : public QObject
{
Q_OBJECT
private:
class Policy : public Genode::Slave::Policy
{
private:
Input_service &_input_service;
Framebuffer_service_factory &_framebuffer_service_factory;
const char *_mediafile;
int _sdl_audio_volume;
QByteArray _config_byte_array;
const char *_config()
{
QDomDocument config_doc;
QDomElement config_node = config_doc.createElement("config");
config_doc.appendChild(config_node);
QDomElement arg0_node = config_doc.createElement("arg");
arg0_node.setAttribute("value", "avplay");
config_node.appendChild(arg0_node);
QDomElement arg1_node = config_doc.createElement("arg");
arg1_node.setAttribute("value", _mediafile);
config_node.appendChild(arg1_node);
/*
* Configure libc of avplay to direct output to LOG and to obtain
* the mediafile from ROM.
*/
QDomElement libc_node = config_doc.createElement("libc");
libc_node.setAttribute("stdout", "/dev/log");
libc_node.setAttribute("stderr", "/dev/log");
QDomElement libc_vfs_node = config_doc.createElement("vfs");
QDomElement libc_vfs_dev_node = config_doc.createElement("dir");
libc_vfs_dev_node.setAttribute("name", "dev");
QDomElement libc_vfs_dev_log_node = config_doc.createElement("log");
libc_vfs_dev_node.appendChild(libc_vfs_dev_log_node);
libc_vfs_node.appendChild(libc_vfs_dev_node);
QDomElement libc_vfs_mediafile_node = config_doc.createElement("rom");
libc_vfs_mediafile_node.setAttribute("name", "mediafile");
libc_vfs_node.appendChild(libc_vfs_mediafile_node);
libc_node.appendChild(libc_vfs_node);
config_node.appendChild(libc_node);
QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume");
sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume));
config_node.appendChild(sdl_audio_volume_node);
_config_byte_array = config_doc.toByteArray(4);
return _config_byte_array.constData();
}
static Genode::size_t _quota() { return 32*1024*1024; }
static Name _name() { return "avplay"; }
protected:
const char **_permitted_services() const override
{
static const char *permitted_services[] = {
"CPU", "LOG", "PD", "RAM", "RM", "ROM", "Timer", "Audio_out", 0 };
return permitted_services;
};
public:
Policy(Genode::Rpc_entrypoint &entrypoint,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
Input_service &input_service,
Framebuffer_service_factory &framebuffer_service_factory,
char const *mediafile)
: Genode::Slave::Policy(_name(), _name(), entrypoint, rm, ram,
_quota()),
_input_service(input_service),
_framebuffer_service_factory(framebuffer_service_factory),
_mediafile(mediafile),
_sdl_audio_volume(100)
{
configure(_config());
}
Genode::Service &resolve_session_request(Genode::Service::Name const &service_name,
Genode::Session_state::Args const &args) override
{
if (service_name == "Input")
return _input_service;
if (service_name == "Framebuffer")
return _framebuffer_service_factory.create(args);
return Genode::Slave::Policy::resolve_session_request(service_name, args);
}
void volume_changed(int value)
{
_sdl_audio_volume = value;
configure(_config());
}
};
Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t);
Genode::Rpc_entrypoint _ep;
Policy _policy;
Genode::Child _child;
public:
/**
* Constructor
*/
Avplay_slave(Genode::Pd_session &pd,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
Input_service &input_service,
Framebuffer_service_factory &framebuffer_service_factory,
char const *mediafile)
:
_ep(&pd, _ep_stack_size, "avplay_ep"),
_policy(_ep, rm, ram, input_service, framebuffer_service_factory, mediafile),
_child(rm, _ep, _policy)
{ }
public Q_SLOTS:
void volume_changed(int value)
{
_policy.volume_changed(value);
}
};
#endif /* _AVPLAY_SLAVE_H_ */

View File

@ -24,15 +24,15 @@
void Control_bar::_rewind()
{
/* mouse click at horizontal position 0 */
_event_queue.add(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
_event_queue.add(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0));
_input.submit(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
_input.submit(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0));
}
void Control_bar::_pause_resume()
{
_event_queue.add(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
_event_queue.add(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
_input.submit(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
_input.submit(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
_playing = !_playing;
if (_playing)
@ -51,9 +51,9 @@ void Control_bar::_stop()
}
Control_bar::Control_bar(Input::Event_queue &event_queue)
Control_bar::Control_bar(Input::Session_component &input)
:
_event_queue(event_queue), _playing(true)
_input(input), _playing(true)
{
update_style_id(_play_pause_button, "play");

View File

@ -23,7 +23,7 @@
#include <qoost/qmember.h>
/* Genode includes */
#include <input/event_queue.h>
#include <input/component.h>
struct Play_pause_button : QPushButton { Q_OBJECT };
struct Stop_button : QPushButton { Q_OBJECT };
@ -36,7 +36,7 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
private:
Input::Event_queue &_event_queue;
Input::Session_component &_input;
QMember<Play_pause_button> _play_pause_button;
QMember<Stop_button> _stop_button;
@ -54,7 +54,7 @@ class Control_bar : public Compound_widget<QWidget, QHBoxLayout>
public:
Control_bar(Input::Event_queue &event_queue);
Control_bar(Input::Session_component &input);
Q_SIGNALS:

View File

@ -1,76 +0,0 @@
/*
* \brief Filter framebuffer policy
* \author Christian Prochaska
* \date 2012-04-11
*/
/*
* Copyright (C) 2012-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 _FILTER_FRAMEBUFFER_POLICY_H_
#define _FILTER_FRAMEBUFFER_POLICY_H_
/* Genode includes */
#include <base/service.h>
#include <os/slave.h>
class Filter_framebuffer_policy : public Genode::Slave_policy
{
private:
Genode::Service_registry &_framebuffer_in;
Genode::Service_registry &_framebuffer_out;
protected:
const char **_permitted_services() const
{
static const char *permitted_services[] = {
"LOG", "RM", "ROM", "Timer", 0 };
return permitted_services;
};
public:
Filter_framebuffer_policy(const char *name,
Genode::Rpc_entrypoint &entrypoint,
Genode::Service_registry &framebuffer_in,
Genode::Service_registry &framebuffer_out)
: Genode::Slave_policy(name, entrypoint, Genode::env()->ram_session()),
_framebuffer_in(framebuffer_in),
_framebuffer_out(framebuffer_out) { }
Genode::Service *resolve_session_request(const char *service_name,
const char *args)
{
if (strcmp(service_name, "Framebuffer") == 0) {
Genode::Client client;
return _framebuffer_in.wait_for_service(service_name, &client, name());
}
return Slave_policy::resolve_session_request(service_name, args);
}
bool announce_service(const char *name,
Genode::Root_capability root,
Genode::Allocator *alloc,
Genode::Server *server)
{
if (strcmp(name, "Framebuffer") == 0) {
_framebuffer_out.insert(new (alloc) Genode::Child_service(name, root, server));
return true;
}
return Slave_policy::announce_service(name, root, alloc, server);
}
};
#endif /* _FILTER_FRAMEBUFFER_POLICY_H_ */

View File

@ -0,0 +1,91 @@
/*
* \brief Filter framebuffer policy
* \author Christian Prochaska
* \date 2012-04-11
*/
/*
* Copyright (C) 2012-2016 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 _FILTER_FRAMEBUFFER_SLAVE_H_
#define _FILTER_FRAMEBUFFER_SLAVE_H_
/* Genode includes */
#include <base/service.h>
#include <os/slave.h>
/* local includes */
#include "framebuffer_service_factory.h"
class Filter_framebuffer_slave
{
private:
class Policy : public Genode::Slave::Policy
{
private:
Framebuffer_service_factory &_framebuffer_service_factory;
protected:
const char **_permitted_services() const
{
static const char *permitted_services[] = {
"CPU", "LOG", "PD", "RAM", "RM", "ROM", "Timer", 0 };
return permitted_services;
};
public:
Policy(Genode::Rpc_entrypoint &entrypoint,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
Name const &name,
size_t quota,
Framebuffer_service_factory &framebuffer_service_factory)
: Genode::Slave::Policy(name, name, entrypoint, rm, ram, quota),
_framebuffer_service_factory(framebuffer_service_factory) { }
Genode::Service &resolve_session_request(Genode::Service::Name const &service_name,
Genode::Session_state::Args const &args) override
{
if (service_name == "Framebuffer")
return _framebuffer_service_factory.create(args);
return Genode::Slave::Policy::resolve_session_request(service_name, args);
}
};
Genode::size_t const _ep_stack_size = 2*1024*sizeof(Genode::addr_t);
Genode::Rpc_entrypoint _ep;
Policy _policy;
Genode::Child _child;
public:
/**
* Constructor
*/
Filter_framebuffer_slave(Genode::Pd_session &pd,
Genode::Region_map &rm,
Genode::Ram_session_capability ram,
Genode::Slave::Policy::Name const &name,
size_t quota,
Framebuffer_service_factory &framebuffer_service_factory)
:
_ep(&pd, _ep_stack_size, "filter_framebuffer_ep"),
_policy(_ep, rm, ram, name, quota, framebuffer_service_factory),
_child(rm, _ep, _policy)
{ }
Genode::Slave::Policy &policy() { return _policy; }
};
#endif /* _FILTER_FRAMEBUFFER_SLAVE_H_ */

View File

@ -1,64 +0,0 @@
/*
* \brief Framebuffer root
* \author Christian Prochaska
* \date 2012-04-02
*/
/*
* Copyright (C) 2012-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 _FRAMEBUFFER_ROOT_H_
#define _FRAMEBUFFER_ROOT_H_
/* Genode includes */
#include <root/component.h>
#include "framebuffer_session_component.h"
namespace Framebuffer {
/**
* Shortcut for single-client root component
*/
typedef Genode::Root_component<Session_component, Genode::Single_client> Root_component;
class Root : public Root_component
{
private:
QNitpickerViewWidget &_nitpicker_view_widget;
int _max_width;
int _max_height;
protected:
Session_component *_create_session(const char *args)
{
return new (md_alloc())
Session_component(args, _nitpicker_view_widget,
_max_width, _max_height);
}
public:
Root(Genode::Rpc_entrypoint *session_ep,
Genode::Allocator *md_alloc,
QNitpickerViewWidget &nitpicker_view_widget,
int max_width = 0,
int max_height = 0)
: Root_component(session_ep, md_alloc),
_nitpicker_view_widget(nitpicker_view_widget),
_max_width(max_width),
_max_height(max_height) { }
};
}
#endif /* _FRAMEBUFFER_ROOT_H_ */

View File

@ -0,0 +1,141 @@
/*
* \brief Framebuffer service factory
* \author Christian Prochaska
* \date 2016-11-24
*/
/*
* Copyright (C) 2016 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 _FRAMEBUFFER_SERVICE_FACTORY_H_
#define _FRAMEBUFFER_SERVICE_FACTORY_H_
/* Genode includes */
#include <base/service.h>
#include <os/slave.h>
#include <framebuffer_session/connection.h>
#include <os/single_session_service.h>
#include <nitpicker_session/connection.h>
/* Qt includes */
#include <qnitpickerplatformwindow.h>
#include <qnitpickerviewwidget/qnitpickerviewwidget.h>
struct Framebuffer_service_factory
{
virtual Genode::Service &create(Genode::Session_state::Args const &args) = 0;
typedef Genode::Single_session_service<Framebuffer::Session> Session_service;
};
class Nitpicker_framebuffer_service_factory : public Framebuffer_service_factory
{
private:
Nitpicker::Connection _nitpicker;
Session_service _service;
QNitpickerViewWidget &_nitpicker_view_widget;
int _max_width;
int _max_height;
int _limited_size(int requested_size, int max_size)
{
if (requested_size == 0)
return max_size;
else
return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size;
}
static inline long _session_arg(Genode::Session_state::Args const &args, const char *key)
{
return Genode::Arg_string::find_arg(args.string(), key).long_value(0);
}
public:
Nitpicker_framebuffer_service_factory(Genode::Env &env,
QNitpickerViewWidget &nitpicker_view_widget,
int max_width = 0,
int max_height = 0)
: _nitpicker(env),
_service(_nitpicker.framebuffer_session()),
_nitpicker_view_widget(nitpicker_view_widget),
_max_width(max_width), _max_height(max_height)
{ }
Genode::Service &create(Genode::Session_state::Args const &args)
{
Framebuffer::Mode const
mode(_limited_size(_session_arg(args, "fb_width"), _max_width),
_limited_size(_session_arg(args, "fb_height"), _max_height),
_nitpicker.mode().format());
_nitpicker.buffer(mode, false);
QNitpickerPlatformWindow *platform_window =
dynamic_cast<QNitpickerPlatformWindow*>(_nitpicker_view_widget
.window()->windowHandle()->handle());
Nitpicker::Session::View_handle parent_view_handle =
_nitpicker.view_handle(platform_window->view_cap());
Nitpicker::Session::View_handle nitpicker_view_handle =
_nitpicker.create_view(parent_view_handle);
_nitpicker.release_view_handle(parent_view_handle);
Framebuffer::Session_client framebuffer(_nitpicker.framebuffer_session());
Framebuffer::Mode framebuffer_mode = framebuffer.mode();
_nitpicker_view_widget.setNitpickerView(&_nitpicker,
nitpicker_view_handle,
0, 0,
framebuffer_mode.width(),
framebuffer_mode.height());
return _service.service();
}
};
class Filter_framebuffer_service_factory : public Framebuffer_service_factory
{
private:
typedef Genode::Slave::Connection<Framebuffer::Connection> Framebuffer_connection;
Genode::Slave::Policy &_policy;
Framebuffer_connection *_slave_connection { nullptr };
Session_service *_service { nullptr };
public:
Filter_framebuffer_service_factory(Genode::Slave::Policy &policy)
: _policy(policy)
{ }
~Filter_framebuffer_service_factory()
{
delete _service;
delete _slave_connection;
}
Genode::Service &create(Genode::Session_state::Args const &args)
{
_slave_connection = new Framebuffer_connection(_policy, args);
_service = new Session_service(*_slave_connection);
return _service->service();
}
};
#endif /* _FRAMEBUFFER_SERVICE_FACTORY_H_ */

View File

@ -1,102 +0,0 @@
/*
* \brief Framebuffer session component
* \author Christian Prochaska
* \date 2012-04-02
*/
/*
* Copyright (C) 2012-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 <base/env.h>
#include <nitpicker_session/client.h>
#include <util/arg_string.h>
#include <util/misc_math.h>
#include "framebuffer_session_component.h"
#include <qnitpickerplatformwindow.h>
namespace Framebuffer {
int Session_component::_limited_size(int requested_size, int max_size)
{
if (requested_size == 0)
return max_size;
else
return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size;
}
static inline long session_arg(const char *arg, const char *key)
{
return Genode::Arg_string::find_arg(arg, key).long_value(0);
}
Session_component::Session_component(const char *args,
QNitpickerViewWidget &nitpicker_view_widget,
int max_width,
int max_height)
:
_framebuffer(_nitpicker.framebuffer_session())
{
Framebuffer::Mode const
mode(_limited_size(session_arg(args, "fb_width"), max_width),
_limited_size(session_arg(args, "fb_height"), max_height),
_nitpicker.mode().format());
_nitpicker.buffer(mode, false);
QNitpickerPlatformWindow *platform_window =
dynamic_cast<QNitpickerPlatformWindow*>(nitpicker_view_widget
.window()->windowHandle()->handle());
Nitpicker::Session::View_handle parent_view_handle =
_nitpicker.view_handle(platform_window->view_cap());
Nitpicker::Session::View_handle nitpicker_view_handle =
_nitpicker.create_view(parent_view_handle);
_nitpicker.release_view_handle(parent_view_handle);
Mode _mode = _framebuffer.mode();
nitpicker_view_widget.setNitpickerView(&_nitpicker,
nitpicker_view_handle,
0, 0,
_mode.width(),
_mode.height());
}
Genode::Dataspace_capability Session_component::dataspace()
{
return _framebuffer.dataspace();
}
Mode Session_component::mode() const
{
return _framebuffer.mode();
}
void Session_component::mode_sigh(Genode::Signal_context_capability sigh_cap)
{
_framebuffer.mode_sigh(sigh_cap);
}
void Session_component::sync_sigh(Genode::Signal_context_capability sigh_cap)
{
_framebuffer.sync_sigh(sigh_cap);
}
void Session_component::refresh(int x, int y, int w, int h)
{
_framebuffer.refresh(x, y, w, h);
}
}

View File

@ -1,57 +0,0 @@
/*
* \brief Framebuffer session component
* \author Christian Prochaska
* \date 2012-04-02
*/
/*
* Copyright (C) 2012-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 _FRAMEBUFFER_SESSION_COMPONENT_H_
#define _FRAMEBUFFER_SESSION_COMPONENT_H_
/* Genode includes */
#include <base/rpc_server.h>
#include <framebuffer_session/client.h>
#include <nitpicker_session/connection.h>
/* Qt includes */
#include <qnitpickerviewwidget/qnitpickerviewwidget.h>
namespace Framebuffer {
class Session_component : public Genode::Rpc_object<Session>
{
private:
Nitpicker::Connection _nitpicker;
Session_client _framebuffer;
int _limited_size(int requested_size, int max_size);
public:
/**
* Constructor
*/
Session_component(const char *args,
QNitpickerViewWidget &nitpicker_view_widget,
int max_width = 0,
int max_height = 0);
Genode::Dataspace_capability dataspace() override;
Mode mode() const override;
void mode_sigh(Genode::Signal_context_capability) override;
void sync_sigh(Genode::Signal_context_capability) override;
void refresh(int, int, int, int) override;
};
}
#endif /* _FRAMEBUFFER_SESSION_COMPONENT_H_ */

View File

@ -18,7 +18,7 @@
#include "main_window.h"
/* Genode includes */
#include <rom_session/connection.h>
#include <base/component.h>
#include <base/printf.h>
@ -35,15 +35,18 @@ static inline void load_stylesheet()
}
int main(int argc, char *argv[])
extern int genode_argc;
extern char **genode_argv;
void Component::construct(Genode::Env &env)
{
QApplication app(argc, argv);
QApplication app(genode_argc, genode_argv);
load_stylesheet();
QMember<Main_window> main_window;
QMember<Main_window> main_window(env);
main_window->show();
return app.exec();
app.exec();
}

View File

@ -12,9 +12,7 @@
*/
/* qt_avplay includes */
#include "avplay_policy.h"
#include "filter_framebuffer_policy.h"
#include "framebuffer_root.h"
#include "filter_framebuffer_slave.h"
#include "main_window.h"
@ -24,22 +22,19 @@ using namespace Genode;
struct Framebuffer_filter
{
enum { MAX_FILTER_NAME_SIZE = 32 };
char name[MAX_FILTER_NAME_SIZE];
Genode::Number_of_bytes ram_quota;
Service_registry *framebuffer_out_registry;
Rpc_entrypoint *ep;
Filter_framebuffer_policy *policy;
Slave *slave;
char name[MAX_FILTER_NAME_SIZE];
Genode::Number_of_bytes ram_quota;
Filter_framebuffer_slave *slave;
};
Main_window::Main_window()
Main_window::Main_window(Genode::Env &env)
:
_control_bar(_input_session.event_queue())
_env(env),
_control_bar(_input_session_component)
{
_input_registry.insert(&_input_service);
_ep.manage(&_input_root);
_input_session_component.event_queue().enabled(true);
_ep.manage(&_input_session_component);
/* find out which filtering framebuffer services to start and sort them in reverse order */
@ -55,49 +50,33 @@ Main_window::Main_window()
}
} catch (Xml_node::Nonexistent_sub_node) { }
Framebuffer_service_factory *framebuffer_service_factory =
&_nitpicker_framebuffer_service_factory;
/* start the filtering framebuffer services */
Service_registry *framebuffer_in_registry = &_nitpicker_framebuffer_registry;
Q_FOREACH(Framebuffer_filter *framebuffer_filter, framebuffer_filters) {
framebuffer_filter->framebuffer_out_registry = new Service_registry;
framebuffer_filter->ep = new Rpc_entrypoint(&_cap, STACK_SIZE, "filter_fb_ep");
framebuffer_filter->policy = new Filter_framebuffer_policy(framebuffer_filter->name,
*framebuffer_filter->ep,
*framebuffer_in_registry,
*framebuffer_filter->framebuffer_out_registry);
framebuffer_filter->slave = new Slave(*framebuffer_filter->ep,
*framebuffer_filter->policy,
framebuffer_filter->ram_quota);
framebuffer_in_registry = framebuffer_filter->framebuffer_out_registry;
framebuffer_filter->slave = new Filter_framebuffer_slave(_env.pd(), _env.rm(),
_env.ram_session_cap(),
framebuffer_filter->name,
framebuffer_filter->ram_quota,
*framebuffer_service_factory);
framebuffer_service_factory =
new Filter_framebuffer_service_factory(framebuffer_filter->slave->policy());
}
Rpc_entrypoint *local_framebuffer_ep = framebuffer_filters.isEmpty() ?
&_ep :
framebuffer_filters.at(0)->ep;
static Framebuffer::Root framebuffer_root(local_framebuffer_ep, env()->heap(), *_avplay_widget, 640, 480);
static Local_service framebuffer_service(Framebuffer::Session::service_name(), &framebuffer_root);
_nitpicker_framebuffer_registry.insert(&framebuffer_service);
/* obtain dynamic linker */
Dataspace_capability ldso_ds;
try {
static Rom_connection rom("ld.lib.so");
ldso_ds = rom.dataspace();
} catch (...) { }
/* start avplay */
static Avplay_policy avplay_policy(_ep, _input_registry, *framebuffer_in_registry, _mediafile_name.buf);
static Genode::Slave avplay_slave(_ep, avplay_policy, 32*1024*1024,
env()->ram_session_cap(), ldso_ds);
/* add widgets to layout */
_layout->addWidget(_avplay_widget);
_layout->addWidget(_control_bar);
connect(_control_bar, SIGNAL(volume_changed(int)), &avplay_policy, SLOT(volume_changed(int)));
/* start avplay */
Avplay_slave *avplay_slave = new Avplay_slave(_env.pd(), _env.rm(),
_env.ram_session_cap(),
_input_service,
*framebuffer_service_factory,
_mediafile_name.buf);
connect(_control_bar, SIGNAL(volume_changed(int)), avplay_slave, SLOT(volume_changed(int)));
}

View File

@ -31,8 +31,9 @@
#include <rom_session/connection.h>
/* local includes */
#include "avplay_slave.h"
#include "control_bar.h"
#include "framebuffer_service_factory.h"
class Main_window : public Compound_widget<QWidget, QVBoxLayout>
{
@ -56,25 +57,29 @@ class Main_window : public Compound_widget<QWidget, QVBoxLayout>
Genode::warning("no <mediafile> config node found, using \"mediafile\"");
}
}
} _mediafile_name;
};
enum { STACK_SIZE = 2*sizeof(Genode::addr_t)*1024 };
Genode::Cap_connection _cap;
Genode::Rpc_entrypoint _ep { &_cap, STACK_SIZE, "avplay_ep" };
Genode::Service_registry _input_registry;
Genode::Service_registry _nitpicker_framebuffer_registry;
Genode::Env &_env;
Input::Session_component _input_session;
Input::Root_component _input_root { _ep, _input_session };
Mediafile_name _mediafile_name;
Genode::Local_service _input_service { Input::Session::service_name(), &_input_root };
QMember<QNitpickerViewWidget> _avplay_widget;
QMember<Control_bar> _control_bar;
QMember<QNitpickerViewWidget> _avplay_widget;
QMember<Control_bar> _control_bar;
Genode::size_t const _ep_stack_size { 2*sizeof(Genode::addr_t)*1024 };
Genode::Rpc_entrypoint _ep { &_env.pd(), _ep_stack_size, "avplay_ep" };
Nitpicker_framebuffer_service_factory _nitpicker_framebuffer_service_factory { _env,
*_avplay_widget,
640, 480 };
Input::Session_component _input_session_component { _env, _env.ram() };
Input_service::Single_session_factory _input_factory { _input_session_component };
Input_service _input_service { _input_factory };
public:
Main_window();
Main_window(Genode::Env &env);
};
#endif /* _MAIN_WINDOW_H_ */

View File

@ -1,11 +1,10 @@
TEMPLATE = app
TARGET = qt_avplay
QT = core gui xml
HEADERS = avplay_policy.h \
HEADERS = avplay_slave.h \
control_bar.h \
main_window.h
SOURCES = control_bar.cpp \
framebuffer_session_component.cc \
main.cpp \
main_window.cpp
RESOURCES = style.qrc

View File

@ -6,14 +6,15 @@
#include "child_entry.h"
Child_entry::Child_entry(const char *name, int quota_kb, int max_quota_kb,
Launchpad *launchpad, Launchpad_child *launchpad_child,
Child_entry::Child_entry(Launchpad_child::Name const &name, int quota_kb,
int max_quota_kb, Launchpad &launchpad,
Launchpad_child &launchpad_child,
QWidget *parent)
: QWidget(parent), _launchpad(launchpad), _launchpad_child(launchpad_child)
{
ui.setupUi(this);
ui.nameLabel->setText(name);
ui.nameLabel->setText(name.string());
ui.quotaBar->setMaximum(max_quota_kb);
ui.quotaBar->setValue(quota_kb);
}
@ -21,5 +22,5 @@ Child_entry::Child_entry(const char *name, int quota_kb, int max_quota_kb,
void Child_entry::on_exitButton_clicked()
{
_launchpad->exit_child(_launchpad_child);
_launchpad.exit_child(_launchpad_child);
}

View File

@ -28,8 +28,8 @@ class Child_entry : public QWidget
Ui::Child_entryClass ui;
Launchpad *_launchpad;
Launchpad_child *_launchpad_child;
Launchpad &_launchpad;
Launchpad_child &_launchpad_child;
private slots:
@ -37,8 +37,9 @@ class Child_entry : public QWidget
public:
Child_entry(const char *name, int quota_kb, int max_quota_kb,
Launchpad *launchpad, Launchpad_child *launchpad_child,
Child_entry(Launchpad_child::Name const &name, int quota_kb,
int max_quota_kb, Launchpad &launchpad,
Launchpad_child &launchpad_child,
QWidget *parent = 0);
};

View File

@ -6,19 +6,20 @@
#include "launch_entry.h"
Launch_entry::Launch_entry(const char *filename, unsigned long default_quota,
Launch_entry::Launch_entry(Launchpad_child::Name const &prg_name,
unsigned long default_quota,
unsigned long max_quota,
Genode::Dataspace_capability config_ds,
Launchpad *launchpad,
Genode::Dataspace_capability config_ds,
QWidget *parent)
: QWidget(parent),
_filename(filename),
_config_ds(config_ds),
_launchpad(launchpad)
_prg_name(prg_name),
_launchpad(launchpad),
_config_ds(config_ds)
{
ui.setupUi(this);
ui.launchButton->setText(filename);
ui.launchButton->setText(prg_name.string());
ui.quotaDial->setMaximum(max_quota);
ui.quotaDial->setSingleStep(max_quota / 100);
@ -28,7 +29,7 @@ Launch_entry::Launch_entry(const char *filename, unsigned long default_quota,
void Launch_entry::on_launchButton_clicked()
{
_launchpad->start_child(_filename,
_launchpad->start_child(_prg_name,
1024 * ui.quotaDial->value(),
_config_ds);
}

View File

@ -28,9 +28,9 @@ class Launch_entry : public QWidget
Ui::Launch_entryClass ui;
const char *_filename;
Genode::Dataspace_capability _config_ds;
Launchpad *_launchpad;
Launchpad_child::Name const &_prg_name;
Launchpad *_launchpad;
Genode::Dataspace_capability _config_ds;
private slots:
@ -38,11 +38,11 @@ class Launch_entry : public QWidget
public:
Launch_entry(const char *filename,
Launch_entry(Launchpad_child::Name const &prg_name,
unsigned long default_quota,
unsigned long max_quota,
Genode::Dataspace_capability config_ds,
Launchpad *launchpad,
Genode::Dataspace_capability config_ds,
QWidget *parent = 0);
};

View File

@ -12,14 +12,57 @@
#include <QApplication>
/* Genode includes */
#include <base/component.h>
#include <base/env.h>
#include <rom_session/connection.h>
int main(int argc, char *argv[])
extern int genode_argc;
extern char **genode_argv;
namespace Qt_launchpad_namespace {
struct Local_env;
using namespace Genode;
}
struct Qt_launchpad_namespace::Local_env : Genode::Env
{
static QApplication a(argc, argv);
Genode::Env &genode_env;
static Qt_launchpad launchpad(Genode::env()->ram_session()->quota());
Genode::Entrypoint local_ep { genode_env,
2*1024*sizeof(addr_t),
"qt_launchpad_ep" };
Local_env(Env &genode_env) : genode_env(genode_env) { }
Parent &parent() { return genode_env.parent(); }
Ram_session &ram() { return genode_env.ram(); }
Cpu_session &cpu() { return genode_env.cpu(); }
Region_map &rm() { return genode_env.rm(); }
Pd_session &pd() { return genode_env.pd(); }
Entrypoint &ep() { return local_ep; }
Ram_session_capability ram_session_cap() { return genode_env.ram_session_cap(); }
Cpu_session_capability cpu_session_cap() { return genode_env.cpu_session_cap(); }
Pd_session_capability pd_session_cap() { return genode_env.pd_session_cap(); }
Id_space<Parent::Client> &id_space() { return genode_env.id_space(); }
Session_capability session(Parent::Service_name const &service_name,
Parent::Client::Id id,
Parent::Session_args const &session_args,
Affinity const &affinity)
{ return genode_env.session(service_name, id, session_args, affinity); }
void upgrade(Parent::Client::Id id, Parent::Upgrade_args const &args)
{ return genode_env.upgrade(id, args); }
void close(Parent::Client::Id id) { return genode_env.close(id); }
};
void Component::construct(Genode::Env &env)
{
static Qt_launchpad_namespace::Local_env local_env(env);
static QApplication a(genode_argc, genode_argv);
static Qt_launchpad launchpad(local_env, env.ram().avail());
try {
launchpad.process_config();
@ -30,7 +73,5 @@ int main(int argc, char *argv[])
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
int const result = a.exec();
return result;
a.exec();
}

View File

@ -11,8 +11,9 @@
#include "launch_entry.h"
#include "child_entry.h"
Qt_launchpad::Qt_launchpad(unsigned long initial_quota, QWidget *parent)
: QMainWindow(parent), Launchpad(initial_quota)
Qt_launchpad::Qt_launchpad(Genode::Env &env, unsigned long initial_quota,
QWidget *parent)
: QMainWindow(parent), Launchpad(env, initial_quota)
{
setupUi(this);
@ -72,40 +73,40 @@ void Qt_launchpad::quota(unsigned long quota)
}
void Qt_launchpad::add_launcher(const char *filename,
void Qt_launchpad::add_launcher(Launchpad_child::Name const &binary_name,
unsigned long default_quota,
Genode::Dataspace_capability config_ds)
{
Launch_entry *launch_entry = new Launch_entry(filename,
Launch_entry *launch_entry = new Launch_entry(binary_name,
default_quota / 1024,
initial_quota() / 1024,
config_ds,
this);
this,
config_ds);
launcherDockWidgetContents->layout()->addWidget(launch_entry);
launch_entry->show();
launcherDockWidgetContents->adjustSize();
}
void Qt_launchpad::add_child(const char *unique_name,
void Qt_launchpad::add_child(Launchpad_child::Name const &name,
unsigned long quota,
Launchpad_child *launchpad_child,
Genode::Allocator *alloc)
Launchpad_child &launchpad_child,
Genode::Allocator &alloc)
{
Child_entry *child_entry = new Child_entry(unique_name, quota / 1024,
Child_entry *child_entry = new Child_entry(name, quota / 1024,
initial_quota() / 1024,
this, launchpad_child);
child_entry->setObjectName(QString(unique_name) + "_child_entry");
*this, launchpad_child);
child_entry->setObjectName(QString(name.string()) + "_child_entry");
childrenDockWidgetContents->layout()->addWidget(child_entry);
child_entry->show();
childrenDockWidgetContents->adjustSize();
}
void Qt_launchpad::remove_child(const char *name, Genode::Allocator *alloc)
void Qt_launchpad::remove_child(Launchpad_child::Name const &name, Genode::Allocator &alloc)
{
Child_entry *child_entry =
childrenDockWidgetContents->findChild<Child_entry*>(QString(name) + "_child_entry");
childrenDockWidgetContents->findChild<Child_entry*>(QString(name.string()) + "_child_entry");
if (!child_entry) {
PWRN("child entry lookup failed");

View File

@ -29,20 +29,22 @@ class Qt_launchpad : public QMainWindow, public Launchpad, private Ui::Qt_launch
public:
Qt_launchpad(unsigned long initial_quota, QWidget *parent = 0);
Qt_launchpad(Genode::Env &env, unsigned long initial_quota,
QWidget *parent = 0);
virtual void quota(unsigned long quota) override;
virtual void add_launcher(const char *filename,
virtual void add_launcher(Launchpad_child::Name const &binary_name,
unsigned long default_quota,
Genode::Dataspace_capability config_ds) override;
virtual void add_child(const char *unique_name,
virtual void add_child(Launchpad_child::Name const &name,
unsigned long quota,
Launchpad_child *launchpad_child,
Genode::Allocator *alloc) override;
Launchpad_child &launchpad_child,
Genode::Allocator &alloc) override;
virtual void remove_child(const char *name, Genode::Allocator *alloc) override;
virtual void remove_child(Launchpad_child::Name const &name,
Genode::Allocator &alloc) override;
};
#endif /* QT_LAUNCHPAD_H */

View File

@ -74,3 +74,14 @@
/*
* Make sure that a handler exists. If not, report an error
+++ src/lib/acpica/source/include/platform/acgcc.h
@@ -44,7 +44,9 @@
#ifndef __ACGCC_H__
#define __ACGCC_H__
+#ifndef ACPI_INLINE
#define ACPI_INLINE __inline__
+#endif
/* Function name is used for debug output. Non-ANSI, compiler-dependent */

View File

@ -0,0 +1,60 @@
/*
* \brief Genode environment for ACPICA library
* \author Christian Helmuth
* \date 2016-11-14
*/
/*
* Copyright (C) 2016 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 <util/volatile_object.h>
#include <acpica/acpica.h>
#include <platform_session/client.h>
#include "env.h"
namespace Acpica { struct Env; }
struct Acpica::Env
{
Genode::Env &env;
Genode::Allocator &heap;
Genode::Parent::Service_name announce_for_acpica { "Acpi" };
Genode::Parent::Client parent_client;
Genode::Id_space<Genode::Parent::Client>::Element id_space_element {
parent_client, env.id_space() };
Genode::Capability<Platform::Session> cap {
Genode::reinterpret_cap_cast<Platform::Session>(
env.session(announce_for_acpica,
id_space_element.id(),
"ram_quota=24K", Genode::Affinity())) };
Platform::Client platform { cap };
Env(Genode::Env &env, Genode::Allocator &heap)
: env(env), heap(heap) { }
};
static Genode::Lazy_volatile_object<Acpica::Env> instance;
Genode::Allocator & Acpica::heap() { return instance->heap; }
Genode::Env & Acpica::env() { return instance->env; }
Platform::Client & Acpica::platform() { return instance->platform; }
void Acpica::init(Genode::Env &env, Genode::Allocator &heap)
{
instance.construct(env, heap);
}

View File

@ -0,0 +1,27 @@
/*
* \brief Genode environment for ACPICA library
* \author Christian Helmuth
* \date 2016-11-14
*/
/*
* Copyright (C) 2016 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 _ACPICA__ENV_H_
#define _ACPICA__ENV_H_
#include <base/env.h>
#include <base/allocator.h>
#include <platform_session/client.h>
namespace Acpica {
Genode::Env & env();
Genode::Allocator & heap();
Platform::Client & platform();
}
#endif /* _ACPICA__ENV_H_ */

View File

@ -1,7 +1,7 @@
/*
* \brief I/O memory backend for ACPICA library
* \author Alexander Boettcher
*
* \date 2016-11-14
*/
/*
@ -12,12 +12,13 @@
*/
#include <base/log.h>
#include <base/env.h>
#include <util/misc_math.h>
#include <io_mem_session/connection.h>
#include <rm_session/connection.h>
#include "env.h"
extern "C" {
#include "acpi.h"
#include "acpiosxf.h"
@ -31,9 +32,7 @@ extern "C" {
return retval; \
}
namespace Acpica {
class Io_mem;
};
namespace Acpica { class Io_mem; };
class Acpica::Io_mem
{
@ -77,7 +76,7 @@ class Acpica::Io_mem
void invalidate(ACPI_SIZE s)
{
if (_io_mem && refs())
Genode::destroy(Genode::env()->heap(), _io_mem);
Genode::destroy(Acpica::heap(), _io_mem);
ACPI_PHYSICAL_ADDRESS const p = _phys;
@ -139,7 +138,7 @@ class Acpica::Io_mem
io_mem._ref = r;
io_mem._virt = 0;
io_mem._io_mem = new (Genode::env()->heap())
io_mem._io_mem = new (Acpica::heap())
Genode::Io_mem_connection(io_mem._phys, io_mem._size);
return &io_mem;
@ -152,7 +151,8 @@ class Acpica::Io_mem
if (!io_mem)
return 0UL;
io_mem->_virt = Genode::env()->rm_session()->attach(io_mem->_io_mem->dataspace(), io_mem->_size);
io_mem->_virt = Acpica::env().rm().attach(io_mem->_io_mem->dataspace(),
io_mem->_size);
return reinterpret_cast<Genode::addr_t>(io_mem->_virt);
}
@ -160,7 +160,7 @@ class Acpica::Io_mem
Genode::addr_t pre_expand(ACPI_PHYSICAL_ADDRESS p, ACPI_SIZE s)
{
if (_io_mem)
Genode::destroy(Genode::env()->heap(), _io_mem);
Genode::destroy(Acpica::heap(), _io_mem);
_io_mem = nullptr;
@ -174,7 +174,7 @@ class Acpica::Io_mem
Genode::addr_t post_expand(ACPI_PHYSICAL_ADDRESS p, ACPI_SIZE s)
{
if (_io_mem)
Genode::destroy(Genode::env()->heap(), _io_mem);
Genode::destroy(Acpica::heap(), _io_mem);
ACPI_SIZE xsize = p + s - _phys;
if (!allocate(_phys, xsize, _ref))
@ -211,8 +211,7 @@ class Acpica::Io_mem
io2._io_mem = io_mem._io_mem;
Genode::addr_t virt = reinterpret_cast<Genode::addr_t>(io2._virt);
Genode::env()->rm_session()->attach_at(io_ds, virt,
io2._size, off_phys);
Acpica::env().rm().attach_at(io_ds, virt, io2._size, off_phys);
});
/**
@ -227,7 +226,7 @@ class Acpica::Io_mem
FAIL(0UL);
/* attach whole memory */
io_mem._virt = Genode::env()->rm_session()->attach(io_ds);
io_mem._virt = Acpica::env().rm().attach(io_ds);
return io_mem.to_virt(p);
});

View File

@ -1,7 +1,7 @@
/*
* \brief OS specific backend for ACPICA library
* \author Alexander Boettcher
*
* \date 2016-11-14
*/
/*
@ -12,17 +12,21 @@
*/
#include <base/log.h>
#include <base/env.h>
#include <util/misc_math.h>
#include <io_port_session/connection.h>
#include <timer_session/connection.h>
#include <acpica/acpica.h>
#include "env.h"
extern "C" {
#include "acpi.h"
#include "acpiosxf.h"
}
#define FAIL(retval) \
{ \
Genode::error(__func__, ":", __LINE__, " called - dead"); \
@ -39,21 +43,20 @@ ACPI_STATUS AcpiOsPredefinedOverride (const ACPI_PREDEFINED_NAMES *pre,
}
void * AcpiOsAllocate (ACPI_SIZE size) {
return Genode::env()->heap()->alloc(size); }
void * AcpiOsAllocate (ACPI_SIZE size) { return Acpica::heap().alloc(size); }
void AcpiOsFree (void *ptr)
{
if (Genode::env()->heap()->need_size_for_free())
if (Acpica::heap().need_size_for_free())
Genode::warning(__func__, " called - warning - ptr=", ptr);
Genode::env()->heap()->free(ptr, 0);
Acpica::heap().free(ptr, 0);
}
ACPI_STATUS AcpiOsCreateLock (ACPI_SPINLOCK *spin_lock)
{
*spin_lock = new (Genode::env()->heap()) Genode::Lock();
*spin_lock = new (Acpica::heap()) Genode::Lock();
return AE_OK;
}
@ -80,7 +83,7 @@ void AcpiOsReleaseLock (ACPI_SPINLOCK h, ACPI_CPU_FLAGS flags)
ACPI_STATUS AcpiOsCreateSemaphore (UINT32 max, UINT32 initial,
ACPI_SEMAPHORE *sem)
{
*sem = new (Genode::env()->heap()) Genode::Semaphore(initial);
*sem = new (Acpica::heap()) Genode::Semaphore(initial);
return AE_OK;
}
@ -200,7 +203,8 @@ ACPI_STATUS AcpiOsWritePort (ACPI_IO_ADDRESS port, UINT32 value, UINT32 width)
return AE_OK;
}
static struct {
static struct
{
ACPI_EXECUTE_TYPE type;
ACPI_OSD_EXEC_CALLBACK func;
void *context;

View File

@ -1,7 +1,7 @@
/*
* \brief PCI specific backend for ACPICA library
* \author Alexander Boettcher
*
* \date 2016-11-14
*/
/*
@ -12,9 +12,8 @@
*/
#include <base/log.h>
#include <base/env.h>
#include <parent/parent.h>
#include <platform_session/client.h>
#include "env.h"
extern "C" {
#include "acpi.h"
@ -42,44 +41,12 @@ struct Bdf
};
static Platform::Client & platform()
{
static bool connected = false;
typedef Genode::Capability<Platform::Session> Platform_session_capability;
Platform_session_capability platform_cap;
if (!connected) {
Genode::Parent::Service_name announce_for_acpica("Acpi");
Genode::Native_capability cap = Genode::env()->parent()->session(announce_for_acpica, "ram_quota=20K");
platform_cap = Genode::reinterpret_cap_cast<Platform::Session>(cap);
connected = true;
}
static Platform::Client conn(platform_cap);
return conn;
}
ACPI_STATUS AcpiOsInitialize (void)
{
/* acpi_drv uses IOMEM concurrently to us - wait until it is done */
Genode::log("wait for platform drv");
try {
platform();
} catch (...) {
Genode::error("did not get Platform connection");
Genode::Lock lock(Genode::Lock::LOCKED);
lock.lock();
}
Genode::log("wait for platform drv - done");
return AE_OK;
}
ACPI_STATUS AcpiOsInitialize (void) { return AE_OK; }
ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
UINT64 *value, UINT32 width)
{
Platform::Device_capability cap = platform().first_device();
Platform::Device_capability cap = Acpica::platform().first_device();
while (cap.valid()) {
Platform::Device_client client(cap);
@ -103,7 +70,7 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
break;
default:
Genode::error(__func__, " : unsupported access size ", width);
platform().release_device(client);
Acpica::platform().release_device(client);
return AE_ERROR;
};
@ -114,13 +81,13 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
"width=", width, " -> "
"value=", Genode::Hex(*value));
platform().release_device(client);
Acpica::platform().release_device(client);
return AE_OK;
}
cap = platform().next_device(cap);
cap = Acpica::platform().next_device(cap);
platform().release_device(client);
Acpica::platform().release_device(client);
}
Genode::error(__func__, " unknown device - segment=", pcidev->Segment, " "
@ -134,7 +101,7 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
UINT64 value, UINT32 width)
{
Platform::Device_capability cap = platform().first_device();
Platform::Device_capability cap = Acpica::platform().first_device();
while (cap.valid()) {
Platform::Device_client client(cap);
@ -158,7 +125,7 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
break;
default:
Genode::error(__func__, " : unsupported access size ", width);
platform().release_device(client);
Acpica::platform().release_device(client);
return AE_ERROR;
};
@ -169,13 +136,13 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg,
"width=", width, " "
"value=", Genode::Hex(value));
platform().release_device(client);
Acpica::platform().release_device(client);
return AE_OK;
}
cap = platform().next_device(cap);
cap = Acpica::platform().next_device(cap);
platform().release_device(client);
Acpica::platform().release_device(client);
}
Genode::error(__func__, " unknown device - segment=", pcidev->Segment, " ",

View File

@ -1,6 +1,7 @@
/*
* \brief Lookup code for initial ACPI RSDP pointer
* \author Alexander Boettcher
* \date 2016-11-14
*/
/*
@ -13,6 +14,8 @@
#include <io_mem_session/connection.h>
#include <os/attached_io_mem_dataspace.h>
#include "env.h"
extern "C" {
#include "acpi.h"
}
@ -48,9 +51,11 @@ class Genode::Acpi_table
{
uint8_t * local = 0;
Genode::Env &env = Acpica::env();
/* try BIOS area */
{
Genode::Attached_io_mem_dataspace io_mem(BIOS_BASE, BIOS_SIZE);
Genode::Attached_io_mem_dataspace io_mem(env, BIOS_BASE, BIOS_SIZE);
local = _search_rsdp(io_mem.local_addr<uint8_t>());
if (local)
return BIOS_BASE + (local - io_mem.local_addr<uint8_t>());
@ -60,7 +65,7 @@ class Genode::Acpi_table
try {
unsigned short base = 0;
{
Genode::Attached_io_mem_dataspace io_mem(0, 0x1000);
Genode::Attached_io_mem_dataspace io_mem(env, 0, 0x1000);
local = io_mem.local_addr<uint8_t>();
if (local)
base = (*reinterpret_cast<unsigned short *>(local + 0x40e)) << 4;
@ -69,7 +74,7 @@ class Genode::Acpi_table
if (!base)
return 0;
Genode::Attached_io_mem_dataspace io_mem(base, 1024);
Genode::Attached_io_mem_dataspace io_mem(env, base, 1024);
local = _search_rsdp(io_mem.local_addr<uint8_t>());
if (local)

View File

@ -50,8 +50,7 @@ const char *config = " \
<resource name=\"RAM\" quantum=\"2G\"/> \
<configfile name=\"config.plugin\"/> \
<route> \
<service name=\"ROM\"> \
<if-arg key=\"filename\" value=\"config.plugin\" /> \
<service name=\"ROM\" label=\"config.plugin\"> \
<child name=\"tar_rom\"/> \
</service> \
<any-service> <parent /> </any-service> \

View File

@ -28,13 +28,14 @@ class QNitpickerScreen : public QPlatformScreen
{
private:
Nitpicker::Connection _nitpicker;
QRect _geometry;
public:
QNitpickerScreen()
{
Nitpicker::Connection _nitpicker;
Framebuffer::Mode const scr_mode = _nitpicker.mode();
if (scr_mode.format() != Framebuffer::Mode::RGB565)
@ -42,8 +43,6 @@ class QNitpickerScreen : public QPlatformScreen
_geometry.setRect(0, 0, scr_mode.width(),
scr_mode.height());
Genode::env()->parent()->close(_nitpicker.cap());
}
QRect geometry() const { return _geometry; }

View File

@ -260,7 +260,8 @@ class Child_base : public Genode::Child_policy
** Child_policy interface **
****************************/
Name name() const override { return _label.string(); }
Name name() const override { return _label; }
Binary_name binary_name() const override { return _binary_name; }
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
Genode::Ram_session &ref_ram() override { return _ref_ram; }

View File

@ -24,6 +24,10 @@ namespace Framebuffer { class Connection; }
class Framebuffer::Connection : public Genode::Connection<Session>,
public Session_client
{
public:
enum { RAM_QUOTA = 8*1024UL };
private:
/**
@ -39,7 +43,7 @@ class Framebuffer::Connection : public Genode::Connection<Session>,
char argbuf[ARGBUF_SIZE];
/* donate ram quota for storing server-side meta data */
Genode::strncpy(argbuf, "ram_quota=8K", sizeof(argbuf));
Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", RAM_QUOTA);
/* set optional session-constructor arguments */
if (width)

View File

@ -23,6 +23,7 @@ namespace Framebuffer {
struct Mode;
struct Session;
struct Session_client;
}
@ -81,6 +82,8 @@ struct Framebuffer::Session : Genode::Session
{
static const char *service_name() { return "Framebuffer"; }
typedef Session_client Client;
virtual ~Session() { }
/**

View File

@ -28,7 +28,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
{
public:
enum { RAM_QUOTA = 36*1024UL };
enum { RAM_QUOTA = 36*1024UL };
private:

View File

@ -0,0 +1,61 @@
/*
* \brief Utility for implementing a local service with a single session
* \author Norman Feske
* \date 2014-02-14
*/
/*
* Copyright (C) 2014 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__OS__SINGLE_SESSION_SERVICE_H_
#define _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_
/* Genode includes */
#include <base/service.h>
namespace Genode { template <typename> class Single_session_service; }
template <typename SESSION>
class Genode::Single_session_service
{
public:
typedef Capability<SESSION> Session_capability;
private:
/*
* Wrap client object to be compabile with 'Rpc_object::cap' calls
*
* We hand out the capability via 'cap' method to be compatible with
* the interface normally provided by server-side component objects.
* The 'Single_session_factory' requests the capability via this
* method.
*/
struct Client : SESSION::Client
{
Client(Session_capability cap) : SESSION::Client(cap) { }
Session_capability cap() const { return *this; }
};
typedef Local_service<Client> Service;
typedef typename Service::Single_session_factory Factory;
Client _client;
Factory _factory { _client };
Service _service { _factory };
public:
Single_session_service(Session_capability cap) : _client(cap) { }
Service &service() { return _service; }
};
#endif /* _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_ */

View File

@ -25,25 +25,29 @@ struct Child : Child_base, List<Child>::Element
Argument argument;
Child(Ram &ram,
char const *label,
char const *binary,
Genode::Cap_session &cap_session,
Name const &label,
Binary_name const &binary,
Genode::Pd_session &pd_session,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Genode::Region_map &local_rm,
Genode::size_t ram_quota,
Genode::size_t ram_limit,
Genode::Signal_context_capability yield_response_sig_cap,
Genode::Signal_context_capability exit_sig_cap,
Genode::Dataspace_capability ldso_ds)
Genode::Signal_context_capability exit_sig_cap)
:
Child_base(ram,
label,
binary,
cap_session,
pd_session,
ref_ram,
ref_ram_cap,
local_rm,
ram_quota,
ram_limit,
yield_response_sig_cap,
exit_sig_cap,
ldso_ds),
argument(label, "subsystem")
exit_sig_cap),
argument(label.string(), "subsystem")
{ }
};

View File

@ -30,7 +30,7 @@ class Child_registry : public List<Child>
bool _child_name_exists(const char *label)
{
for (Child *child = first() ; child; child = child->next())
if (strcmp(child->name(), label) == 0)
if (child->name() == label)
return true;
return false;
}

View File

@ -23,7 +23,7 @@ struct Kill_command : Command
void _destroy_child(Child *child, Terminal::Session &terminal)
{
tprintf(terminal, "destroying subsystem '%s'\n", child->name());
tprintf(terminal, "destroying subsystem '%s'\n", child->name().string());
_children.remove(child);
Genode::destroy(Genode::env()->heap(), child);
}
@ -38,8 +38,8 @@ struct Kill_command : Command
void _for_each_argument(Argument_fn const &fn) const override
{
auto child_name_fn = [&] (char const *child_name) {
Argument arg(child_name, "");
auto child_name_fn = [&] (Child_base::Name const &child_name) {
Argument arg(child_name.string(), "");
fn(arg);
};
@ -65,7 +65,7 @@ struct Kill_command : Command
/* lookup child by its unique name */
for (Child *child = _children.first(); child; child = child->next()) {
if (strcmp(child->name(), label) == 0) {
if (child->name() == label) {
_destroy_child(child, terminal);
return;
}

View File

@ -132,11 +132,12 @@ void Component::construct(Genode::Env &env)
commands.insert(new Help_command);
Kill_command kill_command(children);
commands.insert(&kill_command);
commands.insert(new Start_command(ram, cap, children,
commands.insert(new Start_command(ram, env.pd(),
env.ram(), env.ram_session_cap(),
env.rm(), children,
subsystem_config_registry,
yield_response_sig_cap,
exited_child_sig_cap,
ldso_ds));
exited_child_sig_cap));
commands.insert(new Status_command(ram, children));
commands.insert(new Yield_command(children));
commands.insert(new Ram_command(children));

View File

@ -40,13 +40,13 @@ struct Ram_command : Command
size_t const avail = Genode::env()->ram_session()->avail();
if (amount > avail) {
tprintf(terminal, "upgrade of '%s' exceeds available quota of ",
child.name());
child.name().string());
tprint_bytes(terminal, avail);
tprintf(terminal, "\n");
amount = avail;
}
tprintf(terminal, "upgrading quota of '%s' to ", child.name());
tprintf(terminal, "upgrading quota of '%s' to ", child.name().string());
tprint_bytes(terminal, old_quota + amount);
tprintf(terminal, "\n");
@ -69,7 +69,7 @@ struct Ram_command : Command
amount = avail;
}
tprintf(terminal, "depleting quota of '%s' to ", child.name());
tprintf(terminal, "depleting quota of '%s' to ", child.name().string());
tprint_bytes(terminal, old_quota - amount);
tprintf(terminal, "\n");
@ -82,8 +82,8 @@ struct Ram_command : Command
void _for_each_argument(Argument_fn const &fn) const override
{
auto child_name_fn = [&] (char const *child_name) {
Argument arg(child_name, "");
auto child_name_fn = [&] (Child_base::Name const &child_name) {
Argument arg(child_name.string(), "");
fn(arg);
};
@ -102,7 +102,7 @@ struct Ram_command : Command
/* lookup child by its unique name */
Child *child = _children.first();
for (; child; child = child->next())
if (strcmp(child->name(), label) == 0)
if (child->name() == label)
break;
if (!child) {

View File

@ -28,14 +28,16 @@ class Start_command : public Command
typedef Genode::Signal_context_capability Signal_context_capability;
typedef Genode::Dataspace_capability Dataspace_capability;
Ram &_ram;
Child_registry &_children;
Genode::Cap_session &_cap;
Subsystem_config_registry &_subsystem_configs;
List<Argument> _arguments;
Signal_context_capability _yield_response_sigh_cap;
Signal_context_capability _exit_sig_cap;
Dataspace_capability _ldso_ds;
Ram &_ram;
Child_registry &_children;
Genode::Pd_session &_pd;
Genode::Ram_session &_ref_ram;
Genode::Ram_session_capability _ref_ram_cap;
Genode::Region_map &_local_rm;
Subsystem_config_registry &_subsystem_configs;
List<Argument> _arguments;
Signal_context_capability _yield_response_sigh_cap;
Signal_context_capability _exit_sig_cap;
void _execute_subsystem(char const *name, Command_line &cmd,
Terminal::Session &terminal,
@ -107,11 +109,12 @@ class Start_command : public Command
Child *child = 0;
try {
child = new (Genode::env()->heap())
Child(_ram, label, binary_name, _cap, ram, ram_limit,
_yield_response_sigh_cap, _exit_sig_cap, _ldso_ds);
Child(_ram, label, binary_name, _pd, _ref_ram, _ref_ram_cap,
_local_rm, ram, ram_limit,
_yield_response_sigh_cap, _exit_sig_cap);
}
catch (Genode::Rom_connection::Rom_connection_failed) {
tprintf(terminal, "Error: could not obtain ROM module \"%s\"\n",
catch (Genode::Parent::Service_denied) {
tprintf(terminal, "Error: could not start child \"%s\"\n",
binary_name);
return;
}
@ -146,18 +149,22 @@ class Start_command : public Command
public:
Start_command(Ram &ram, Genode::Cap_session &cap, Child_registry &children,
Subsystem_config_registry &subsustem_configs,
Signal_context_capability yield_response_sigh_cap,
Signal_context_capability exit_sig_cap,
Dataspace_capability ldso_ds)
Start_command(Ram &ram,
Genode::Pd_session &pd,
Genode::Ram_session &ref_ram,
Genode::Ram_session_capability ref_ram_cap,
Genode::Region_map &local_rm,
Child_registry &children,
Subsystem_config_registry &subsustem_configs,
Signal_context_capability yield_response_sigh_cap,
Signal_context_capability exit_sig_cap)
:
Command("start", "create new subsystem"),
_ram(ram), _children(children), _cap(cap),
_ram(ram), _children(children), _pd(pd),
_ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap), _local_rm(local_rm),
_subsystem_configs(subsustem_configs),
_yield_response_sigh_cap(yield_response_sigh_cap),
_exit_sig_cap(exit_sig_cap),
_ldso_ds(ldso_ds)
_exit_sig_cap(exit_sig_cap)
{
add_parameter(new Parameter("--count", Parameter::NUMBER, "number of instances"));
add_parameter(new Parameter("--ram", Parameter::NUMBER, "initial RAM quota"));

View File

@ -139,7 +139,7 @@ struct Status_command : Command
Child_info child_info[num_children];
unsigned i = 0;
for (Child *c = _children.first(); c && i < num_children; c = c->next(), i++)
child_info[i] = Child_info(c->name(), c->ram_status());
child_info[i] = Child_info(c->name().string(), c->ram_status());
/*
* Print table

View File

@ -32,8 +32,8 @@ struct Yield_command : Command
void _for_each_argument(Argument_fn const &fn) const override
{
auto child_name_fn = [&] (char const *child_name) {
Argument arg(child_name, "");
auto child_name_fn = [&] (Child_base::Name const &child_name) {
Argument arg(child_name.string(), "");
fn(arg);
};
@ -57,7 +57,7 @@ struct Yield_command : Command
/* lookup child by its unique name */
Child *child = _children.first();
for (; child; child = child->next())
if (strcmp(child->name(), label) == 0)
if (child->name() == label)
break;
if (!child) {
@ -67,7 +67,7 @@ struct Yield_command : Command
child->yield(ram, greedy);
tprintf(terminal, "requesting '%s' to yield ", child->name());
tprintf(terminal, "requesting '%s' to yield ", child->name().string());
tprint_bytes(terminal, ram);
tprintf(terminal, "\n");
}

View File

@ -115,9 +115,7 @@ namespace L4lx {
use_local_addr,
local_addr,
executable); },
[&] () {
Genode::env()->parent()->upgrade(Rm_connection::cap(), "ram_quota=8K");
});
[&] () { Rm_connection::upgrade_ram(8*1024); });
}
};

View File

@ -56,30 +56,4 @@ auto retry(FUNC func, HANDLER handler, unsigned attempts = ~0U) -> decltype(func
throw EXC();
}
/**
* Client object for a session that may get its session quota upgraded
*/
template <typename CLIENT>
struct Upgradeable_client : CLIENT
{
typedef Genode::Capability<typename CLIENT::Rpc_interface> Capability;
Capability _cap;
Upgradeable_client(Capability cap) : CLIENT(cap), _cap(cap) { }
void upgrade_ram(Genode::size_t quota)
{
Genode::log("upgrading quota donation for "
"Env::", CLIENT::Rpc_interface::service_name(), " "
"(", quota, " bytes)");
char buf[128];
Genode::snprintf(buf, sizeof(buf), "ram_quota=%ld", quota);
Genode::env()->parent()->upgrade(_cap, buf);
}
};
#endif /* _PLATFORM_ENV_H_ */

View File

@ -83,7 +83,7 @@ static void map_kip()
using namespace Genode;
/* Open the KIP special file and keep it open */
static Genode::Rom_connection kip_rom("kip");
static Genode::Rom_connection kip_rom("l4v2_kip");
/* Attach and register dataspace */
l4lx_kinfo = L4lx::Env::env()->rm()->attach(kip_rom.dataspace(), "KIP");

View File

@ -40,6 +40,18 @@ struct Noux::Connection : Genode::Connection<Session>, Session_client
*/
Connection()
: Genode::Connection<Session>(session("")), Session_client(cap()) { }
/**
* Remove session ID of the noux session from the ID space.
*
* This must by done before reinitializing the noux connection in a
* freshly forked process. Otherwise, an overwritten 'Noux::Connection'
* object would still be referenced by the AVL tree of the the ID space.
*/
void discard_session_id()
{
_id_space_element.~Element();
}
};
#endif /* _INCLUDE__NOUX_SESSION__CONNECTION_H_ */

View File

@ -38,8 +38,8 @@ class Vmm::Vcpu_dispatcher : public T
enum { WEIGHT = Genode::Cpu_session::Weight::DEFAULT_WEIGHT };
Pd_session &_pd;
Nova_native_pd_client _native_pd { _pd.native_pd() };
Env &_env;
Nova_native_pd_client _native_pd { _env.pd().native_pd() };
/**
* Portal entry point entered on virtualization events
@ -69,12 +69,12 @@ class Vmm::Vcpu_dispatcher : public T
unsigned int exit_reason = 0;
Vcpu_dispatcher(Genode::size_t stack_size, Pd_session &pd,
Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size,
Cpu_session * cpu_session,
Genode::Affinity::Location location,
const char * name = "vCPU dispatcher")
:
T(WEIGHT, name, stack_size, location), _pd(pd)
T(WEIGHT, name, stack_size, location), _env(env)
{
using namespace Genode;
@ -85,13 +85,13 @@ class Vmm::Vcpu_dispatcher : public T
}
template <typename X>
Vcpu_dispatcher(Genode::size_t stack_size, Pd_session &pd,
Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size,
Cpu_session * cpu_session,
Genode::Affinity::Location location,
X attr, void *(*start_routine) (void *), void *arg,
const char * name = "vCPU dispatcher")
: T(attr, start_routine, arg, stack_size, name, nullptr, location),
_pd(pd)
_env(env)
{
using namespace Genode;
@ -125,11 +125,7 @@ class Vmm::Vcpu_dispatcher : public T
},
[&] () {
Thread::myself()->native_thread().reset_client_rcv_sel();
Pd_session_client *client =
dynamic_cast<Pd_session_client*>(&_pd);
if (client)
env()->parent()->upgrade(*client, "ram_quota=16K");
_env.parent().upgrade(Parent::Env::pd(), "ram_quota=16K");
});
/* revert selector allocation to automatic mode of operation */

View File

@ -64,6 +64,22 @@ append config {
<start name="loader">
<resource name="RAM" quantum="2M"/>
<provides><service name="Loader"/></provides>
<config>
<policy label="arora">
<parent-rom name="ld.lib.so"/>
<parent-rom name="init"/>
<parent-rom name="tar_rom"/>
<parent-rom name="nit_fb"/>
<parent-rom name="nitpicker"/>
<parent-rom name="pointer"/>
<parent-rom name="launchpad"/>
<parent-rom name="testnit"/>
</policy>
</config>
<route>
<service name="Nitpicker"> <child name="wm"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>
<start name="arora">

View File

@ -104,7 +104,7 @@ append config {
append_if $use_nic_driver config {
<start name="nic_drv">
<resource name="RAM" quantum="5M"/>
<resource name="RAM" quantum="8M"/>
<provides> <service name="Nic"/> </provides>
</start>}

View File

@ -212,7 +212,7 @@ append_platform_drv_config
append_if $use_nic_session config {
<start name="nic_drv" priority="-2">
<resource name="RAM" quantum="4M"/>
<resource name="RAM" quantum="8M"/>
<provides><service name="Nic"/></provides>
<route> <any-service><any-child/><parent/></any-service> </route>
</start>

Some files were not shown because too many files have changed in this diff Show More