mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-01 00:10:37 +00:00
run: Rpc_entrypoint test running on multiple CPUs
Add run script to autopilot list Issue #814
This commit is contained in:
parent
9e8255948d
commit
2e58428b51
78
base/run/mp_server.run
Normal file
78
base/run/mp_server.run
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#
|
||||||
|
# \brief Test to start and call RPC entrypoint on all available CPUs
|
||||||
|
# \author Norman Feske
|
||||||
|
# \author Alexander Boettcher
|
||||||
|
#
|
||||||
|
|
||||||
|
if {![have_spec nova] && ![have_spec foc]} {
|
||||||
|
puts "Platform is unsupported."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
build "core init test/mp_server"
|
||||||
|
|
||||||
|
create_boot_directory
|
||||||
|
|
||||||
|
install_config {
|
||||||
|
<config>
|
||||||
|
<parent-provides>
|
||||||
|
<service name="LOG"/>
|
||||||
|
<service name="CPU"/>
|
||||||
|
<service name="RM"/>
|
||||||
|
<service name="CAP"/>
|
||||||
|
</parent-provides>
|
||||||
|
<default-route>
|
||||||
|
<any-service> <parent/> </any-service>
|
||||||
|
</default-route>
|
||||||
|
<start name="test-server-mp">
|
||||||
|
<resource name="RAM" quantum="10M"/>
|
||||||
|
</start>
|
||||||
|
</config>
|
||||||
|
}
|
||||||
|
|
||||||
|
build_boot_image "core init test-server-mp"
|
||||||
|
|
||||||
|
if {[is_qemu_available]} {
|
||||||
|
set want_cpus 2
|
||||||
|
append qemu_args " -nographic -m 64 -smp $want_cpus,cores=$want_cpus "
|
||||||
|
}
|
||||||
|
|
||||||
|
# run the test
|
||||||
|
run_genode_until {\[init -\> test-server-mp\] done.*\n} 20
|
||||||
|
|
||||||
|
set cpus [regexp -inline {Detected [0-9]+ CPU[ s].*\n} $output]
|
||||||
|
set cpus [regexp -inline {[0-9]+} $cpus]
|
||||||
|
|
||||||
|
if {[is_qemu_available]} {
|
||||||
|
if {$want_cpus != $cpus} {
|
||||||
|
puts "CPU count is not as expected: $want_cpus != $cpus"
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# pay only attention to the output of init and its children
|
||||||
|
grep_output {^\[init }
|
||||||
|
|
||||||
|
unify_output {transfer cap [a-f0-9]+} "transfer cap UNIFIED"
|
||||||
|
unify_output {yes - idx [a-f0-9]+} "yes - idx UNIFIED"
|
||||||
|
unify_output {\- received cap [a-f0-9]+} "- received cap UNIFIED"
|
||||||
|
|
||||||
|
compare_output_to {
|
||||||
|
[init -> test-server-mp] --- test-mp_server started ---
|
||||||
|
[init -> test-server-mp] Detected 2 CPUs.
|
||||||
|
[init -> test-server-mp] call server on CPU 0
|
||||||
|
[init -> test-server-mp] function test_untyped: got value 0
|
||||||
|
[init -> test-server-mp] call server on CPU 1
|
||||||
|
[init -> test-server-mp] function test_untyped: got value 1
|
||||||
|
[init -> test-server-mp] call server on CPU 0 - transfer cap UNIFIED
|
||||||
|
[init -> test-server-mp] function test_cap: capability is valid ? yes - idx UNIFIED
|
||||||
|
[init -> test-server-mp] call server on CPU 1 - transfer cap UNIFIED
|
||||||
|
[init -> test-server-mp] function test_cap: capability is valid ? yes - idx UNIFIED
|
||||||
|
[init -> test-server-mp] call server on CPU 0 - transfer cap UNIFIED
|
||||||
|
[init -> test-server-mp] function test_cap_reply: capability is valid ? yes - idx UNIFIED
|
||||||
|
[init -> test-server-mp] got from server on CPU 0 - received cap UNIFIED
|
||||||
|
[init -> test-server-mp] call server on CPU 1 - transfer cap UNIFIED
|
||||||
|
[init -> test-server-mp] function test_cap_reply: capability is valid ? yes - idx UNIFIED
|
||||||
|
[init -> test-server-mp] got from server on CPU 1 - received cap UNIFIED
|
||||||
|
[init -> test-server-mp] done
|
||||||
|
}
|
138
base/src/test/mp_server/main.cc
Normal file
138
base/src/test/mp_server/main.cc
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* \brief Multiprocessor test for a server having multiple Rpc_entrypoints on
|
||||||
|
* different CPUs
|
||||||
|
* \author Alexander Boettcher
|
||||||
|
* \date 2013-07-19
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
|
* under the terms of the GNU General Public License version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Genode includes */
|
||||||
|
#include <base/printf.h>
|
||||||
|
#include <base/thread.h>
|
||||||
|
#include <base/env.h>
|
||||||
|
#include <base/sleep.h>
|
||||||
|
|
||||||
|
#include <cap_session/connection.h>
|
||||||
|
#include <base/rpc_server.h>
|
||||||
|
|
||||||
|
namespace Test {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test session interface definition
|
||||||
|
*/
|
||||||
|
struct Session : Genode::Session
|
||||||
|
{
|
||||||
|
static const char *service_name() { return "MP_RPC_TEST"; }
|
||||||
|
|
||||||
|
GENODE_RPC(Rpc_test_untyped, void, test_untyped, unsigned);
|
||||||
|
GENODE_RPC(Rpc_test_cap, void, test_cap, Genode::Native_capability);
|
||||||
|
GENODE_RPC(Rpc_test_cap_reply, Genode::Native_capability,
|
||||||
|
test_cap_reply, Genode::Native_capability);
|
||||||
|
GENODE_RPC_INTERFACE(Rpc_test_untyped, Rpc_test_cap, Rpc_test_cap_reply);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Client : Genode::Rpc_client<Session>
|
||||||
|
{
|
||||||
|
Client(Capability<Session> cap) : Rpc_client<Session>(cap) { }
|
||||||
|
|
||||||
|
void test_untyped(unsigned value) { call<Rpc_test_untyped>(value); }
|
||||||
|
void test_cap(Genode::Native_capability cap) { call<Rpc_test_cap>(cap); }
|
||||||
|
Genode::Native_capability test_cap_reply(Genode::Native_capability cap) {
|
||||||
|
return call<Rpc_test_cap_reply>(cap); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Component : Genode::Rpc_object<Session, Component>
|
||||||
|
{
|
||||||
|
/* Test to just sent plain words (untyped items) */
|
||||||
|
void test_untyped(unsigned);
|
||||||
|
/* Test to transfer a object capability during send */
|
||||||
|
void test_cap(Genode::Native_capability);
|
||||||
|
/* Test to transfer a object capability during send+reply */
|
||||||
|
Genode::Native_capability test_cap_reply(Genode::Native_capability);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Genode::Capability<Session> Capability;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session implementation
|
||||||
|
*/
|
||||||
|
void Component::test_untyped(unsigned value) {
|
||||||
|
Genode::printf("function %s: got value %u\n", __FUNCTION__, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::test_cap(Genode::Native_capability cap) {
|
||||||
|
Genode::printf("function %s: capability is valid ? %s - idx %lx\n",
|
||||||
|
__FUNCTION__, cap.valid() ? "yes" : "no",
|
||||||
|
cap.local_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
Genode::Native_capability Component::test_cap_reply(Genode::Native_capability cap) {
|
||||||
|
Genode::printf("function %s: capability is valid ? %s - idx %lx\n",
|
||||||
|
__FUNCTION__, cap.valid() ? "yes" : "no",
|
||||||
|
cap.local_name());
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up a server running on every CPU one Rpc_entrypoint
|
||||||
|
*/
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
printf("--- test-mp_server started ---\n");
|
||||||
|
|
||||||
|
unsigned cpus = env()->cpu_session()->num_cpus();
|
||||||
|
printf("Detected %u CPU%c.\n", cpus, cpus > 1 ? 's' : ' ');
|
||||||
|
|
||||||
|
enum { STACK_SIZE = 4096 };
|
||||||
|
|
||||||
|
static Cap_connection cap;
|
||||||
|
Rpc_entrypoint ** eps = new (env()->heap()) Rpc_entrypoint*[cpus];
|
||||||
|
for (unsigned i = 0; i < cpus; i++)
|
||||||
|
eps[i] = new (env()->heap()) Rpc_entrypoint(&cap, STACK_SIZE, "rpc en",
|
||||||
|
true, i);
|
||||||
|
|
||||||
|
/* XXX using the same object and putting it to different queues fails XXX */
|
||||||
|
Test::Component * components = new (env()->heap()) Test::Component[cpus];
|
||||||
|
|
||||||
|
Test::Capability * caps = new (env()->heap()) Test::Capability[cpus];
|
||||||
|
for (unsigned i = 0; i < cpus; i++)
|
||||||
|
caps[i] = eps[i]->manage(&components[i]);
|
||||||
|
|
||||||
|
Test::Client ** clients = new (env()->heap()) Test::Client*[cpus];
|
||||||
|
for (unsigned i = 0; i < cpus; i++)
|
||||||
|
clients[i] = new (env()->heap()) Test::Client(caps[i]);
|
||||||
|
|
||||||
|
/* Test: Invoke RPC entrypoint on different CPUs */
|
||||||
|
for (unsigned i = 0; i < cpus; i++) {
|
||||||
|
printf("call server on CPU %u\n", i);
|
||||||
|
clients[i]->test_untyped(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test: Transfer a capability to RPC Entrypoints on different CPUs */
|
||||||
|
for (unsigned i = 0; i < cpus; i++) {
|
||||||
|
Native_capability cap = caps[0];
|
||||||
|
printf("call server on CPU %u - transfer cap %lx\n", i, cap.local_name());
|
||||||
|
clients[i]->test_cap(cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test: Transfer a capability to RPC Entrypoints and back */
|
||||||
|
for (unsigned i = 0; i < cpus; i++) {
|
||||||
|
Native_capability cap = caps[0];
|
||||||
|
printf("call server on CPU %u - transfer cap %lx\n", i, cap.local_name());
|
||||||
|
Native_capability rcap = clients[i]->test_cap_reply(cap);
|
||||||
|
printf("got from server on CPU %u - received cap %lx\n", i, rcap.local_name());
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("done\n");
|
||||||
|
|
||||||
|
sleep_forever();
|
||||||
|
}
|
3
base/src/test/mp_server/target.mk
Normal file
3
base/src/test/mp_server/target.mk
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TARGET = test-server-mp
|
||||||
|
SRC_CC = main.cc
|
||||||
|
LIBS = base
|
@ -26,3 +26,4 @@ l4linux_netperf_usb30
|
|||||||
l4linux_netperf_bridge
|
l4linux_netperf_bridge
|
||||||
noux_tool_chain_auto
|
noux_tool_chain_auto
|
||||||
affinity
|
affinity
|
||||||
|
mp_server
|
||||||
|
Loading…
x
Reference in New Issue
Block a user