round.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "stdinc.h"
  2. #include "dat.h"
  3. #include "fns.h"
  4. void
  5. waitforkick(Round *r)
  6. {
  7. int n;
  8. qlock(&r->lock);
  9. r->last = r->current;
  10. assert(r->current+1 == r->next);
  11. rwakeupall(&r->finish);
  12. while(!r->doanother)
  13. rsleep(&r->start);
  14. n = r->next++;
  15. r->current = n;
  16. r->doanother = 0;
  17. qunlock(&r->lock);
  18. }
  19. static void
  20. _kickround(Round *r, int wait)
  21. {
  22. int n;
  23. if(!r->doanother)
  24. trace(TraceProc, "kick %s", r->name);
  25. r->doanother = 1;
  26. rwakeup(&r->start);
  27. if(wait){
  28. n = r->next;
  29. while((int)(n - r->last) > 0){
  30. r->doanother = 1;
  31. rwakeup(&r->start);
  32. rsleep(&r->finish);
  33. }
  34. }
  35. }
  36. void
  37. kickround(Round *r, int wait)
  38. {
  39. qlock(&r->lock);
  40. _kickround(r, wait);
  41. qunlock(&r->lock);
  42. }
  43. void
  44. initround(Round *r, char *name, int delay)
  45. {
  46. memset(r, 0, sizeof *r);
  47. r->name = name;
  48. r->start.l = &r->lock;
  49. r->finish.l = &r->lock;
  50. r->delaywait.l = &r->lock;
  51. r->last = 0;
  52. r->current = 0;
  53. r->next = 1;
  54. r->doanother = 0;
  55. r->delaytime = delay;
  56. }
  57. void
  58. delaykickround(Round *r)
  59. {
  60. qlock(&r->lock);
  61. r->delaykick = 1;
  62. rwakeup(&r->delaywait);
  63. qunlock(&r->lock);
  64. }
  65. void
  66. delaykickroundproc(void *v)
  67. {
  68. Round *r = v;
  69. int n;
  70. threadsetname("delaykickproc %s", r->name);
  71. qlock(&r->lock);
  72. for(;;){
  73. while(r->delaykick == 0){
  74. trace(TraceProc, "sleep");
  75. rsleep(&r->delaywait);
  76. }
  77. n = r->next;
  78. qunlock(&r->lock);
  79. trace(TraceProc, "waitround 0x%ux", (uint)n);
  80. sleep(r->delaytime);
  81. qlock(&r->lock);
  82. if(n == r->next){
  83. trace(TraceProc, "kickround 0x%ux", (uint)n);
  84. _kickround(r, 1);
  85. }
  86. trace(TraceProc, "finishround 0x%ux", (uint)n);
  87. }
  88. }