genode/repos/base/src/test/fpu/main.cc

87 lines
1.8 KiB
C++

/*
* \brief Test pseudo-parallel use of FPU if available
* \author Martin Stein
* \date 2014-04-29
*/
/*
* Copyright (C) 2012-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
/* Genode includes */
#include <base/component.h>
#include <base/heap.h>
#include <base/log.h>
#include <base/thread.h>
using namespace Genode;
class Fpu_user : public Thread
{
private:
float _x;
Signal_transmitter _st;
Semaphore & _sem;
void _calc(float volatile & x, float volatile & y)
{
for (unsigned j = 0; j < 100; j++) {
x *= (y * 1.357);
x /= (y * 1.246);
}
}
public:
Fpu_user(Env & env, float x, Signal_context_capability c, Semaphore &s)
: Thread(env, "fpu_user", sizeof(size_t)*2048), _x(x), _st(c), _sem(s) {
start(); }
void entry()
{
log("FPU user started");
enum { TRIALS = 1000 };
for (unsigned i = 0; i < TRIALS; i++) {
float volatile a = _x + (float)i * ((float)1 / TRIALS);
float volatile b = _x + (float)i * ((float)1 / TRIALS);
float volatile c = _x;
_calc(a, c);
_calc(b, c);
if (a != b) {
error("calculation error");
break;
}
}
_sem.up();
_st.submit();
}
};
struct Main
{
enum { FPU_USERS = 10 };
Semaphore sem { };
Env & env;
Heap heap { env.ram(), env.rm() };
Signal_handler<Main> handler { env.ep(), *this, &Main::handle };
Main(Env & env) : env(env) {
for (unsigned i = 0; i < FPU_USERS; i++)
new (heap) Fpu_user(env, (i + 1) * 1.234, handler, sem); }
void handle() {
if (sem.cnt() >= FPU_USERS) log("test done"); }
};
void Component::construct(Genode::Env & env) {
static Main main(env); }