diff options
author | root <root@ubuntu-qemu.(none)> | 2013-05-06 16:14:48 -0400 |
---|---|---|
committer | root <root@ubuntu-qemu.(none)> | 2013-05-06 16:14:48 -0400 |
commit | 7a9281a049ea2c5717dd6360bd226973ead392c4 (patch) | |
tree | c729effee60aeea62dcc0c7eb2cf1047897981dd | |
parent | ff4b3e6b1353fed910dd0532186dc53d648bd2de (diff) |
Overhead measurement
-rw-r--r-- | bin/rwrnlp.c | 16 | ||||
-rw-r--r-- | src/spinlocks.c | 120 |
2 files changed, 112 insertions, 24 deletions
diff --git a/bin/rwrnlp.c b/bin/rwrnlp.c index c3221d8..07e3899 100644 --- a/bin/rwrnlp.c +++ b/bin/rwrnlp.c | |||
@@ -297,21 +297,21 @@ static int job(struct thread_context *ctx, double program_end) | |||
297 | loop_for(ncs_length, program_end + 1); | 297 | loop_for(ncs_length, program_end + 1); |
298 | 298 | ||
299 | if(ctx->type == read_req){ | 299 | if(ctx->type == read_req){ |
300 | printf("%d:%d read locking...\n", __sync_fetch_and_add(&events,1), gettid()); | 300 | //printf("%d:%d read locking...\n", __sync_fetch_and_add(&events,1), gettid()); |
301 | rwrnlp_read_lock(&rw_lock, ctx->resources, ctx->processor); | 301 | rwrnlp_read_lock(&rw_lock, ctx->resources, ctx->processor); |
302 | printf("%d:%d read CS...\n", __sync_fetch_and_add(&events, 1), gettid()); | 302 | //printf("%d:%d read CS...\n", __sync_fetch_and_add(&events, 1), gettid()); |
303 | loop_for(ctx->cs_length*S_PER_MS, program_end + 1); | 303 | loop_for(ctx->cs_length*S_PER_MS, program_end + 1); |
304 | printf("%d:%d read unlocking...\n", __sync_fetch_and_add(&events,1), gettid()); | 304 | //printf("%d:%d read unlocking...\n", __sync_fetch_and_add(&events,1), gettid()); |
305 | rwrnlp_read_unlock(&rw_lock, ctx->processor); | 305 | rwrnlp_read_unlock(&rw_lock, ctx->processor); |
306 | printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid()); | 306 | //printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid()); |
307 | }else{ | 307 | }else{ |
308 | printf("%d:%d write locking %lu\n", __sync_fetch_and_add(&events,1), gettid(), ctx->resources); | 308 | //printf("%d:%d write locking %lu\n", __sync_fetch_and_add(&events,1), gettid(), ctx->resources); |
309 | rwrnlp_write_lock(&rw_lock, ctx->resources, ctx->processor); | 309 | rwrnlp_write_lock(&rw_lock, ctx->resources, ctx->processor); |
310 | printf("%d:%d write CS...\n", __sync_fetch_and_add(&events,1), gettid()); | 310 | //printf("%d:%d write CS...\n", __sync_fetch_and_add(&events,1), gettid()); |
311 | loop_for(ctx->cs_length*S_PER_MS, program_end + 1); | 311 | loop_for(ctx->cs_length*S_PER_MS, program_end + 1); |
312 | printf("%d:%d write unlocking...\n", __sync_fetch_and_add(&events,1), gettid()); | 312 | //printf("%d:%d write unlocking...\n", __sync_fetch_and_add(&events,1), gettid()); |
313 | rwrnlp_write_unlock(&rw_lock, ctx->processor); | 313 | rwrnlp_write_unlock(&rw_lock, ctx->processor); |
314 | printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid()); | 314 | //printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid()); |
315 | } | 315 | } |
316 | 316 | ||
317 | 317 | ||
diff --git a/src/spinlocks.c b/src/spinlocks.c index 9847aac..9b04702 100644 --- a/src/spinlocks.c +++ b/src/spinlocks.c | |||
@@ -1,14 +1,32 @@ | |||
1 | #include <stdlib.h> | 1 | #include <stdlib.h> |
2 | #include <stdio.h> | 2 | #include <stdio.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include <time.h> | ||
4 | 5 | ||
5 | #include "litmus.h" | 6 | #include "litmus.h" |
6 | #include "spinlocks.h" | 7 | #include "spinlocks.h" |
7 | 8 | ||
8 | #define NR_RESOURCES sizeof(resource_mask_t)*8 | 9 | #define NR_RESOURCES sizeof(resource_mask_t)*8 |
9 | 10 | ||
11 | #define MEASURE TRUE | ||
12 | |||
10 | int events; | 13 | int events; |
11 | 14 | ||
15 | #if MEASURE==TRUE | ||
16 | static inline long diff_ns(const struct timespec *s, const struct timespec *e) | ||
17 | { | ||
18 | const int64_t ns_in_s = 1000000000LL; | ||
19 | struct timespec temp = *e; | ||
20 | temp.tv_sec -= s->tv_sec; | ||
21 | temp.tv_nsec -= s->tv_nsec; | ||
22 | if (temp.tv_nsec < 0) { | ||
23 | --temp.tv_sec; | ||
24 | temp.tv_nsec += ns_in_s; | ||
25 | } | ||
26 | return temp.tv_sec * ns_in_s + temp.tv_nsec; | ||
27 | } | ||
28 | #endif | ||
29 | |||
12 | void spin_init(spinlock_t *lock){ | 30 | void spin_init(spinlock_t *lock){ |
13 | lock->serving = 0; | 31 | lock->serving = 0; |
14 | lock->next_ticket = 0; | 32 | lock->next_ticket = 0; |
@@ -16,8 +34,8 @@ void spin_init(spinlock_t *lock){ | |||
16 | 34 | ||
17 | void spin_lock(spinlock_t *lock){ | 35 | void spin_lock(spinlock_t *lock){ |
18 | int ticket = __sync_fetch_and_add(&(lock->next_ticket), 1); | 36 | int ticket = __sync_fetch_and_add(&(lock->next_ticket), 1); |
19 | printf("%d:%d waiting for ticket %d serving %d\n", | 37 | // printf("%d:%d waiting for ticket %d serving %d\n", |
20 | __sync_fetch_and_add(&events,1), gettid(), ticket, lock->serving); | 38 | // __sync_fetch_and_add(&events,1), gettid(), ticket, lock->serving); |
21 | while(lock->serving != ticket); | 39 | while(lock->serving != ticket); |
22 | } | 40 | } |
23 | 41 | ||
@@ -50,6 +68,11 @@ void rwrnlp_init(rwrnlp *lock) | |||
50 | void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) | 68 | void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) |
51 | { | 69 | { |
52 | request *req; | 70 | request *req; |
71 | #if MEASURE==TRUE | ||
72 | long overhead = 0; | ||
73 | struct timespec now, last; | ||
74 | clock_gettime(CLOCK_MONOTONIC, &last); | ||
75 | #endif | ||
53 | 76 | ||
54 | enter_np(); | 77 | enter_np(); |
55 | 78 | ||
@@ -59,7 +82,7 @@ void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) | |||
59 | req->status = waiting; | 82 | req->status = waiting; |
60 | lock->enter[processor]+=1; | 83 | lock->enter[processor]+=1; |
61 | 84 | ||
62 | printf("%d:%d rwrnlp_read_lock %lu\n",__sync_fetch_and_add(&events,1), gettid(), req->resources); | 85 | // printf("%d:%d rwrnlp_read_lock %lu\n",__sync_fetch_and_add(&events,1), gettid(), req->resources); |
63 | 86 | ||
64 | spin_lock(lock->state); | 87 | spin_lock(lock->state); |
65 | if((req->resources & lock->unavailable) == 0){ | 88 | if((req->resources & lock->unavailable) == 0){ |
@@ -68,14 +91,35 @@ void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) | |||
68 | spin_unlock(lock->state); | 91 | spin_unlock(lock->state); |
69 | 92 | ||
70 | if(req->status != acquired){ | 93 | if(req->status != acquired){ |
71 | printf("%d:%d waiting to become entitled\n",__sync_fetch_and_add(&events,1), gettid()); | 94 | // printf("%d:%d waiting to become entitled\n",__sync_fetch_and_add(&events,1), gettid()); |
95 | #if MEASURE==TRUE | ||
96 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
97 | overhead += diff_ns(&last,&now); | ||
98 | #endif | ||
99 | |||
72 | while((req->resources & lock->wentitled) != 0); | 100 | while((req->resources & lock->wentitled) != 0); |
101 | #if MEASURE==TRUE | ||
102 | clock_gettime(CLOCK_MONOTONIC, &last); | ||
103 | #endif | ||
73 | req->status = entitled; | 104 | req->status = entitled; |
74 | printf("%d:%d waiting to acquire\n", __sync_fetch_and_add(&events,1), gettid()); | 105 | #if MEASURE==TRUE |
106 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
107 | overhead += diff_ns(&last, &now); | ||
108 | #endif | ||
109 | |||
110 | // printf("%d:%d waiting to acquire\n", __sync_fetch_and_add(&events,1), gettid()); | ||
75 | while((req->resources & lock->wlocked) != 0); | 111 | while((req->resources & lock->wlocked) != 0); |
76 | } | 112 | } |
113 | #if MEASURE==TRUE | ||
114 | else{ | ||
115 | //acquire, but measure overheads | ||
116 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
117 | overhead += diff_ns(&last, &now); | ||
118 | } | ||
119 | printf("read lock overhead: %ld\n", overhead); | ||
120 | #endif | ||
77 | 121 | ||
78 | printf("%d:%d reader satisfied\n", __sync_fetch_and_add(&events,1), gettid()); | 122 | // printf("%d:%d reader satisfied\n", __sync_fetch_and_add(&events,1), gettid()); |
79 | } | 123 | } |
80 | 124 | ||
81 | void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) | 125 | void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) |
@@ -83,10 +127,15 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) | |||
83 | int r,i,start,end; | 127 | int r,i,start,end; |
84 | request *req, *contender; | 128 | request *req, *contender; |
85 | resource_mask_t tmp = resources; | 129 | resource_mask_t tmp = resources; |
130 | #if MEASURE==TRUE | ||
131 | struct timespec now, last; | ||
132 | long overhead = 0; | ||
133 | clock_gettime(CLOCK_MONOTONIC, &last); | ||
134 | #endif | ||
86 | 135 | ||
87 | enter_np(); | 136 | enter_np(); |
88 | 137 | ||
89 | printf("%d:%d rwrnlp_write_lock\n", __sync_fetch_and_add(&events,1), gettid()); | 138 | // printf("%d:%d rwrnlp_write_lock\n", __sync_fetch_and_add(&events,1), gettid()); |
90 | 139 | ||
91 | req = &lock->requests[processor]; | 140 | req = &lock->requests[processor]; |
92 | 141 | ||
@@ -110,8 +159,15 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) | |||
110 | r = ffsl(tmp); | 159 | r = ffsl(tmp); |
111 | while(r != 0){ | 160 | while(r != 0){ |
112 | r = r-1; | 161 | r = r-1; |
113 | printf("%d:%d write waiting to become head of %d\n", __sync_fetch_and_add(&events,1), gettid(), r); | 162 | // printf("%d:%d write waiting to become head of %d\n", __sync_fetch_and_add(&events,1), gettid(), r); |
163 | #if MEASURE==TRUE | ||
164 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
165 | overhead += diff_ns(&last, &now); | ||
166 | #endif | ||
114 | while(lock->wqueue[r][lock->whead[r]] != req); | 167 | while(lock->wqueue[r][lock->whead[r]] != req); |
168 | #if MEASURE==TRUE | ||
169 | clock_gettime(CLOCK_MONOTONIC, &last); | ||
170 | #endif | ||
115 | tmp &= ~(1<<r); | 171 | tmp &= ~(1<<r); |
116 | r = ffsl(tmp); | 172 | r = ffsl(tmp); |
117 | } | 173 | } |
@@ -132,8 +188,16 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) | |||
132 | (contender->resources & req->resources) == 0) | 188 | (contender->resources & req->resources) == 0) |
133 | continue; | 189 | continue; |
134 | 190 | ||
135 | printf("%d:%d waiting for reader on processor %d\n", __sync_fetch_and_add(&events,1), gettid(), i); | 191 | // printf("%d:%d waiting for reader on processor %d\n", __sync_fetch_and_add(&events,1), gettid(), i); |
192 | |||
193 | #if MEASURE==TRUE | ||
194 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
195 | overhead += diff_ns(&last, &now); | ||
196 | #endif | ||
136 | while(lock->leave[i] < start); | 197 | while(lock->leave[i] < start); |
198 | #if MEASURE==TRUE | ||
199 | clock_gettime(CLOCK_MONOTONIC, &last); | ||
200 | #endif | ||
137 | } | 201 | } |
138 | } | 202 | } |
139 | 203 | ||
@@ -142,23 +206,43 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) | |||
142 | lock->wlocked |= req->resources; | 206 | lock->wlocked |= req->resources; |
143 | spin_unlock(lock->state); | 207 | spin_unlock(lock->state); |
144 | 208 | ||
145 | printf("%d:%d writer satisfied\n", __sync_fetch_and_add(&events,1), gettid()); | 209 | // printf("%d:%d writer satisfied\n", __sync_fetch_and_add(&events,1), gettid()); |
210 | #if MEASURE==TRUE | ||
211 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
212 | overhead += diff_ns(&last, &now); | ||
213 | printf("write lock overhead: %ld\n", overhead); | ||
214 | #endif | ||
146 | } | 215 | } |
147 | 216 | ||
148 | void rwrnlp_read_unlock(rwrnlp *lock, int processor) | 217 | void rwrnlp_read_unlock(rwrnlp *lock, int processor) |
149 | { | 218 | { |
219 | #if MEASURE==TRUE | ||
220 | struct timespec now, last; | ||
221 | clock_gettime(CLOCK_MONOTONIC, &last); | ||
222 | #endif | ||
150 | lock->leave[processor] += 1; | 223 | lock->leave[processor] += 1; |
151 | printf("%d:%d rwrnlp_read_unlock\n", __sync_fetch_and_add(&events,1), gettid()); | 224 | // printf("%d:%d rwrnlp_read_unlock\n", __sync_fetch_and_add(&events,1), gettid()); |
152 | exit_np(); | 225 | exit_np(); |
226 | |||
227 | #if MEASURE==TRUE | ||
228 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
229 | printf("read unlock overhead: %ld\n", diff_ns(&last, &now)); | ||
230 | #endif | ||
153 | } | 231 | } |
154 | 232 | ||
155 | void rwrnlp_write_unlock(rwrnlp *lock, int processor) | 233 | void rwrnlp_write_unlock(rwrnlp *lock, int processor) |
156 | { | 234 | { |
157 | int r; | 235 | int r; |
158 | request *req = &lock->requests[processor]; | 236 | request *req; |
159 | resource_mask_t tmp = req->resources; | 237 | resource_mask_t tmp; |
238 | #if MEASURE==TRUE | ||
239 | struct timespec now, last; | ||
240 | clock_gettime(CLOCK_MONOTONIC, &last); | ||
241 | #endif | ||
242 | req= &lock->requests[processor]; | ||
243 | tmp = req->resources; | ||
160 | 244 | ||
161 | printf("%d:%d rwrnlp_write_unlock\n", __sync_fetch_and_add(&events,1), gettid()); | 245 | // printf("%d:%d rwrnlp_write_unlock\n", __sync_fetch_and_add(&events,1), gettid()); |
162 | 246 | ||
163 | lock->leave[processor] += 1; | 247 | lock->leave[processor] += 1; |
164 | 248 | ||
@@ -174,7 +258,11 @@ void rwrnlp_write_unlock(rwrnlp *lock, int processor) | |||
174 | lock->unavailable &= ~(req->resources); | 258 | lock->unavailable &= ~(req->resources); |
175 | spin_unlock(lock->state); | 259 | spin_unlock(lock->state); |
176 | 260 | ||
177 | printf("%d:%d write unlocked %lu\n", __sync_fetch_and_add(&events,1), gettid(), req->resources); | 261 | // 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); | 262 | // printf("unavailable %lu\nwentitled %lu\nwlocked %lu\n", lock->unavailable, lock->wentitled, lock->wlocked); |
179 | exit_np(); | 263 | exit_np(); |
264 | #if MEASURE==TRUE | ||
265 | clock_gettime(CLOCK_MONOTONIC, &now); | ||
266 | printf("write unlock overhead: %ld\n", diff_ns(&last, &now)); | ||
267 | #endif | ||
180 | } | 268 | } |