diff --git a/repos/mml/src/app/volatile_cell/target.mk b/repos/mml/src/app/volatile_cell/target.mk
index ec6dfc3aae..cf18e8f9f4 100644
--- a/repos/mml/src/app/volatile_cell/target.mk
+++ b/repos/mml/src/app/volatile_cell/target.mk
@@ -1,3 +1,3 @@
TARGET = volatile_cell
-SRC_CC = volatile_cell.cc
+SRC_CC = volatile_cell.cc loop.c
LIBS += base
\ No newline at end of file
diff --git a/repos/mml/src/app/volatile_cell/volatile_cell.cc b/repos/mml/src/app/volatile_cell/volatile_cell.cc
index 5f866d1cb4..bf5c8f7c1f 100644
--- a/repos/mml/src/app/volatile_cell/volatile_cell.cc
+++ b/repos/mml/src/app/volatile_cell/volatile_cell.cc
@@ -2,11 +2,61 @@
#include
#include
#include
-
+#include
+#include
+#include
+#include
+#include "loop.h"
namespace Hoitaja_test {
class Volatile_cell;
+ struct Worker;
}
+#define LOOPS 100000
+#define ALLOC
+
+static Nova::mword_t channel;
+
+void short_loop(unsigned long k)
+{
+ for (unsigned long i = 0; i < k; i++) {
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ asm volatile("nop");
+ }
+}
+
+struct Hoitaja_test::Worker : public Genode::Thread
+{
+ Genode::uint16_t _id;
+
+ void entry() override
+ {
+ Nova::mword_t channel_id = 0;
+ Nova::cpu_id(channel_id);
+ unsigned long volatile *my_channel = &reinterpret_cast(channel)[channel_id];
+
+ //Genode::log("Started worker ", _id, " on CPU ", channel_id);
+ Nova::yield();
+ while (true) {
+ while (!(__atomic_load_n(my_channel, __ATOMIC_SEQ_CST)))
+ short_loop(770);
+ //Genode::log("Returning core ", channel_id);
+ Nova::yield(false);
+ }
+ }
+
+ Worker(Genode::Env &env, Genode::uint16_t id, Location const &location)
+ : Thread(env, Name("test_", location.xpos(), "x", location.ypos()), 4 * 4096, location, Weight(), env.cpu()), _id(id)
+ { }
+};
class Hoitaja_test::Volatile_cell
{
@@ -14,21 +64,72 @@ class Hoitaja_test::Volatile_cell
Genode::Env &_env;
Timer::Connection _timer{_env};
- void _handle_timeout()
- {
- Genode::log("My time has come. Exiting ...");
- _env.parent().exit(0);
- }
-
- Genode::Signal_handler _timeout_handler{
- _env.ep(), *this, &Volatile_cell::_handle_timeout};
-
public:
Volatile_cell(Genode::Env &env) : _env(env)
{
Genode::log("My affinity space is ", _env.cpu().affinity_space());
- _timer.sigh(_timeout_handler);
- _timer.trigger_once(30 * 1000 * 1000);
+
+ /* Pseuda-MxTasking Initialization */
+ Nova::uint8_t rc = 0;
+ Genode::Ram_dataspace_capability ds = env.ram().alloc(4096);
+ channel = env.rm().attach(ds);
+
+ if ((rc = Nova::mxinit(0, 0, channel))) {
+ Genode::error("Failed to init MxTasking: ", rc);
+ }
+
+ Genode::Heap _heap{env.ram(), env.rm()};
+
+ Nova::mword_t my_cpu = 0;
+ Nova::cpu_id(my_cpu);
+
+ Genode::log("Main thread on CPU ", my_cpu);
+
+ unsigned cores_total = env.topo().global_affinity_space().total();
+
+
+ for (Genode::uint16_t cpu = 1; cpu < cores_total; cpu++)
+ {
+ if (cpu == cores_total - my_cpu)
+ continue;
+ //Genode::log("Created worker for CPU ", cpu);
+ Worker *worker = new (_heap) Worker(env, cpu, env.topo().global_affinity_space().location_of_index(cpu));
+ worker->start();
+ }
+ Nova::mword_t mask = 0;
+ Nova::core_allocation(mask, true);
+
+ _timer.msleep(my_cpu);
+
+ Genode::log("Initial allocation: ", mask);
+
+ for (; ;) {
+#ifdef ALLOC
+ Nova::mword_t allocation = 0;
+ if (Nova::alloc_cores(32, allocation) != Nova::NOVA_OK) {
+ //Genode::error("Failed to allocate cores");
+ }
+ /*if (allocation != mask)
+ {
+ Genode::log("Allocated cmap = ",allocation);
+ }*/
+ //_timer.usleep(2000);
+ while ((allocation != (mask | 0x1)) && (allocation != mask) ){
+ Nova::core_allocation(allocation);
+ //Genode::log("Core allocation = ", allocation, " mask = ", mask);
+ __builtin_ia32_pause();
+ }
+
+ loop(500);
+#endif
+
+ //_timer.msleep(20);
+ }
+ while (true)
+ ;
+ // Genode::log("My time has come. Exiting ... cmap = ", allocation);
+ _timer.msleep(1000UL * 1000);
+ _env.parent().exit(0);
}
};