void call(Core dest, F func, void (F::*mf)() const) { delegate_ops++; Core origin = Grappa::mycore(); if (dest == origin) { // short-circuit if local delegate_short_circuits++; func(); } else { struct Desc { int64_t network_time; int64_t start_time; } desc; desc.network_time = 0; desc.start_time = Grappa::timestamp(); FullEmpty<Desc*> result(&desc); result.readFE(); auto ra = make_global(&result); send_message(dest, [ra,func] { delegate_targets++; func(); // TODO: replace with handler-safe send_message send_heap_message(ra.core(), [ra] { auto r = ra->readXX(); r->network_time = Grappa::timestamp(); record_network_latency(r->start_time); ra->writeXF(r); }); }); // send message // ... and wait for the call to complete result.readFF(); record_wakeup_latency(desc.start_time, desc.network_time); } }
T writeFF( T t ) { block_until(State::FULL); T tt = writeXF( t ); return tt; }
T writeEF( T t ) { block_until(State::EMPTY); T tt = writeXF( t ); return tt; }