diff --git a/repos/hello_tutorial/README b/repos/hello_tutorial/README
index 1e1639cb4d..0b90a254da 100644
--- a/repos/hello_tutorial/README
+++ b/repos/hello_tutorial/README
@@ -1,2 +1,2 @@
-This repository contains the source code of the 'Hello' client-server tutorial
-written by Björn Döbel. Please find the document at 'doc/hello_tutorial.txt'.
+This repository contains the source code of a simple client-server scenario
+using Genode's RPC mechanism.
diff --git a/repos/hello_tutorial/config/config b/repos/hello_tutorial/config/config
deleted file mode 100644
index 67def090a4..0000000000
--- a/repos/hello_tutorial/config/config
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/repos/hello_tutorial/doc/hello_tutorial.txt b/repos/hello_tutorial/doc/hello_tutorial.txt
index 75d391fb49..99b2c44a01 100644
--- a/repos/hello_tutorial/doc/hello_tutorial.txt
+++ b/repos/hello_tutorial/doc/hello_tutorial.txt
@@ -1,32 +1,25 @@
- Creating your first Genode application
+ A simple client-server scenario
- Björn Döbel and Norman Feske
+ Björn Döbel and Norman Feske
Abstract
########
-This section will give you a step-by-step introduction for writing your first
-little client-server application using the Genode OS Framework. We will create
+This tutorial will give you a step-by-step introduction for creating your first
+little client-server application scenario using the Genode OS Framework. We will create
a server that provides two functions to its clients and a client that uses
these functions. The code samples in this section are not necessarily complete.
-You can download the complete tutorial source code from the link at the bottom
-of this page.
+You can can find the complete source code at the _repos/hello_tutorial_
+directory within Genode's source tree.
Prerequisites
#############
-We assume that you know how to write code and have read:
-
-Norman Feske and Christian Helmuth:
-"Design of the Genode OS Architecture",
-_TU Dresden technical report TUD-FI06-07, Dresden, Germany, December 2006_.
-
-[http://genode-labs.com/publications/bastei-design-2006.pdf]
-
-so that you have a basic understanding of what Genode is and how things work.
-Of course, you will also need to check out Genode before going any further.
+We assume that you have acquainted yourself with the basic concepts of
+Genode and have read the "Getting started" section of the Genode Foundations
+book. Our can download the book from [http://genode.org].
Setting up the build environment
@@ -46,16 +39,16 @@ following subdirectory structure:
! hello_tutorial/src/hello/client
In the remaining document when referring to non-absolute directories, these are
-local to 'hello_tutorial'.
-Now we tell the Genode build system, that there is a new repository. Therefore
-we add the path to our new repository to 'build/etc/build.conf':
+local to _hello_tutorial_.
+Now we tell the Genode build system that there is a new repository. Therefore
+we add the path to our new repository to _build/etc/build.conf_:
! REPOSITORIES += /path/to/your/hello_tutorial
-Later we will place build description files into the tutorial subdirectories so
-that the build system can figure out what is needed to build your applications.
-You can then build these apps from the 'build' directory using one of the
-following commands:
+Later we will place build description files into the tutorial subdirectories
+so that the build system can figure out what is needed to build your custom
+components. You can then build these components from the _build_ directory
+using one of the following commands:
! make hello
! make hello/server
@@ -67,8 +60,8 @@ commands build only the specific target respectively.
Defining an interface
#####################
-In our example we are going to implement a server providing two functions:
-:'void say_hello()': makes the server print "Hello world."
+In our example, we are going to implement a server providing two functions:
+:'void say_hello()': makes the server print a message, and
:'int add(int a, int b)': adds two integers and returns the result.
The interface of a Genode service is called a _session_. We will define it as a
@@ -77,36 +70,35 @@ C++ class in 'include/hello_session/hello_session.h'
!#include
!#include
!
-!namespace Hello {
+!namespace Hello { struct Session; }
!
-! struct Session : public Genode::Session
-! {
-! static const char *service_name() { return "Hello"; }
+!struct Hello::Session : Genode::Session
+!{
+! static const char *service_name() { return "Hello"; }
!
-! virtual void say_hello() = 0;
-! virtual int add(int a, int b) = 0;
+! virtual void say_hello() = 0;
+! virtual int add(int a, int b) = 0;
!
-! GENODE_RPC(Rpc_say_hello, void, say_hello);
-! GENODE_RPC(Rpc_add, int, add, int, int);
-! GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_add);
-! };
-!}
+! GENODE_RPC(Rpc_say_hello, void, say_hello);
+! GENODE_RPC(Rpc_add, int, add, int, int);
+! GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_add);
+!};
As a good practice, we place the Hello service into a dedicated namespace. The
_Hello::Session_ class defines the public interface for our service as well as
the meta information that Genode needs to perform remote procedure calls (RPC)
-accross process boundaries.
-Furthermore, we use the interface to specify the name of the
-service by using the 'service_name' function. This function will later
-be used by both the server for announcing the service at its parent and
-the client for requesting the creation of a "Hello" session.
+across component boundaries.
+Furthermore, we use the interface to specify the name of the service by
+providing the 'service_name' method. This method will later be used by both
+the server for announcing the service at its parent and the client for
+requesting the creation of a "Hello" session.
The 'GENODE_RPC' macro is used to declare an RPC function. Its first argument
is a type name that is used to refer to the RPC function. The type name can
-be choosen freely. However, it is a good practice to prefix the type name
+be chosen freely. However, it is a good practice to prefix the type name
with 'Rpc_'. The remaining arguments are the return type of the RPC function,
the server-side name of the RPC implementation, and the function arguments.
-The 'GENODE_RPC_INTERFACE' macros declares the list of RPC functions that the
+The 'GENODE_RPC_INTERFACE' macro declares the list of RPC functions that the
RPC interface is comprised of. Under the hood, the 'GENODE_RPC*' macros enrich
the compound class with the type information used to automatically generate the
RPC communication code at compile time. They do not add any members to the
@@ -129,21 +121,20 @@ instantiating this template class with the session interface as argument, the
'Session_component' class gets equipped with the communication code that
will make the server's functions accessible via RPC.
-!#include
+!#include
!#include
!#include
!
-!namespace Hello {
+!namespace Hello { struct Session_component; }
!
-! struct Session_component : Genode::Rpc_object
-! {
-! void say_hello() {
-! PDBG("I am here... Hello."); }
+!struct Hello::Session_component : Genode::Rpc_object
+!{
+! void say_hello() {
+! Genode::log("I am here... Hello."); }
!
-! int add(int a, int b) {
-! return a + b; }
-! };
-!}
+! int add(int a, int b) {
+! return a + b; }
+!};
Getting ready to start
@@ -157,82 +148,80 @@ application. Starting a service with Genode works as follows:
client to communicate with the server.
The class 'Hello::Root_component' is derived from Genode's 'Root_component'
-class template. This class defines a '_create_session' method which is called
+class template. This class defines a '_create_session' method, which is called
each time a client wants to establish a connection to the server. This function
is responsible for parsing the parameter string the client hands over to the
-server and creating a 'Hello::Session_component' object from these parameters.
+server and for creating a 'Hello::Session_component' object from these
+parameters.
-!#include
+!#include
!#include
!
-!namespace Hello {
+!namespace Hello { class Root_component; }
!
-! class Root_component : public Genode::Root_component
-! {
-! protected:
-!
-! Session_component *_create_session(const char *args)
-! {
-! PDBG("creating hello session.");
-! return new (md_alloc()) Session_component();
-! }
-!
-! public:
-!
-! Root_component(Genode::Rpc_entrypoint *ep,
-! Genode::Allocator *allocator)
-! : Genode::Root_component(ep, allocator)
-! {
-! PDBG("Creating root component.");
-! }
-! };
-!}
-
-Now we only need a main method that announces the service to our parent:
-
-!#include
-!#include
-!
-!using namespace Genode;
-!
-!int main(void)
+!class Hello::Root_component
+!:
+! public Genode::Root_component
!{
-! /*
-! * Get a session for the parent's capability service, so that we
-! * are able to create capabilities.
-! */
-! Cap_connection cap;
+! protected:
!
-! /*
-! * A sliced heap is used for allocating session objects - thereby we
-! * can release objects separately.
-! */
-! static Sliced_heap sliced_heap(env()->ram_session(),
-! env()->rm_session());
+! Session_component *_create_session(const char *args)
+! {
+! Genode::log("creating hello session");
+! return new (md_alloc()) Session_component();
+! }
!
-! /*
-! * Create objects for use by the framework.
-! *
-! * An 'Rpc_entrypoint' is created to announce our service's root
-! * capability to our parent, manage incoming session creation
-! * requests, and dispatch the session interface. The incoming RPC
-! * requests are dispatched via a dedicated thread. The 'STACK_SIZE'
-! * argument defines the size of the thread's stack. The additional
-! * string argument is the name of the entry point, used for
-! * debugging purposes only.
-! */
-! enum { STACK_SIZE = 4096 };
-! static Rpc_entrypoint ep(&cap, STACK_SIZE, "hello_ep");
+! public:
!
-! static Hello::Root_component hello_root(&ep, &sliced_heap);
-! env()->parent()->announce(ep.manage(&hello_root));
+! Root_component(Genode::Entrypoint &ep,
+! Genode::Allocator &alloc)
+! :
+! Genode::Root_component(ep, alloc)
+! {
+! Genode::log("creating root component");
+! }
+!};
+
+Now we only need the actual application code that instantiates the root
+component and the service to our parent. It is good practice to represent
+the applications as a class called 'Main' with its constructor taking the
+component's environment as argument.
+
+!#include
!
-! /*
-! * We are done with this and only act upon client requests now.
-! */
-! sleep_forever();
+!namespace Hello { struct Main; }
!
-! return 0;
+!struct Hello::Main
+!{
+! Genode::Env &env;
+!
+! Genode::Sliced_heap sliced_heap { env.ram(), env.rm() };
+!
+! Hello::Root_component root { env.ep(), sliced_heap };
+!
+! Main(Genode::Env &env) : env(env)
+! {
+! env.parent().announce(env.ep().manage(root));
+! }
+!};
+
+The sliced heap is used for the dynamic allocation of session objects.
+It interacts with the component's RAM session to obtain the backing store
+for the allocations, and the component's region map to make
+backing store visible within its virtual address space.
+
+The announcement of the service is performed by the body of the constructor by
+creating a capability for the root component as return value of the 'manage'
+method, and passing this capability to the parent.
+
+The 'Component::construct' function of the hello server simply constructs a singleton
+instance of 'Hello::Main' as a _static_ local variable.
+
+!Genode::size_t Component::stack_size() { return 64*1024; }
+!
+!void Component::construct(Genode::Env &env)
+!{
+! static Hello::Main main(env);
!}
@@ -248,13 +237,12 @@ create a 'target.mk' file in 'src/hello/server':
! SRC_CC = main.cc
! LIBS = base
-To tell the init process to start the new program, we have to add a ''
+To tell the init component to start the new program, we have to add a ''
entry to init's 'config' file, which is located at 'build/bin/config'.
!
!
!
-!
!
!
!
@@ -265,53 +253,51 @@ entry to init's 'config' file, which is located at 'build/bin/config'.
!
!
-For information about the configuring the init process, please refer
-to [http://genode.org/documentation/developer-resources/init].
-
-Now rebuild 'core', 'init', and 'hello/server', go to 'build/bin', run './core'.
+For information about the configuring concept, please refer to the
+"System configuration" section of the Genode Foundations book.
Writing client code
###################
-In the next part we are going to have a look at the client-side implementation.
+In the next part, we are going to have a look at the client-side implementation.
The most basic steps here are:
-* Get a capability for the "Hello" service from our parent
+* Obtain a capability for the "Hello" service from our parent
* Invoke RPCs via the obtained capability
A client object
===============
-We will encapsulate the Genode IPC interface in a 'Hello::Session_client' class.
+We will encapsulate the Genode RPC interface in a 'Hello::Session_client' class.
This class derives from 'Hello:Session' and implements a client-side object.
Therefore edit 'include/hello_session/client.h':
!#include
!#include
-!#include
+!#include
!
-!namespace Hello {
+!namespace Hello { struct Session_client; }
!
-! struct Session_client : Genode::Rpc_client
+!
+!struct Hello::Session_client : Genode::Rpc_client
+!{
+! Session_client(Genode::Capability cap)
+! : Genode::Rpc_client(cap) { }
+!
+! void say_hello()
! {
-! Session_client(Genode::Capability cap)
-! : Genode::Rpc_client(cap) { }
+! Genode::log("issue RPC for saying hello");
+! call();
+! Genode::log("returned from 'say_hello' RPC call");
+! }
!
-! void say_hello()
-! {
-! PDBG("Saying Hello.");
-! call();
-! }
-!
-! int add(int a, int b)
-! {
-! return call(a, b);
-! }
-! };
-!}
-
+! int add(int a, int b)
+! {
+! return call(a, b);
+! }
+!};
A 'Hello::Session_client' object takes a 'Capability' as constructor argument.
This capability is tagged with the session type and gets passed to the
@@ -320,51 +306,26 @@ code via the 'call' template function. The template argument for 'call' is the
RPC type as declared in the session interface.
-Client implementation
-=====================
+A connection object
+===================
-The client-side implementation using the 'Hello::Session_client' object is pretty
-straightforward. We request a capability for the Hello service from our parent.
-This call blocks as long as the service has not been registered at the parent.
-Afterwards, we create a 'Hello::Session_client' object with it and invoke calls. In
-addition, we use the Timer service that comes with Genode. This server
-enables us to sleep for a certain amount of milliseconds.
+Whereas the 'Hello::Session_client' is able to perform RPC calls to an RPC
+object when given a capability for such an object, the question of how
+the client obtains this capability is still open.
+Here, the so-called connection object enters the picture. A connection
+object has the purposes:
-Put this code into 'src/hello/client/main.cc':
+* It transforms session-specific parameters into a format that can be
+ passed to the server along with the session request. The connection
+ object thereby hides the details of how the session parameters are
+ represented "on the wire".
-!#include
-!#include
-!#include
-!#include
-!
-!using namespace Genode;
-!
-!int main(void)
-!{
-! Capability h_cap =
-! env()->parent()->session("foo, ram_quota=4K");
-!
-! Hello::Session_client h(h_cap);
-!
-! Timer::Connection timer;
-!
-! while (1) {
-! h.say_hello();
-! timer.msleep(1000);
-!
-! int foo = h.add(2,5);
-! PDBG("Added 2 + 5 = %d", foo);
-! timer.msleep(1000);
-! }
-!
-! return 0;
-!}
+* It issues a session request to the parent and retrieves a session
+ capability as response.
+
+* It acts as a session-client object such that the session's RPC functions
+ can directly be called on the connection object.
-Compared to the creation of the Timer session, the creation of "Hello" session
-looks rather inconvenient and takes multiple lines of code. For this reason, it
-is a good practice to supply a convenience wrapper for creating sessions as
-used for the timer session. This wrapper is also the right place to for
-documenting session-construction arguments and assembling the argument string.
By convention, the wrapper is called 'connection.h' and placed in the directory
of the session interface. For our case, the file
'include/hello_session/connection.h' looks like this:
@@ -372,27 +333,44 @@ of the session interface. For our case, the file
!#include
!#include
!
-!namespace Hello {
+!namespace Hello { struct Connection; }
!
-! struct Connection : Genode::Connection, Session_client
-! {
-! Connection()
-! :
-! /* create session */
-! Genode::Connection(session("foo, ram_quota=4K")),
+!struct Hello::Connection : Genode::Connection, Session_client
+!{
+! Connection(Genode::Env &env)
+! :
+! /* create session */
+! Genode::Connection(env, session(env.parent(),
+! "ram_quota=4K")),
+! /* initialize RPC interface */
+! Session_client(cap()) { }
+!};
+
+
+Client implementation
+=====================
+
+The client-side implementation using the 'Hello::Connection' object is pretty
+straightforward. Put this code into 'src/hello/client/main.cc':
+
+!#include
+!#include
+!#include
!
-! /* initialize RPC interface */
-! Session_client(cap()) { }
-! };
+!Genode::size_t Component::stack_size() { return 64*1024; }
+!
+!void Component::construct(Genode::Env &env)
+!{
+! Hello::Connection hello(env);
+!
+! hello.say_hello();
+!
+! int const sum = hello.add(2, 5);
+! Genode::log("added 2 + 5 = ", sum);
+!
+! Genode::log("hello test completed");
!}
-With the 'Connection' class in place, we can now use Hello sessions
-by just instantiating 'Hello::Connection' objects and invoke
-functions directly on such an object. For example:
-
-!Hello::Connection hello;
-!int foo = hello.add(2, 5);
-
Ready, set, go...
=================
@@ -403,19 +381,56 @@ Add a 'target.mk' file with the following content to 'src/hello/client/':
! SRC_CC = main.cc
! LIBS = base
-Extend your 'config' file as follows.
+Extend your init _config_ as follows to also start the hello-client component:
-# Add start entries for 'Timer' service and hello client:
+!
+!
+!
- !
- !
- !
- !
- !
- !
- !
-Build 'drivers/timer', and 'hello/client', go to 'build/bin', and run './core'
-again. You have now successfully implemented your first Genode client-server
-scenario.
+Creating a run script to automate your work flow
+================================================
+The procedure of building, configuring, integrating, and executing Genode
+system scenarios across different kernels can be automated using a run
+script, which can be executed directly from within your build directory.
+A run script for the hello client-server scenario should be placed
+at the _run/hello.run_ and look as follows:
+
+!build { core init hello }
+!
+!create_boot_directory
+!
+!install_config {
+!
+!
+!
+!
+!
+!
+!
+!
+!
+!
+!
+!
+!
+!
+!}
+!
+!build_boot_image { core init hello_client hello_server }
+!
+!append qemu_args " -nographic "
+!
+!run_genode_until "hello test completed.*\n" 10
+
+When executed via 'make run/hello', it performs the given steps in sequence.
+Note that the run script is kernel-agnostic. Hence, you can execute the system
+scenario on all the different kernels supported by Genode without any
+modification. The regular expression specified to the 'run_genode_until' step
+is used as pattern for detecting the success of the step. If the log output
+produced by the scenario matches the pattern, the run script completes
+successfully. If the pattern does not appear within the specified time (in
+this example ten seconds), the run script aborts with an error. By creating
+the run script, we have not just automated our work flow but have actually
+created an automated test case for our components.
diff --git a/repos/hello_tutorial/include/hello_session/client.h b/repos/hello_tutorial/include/hello_session/client.h
index 2415cd41e7..2165836aab 100644
--- a/repos/hello_tutorial/include/hello_session/client.h
+++ b/repos/hello_tutorial/include/hello_session/client.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2008-2013 Genode Labs GmbH
+ * Copyright (C) 2008-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.
@@ -16,26 +16,27 @@
#include
#include
-#include
+#include
-namespace Hello {
+namespace Hello { struct Session_client; }
- struct Session_client : Genode::Rpc_client
+
+struct Hello::Session_client : Genode::Rpc_client
+{
+ Session_client(Genode::Capability cap)
+ : Genode::Rpc_client(cap) { }
+
+ void say_hello()
{
- Session_client(Genode::Capability cap)
- : Genode::Rpc_client(cap) { }
+ Genode::log("issue RPC for saying hello");
+ call();
+ Genode::log("returned from 'say_hello' RPC call");
+ }
- void say_hello()
- {
- PDBG("Saying Hello.");
- call();
- }
-
- int add(int a, int b)
- {
- return call(a, b);
- }
- };
-}
+ int add(int a, int b)
+ {
+ return call(a, b);
+ }
+};
#endif /* _INCLUDE__HELLO_SESSION_H__CLIENT_H_ */
diff --git a/repos/hello_tutorial/include/hello_session/connection.h b/repos/hello_tutorial/include/hello_session/connection.h
index 364444392f..dffb9a3934 100644
--- a/repos/hello_tutorial/include/hello_session/connection.h
+++ b/repos/hello_tutorial/include/hello_session/connection.h
@@ -17,18 +17,19 @@
#include
#include
-namespace Hello {
+namespace Hello { struct Connection; }
- struct Connection : Genode::Connection, Session_client
- {
- Connection()
- :
- /* create session */
- Genode::Connection(session("foo, ram_quota=4K")),
- /* initialize RPC interface */
- Session_client(cap()) { }
- };
-}
+struct Hello::Connection : Genode::Connection, Session_client
+{
+ Connection(Genode::Env &env)
+ :
+ /* create session */
+ Genode::Connection(env, session(env.parent(),
+ "ram_quota=4K")),
+
+ /* initialize RPC interface */
+ Session_client(cap()) { }
+};
#endif /* _INCLUDE__HELLO_SESSION__CONNECTION_H_ */
diff --git a/repos/hello_tutorial/include/hello_session/hello_session.h b/repos/hello_tutorial/include/hello_session/hello_session.h
index 63f27bb112..a50b19ea10 100644
--- a/repos/hello_tutorial/include/hello_session/hello_session.h
+++ b/repos/hello_tutorial/include/hello_session/hello_session.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2008-2013 Genode Labs GmbH
+ * Copyright (C) 2008-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.
@@ -17,25 +17,25 @@
#include
#include
-namespace Hello {
-
- struct Session : Genode::Session
- {
- static const char *service_name() { return "Hello"; }
-
- virtual void say_hello() = 0;
- virtual int add(int a, int b) = 0;
+namespace Hello { struct Session; }
- /*******************
- ** RPC interface **
- *******************/
+struct Hello::Session : Genode::Session
+{
+ static const char *service_name() { return "Hello"; }
- GENODE_RPC(Rpc_say_hello, void, say_hello);
- GENODE_RPC(Rpc_add, int, add, int, int);
+ virtual void say_hello() = 0;
+ virtual int add(int a, int b) = 0;
- GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_add);
- };
-}
+
+ /*******************
+ ** RPC interface **
+ *******************/
+
+ GENODE_RPC(Rpc_say_hello, void, say_hello);
+ GENODE_RPC(Rpc_add, int, add, int, int);
+
+ GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_add);
+};
#endif /* _INCLUDE__HELLO_SESSION__HELLO_SESSION_H_ */
diff --git a/repos/hello_tutorial/run/hello.run b/repos/hello_tutorial/run/hello.run
index 09c7d292f8..0dd52d8ca4 100644
--- a/repos/hello_tutorial/run/hello.run
+++ b/repos/hello_tutorial/run/hello.run
@@ -2,7 +2,7 @@
# Build
#
-build { core init hello drivers/timer }
+build { core init hello }
create_boot_directory
@@ -14,27 +14,13 @@ install_config {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -45,8 +31,8 @@ install_config {
# Boot image
#
-build_boot_image { core init hello_client hello_server timer }
+build_boot_image { core init hello_client hello_server }
append qemu_args " -nographic "
-run_genode_until forever
+run_genode_until "hello test completed.*\n" 10
diff --git a/repos/hello_tutorial/src/hello/client/main.cc b/repos/hello_tutorial/src/hello/client/main.cc
index 6808b5e9f0..f600117a02 100644
--- a/repos/hello_tutorial/src/hello/client/main.cc
+++ b/repos/hello_tutorial/src/hello/client/main.cc
@@ -1,38 +1,33 @@
/*
* \brief Test client for the Hello RPC interface
* \author Björn Döbel
+ * \author Norman Feske
* \date 2008-03-20
*/
/*
- * Copyright (C) 2008-2013 Genode Labs GmbH
+ * Copyright (C) 2008-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.
*/
-#include
-#include
-#include
+#include
+#include
#include
-#include
-using namespace Genode;
+Genode::size_t Component::stack_size() { return 64*1024; }
-int main(void)
+
+void Component::construct(Genode::Env &env)
{
- Hello::Connection h;
+ Hello::Connection hello(env);
- Timer::Connection timer;
+ hello.say_hello();
- while (1) {
- h.say_hello();
+ int const sum = hello.add(2, 5);
+ Genode::log("added 2 + 5 = ", sum);
- int foo = h.add(2, 5);
- PDBG("Added 2 + 5 = %d", foo);
- timer.msleep(1000);
- }
-
- return 0;
+ Genode::log("hello test completed");
}
diff --git a/repos/hello_tutorial/src/hello/server/main.cc b/repos/hello_tutorial/src/hello/server/main.cc
index 6dc2771318..9b0ae07832 100644
--- a/repos/hello_tutorial/src/hello/server/main.cc
+++ b/repos/hello_tutorial/src/hello/server/main.cc
@@ -1,93 +1,91 @@
/*
* \brief Main program of the Hello server
* \author Björn Döbel
+ * \author Norman Feske
* \date 2008-03-20
*/
/*
- * Copyright (C) 2008-2013 Genode Labs GmbH
+ * Copyright (C) 2008-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.
*/
-#include
-#include
-#include
-#include
+#include
+#include
#include
#include
#include
namespace Hello {
-
- struct Session_component : Genode::Rpc_object
- {
- void say_hello() {
- PDBG("I am here... Hello."); }
-
- int add(int a, int b) {
- return a + b; }
- };
-
- class Root_component : public Genode::Root_component
- {
- protected:
-
- Hello::Session_component *_create_session(const char *args)
- {
- PDBG("creating hello session.");
- return new (md_alloc()) Session_component();
- }
-
- public:
-
- Root_component(Genode::Rpc_entrypoint *ep,
- Genode::Allocator *allocator)
- : Genode::Root_component(ep, allocator)
- {
- PDBG("Creating root component.");
- }
- };
+ struct Session_component;
+ struct Root_component;
+ struct Main;
}
-using namespace Genode;
-
-int main(void)
+struct Hello::Session_component : Genode::Rpc_object
{
- /*
- * Get a session for the parent's capability service, so that we
- * are able to create capabilities.
- */
- Cap_connection cap;
+ void say_hello() {
+ Genode::log("I am here... Hello."); }
+
+ int add(int a, int b) {
+ return a + b; }
+};
+
+
+class Hello::Root_component
+:
+ public Genode::Root_component
+{
+ protected:
+
+ Session_component *_create_session(const char *args)
+ {
+ Genode::log("creating hello session");
+ return new (md_alloc()) Session_component();
+ }
+
+ public:
+
+ Root_component(Genode::Entrypoint &ep,
+ Genode::Allocator &alloc)
+ :
+ Genode::Root_component(ep, alloc)
+ {
+ Genode::log("creating root component");
+ }
+};
+
+
+struct Hello::Main
+{
+ Genode::Env &env;
/*
* A sliced heap is used for allocating session objects - thereby we
* can release objects separately.
*/
- static Sliced_heap sliced_heap(env()->ram_session(),
- env()->rm_session());
+ Genode::Sliced_heap sliced_heap { env.ram(), env.rm() };
- /*
- * Create objects for use by the framework.
- *
- * An 'Rpc_entrypoint' is created to announce our service's root
- * capability to our parent, manage incoming session creation
- * requests, and dispatch the session interface. The incoming RPC
- * requests are dispatched via a dedicated thread. The 'STACK_SIZE'
- * argument defines the size of the thread's stack. The additional
- * string argument is the name of the entry point, used for
- * debugging purposes only.
- */
- enum { STACK_SIZE = 4096 };
- static Rpc_entrypoint ep(&cap, STACK_SIZE, "hello_ep");
+ Hello::Root_component root { env.ep(), sliced_heap };
- static Hello::Root_component hello_root(&ep, &sliced_heap);
- env()->parent()->announce(ep.manage(&hello_root));
+ Main(Genode::Env &env) : env(env)
+ {
+ /*
+ * Create a RPC object capability for the root interface and
+ * announce the service to our parent.
+ */
+ env.parent().announce(env.ep().manage(root));
+ }
+};
- /* We are done with this and only act upon client requests now. */
- sleep_forever();
- return 0;
+Genode::size_t Component::stack_size() { return 64*1024; }
+
+
+void Component::construct(Genode::Env &env)
+{
+ static Hello::Main main(env);
}