parent
4b7d58fccc
commit
f45cf49405
60
repos/base/run/fpu.run
Normal file
60
repos/base/run/fpu.run
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#
|
||||||
|
# Build
|
||||||
|
#
|
||||||
|
|
||||||
|
build "core init test/fpu"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Boot image
|
||||||
|
#
|
||||||
|
|
||||||
|
create_boot_directory
|
||||||
|
|
||||||
|
install_config {
|
||||||
|
<config>
|
||||||
|
<parent-provides>
|
||||||
|
<service name="ROM"/>
|
||||||
|
<service name="RAM"/>
|
||||||
|
<service name="CPU"/>
|
||||||
|
<service name="RM"/>
|
||||||
|
<service name="CAP"/>
|
||||||
|
<service name="PD"/>
|
||||||
|
<service name="LOG"/>
|
||||||
|
<service name="SIGNAL"/>
|
||||||
|
</parent-provides>
|
||||||
|
<default-route>
|
||||||
|
<any-service> <parent/> </any-service>
|
||||||
|
</default-route>
|
||||||
|
<start name="test">
|
||||||
|
<binary name="test-fpu"/>
|
||||||
|
<resource name="RAM" quantum="10M"/>
|
||||||
|
</start>
|
||||||
|
</config>
|
||||||
|
}
|
||||||
|
|
||||||
|
build_boot_image "core init test-fpu"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Execution
|
||||||
|
#
|
||||||
|
|
||||||
|
append qemu_args "-nographic -m 64"
|
||||||
|
|
||||||
|
run_genode_until "test done.*\n" 60
|
||||||
|
|
||||||
|
grep_output {^\[init -\> test\]}
|
||||||
|
|
||||||
|
compare_output_to {
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] FPU user started
|
||||||
|
[init -> test] test done
|
||||||
|
}
|
||||||
|
|
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
|
Loading…
Reference in New Issue
Block a user