Beispiel #1
0
 T readFF(GlobalAddress<FullEmpty<T>> fe_addr) {
   if (fe_addr.core() == mycore()) {
     DVLOG(2) << "local";
     return fe_addr.pointer()->readFF();
   }
   
   FullEmpty<T> result;
   auto result_addr = make_global(&result);
   
   send_message(fe_addr.core(), [fe_addr,result_addr]{
     auto& fe = *fe_addr.pointer();
     
     if (fe.full()) {
       // DVLOG(2) << "no need to block";
       fill_remote(result_addr, fe.readFF());
       return;
     }
     
     DVLOG(2) << "setting up to block (" << fe_addr << ")";
     auto* c = SuspendedDelegate::create([&fe,result_addr]{
       VLOG(0) << "suspended_delegate!";
       fill_remote(result_addr, fe.readFF());
     });
     add_waiter(&fe, c);
   });
   
   return result.readFF();
 }
Beispiel #2
0
 void call_async(Core dest, F func) {
   static_assert(std::is_same<R, decltype(func())>::value, "return type of callable must match the type of this Promise");
   _result.reset();
   delegate_ops++;
   delegate_async_ops++;
   Core origin = Grappa::mycore();
   
   if (dest == origin) {
     // short-circuit if local
     delegate_targets++;
     delegate_short_circuits++;
     fill(func());
   } else {
     start_time = Grappa::timestamp();
     
     send_heap_message(dest, [origin, func, this] {
       delegate_targets++;
       R val = func();
       
       // TODO: replace with handler-safe send_message
       send_heap_message(origin, [val, this] {
         this->network_time = Grappa::timestamp();
         Grappa::impl::record_network_latency(this->start_time);
         this->fill(val);
       });
     }); // send message
   }
 }
Beispiel #3
0
 /// Block on result being returned.
 inline const R get() {
   // ... and wait for the result
   const R r = _result.readFF();
   Grappa::impl::record_wakeup_latency(start_time, network_time);
   return r;
 }
Beispiel #4
0
 inline void fill(const R& r) {
   _result.writeXF(r);
 }