mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 18:06:50 +00:00
run: extend affinity test
* read out supported number of CPUs * start per CPU a thread * monitor by main thread liveness of remote CPU threads * add a round variable * terminate run script after a specific round or after 90s * on qemu wait 5 rounds, on native runs 40 Add run script to autopilot list Issue #814
This commit is contained in:
parent
683832f461
commit
fdaeda47bb
@ -1,3 +1,15 @@
|
|||||||
|
#
|
||||||
|
# \brief Test to start threads 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/affinity"
|
build "core init test/affinity"
|
||||||
|
|
||||||
create_boot_directory
|
create_boot_directory
|
||||||
@ -20,6 +32,33 @@ install_config {
|
|||||||
|
|
||||||
build_boot_image "core init test-affinity"
|
build_boot_image "core init test-affinity"
|
||||||
|
|
||||||
append qemu_args " -nographic -m 64 -smp 2,cores=2 "
|
if {[is_qemu_available]} {
|
||||||
|
set want_cpus 4
|
||||||
|
set rounds "05"
|
||||||
|
append qemu_args "-nographic -m 64 -smp $want_cpus,cores=$want_cpus "
|
||||||
|
} else {
|
||||||
|
set rounds "10"
|
||||||
|
if {[have_spec x86]} { set rounds "40" }
|
||||||
|
}
|
||||||
|
|
||||||
run_genode_until forever
|
run_genode_until "Round $rounds:.*\n" 90
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set good_string {[init -> test-affinity] Round XX:}
|
||||||
|
for {set i 0} {$i < $cpus} {incr i} {
|
||||||
|
append good_string " A"
|
||||||
|
}
|
||||||
|
|
||||||
|
grep_output {\[init -\> test-affinity\] Round}
|
||||||
|
unify_output {[0-9]+} "XX"
|
||||||
|
|
||||||
|
compare_output_to $good_string
|
||||||
|
@ -18,35 +18,38 @@
|
|||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
|
|
||||||
|
|
||||||
enum { STACK_SIZE = sizeof(long)*1024 };
|
enum { STACK_SIZE = sizeof(long)*1024, COUNT_VALUE = 10 * 1024 * 1024 };
|
||||||
|
|
||||||
struct Spinning_thread : Genode::Thread<STACK_SIZE>
|
struct Spinning_thread : Genode::Thread<STACK_SIZE>
|
||||||
{
|
{
|
||||||
int const cpu_number;
|
unsigned const _cpu_number;
|
||||||
|
|
||||||
unsigned long volatile cnt;
|
Genode::uint64_t volatile cnt;
|
||||||
|
|
||||||
Genode::Lock barrier;
|
Genode::Lock barrier;
|
||||||
|
|
||||||
void entry()
|
void entry()
|
||||||
{
|
{
|
||||||
PINF("thread started on CPU %d, spinning...", cpu_number);
|
|
||||||
|
|
||||||
barrier.unlock();
|
barrier.unlock();
|
||||||
|
|
||||||
|
PINF("thread started on CPU %u, spinning...", _cpu_number);
|
||||||
|
|
||||||
|
unsigned round = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
/* show a life sign every now and then... */
|
/* show a life sign every now and then... */
|
||||||
if (cnt > 100*1024*1024) {
|
if (cnt % COUNT_VALUE == 0) {
|
||||||
PINF("thread on CPU %d keeps counting...\n", cpu_number);
|
PINF("thread on CPU %u keeps counting - round %u...\n",
|
||||||
cnt = 0;
|
_cpu_number, round++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Spinning_thread(unsigned cpu_number, char const *name)
|
Spinning_thread(unsigned cpu_number, char const *name)
|
||||||
:
|
:
|
||||||
Genode::Thread<STACK_SIZE>(name), cpu_number(cpu_number), cnt(0),
|
Genode::Thread<STACK_SIZE>(name), _cpu_number(cpu_number), cnt(0ULL),
|
||||||
barrier(Genode::Lock::LOCKED)
|
barrier(Genode::Lock::LOCKED)
|
||||||
{
|
{
|
||||||
Genode::env()->cpu_session()->affinity(Thread_base::cap(), cpu_number);
|
Genode::env()->cpu_session()->affinity(Thread_base::cap(), cpu_number);
|
||||||
@ -60,15 +63,62 @@ int main(int argc, char **argv)
|
|||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
printf("--- test-affinity started ---\n");
|
printf("--- test-affinity started ---\n");
|
||||||
static Spinning_thread thread_0(0, "thread_0");
|
|
||||||
static Spinning_thread thread_1(1, "thread_1");
|
|
||||||
|
|
||||||
/* wait until both threads are up and running */
|
unsigned cpus = env()->cpu_session()->num_cpus();
|
||||||
thread_0.barrier.lock();
|
printf("Detected %u CPU%c.\n", cpus, cpus > 1 ? 's' : ' ');
|
||||||
thread_1.barrier.lock();
|
|
||||||
|
/* get some memory for the thread objects */
|
||||||
|
Spinning_thread ** threads = new (env()->heap()) Spinning_thread*[cpus];
|
||||||
|
uint64_t * thread_cnt = new (env()->heap()) uint64_t[cpus];
|
||||||
|
|
||||||
|
/* construct the thread objects */
|
||||||
|
for (unsigned i = 0; i < cpus; i++)
|
||||||
|
threads[i] = new (env()->heap()) Spinning_thread(i, "thread");
|
||||||
|
|
||||||
|
/* wait until all threads are up and running */
|
||||||
|
for (unsigned i = 0; i < cpus; i++)
|
||||||
|
threads[i]->barrier.lock();
|
||||||
|
|
||||||
printf("Threads started on a different CPU each.\n");
|
printf("Threads started on a different CPU each.\n");
|
||||||
printf("You may inspect them using the kernel debugger\n");
|
printf("You may inspect them using the kernel debugger - if you have one.\n");
|
||||||
|
printf("Main thread monitors client threads and prints the status of them.\n");
|
||||||
|
printf("Legend : D - DEAD, A - ALIVE\n");
|
||||||
|
|
||||||
|
volatile uint64_t cnt = 0;
|
||||||
|
unsigned round = 0;
|
||||||
|
|
||||||
|
char const text_cpu[] = " CPU: ";
|
||||||
|
char const text_round[] = "Round %2u: ";
|
||||||
|
char * output_buffer = new (env()->heap()) char [sizeof(text_cpu) + 3 * cpus];
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
cnt++;
|
||||||
|
|
||||||
|
/* try to get a life sign by the main thread from the remote threads */
|
||||||
|
if (cnt % COUNT_VALUE == 0) {
|
||||||
|
char * output = output_buffer;
|
||||||
|
snprintf(output, sizeof(text_cpu), text_cpu);
|
||||||
|
output += sizeof(text_cpu) - 1;
|
||||||
|
for (unsigned i = 0; i < cpus; i++) {
|
||||||
|
snprintf(output, 4, "%2u ", i);
|
||||||
|
output += 3;
|
||||||
|
}
|
||||||
|
printf("%s\n", output_buffer);
|
||||||
|
|
||||||
|
output = output_buffer;
|
||||||
|
snprintf(output, sizeof(text_round), text_round, round);
|
||||||
|
output += sizeof(text_round) - 2;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < cpus; i++) {
|
||||||
|
snprintf(output, 4, "%s ",
|
||||||
|
thread_cnt[i] == threads[i]->cnt ? " D" : " A");
|
||||||
|
output += 3;
|
||||||
|
thread_cnt[i] = threads[i]->cnt;
|
||||||
|
}
|
||||||
|
printf("%s\n", output_buffer);
|
||||||
|
|
||||||
|
round ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
sleep_forever();
|
sleep_forever();
|
||||||
}
|
}
|
||||||
|
@ -25,3 +25,4 @@ l4linux_netperf
|
|||||||
l4linux_netperf_usb30
|
l4linux_netperf_usb30
|
||||||
l4linux_netperf_bridge
|
l4linux_netperf_bridge
|
||||||
noux_tool_chain_auto
|
noux_tool_chain_auto
|
||||||
|
affinity
|
||||||
|
Loading…
x
Reference in New Issue
Block a user