]> git.lizzy.rs Git - plan9front.git/blob - sys/src/ape/lib/ap/mips/lock.c
ape: silence compiler "no return at end of function" for mips lock.c
[plan9front.git] / sys / src / ape / lib / ap / mips / lock.c
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 static void
25 lockinit(void)
26 {
27         int n;
28
29         if(arch != 0)
30                 return; /* allow multiple calls */
31         arch = C_fcr0();
32         switch(arch) {
33         case POWER:
34                 if(_SEGATTACH(0,  "lock", (void*)Lockaddr, Pagesize) == (void*)-1) {
35                         arch = MAGNUM;
36                         break;
37                 }
38                 memset((void*)Lockaddr, 0, Pagesize);
39                 break;
40         case MAGNUM:
41         case MAGNUMII:
42         case R4K:
43                 break;
44         default:
45                 abort();
46         }
47         
48 }
49
50 void
51 lock(Lock *lk)
52 {
53         int *hwsem;
54         int hash;
55
56 retry:
57         switch(arch) {
58         case 0:
59                 lockinit();
60                 goto retry;
61         case MAGNUM:
62         case MAGNUMII:
63                 while(C_3ktas(&lk->val))
64                         _SLEEP(0);
65                 return;
66         case R4K:
67                 for(;;){
68                         while(lk->val)
69                                 ;
70                         if(C_4ktas(&lk->val) == 0)
71                                 return;
72                 }
73                 break;
74         case POWER:
75                 /* Use low order lock bits to generate hash */
76                 hash = ((int)lk/sizeof(int)) & (Semperpg-1);
77                 hwsem = (int*)Lockaddr+hash;
78
79                 for(;;) {
80                         if((*hwsem & 1) == 0) {
81                                 if(lk->val)
82                                         *hwsem = 0;
83                                 else {
84                                         lk->val = 1;
85                                         *hwsem = 0;
86                                         return;
87                                 }
88                         }
89                         while(lk->val)
90                                 ;
91                 }
92         }       
93 }
94
95 int
96 canlock(Lock *lk)
97 {
98         int *hwsem;
99         int hash;
100
101 retry:
102         switch(arch) {
103         case 0:
104                 lockinit();
105                 goto retry;
106         case MAGNUM:
107         case MAGNUMII:
108                 if(C_3ktas(&lk->val))
109                         return 0;
110                 return 1;
111         case R4K:
112                 if(C_4ktas(&lk->val))
113                         return 0;
114                 return 1;
115         case POWER:
116                 /* Use low order lock bits to generate hash */
117                 hash = ((int)lk/sizeof(int)) & (Semperpg-1);
118                 hwsem = (int*)Lockaddr+hash;
119
120                 if((*hwsem & 1) == 0) {
121                         if(lk->val)
122                                 *hwsem = 0;
123                         else {
124                                 lk->val = 1;
125                                 *hwsem = 0;
126                                 return 1;
127                         }
128                 }
129                 return 0;
130         }
131         return -1;      /* not reached */
132 }
133
134 void
135 unlock(Lock *lk)
136 {
137         lk->val = 0;
138 }
139
140 int
141 tas(int *p)
142 {
143         int *hwsem;
144         int hash;
145
146 retry:
147         switch(arch) {
148         case 0:
149                 lockinit();
150                 goto retry;
151         case MAGNUM:
152         case MAGNUMII:
153                 return C_3ktas(p);
154         case R4K:
155                 return C_4ktas(p);
156         case POWER:
157                 /* Use low order lock bits to generate hash */
158                 hash = ((int)p/sizeof(int)) & (Semperpg-1);
159                 hwsem = (int*)Lockaddr+hash;
160
161                 if((*hwsem & 1) == 0) {
162                         if(*p)
163                                 *hwsem = 0;
164                         else {
165                                 *p = 1;
166                                 *hwsem = 0;
167                                 return 0;
168                         }
169                 }
170                 return 1;
171         }
172         return -1;      /* not reached */
173 }