aboutsummaryrefslogtreecommitdiffstats
path: root/src/spinlocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/spinlocks.c')
-rw-r--r--src/spinlocks.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/src/spinlocks.c b/src/spinlocks.c
index 9b04702..520e12a 100644
--- a/src/spinlocks.c
+++ b/src/spinlocks.c
@@ -60,12 +60,13 @@ void rwrnlp_init(rwrnlp *lock)
60 for(i = 0; i < NR_CPUS; i++){ 60 for(i = 0; i < NR_CPUS; i++){
61 lock->enter[i] = 0; 61 lock->enter[i] = 0;
62 lock->leave[i] = 0; 62 lock->leave[i] = 0;
63 lock->curr[i] = 0;
63 } 64 }
64 spin_init(lock->enqueue); 65 spin_init(lock->enqueue);
65 spin_init(lock->state); 66 spin_init(lock->state);
66} 67}
67 68
68void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) 69long rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor)
69{ 70{
70 request *req; 71 request *req;
71#if MEASURE==TRUE 72#if MEASURE==TRUE
@@ -76,7 +77,7 @@ void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor)
76 77
77 enter_np(); 78 enter_np();
78 79
79 req = &lock->requests[processor]; 80 req = &lock->requests[processor][lock->curr[processor]];
80 req->resources = resources; 81 req->resources = resources;
81 req->type = read_req; 82 req->type = read_req;
82 req->status = waiting; 83 req->status = waiting;
@@ -116,13 +117,15 @@ void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor)
116 clock_gettime(CLOCK_MONOTONIC, &now); 117 clock_gettime(CLOCK_MONOTONIC, &now);
117 overhead += diff_ns(&last, &now); 118 overhead += diff_ns(&last, &now);
118 } 119 }
119 printf("read lock overhead: %ld\n", overhead); 120 return overhead;
121#else
122 return 0;
120#endif 123#endif
121 124
122// printf("%d:%d reader satisfied\n", __sync_fetch_and_add(&events,1), gettid()); 125// printf("%d:%d reader satisfied\n", __sync_fetch_and_add(&events,1), gettid());
123} 126}
124 127
125void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) 128long rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor)
126{ 129{
127 int r,i,start,end; 130 int r,i,start,end;
128 request *req, *contender; 131 request *req, *contender;
@@ -137,7 +140,7 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor)
137 140
138// printf("%d:%d rwrnlp_write_lock\n", __sync_fetch_and_add(&events,1), gettid()); 141// printf("%d:%d rwrnlp_write_lock\n", __sync_fetch_and_add(&events,1), gettid());
139 142
140 req = &lock->requests[processor]; 143 req = &lock->requests[processor][lock->curr[processor]];
141 144
142 req->resources = resources; 145 req->resources = resources;
143 req->type = write_req; 146 req->type = write_req;
@@ -179,9 +182,9 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor)
179 182
180 for(i = 0; i < NR_CPUS; i++){ 183 for(i = 0; i < NR_CPUS; i++){
181 if(i != processor){ 184 if(i != processor){
182 start = lock->enter[i];
183 contender = &lock->requests[i];
184 end = lock->leave[i]; 185 end = lock->leave[i];
186 contender = &lock->requests[i][lock->curr[processor]];
187 start = lock->enter[i];
185 if(start <= end || 188 if(start <= end ||
186 contender->type == write_req || 189 contender->type == write_req ||
187 contender->status == waiting || 190 contender->status == waiting ||
@@ -210,27 +213,32 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor)
210#if MEASURE==TRUE 213#if MEASURE==TRUE
211 clock_gettime(CLOCK_MONOTONIC, &now); 214 clock_gettime(CLOCK_MONOTONIC, &now);
212 overhead += diff_ns(&last, &now); 215 overhead += diff_ns(&last, &now);
213 printf("write lock overhead: %ld\n", overhead); 216 return overhead;
217#else
218 return 0;
214#endif 219#endif
215} 220}
216 221
217void rwrnlp_read_unlock(rwrnlp *lock, int processor) 222long rwrnlp_read_unlock(rwrnlp *lock, int processor)
218{ 223{
219#if MEASURE==TRUE 224#if MEASURE==TRUE
220 struct timespec now, last; 225 struct timespec now, last;
221 clock_gettime(CLOCK_MONOTONIC, &last); 226 clock_gettime(CLOCK_MONOTONIC, &last);
222#endif 227#endif
223 lock->leave[processor] += 1; 228 lock->leave[processor] += 1;
229 lock->curr[processor] = (lock->curr[processor] + 1) % 2;
224// printf("%d:%d rwrnlp_read_unlock\n", __sync_fetch_and_add(&events,1), gettid()); 230// printf("%d:%d rwrnlp_read_unlock\n", __sync_fetch_and_add(&events,1), gettid());
225 exit_np(); 231 exit_np();
226 232
227#if MEASURE==TRUE 233#if MEASURE==TRUE
228 clock_gettime(CLOCK_MONOTONIC, &now); 234 clock_gettime(CLOCK_MONOTONIC, &now);
229 printf("read unlock overhead: %ld\n", diff_ns(&last, &now)); 235 return diff_ns(&last, &now);
236#else
237 return 0;
230#endif 238#endif
231} 239}
232 240
233void rwrnlp_write_unlock(rwrnlp *lock, int processor) 241long rwrnlp_write_unlock(rwrnlp *lock, int processor)
234{ 242{
235 int r; 243 int r;
236 request *req; 244 request *req;
@@ -239,13 +247,11 @@ void rwrnlp_write_unlock(rwrnlp *lock, int processor)
239 struct timespec now, last; 247 struct timespec now, last;
240 clock_gettime(CLOCK_MONOTONIC, &last); 248 clock_gettime(CLOCK_MONOTONIC, &last);
241#endif 249#endif
242 req= &lock->requests[processor]; 250 req= &lock->requests[processor][lock->curr[processor]];
243 tmp = req->resources; 251 tmp = req->resources;
244 252
245// printf("%d:%d rwrnlp_write_unlock\n", __sync_fetch_and_add(&events,1), gettid()); 253// printf("%d:%d rwrnlp_write_unlock\n", __sync_fetch_and_add(&events,1), gettid());
246 254
247 lock->leave[processor] += 1;
248
249 spin_lock(lock->state); 255 spin_lock(lock->state);
250 r = ffsl(tmp); 256 r = ffsl(tmp);
251 while(r != 0){ 257 while(r != 0){
@@ -257,12 +263,17 @@ void rwrnlp_write_unlock(rwrnlp *lock, int processor)
257 lock->wlocked &= ~(req->resources); 263 lock->wlocked &= ~(req->resources);
258 lock->unavailable &= ~(req->resources); 264 lock->unavailable &= ~(req->resources);
259 spin_unlock(lock->state); 265 spin_unlock(lock->state);
266
267 lock->leave[processor] += 1;
268 lock->curr[processor] = (lock->curr[processor] + 1) % 2;
260 269
261// printf("%d:%d write unlocked %lu\n", __sync_fetch_and_add(&events,1), gettid(), req->resources); 270// printf("%d:%d write unlocked %lu\n", __sync_fetch_and_add(&events,1), gettid(), req->resources);
262// printf("unavailable %lu\nwentitled %lu\nwlocked %lu\n", lock->unavailable, lock->wentitled, lock->wlocked); 271// printf("unavailable %lu\nwentitled %lu\nwlocked %lu\n", lock->unavailable, lock->wentitled, lock->wlocked);
263 exit_np(); 272 exit_np();
264#if MEASURE==TRUE 273#if MEASURE==TRUE
265 clock_gettime(CLOCK_MONOTONIC, &now); 274 clock_gettime(CLOCK_MONOTONIC, &now);
266 printf("write unlock overhead: %ld\n", diff_ns(&last, &now)); 275 return diff_ns(&last, &now);
276#else
277 return 0;
267#endif 278#endif
268} 279}