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:
Alexander Boettcher
2013-07-09 15:56:19 +02:00
committed by Norman Feske
parent 683832f461
commit fdaeda47bb
3 changed files with 107 additions and 17 deletions

View File

@@ -18,35 +18,38 @@
#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>
{
int const cpu_number;
unsigned const _cpu_number;
unsigned long volatile cnt;
Genode::uint64_t volatile cnt;
Genode::Lock barrier;
void entry()
{
PINF("thread started on CPU %d, spinning...", cpu_number);
barrier.unlock();
PINF("thread started on CPU %u, spinning...", _cpu_number);
unsigned round = 0;
for (;;) {
cnt++;
/* show a life sign every now and then... */
if (cnt > 100*1024*1024) {
PINF("thread on CPU %d keeps counting...\n", cpu_number);
cnt = 0;
if (cnt % COUNT_VALUE == 0) {
PINF("thread on CPU %u keeps counting - round %u...\n",
_cpu_number, round++);
}
}
}
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)
{
Genode::env()->cpu_session()->affinity(Thread_base::cap(), cpu_number);
@@ -60,15 +63,62 @@ int main(int argc, char **argv)
using namespace Genode;
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 */
thread_0.barrier.lock();
thread_1.barrier.lock();
unsigned cpus = env()->cpu_session()->num_cpus();
printf("Detected %u CPU%c.\n", cpus, cpus > 1 ? 's' : ' ');
/* 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("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();
}