aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@ubuntu-qemu.(none)>2013-05-06 00:35:28 -0400
committerroot <root@ubuntu-qemu.(none)>2013-05-06 00:35:28 -0400
commitff4b3e6b1353fed910dd0532186dc53d648bd2de (patch)
tree37c35c926cfc566aefaa81ca71449187e4ebb14b
parent0947d7543a9dd0b196d6fedd510422a733908b40 (diff)
More progress.
-rw-r--r--bin/.rwrnlp.c.swpbin20480 -> 0 bytes
-rw-r--r--bin/rwrnlp.c24
-rw-r--r--include/spinlocks.h6
-rw-r--r--multi.csv6
-rw-r--r--simple.csv4
-rw-r--r--src/spinlocks.c101
-rw-r--r--test.csv3
7 files changed, 98 insertions, 46 deletions
diff --git a/bin/.rwrnlp.c.swp b/bin/.rwrnlp.c.swp
deleted file mode 100644
index 207edbb..0000000
--- a/bin/.rwrnlp.c.swp
+++ /dev/null
Binary files differ
diff --git a/bin/rwrnlp.c b/bin/rwrnlp.c
index 157fcf4..c3221d8 100644
--- a/bin/rwrnlp.c
+++ b/bin/rwrnlp.c
@@ -228,6 +228,8 @@ void* rt_thread(void *tcontext)
228 228
229 CALL( set_rt_task_param(gettid(), &param) ); 229 CALL( set_rt_task_param(gettid(), &param) );
230 230
231 fprintf(stderr, "Thread %d on processor %d\n", gettid(), ctx->processor);
232
231 /***** 233 /*****
232 * 2) Transition to real-time mode. 234 * 2) Transition to real-time mode.
233 */ 235 */
@@ -272,7 +274,7 @@ static int loop_for(double exec_time, double emergency_exit)
272 if (emergency_exit && wctime() > emergency_exit) { 274 if (emergency_exit && wctime() > emergency_exit) {
273 /* Oops --- this should only be possible if the execution time tracking 275 /* Oops --- this should only be possible if the execution time tracking
274 * is broken in the LITMUS^RT kernel. */ 276 * is broken in the LITMUS^RT kernel. */
275 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); 277 fprintf(stderr, "!!! rtspin/%d emergency exit!\n", gettid());
276 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); 278 fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n");
277 break; 279 break;
278 } 280 }
@@ -295,21 +297,21 @@ static int job(struct thread_context *ctx, double program_end)
295 loop_for(ncs_length, program_end + 1); 297 loop_for(ncs_length, program_end + 1);
296 298
297 if(ctx->type == read_req){ 299 if(ctx->type == read_req){
298 printf("%d read locking...\n", getpid()); 300 printf("%d:%d read locking...\n", __sync_fetch_and_add(&events,1), gettid());
299 rwrnlp_read_lock(&rw_lock, ctx->resources, ctx->processor); 301 rwrnlp_read_lock(&rw_lock, ctx->resources, ctx->processor);
300 printf("%d read CS...\n", getpid()); 302 printf("%d:%d read CS...\n", __sync_fetch_and_add(&events, 1), gettid());
301 loop_for(ctx->cs_length, program_end + 1); 303 loop_for(ctx->cs_length*S_PER_MS, program_end + 1);
302 printf("%d read unlocking...\n", getpid()); 304 printf("%d:%d read unlocking...\n", __sync_fetch_and_add(&events,1), gettid());
303 rwrnlp_read_unlock(&rw_lock, ctx->processor); 305 rwrnlp_read_unlock(&rw_lock, ctx->processor);
304 printf("%d ncs...\n", getpid()); 306 printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid());
305 }else{ 307 }else{
306 printf("%d write locking...\n", getpid()); 308 printf("%d:%d write locking %lu\n", __sync_fetch_and_add(&events,1), gettid(), ctx->resources);
307 rwrnlp_write_lock(&rw_lock, ctx->resources, ctx->processor); 309 rwrnlp_write_lock(&rw_lock, ctx->resources, ctx->processor);
308 printf("%d write CS...\n", getpid()); 310 printf("%d:%d write CS...\n", __sync_fetch_and_add(&events,1), gettid());
309 loop_for(ctx->cs_length, program_end + 1); 311 loop_for(ctx->cs_length*S_PER_MS, program_end + 1);
310 printf("%d write unlocking...\n", getpid()); 312 printf("%d:%d write unlocking...\n", __sync_fetch_and_add(&events,1), gettid());
311 rwrnlp_write_unlock(&rw_lock, ctx->processor); 313 rwrnlp_write_unlock(&rw_lock, ctx->processor);
312 printf("%d ncs...\n", getpid()); 314 printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid());
313 } 315 }
314 316
315 317
diff --git a/include/spinlocks.h b/include/spinlocks.h
index 9871685..d83a0d8 100644
--- a/include/spinlocks.h
+++ b/include/spinlocks.h
@@ -4,9 +4,11 @@
4#define NR_CPUS 4 4#define NR_CPUS 4
5#define NR_RESOURCES sizeof(resource_mask_t)*8 5#define NR_RESOURCES sizeof(resource_mask_t)*8
6 6
7extern int events;
8
7typedef enum {read_req, write_req} request_type; 9typedef enum {read_req, write_req} request_type;
8typedef enum {waiting, acquired, entitled} request_status; 10typedef enum {waiting, acquired, entitled} request_status;
9typedef long resource_mask_t; 11typedef unsigned long resource_mask_t;
10 12
11typedef struct request_struct { 13typedef struct request_struct {
12 resource_mask_t resources; 14 resource_mask_t resources;
@@ -26,7 +28,7 @@ typedef struct rwrnlp_struct {
26 28
27 int enter[NR_CPUS]; 29 int enter[NR_CPUS];
28 int leave[NR_CPUS]; 30 int leave[NR_CPUS];
29 request* requests[NR_CPUS]; 31 request requests[NR_CPUS];
30 32
31 request* wqueue[NR_RESOURCES][NR_CPUS]; 33 request* wqueue[NR_RESOURCES][NR_CPUS];
32 unsigned int whead[NR_RESOURCES]; 34 unsigned int whead[NR_RESOURCES];
diff --git a/multi.csv b/multi.csv
new file mode 100644
index 0000000..acf5a3c
--- /dev/null
+++ b/multi.csv
@@ -0,0 +1,6 @@
10 10.0 17.0 3.0 0 1
21 12.0 19.0 8.0 0 3
33 17.0 23.0 8.0 1 4
42 10.0 17.0 3.0 0 5
51 12.0 29.0 8.0 1 1
63 17.0 21.0 8.0 1 4
diff --git a/simple.csv b/simple.csv
new file mode 100644
index 0000000..6a166b1
--- /dev/null
+++ b/simple.csv
@@ -0,0 +1,4 @@
10 10.0 17.0 3.0 0 3
21 12.0 19.0 8.0 1 2
32 17.0 23.0 8.0 1 1
43 17.0 23.0 8.0 1 3
diff --git a/src/spinlocks.c b/src/spinlocks.c
index 16e1f06..9847aac 100644
--- a/src/spinlocks.c
+++ b/src/spinlocks.c
@@ -2,10 +2,13 @@
2#include <stdio.h> 2#include <stdio.h>
3#include <string.h> 3#include <string.h>
4 4
5#include "litmus.h"
5#include "spinlocks.h" 6#include "spinlocks.h"
6 7
7#define NR_RESOURCES sizeof(resource_mask_t)*8 8#define NR_RESOURCES sizeof(resource_mask_t)*8
8 9
10int events;
11
9void spin_init(spinlock_t *lock){ 12void spin_init(spinlock_t *lock){
10 lock->serving = 0; 13 lock->serving = 0;
11 lock->next_ticket = 0; 14 lock->next_ticket = 0;
@@ -13,6 +16,8 @@ void spin_init(spinlock_t *lock){
13 16
14void spin_lock(spinlock_t *lock){ 17void spin_lock(spinlock_t *lock){
15 int ticket = __sync_fetch_and_add(&(lock->next_ticket), 1); 18 int ticket = __sync_fetch_and_add(&(lock->next_ticket), 1);
19 printf("%d:%d waiting for ticket %d serving %d\n",
20 __sync_fetch_and_add(&events,1), gettid(), ticket, lock->serving);
16 while(lock->serving != ticket); 21 while(lock->serving != ticket);
17} 22}
18 23
@@ -23,6 +28,7 @@ void spin_unlock(spinlock_t *lock){
23void rwrnlp_init(rwrnlp *lock) 28void rwrnlp_init(rwrnlp *lock)
24{ 29{
25 int i; 30 int i;
31 events = 0;
26 lock->wlocked = 0; 32 lock->wlocked = 0;
27 lock->wentitled = 0; 33 lock->wentitled = 0;
28 lock->unavailable = 0; 34 lock->unavailable = 0;
@@ -43,43 +49,57 @@ void rwrnlp_init(rwrnlp *lock)
43 49
44void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) 50void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor)
45{ 51{
46 request req; 52 request *req;
47 req.resources = resources; 53
48 req.type = read_req; 54 enter_np();
49 req.status = waiting; 55
56 req = &lock->requests[processor];
57 req->resources = resources;
58 req->type = read_req;
59 req->status = waiting;
50 lock->enter[processor]+=1; 60 lock->enter[processor]+=1;
51 lock->requests[processor] = &req; 61
62 printf("%d:%d rwrnlp_read_lock %lu\n",__sync_fetch_and_add(&events,1), gettid(), req->resources);
52 63
53 spin_lock(lock->state); 64 spin_lock(lock->state);
54 if((req.resources & lock->unavailable) == 0){ 65 if((req->resources & lock->unavailable) == 0){
55 req.status = acquired; 66 req->status = acquired;
56 } 67 }
57 spin_unlock(lock->state); 68 spin_unlock(lock->state);
58 69
59 if(req.status != acquired){ 70 if(req->status != acquired){
60 while((req.resources & lock->wentitled) != 0); 71 printf("%d:%d waiting to become entitled\n",__sync_fetch_and_add(&events,1), gettid());
61 req.status = entitled; 72 while((req->resources & lock->wentitled) != 0);
62 while((req.resources & lock->wlocked) != 0); 73 req->status = entitled;
74 printf("%d:%d waiting to acquire\n", __sync_fetch_and_add(&events,1), gettid());
75 while((req->resources & lock->wlocked) != 0);
63 } 76 }
77
78 printf("%d:%d reader satisfied\n", __sync_fetch_and_add(&events,1), gettid());
64} 79}
65 80
66void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) 81void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor)
67{ 82{
68 int r,i,start,end; 83 int r,i,start,end;
69 request req; 84 request *req, *contender;
70 request* contender;
71 resource_mask_t tmp = resources; 85 resource_mask_t tmp = resources;
72 req.resources = resources; 86
73 req.type = read_req; 87 enter_np();
74 req.status = waiting; 88
89 printf("%d:%d rwrnlp_write_lock\n", __sync_fetch_and_add(&events,1), gettid());
90
91 req = &lock->requests[processor];
92
93 req->resources = resources;
94 req->type = write_req;
95 req->status = waiting;
75 lock->enter[processor]+=1; 96 lock->enter[processor]+=1;
76 lock->requests[processor] = &req;
77 97
78 spin_lock(lock->enqueue); 98 spin_lock(lock->enqueue);
79 r = ffsl(tmp); 99 r = ffsl(tmp);
80 while(r != 0){ 100 while(r != 0){
81 r = r-1; // ffsl gives 1-indexed, since 0 is the return value for 0. 101 r = r-1; // ffsl gives 1-indexed, since 0 is the return value for 0.
82 lock->wqueue[r][lock->wtail[r]] = &req; 102 lock->wqueue[r][lock->wtail[r]] = req;
83 lock->wtail[r] = (lock->wtail[r] + 1) % NR_CPUS; 103 lock->wtail[r] = (lock->wtail[r] + 1) % NR_CPUS;
84 tmp &= ~(1<<r); 104 tmp &= ~(1<<r);
85 r = ffsl(tmp); 105 r = ffsl(tmp);
@@ -87,53 +107,74 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor)
87 spin_unlock(lock->enqueue); 107 spin_unlock(lock->enqueue);
88 108
89 tmp = resources; 109 tmp = resources;
110 r = ffsl(tmp);
90 while(r != 0){ 111 while(r != 0){
91 r = r-1; 112 r = r-1;
92 while(lock->wqueue[r][lock->whead[r]] != &req); 113 printf("%d:%d write waiting to become head of %d\n", __sync_fetch_and_add(&events,1), gettid(), r);
114 while(lock->wqueue[r][lock->whead[r]] != req);
93 tmp &= ~(1<<r); 115 tmp &= ~(1<<r);
94 r = ffsl(tmp); 116 r = ffsl(tmp);
95 } 117 }
96 118
97 spin_lock(lock->state); 119 spin_lock(lock->state);
98 lock->unavailable |= req.resources; 120 lock->unavailable |= req->resources;
99 req.status = entitled; 121 req->status = entitled;
100 spin_unlock(lock->state); 122 spin_unlock(lock->state);
101 123
102 for(i = 0; i < NR_CPUS; i++){ 124 for(i = 0; i < NR_CPUS; i++){
103 if(i != processor){ 125 if(i != processor){
104 start = lock->enter[i]; 126 start = lock->enter[i];
105 contender = lock->requests[i]; 127 contender = &lock->requests[i];
106 end = lock->leave[i]; 128 end = lock->leave[i];
107 if(start <= end || 129 if(start <= end ||
108 contender->type == write_req || 130 contender->type == write_req ||
109 contender->status == waiting || 131 contender->status == waiting ||
110 (contender->resources & req.resources) == 0) 132 (contender->resources & req->resources) == 0)
111 continue; 133 continue;
112 134
135 printf("%d:%d waiting for reader on processor %d\n", __sync_fetch_and_add(&events,1), gettid(), i);
113 while(lock->leave[i] < start); 136 while(lock->leave[i] < start);
114 } 137 }
115 } 138 }
116 139
117 spin_lock(lock->state); 140 spin_lock(lock->state);
118 lock->wentitled &= ~req.resources; 141 lock->wentitled &= ~(req->resources);
119 lock->wlocked |= req.resources; 142 lock->wlocked |= req->resources;
120 spin_unlock(lock->state); 143 spin_unlock(lock->state);
144
145 printf("%d:%d writer satisfied\n", __sync_fetch_and_add(&events,1), gettid());
121} 146}
122 147
123void rwrnlp_read_unlock(rwrnlp *lock, int processor) 148void rwrnlp_read_unlock(rwrnlp *lock, int processor)
124{ 149{
125 lock->leave[processor] += 1; 150 lock->leave[processor] += 1;
126 lock->requests[processor] = NULL; 151 printf("%d:%d rwrnlp_read_unlock\n", __sync_fetch_and_add(&events,1), gettid());
152 exit_np();
127} 153}
128 154
129void rwrnlp_write_unlock(rwrnlp *lock, int processor) 155void rwrnlp_write_unlock(rwrnlp *lock, int processor)
130{ 156{
131 request *req = lock->requests[processor]; 157 int r;
158 request *req = &lock->requests[processor];
159 resource_mask_t tmp = req->resources;
160
161 printf("%d:%d rwrnlp_write_unlock\n", __sync_fetch_and_add(&events,1), gettid());
162
132 lock->leave[processor] += 1; 163 lock->leave[processor] += 1;
133 lock->requests[processor] = NULL;
134 164
135 spin_lock(lock->state); 165 spin_lock(lock->state);
136 lock->wlocked &= ~req->resources; 166 r = ffsl(tmp);
137 lock->unavailable &= ~req->resources; 167 while(r != 0){
168 r = r-1; // ffsl gives 1-indexed, since 0 is the return value for 0.
169 lock->whead[r] = (lock->whead[r] + 1) % NR_CPUS;
170 tmp &= ~(1<<r);
171 r = ffsl(tmp);
172 }
173 lock->wlocked &= ~(req->resources);
174 lock->unavailable &= ~(req->resources);
138 spin_unlock(lock->state); 175 spin_unlock(lock->state);
176
177 printf("%d:%d write unlocked %lu\n", __sync_fetch_and_add(&events,1), gettid(), req->resources);
178 printf("unavailable %lu\nwentitled %lu\nwlocked %lu\n", lock->unavailable, lock->wentitled, lock->wlocked);
179 exit_np();
139} 180}
diff --git a/test.csv b/test.csv
deleted file mode 100644
index 37bf459..0000000
--- a/test.csv
+++ /dev/null
@@ -1,3 +0,0 @@
10 10.0 100.0 1.0 0 0110
21 10.0 100.0 1.0 0 0110
33 10.0 100.0 1.0 1 0010