87 lines
1.8 KiB
C++
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-2014 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/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); }
|