mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 07:08:18 +00:00
committed by
Norman Feske
parent
4b7d58fccc
commit
f45cf49405
114
repos/base/src/test/fpu/main.cc
Normal file
114
repos/base/src/test/fpu/main.cc
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* \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/thread.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
class Sync_signal_transmitter : public Signal_transmitter
|
||||
{
|
||||
private:
|
||||
|
||||
Lock _lock;
|
||||
|
||||
public:
|
||||
|
||||
Sync_signal_transmitter(Signal_context_capability context = Signal_context_capability())
|
||||
:
|
||||
Signal_transmitter(context),
|
||||
_lock(Lock::UNLOCKED)
|
||||
{ }
|
||||
|
||||
void submit(unsigned cnt)
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
Signal_transmitter::submit(cnt);
|
||||
}
|
||||
};
|
||||
|
||||
class Fpu_user : public Thread<4 * 1024>
|
||||
{
|
||||
private:
|
||||
|
||||
float _x;
|
||||
Sync_signal_transmitter * _st;
|
||||
|
||||
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() : Thread("fpu_user"), _x(0), _st(0) { }
|
||||
|
||||
void start(float const x, Sync_signal_transmitter * const st)
|
||||
{
|
||||
_x = x;
|
||||
_st = st;
|
||||
Thread::start();
|
||||
}
|
||||
|
||||
void entry()
|
||||
{
|
||||
Genode::printf("FPU user started\n");
|
||||
bool submitted = false;
|
||||
while (1) {
|
||||
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) {
|
||||
PERR("calculation error");
|
||||
_st->submit(1);
|
||||
sleep_forever();
|
||||
}
|
||||
}
|
||||
if (!submitted) {
|
||||
_st->submit(1);
|
||||
submitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
/* create ack signal */
|
||||
Signal_context sc;
|
||||
Signal_receiver sr;
|
||||
Signal_context_capability const scc = sr.manage(&sc);
|
||||
Sync_signal_transmitter st(scc);
|
||||
|
||||
/* start pseudo-parallel FPU users */
|
||||
enum { FPU_USERS = 10 };
|
||||
Fpu_user fpu_users[FPU_USERS];
|
||||
for (unsigned i = 0; i < FPU_USERS; i++) {
|
||||
float const x = (i + 1) * 1.234;
|
||||
fpu_users[i].start(x, &st);
|
||||
}
|
||||
/* wait for an ack of every FPU user */
|
||||
for (unsigned i = 0; i < FPU_USERS;) { i += sr.wait_for_signal().num(); }
|
||||
printf("test done\n");
|
||||
sleep_forever();
|
||||
return 0;
|
||||
}
|
14
repos/base/src/test/fpu/target.mk
Normal file
14
repos/base/src/test/fpu/target.mk
Normal file
@ -0,0 +1,14 @@
|
||||
#
|
||||
# \brief Test pseudo-parallel use of FPU if available
|
||||
# \author Martin Stein
|
||||
# \date 2012-04-25
|
||||
#
|
||||
|
||||
# Set program name
|
||||
TARGET = test-fpu
|
||||
|
||||
# Add C++ sources
|
||||
SRC_CC += main.cc
|
||||
|
||||
# Add libraries
|
||||
LIBS += base
|
Reference in New Issue
Block a user