1
0

hcube.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <u.h>
  2. #include <lib9.h>
  3. int dim = 6;
  4. int
  5. fdfork(int fd, int post)
  6. {
  7. static int seq;
  8. char path[64];
  9. char buf[64];
  10. int pfd, len;
  11. if(post){
  12. int ch[2];
  13. pipe(ch);
  14. len = snprint(path, sizeof path, "hcube.%d.%d", getpid(), seq++);
  15. pfd = ocreate(path, OWRITE|ORCLOSE, 0666);
  16. if(pfd == -1)
  17. sysfatal("fdfork: create: %r");
  18. snprint(buf, sizeof buf, "%d", ch[0]);
  19. if(write(pfd, buf, strlen(buf)) != strlen(buf)){
  20. remove(path);
  21. sysfatal("fdfork: post '%s': %r", buf);
  22. }
  23. close(ch[0]);
  24. if(write(fd, path, len) != len){
  25. remove(path);
  26. sysfatal("fdfork: write to peer: %r");
  27. }
  28. len = read(fd, buf, sizeof buf-1);
  29. if(len <= 0){
  30. remove(path);
  31. sysfatal("fdfork: read ack: %s from peer: %r", len == -1 ? "error" : "eof");
  32. }
  33. buf[len] = '\0';
  34. if(strcmp(path, buf)){
  35. remove(path);
  36. print("ack from wrong peer: got '%s' want '%s'\n", buf, path);
  37. sysfatal("ack from wrong peer");
  38. }
  39. close(pfd);
  40. //remove(path);
  41. return ch[1];
  42. } else {
  43. len = read(fd, path, sizeof path-1);
  44. if(len <= 0)
  45. sysfatal("fdfork: read path: %s from peer: %r", len == -1 ? "error" : "eof");
  46. path[len] = '\0';
  47. pfd = open(path, OWRITE);
  48. if(pfd == -1)
  49. sysfatal("fdfork: open: %r");
  50. if(write(fd, path, len) != len)
  51. sysfatal("fdfork: write ack to peer: %r");
  52. return pfd;
  53. }
  54. }
  55. int
  56. hyperfork(int *fd, int id, int dim)
  57. {
  58. int chfd[dim];
  59. int ch[2];
  60. int i;
  61. for(i = 0; i < dim; i++)
  62. chfd[i] = fdfork(fd[i], (id & (1<<i)) == 0);
  63. pipe(ch);
  64. switch(fork()){
  65. case -1:
  66. sysfatal("rfork");
  67. case 0:
  68. for(i = 0; i < dim; i++){
  69. close(fd[i]);
  70. fd[i] = chfd[i];
  71. }
  72. id |= 1 << dim;
  73. close(ch[0]);
  74. fd[dim] = ch[1];
  75. break;
  76. default:
  77. for(i = 0; i < dim; i++)
  78. close(chfd[i]);
  79. close(ch[1]);
  80. fd[dim] = ch[0];
  81. break;
  82. }
  83. return id;
  84. }
  85. void
  86. main(int argc, char *argv[])
  87. {
  88. int fd[32];
  89. char buf[32], buf2[32];
  90. int id;
  91. int i;
  92. if(argc > 1)
  93. dim = strtol(argv[1], nil, 0);
  94. id = 0;
  95. chdir("/srv");
  96. for(i = 0; i < dim; i++)
  97. id = hyperfork(fd, id, i);
  98. for(i = 0; i < dim; i++){
  99. int tlen, rlen;
  100. tlen = snprint(buf, sizeof buf, "hello %d\n", id);
  101. write(fd[i], buf, tlen);
  102. rlen = read(fd[i], buf, sizeof buf-1);
  103. buf[rlen] = '\0';
  104. snprint(buf2, sizeof buf2, "%d: %s", id, buf);
  105. }
  106. for(i = 0; i < dim; i++)
  107. if((id & (1<<i)) == 0)
  108. waitpid();
  109. print("PASS\n");
  110. exits("PASS");
  111. }