lock.c 773 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #include <u.h>
  2. #include <libc.h>
  3. int
  4. canlock(Lock *lk)
  5. {
  6. return !tas(&lk->key);
  7. }
  8. void
  9. lock(Lock *lk)
  10. {
  11. int i;
  12. /* easy case */
  13. if(canlock(lk))
  14. return;
  15. /* for multi processor machines */
  16. for(i=0; i<100; i++)
  17. if(canlock(lk))
  18. return;
  19. for(i=0; i<100; i++) {
  20. osyield();
  21. if(canlock(lk))
  22. return;
  23. }
  24. /* looking bad - make sure it is not a priority problem */
  25. for(i=0; i<12; i++) {
  26. osmsleep(1<<i);
  27. if(canlock(lk))
  28. return;
  29. }
  30. /* we are in trouble */
  31. for(;;) {
  32. if(canlock(lk))
  33. return;
  34. iprint("lock loop %ld: val=%d &lock=%ux pc=%p\n", getpid(), lk->key, lk, getcallerpc(&lk));
  35. osmsleep(1000);
  36. }
  37. }
  38. void
  39. unlock(Lock *lk)
  40. {
  41. assert(lk->key);
  42. lk->key = 0;
  43. }
  44. void
  45. ilock(Lock *lk)
  46. {
  47. lock(lk);
  48. }
  49. void
  50. iunlock(Lock *lk)
  51. {
  52. unlock(lk);
  53. }