qlock.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include "u.h"
  2. #include "lib.h"
  3. #include "dat.h"
  4. #include "fns.h"
  5. static void
  6. queue(Proc **first, Proc **last)
  7. {
  8. Proc *t;
  9. t = *last;
  10. if(t == 0)
  11. *first = up;
  12. else
  13. t->qnext = up;
  14. *last = up;
  15. up->qnext = 0;
  16. }
  17. static Proc*
  18. dequeue(Proc **first, Proc **last)
  19. {
  20. Proc *t;
  21. t = *first;
  22. if(t == 0)
  23. return 0;
  24. *first = t->qnext;
  25. if(*first == 0)
  26. *last = 0;
  27. return t;
  28. }
  29. void
  30. qlock(QLock *q)
  31. {
  32. lock(&q->lk);
  33. if(q->hold == 0) {
  34. q->hold = up;
  35. unlock(&q->lk);
  36. return;
  37. }
  38. /*
  39. * Can't assert this because of RWLock
  40. assert(q->hold != up);
  41. */
  42. queue((Proc**)&q->first, (Proc**)&q->last);
  43. unlock(&q->lk);
  44. procsleep();
  45. }
  46. int
  47. canqlock(QLock *q)
  48. {
  49. lock(&q->lk);
  50. if(q->hold == 0) {
  51. q->hold = up;
  52. unlock(&q->lk);
  53. return 1;
  54. }
  55. unlock(&q->lk);
  56. return 0;
  57. }
  58. void
  59. qunlock(QLock *q)
  60. {
  61. Proc *p;
  62. lock(&q->lk);
  63. /*
  64. * Can't assert this because of RWlock
  65. assert(q->hold == CT);
  66. */
  67. p = dequeue((Proc**)&q->first, (Proc**)&q->last);
  68. if(p) {
  69. q->hold = p;
  70. unlock(&q->lk);
  71. procwakeup(p);
  72. } else {
  73. q->hold = 0;
  74. unlock(&q->lk);
  75. }
  76. }
  77. int
  78. holdqlock(QLock *q)
  79. {
  80. return q->hold == up;
  81. }