123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #define _LOCK_EXTENSION
- #include <stdlib.h>
- #include <string.h>
- #include "../plan9/sys9.h"
- #include <lock.h>
- enum
- {
- Pagesize = 4096,
- Semperpg = Pagesize/(16*sizeof(unsigned int)),
- Lockaddr = 0x60000000,
- POWER = 0x320,
- MAGNUM = 0x330,
- MAGNUMII = 0x340,
- R4K = 0x500,
- };
- static int arch;
- extern int C_3ktas(int*);
- extern int C_4ktas(int*);
- extern int C_fcr0(void);
- static void
- lockinit(void)
- {
- int n;
- if(arch != 0)
- return; /* allow multiple calls */
- arch = C_fcr0();
- switch(arch) {
- case POWER:
- n = _SEGATTACH(0, "lock", (void*)Lockaddr, Pagesize);
- if(n < 0) {
- arch = MAGNUM;
- break;
- }
- memset((void*)Lockaddr, 0, Pagesize);
- break;
- case MAGNUM:
- case MAGNUMII:
- case R4K:
- break;
- default:
- abort();
- }
-
- }
- void
- lock(Lock *lk)
- {
- int *hwsem;
- int hash;
- retry:
- switch(arch) {
- case 0:
- lockinit();
- goto retry;
- case MAGNUM:
- case MAGNUMII:
- while(C_3ktas(&lk->val))
- _SLEEP(0);
- return;
- case R4K:
- for(;;){
- while(lk->val)
- ;
- if(C_4ktas(&lk->val) == 0)
- return;
- }
- break;
- case POWER:
- /* Use low order lock bits to generate hash */
- hash = ((int)lk/sizeof(int)) & (Semperpg-1);
- hwsem = (int*)Lockaddr+hash;
- for(;;) {
- if((*hwsem & 1) == 0) {
- if(lk->val)
- *hwsem = 0;
- else {
- lk->val = 1;
- *hwsem = 0;
- return;
- }
- }
- while(lk->val)
- ;
- }
- }
- }
- int
- canlock(Lock *lk)
- {
- int *hwsem;
- int hash;
- retry:
- switch(arch) {
- case 0:
- lockinit();
- goto retry;
- case MAGNUM:
- case MAGNUMII:
- if(C_3ktas(&lk->val))
- return 0;
- return 1;
- case R4K:
- if(C_4ktas(&lk->val))
- return 0;
- return 1;
- case POWER:
- /* Use low order lock bits to generate hash */
- hash = ((int)lk/sizeof(int)) & (Semperpg-1);
- hwsem = (int*)Lockaddr+hash;
- if((*hwsem & 1) == 0) {
- if(lk->val)
- *hwsem = 0;
- else {
- lk->val = 1;
- *hwsem = 0;
- return 1;
- }
- }
- return 0;
- }
- }
- void
- unlock(Lock *lk)
- {
- lk->val = 0;
- }
- int
- tas(int *p)
- {
- int *hwsem;
- int hash;
- retry:
- switch(arch) {
- case 0:
- lockinit();
- goto retry;
- case MAGNUM:
- case MAGNUMII:
- return C_3ktas(p);
- case R4K:
- return C_4ktas(p);
- case POWER:
- /* Use low order lock bits to generate hash */
- hash = ((int)p/sizeof(int)) & (Semperpg-1);
- hwsem = (int*)Lockaddr+hash;
- if((*hwsem & 1) == 0) {
- if(*p)
- *hwsem = 0;
- else {
- *p = 1;
- *hwsem = 0;
- return 0;
- }
- }
- return 1;
- }
- }
|