lock.pre-sema.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #define _LOCK_EXTENSION
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "../plan9/sys9.h"
  5. #include <lock.h>
  6. enum
  7. {
  8. Pagesize = 4096,
  9. Semperpg = Pagesize/(16*sizeof(unsigned int)),
  10. Lockaddr = 0x60000000,
  11. POWER = 0x320,
  12. MAGNUM = 0x330,
  13. MAGNUMII = 0x340,
  14. R4K = 0x500,
  15. };
  16. static int arch;
  17. extern int C_3ktas(int*);
  18. extern int C_4ktas(int*);
  19. extern int C_fcr0(void);
  20. static void
  21. lockinit(void)
  22. {
  23. int n;
  24. if(arch != 0)
  25. return; /* allow multiple calls */
  26. arch = C_fcr0();
  27. switch(arch) {
  28. case POWER:
  29. n = _SEGATTACH(0, "lock", (void*)Lockaddr, Pagesize);
  30. if(n < 0) {
  31. arch = MAGNUM;
  32. break;
  33. }
  34. memset((void*)Lockaddr, 0, Pagesize);
  35. break;
  36. case MAGNUM:
  37. case MAGNUMII:
  38. case R4K:
  39. break;
  40. default:
  41. arch = R4K;
  42. break;
  43. }
  44. }
  45. void
  46. lock(Lock *lk)
  47. {
  48. int *hwsem;
  49. int hash;
  50. retry:
  51. switch(arch) {
  52. case 0:
  53. lockinit();
  54. goto retry;
  55. case MAGNUM:
  56. case MAGNUMII:
  57. while(C_3ktas(&lk->val))
  58. _SLEEP(0);
  59. return;
  60. case R4K:
  61. for(;;){
  62. while(lk->val)
  63. ;
  64. if(C_4ktas(&lk->val) == 0)
  65. return;
  66. }
  67. break;
  68. case POWER:
  69. /* Use low order lock bits to generate hash */
  70. hash = ((int)lk/sizeof(int)) & (Semperpg-1);
  71. hwsem = (int*)Lockaddr+hash;
  72. for(;;) {
  73. if((*hwsem & 1) == 0) {
  74. if(lk->val)
  75. *hwsem = 0;
  76. else {
  77. lk->val = 1;
  78. *hwsem = 0;
  79. return;
  80. }
  81. }
  82. while(lk->val)
  83. ;
  84. }
  85. }
  86. }
  87. int
  88. canlock(Lock *lk)
  89. {
  90. int *hwsem;
  91. int hash;
  92. retry:
  93. switch(arch) {
  94. case 0:
  95. lockinit();
  96. goto retry;
  97. case MAGNUM:
  98. case MAGNUMII:
  99. if(C_3ktas(&lk->val))
  100. return 0;
  101. return 1;
  102. case R4K:
  103. if(C_4ktas(&lk->val))
  104. return 0;
  105. return 1;
  106. case POWER:
  107. /* Use low order lock bits to generate hash */
  108. hash = ((int)lk/sizeof(int)) & (Semperpg-1);
  109. hwsem = (int*)Lockaddr+hash;
  110. if((*hwsem & 1) == 0) {
  111. if(lk->val)
  112. *hwsem = 0;
  113. else {
  114. lk->val = 1;
  115. *hwsem = 0;
  116. return 1;
  117. }
  118. }
  119. return 0;
  120. default:
  121. return 0;
  122. }
  123. }
  124. void
  125. unlock(Lock *lk)
  126. {
  127. lk->val = 0;
  128. }
  129. int
  130. tas(int *p)
  131. {
  132. int *hwsem;
  133. int hash;
  134. retry:
  135. switch(arch) {
  136. case 0:
  137. lockinit();
  138. goto retry;
  139. case MAGNUM:
  140. case MAGNUMII:
  141. return C_3ktas(p);
  142. case R4K:
  143. return C_4ktas(p);
  144. case POWER:
  145. /* Use low order lock bits to generate hash */
  146. hash = ((int)p/sizeof(int)) & (Semperpg-1);
  147. hwsem = (int*)Lockaddr+hash;
  148. if((*hwsem & 1) == 0) {
  149. if(*p)
  150. *hwsem = 0;
  151. else {
  152. *p = 1;
  153. *hwsem = 0;
  154. return 0;
  155. }
  156. }
  157. return 1;
  158. default:
  159. return 0;
  160. }
  161. }