1 #define _LOCK_EXTENSION 2 #include <stdlib.h> 3 #include <string.h> 4 #include "../plan9/sys9.h" 5 #include <lock.h> 6 7 enum 8 { 9 Pagesize = 4096, 10 Semperpg = Pagesize/(16*sizeof(unsigned int)), 11 Lockaddr = 0x60000000, 12 13 POWER = 0x320, 14 MAGNUM = 0x330, 15 MAGNUMII = 0x340, 16 R4K = 0x500, 17 }; 18 19 static int arch; 20 extern int C_3ktas(int*); 21 extern int C_4ktas(int*); 22 extern int C_fcr0(void); 23 24 void 25 lockinit() 26 { 27 int n; 28 29 arch = C_fcr0(); 30 switch(arch) { 31 case POWER: 32 n = _SEGATTACH(0, "lock", (void*)Lockaddr, Pagesize); 33 if(n < 0) { 34 arch = MAGNUM; 35 break; 36 } 37 memset((void*)Lockaddr, 0, Pagesize); 38 break; 39 case MAGNUM: 40 case MAGNUMII: 41 case R4K: 42 break; 43 default: 44 abort(); 45 } 46 47 } 48 49 void 50 lock(Lock *lk) 51 { 52 int *hwsem; 53 int hash; 54 55 switch(arch) { 56 case MAGNUM: 57 case MAGNUMII: 58 while(C_3ktas(&lk->val)) 59 _SLEEP(0); 60 return; 61 case R4K: 62 for(;;){ 63 while(lk->val) 64 ; 65 if(C_4ktas(&lk->val) == 0) 66 return; 67 } 68 break; 69 case POWER: 70 /* Use low order lock bits to generate hash */ 71 hash = ((int)lk/sizeof(int)) & (Semperpg-1); 72 hwsem = (int*)Lockaddr+hash; 73 74 for(;;) { 75 if((*hwsem & 1) == 0) { 76 if(lk->val) 77 *hwsem = 0; 78 else { 79 lk->val = 1; 80 *hwsem = 0; 81 return; 82 } 83 } 84 while(lk->val) 85 ; 86 } 87 } 88 } 89 90 int 91 canlock(Lock *lk) 92 { 93 int *hwsem; 94 int hash; 95 96 switch(arch) { 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 111 if((*hwsem & 1) == 0) { 112 if(lk->val) 113 *hwsem = 0; 114 else { 115 lk->val = 1; 116 *hwsem = 0; 117 return 1; 118 } 119 } 120 return 0; 121 } 122 } 123 124 void 125 unlock(Lock *lk) 126 { 127 lk->val = 0; 128 } 129