rendez.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include "u.h"
  2. #include "lib.h"
  3. #include "dat.h"
  4. #include "fns.h"
  5. #include "error.h"
  6. void
  7. sleep(Rendez *r, int (*f)(void*), void *arg)
  8. {
  9. int s;
  10. s = splhi();
  11. lock(&r->lk);
  12. lock(&up->rlock);
  13. if(r->p){
  14. print("double sleep %lud %lud\n", r->p->pid, up->pid);
  15. dumpstack();
  16. }
  17. /*
  18. * Wakeup only knows there may be something to do by testing
  19. * r->p in order to get something to lock on.
  20. * Flush that information out to memory in case the sleep is
  21. * committed.
  22. */
  23. r->p = up;
  24. if((*f)(arg) || up->notepending){
  25. /*
  26. * if condition happened or a note is pending
  27. * never mind
  28. */
  29. r->p = nil;
  30. unlock(&up->rlock);
  31. unlock(&r->lk);
  32. } else {
  33. /*
  34. * now we are committed to
  35. * change state and call scheduler
  36. */
  37. up->state = Wakeme;
  38. up->r = r;
  39. /* statistics */
  40. /* m->cs++; */
  41. unlock(&up->rlock);
  42. unlock(&r->lk);
  43. procsleep();
  44. }
  45. if(up->notepending) {
  46. up->notepending = 0;
  47. splx(s);
  48. error(Eintr);
  49. }
  50. splx(s);
  51. }
  52. Proc*
  53. wakeup(Rendez *r)
  54. {
  55. Proc *p;
  56. int s;
  57. s = splhi();
  58. lock(&r->lk);
  59. p = r->p;
  60. if(p != nil){
  61. lock(&p->rlock);
  62. if(p->state != Wakeme || p->r != r)
  63. panic("wakeup: state");
  64. r->p = nil;
  65. p->r = nil;
  66. p->state = Running;
  67. procwakeup(p);
  68. unlock(&p->rlock);
  69. }
  70. unlock(&r->lk);
  71. splx(s);
  72. return p;
  73. }