start.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <stdlib.h>
  2. #include "Untrusted.hpp"
  3. #include "start.hpp"
  4. static void route_test(NetIO &netio, char **args)
  5. {
  6. // Count the number of arguments
  7. size_t nargs = 0;
  8. while (args[nargs]) {
  9. ++nargs;
  10. }
  11. uint16_t num_nodes = netio.num_nodes;
  12. size_t sq_nodes = num_nodes;
  13. sq_nodes *= sq_nodes;
  14. if (nargs != sq_nodes) {
  15. printf("Expecting %lu arguments, found %lu\n", sq_nodes, nargs);
  16. return;
  17. }
  18. // The arguments are num_nodes sets of num_nodes values. The jth
  19. // value in the ith set is the number of private routing tokens
  20. // ingestion node i holds for storage node j.
  21. // We are node i = netio.me, so ignore the other sets of values.
  22. uint32_t num_tokens[num_nodes];
  23. uint32_t tot_tokens = 0;
  24. for (nodenum_t j=0;j<num_nodes;++j) {
  25. num_tokens[j] = atoi(args[netio.me*num_nodes+j]);
  26. tot_tokens += num_tokens[j];
  27. }
  28. const Config &config = netio.config();
  29. uint16_t msg_size = config.msg_size;
  30. nodenum_t my_node_num = config.my_node_num;
  31. uint8_t *msgs = new uint8_t[tot_tokens * msg_size];
  32. uint8_t *nextmsg = msgs;
  33. uint32_t dest_uid_mask = (1 << DEST_UID_BITS) - 1;
  34. uint32_t rem_tokens = tot_tokens;
  35. while (rem_tokens > 0) {
  36. // Pick a random remaining token
  37. uint32_t r = uint32_t(lrand48()) % rem_tokens;
  38. for (nodenum_t j=0;j<num_nodes;++j) {
  39. if (r < num_tokens[j]) {
  40. // Use a token from node j
  41. *((uint32_t*)nextmsg) =
  42. (j << DEST_UID_BITS) +
  43. (((r<<8)+(my_node_num&0xff)) & dest_uid_mask);
  44. // Put a bunch of copies of r as the message body
  45. for (uint16_t i=1;i<msg_size/4;++i) {
  46. ((uint32_t*)nextmsg)[i] = r;
  47. }
  48. num_tokens[j] -= 1;
  49. rem_tokens -= 1;
  50. nextmsg += msg_size;
  51. } else {
  52. r -= num_tokens[j];
  53. }
  54. }
  55. }
  56. /*
  57. for (uint32_t i=0;i<tot_tokens;++i) {
  58. for(uint16_t j=0;j<msg_size/4;++j) {
  59. printf("%08x ", ((uint32_t*)msgs)[i*msg_size/4+j]);
  60. }
  61. printf("\n");
  62. }
  63. */
  64. // Precompute some WaksmanNetworks
  65. size_t num_sizes = ecall_precompute_sort(-1);
  66. for (int i=0;i<int(num_sizes);++i) {
  67. ecall_precompute_sort(i);
  68. }
  69. if (!ecall_ingest_raw(msgs, tot_tokens)) {
  70. printf("Ingestion failed\n");
  71. return;
  72. }
  73. ecall_routing_proceed([&](uint32_t round_num) {
  74. printf("Round %u complete\n", round_num);
  75. if (round_num == 1) {
  76. boost::asio::post(netio.io_context(), []{
  77. ecall_routing_proceed([&](uint32_t round_num2) {
  78. printf("Round %u complete\n", round_num2);
  79. });
  80. });
  81. }
  82. });
  83. }
  84. // Once all the networking is set up, start doing whatever we were asked
  85. // to do on the command line
  86. void start(NetIO &netio, char **args)
  87. {
  88. if (*args && !strcmp(*args, "route")) {
  89. ++args;
  90. route_test(netio, args);
  91. return;
  92. }
  93. }