#include #include #include #include "Untrusted.hpp" #include "start.hpp" // Default 4 epochs int num_epochs = 4; // Default epoch_duration of 5 seconds int epoch_duration = 5; // Default of 12 Waksman Networks (3 per private_route for 4 epochs) int num_WN_to_precompute = 12; // We'll always run the WN precomputation in the foreground // TODO: Later fix this to a command line param bool FOREGROUND_PRECOMPUTE = true; #define CEILDIV(x,y) (((x)+(y)-1)/(y)) class Epoch { NetIO &netio; uint32_t epoch_num; std::mutex m; std::condition_variable cv; bool epoch_complete; void round_cb(uint32_t round_num) { if (round_num) { printf("Round %u complete\n", round_num); boost::asio::post(netio.io_context(), [this]{ proceed(); }); } else { printf("Epoch %u complete\n", epoch_num); { std::lock_guard lk(m); epoch_complete = true; } const NodeConfig &my_conf = netio.myconfig(); if(my_conf.roles & ROLE_STORAGE) { boost::asio::post(netio.io_context(), [this]{ netio.send_client_mailbox(); }); } cv.notify_one(); } } public: Epoch(NetIO &netio_obj, uint32_t ep_num): netio(netio_obj), epoch_num(ep_num), epoch_complete(false) {} void proceed() { ecall_routing_proceed([this](uint32_t round_num) { round_cb(round_num); }); } void wait() { std::unique_lock lk(m); cv.wait(lk, [this]{ return epoch_complete; }); } }; static void epoch(NetIO &netio, char **args) { static uint32_t epoch_num = 1; uint16_t num_nodes = netio.num_nodes; uint32_t num_tokens[num_nodes]; uint32_t tot_tokens = 0; for (nodenum_t j=0;j 0) { // Pick a random remaining token uint32_t r = uint32_t(lrand48()) % rem_tokens; for (nodenum_t j=0;j ts; for (int i=0;i ts; for (int i=0;i ts; for (int j=0; j