diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-05-03 15:10:34 -0400 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-05-03 15:10:34 -0400 |
commit | a8cda9d6f58a3074875c09c97001207985960a2f (patch) | |
tree | 66489f270b1954f42190f95ef0170794d9fb4f63 | |
parent | e1e24f60f63ca339f91051e70d371e565547df96 (diff) | |
parent | 03e9cedc1879ffacc8f28a6fd38f0b73888b2826 (diff) |
Merged
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | bin/mc2bench.c | 503 | ||||
-rw-r--r-- | bin/mc2shm.c | 502 | ||||
-rw-r--r-- | bin/mtdag.c (renamed from bin/mttest.c) | 72 | ||||
-rw-r--r-- | bin/test1.c | 453 | ||||
-rw-r--r-- | include/color_shm.h | 1 | ||||
-rw-r--r-- | include/litmus.h | 2 | ||||
-rw-r--r-- | src/kernel_iface.c | 56 | ||||
-rw-r--r-- | src/syscalls.c | 5 |
9 files changed, 1515 insertions, 99 deletions
@@ -73,8 +73,9 @@ AR := ${CROSS_COMPILE}${AR} | |||
73 | 73 | ||
74 | all = lib ${rt-apps} | 74 | all = lib ${rt-apps} |
75 | rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ | 75 | rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ |
76 | base_mt_task uncache runtests resctrl mc2spin test1 mttest \ | 76 | base_mt_task uncache runtests resctrl mc2spin test1 \ |
77 | mc2thrash mc2shm mc2bench | 77 | mc2thrash mc2shm mc2thrash1 mc2thrash2 mc2thrash3 mc2bench\ |
78 | mtdag | ||
78 | 79 | ||
79 | .PHONY: all lib clean dump-config TAGS tags cscope help doc | 80 | .PHONY: all lib clean dump-config TAGS tags cscope help doc |
80 | 81 | ||
@@ -253,15 +254,24 @@ lib-memthrash = -lrt | |||
253 | obj-test1 = test1.o common.o | 254 | obj-test1 = test1.o common.o |
254 | lib-test1 = -lrt -static | 255 | lib-test1 = -lrt -static |
255 | 256 | ||
256 | obj-mttest = mttest.o | ||
257 | ldf-mttest = -pthread | ||
258 | |||
259 | obj-mc2thrash = mc2thrash.o common.o | 257 | obj-mc2thrash = mc2thrash.o common.o |
260 | lib-mc2thrash = -lrt -static | 258 | lib-mc2thrash = -lrt -static |
261 | 259 | ||
260 | obj-mc2thrash1 = mc2thrash.o common.o | ||
261 | lib-mc2thrash1 = -lrt -static | ||
262 | |||
263 | obj-mc2thrash2 = mc2thrash.o common.o | ||
264 | lib-mc2thrash2 = -lrt -static | ||
265 | |||
266 | obj-mc2thrash3 = mc2thrash.o common.o | ||
267 | lib-mc2thrash3 = -lrt -static | ||
268 | |||
262 | obj-mc2shm = mc2shm.o common.o | 269 | obj-mc2shm = mc2shm.o common.o |
263 | lib-mc2shm = -lrt -static | 270 | lib-mc2shm = -lrt -static |
264 | 271 | ||
272 | obj-mtdag = mtdag.o common.o | ||
273 | ldf-mtdag = -lrt -pthread -static | ||
274 | |||
265 | obj-mc2bench = mc2bench.o common.o | 275 | obj-mc2bench = mc2bench.o common.o |
266 | lib-mc2bench = -lrt -static | 276 | lib-mc2bench = -lrt -static |
267 | # ############################################################################## | 277 | # ############################################################################## |
diff --git a/bin/mc2bench.c b/bin/mc2bench.c new file mode 100644 index 0000000..dfb4f15 --- /dev/null +++ b/bin/mc2bench.c | |||
@@ -0,0 +1,503 @@ | |||
1 | #include <sys/time.h> | ||
2 | #include <sys/mman.h> | ||
3 | |||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <unistd.h> | ||
7 | #include <time.h> | ||
8 | #include <string.h> | ||
9 | #include <assert.h> | ||
10 | #include <limits.h> | ||
11 | #include <fcntl.h> | ||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "color_shm.h" | ||
16 | |||
17 | #define PAGE_SIZE (4096) | ||
18 | //#define CACHELINE_SIZE 32 | ||
19 | //#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) | ||
20 | //#define CACHELINES_IN_1KB (1024 / sizeof(cacheline_t)) | ||
21 | #define INTS_IN_1KB (1024 / sizeof(int)) | ||
22 | |||
23 | //typedef struct cacheline | ||
24 | //{ | ||
25 | // int line[INTS_IN_CACHELINE]; | ||
26 | //} __attribute__((aligned(CACHELINE_SIZE))) cacheline_t; | ||
27 | |||
28 | static int loops = 100000; | ||
29 | static cacheline_t* arena = NULL; | ||
30 | static cacheline_t* local_buf = NULL; | ||
31 | |||
32 | struct timeval t1,t2; | ||
33 | |||
34 | lt_t exectime[100000]; | ||
35 | |||
36 | inline unsigned long get_cyclecount (void) | ||
37 | { | ||
38 | unsigned long value; | ||
39 | // Read CCNT Register | ||
40 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
41 | return value; | ||
42 | } | ||
43 | |||
44 | #define UNCACHE_DEV "/dev/litmus/uncache" | ||
45 | |||
46 | static cacheline_t* alloc_shm(int cs, size_t size, int use_huge_pages, int use_uncache_pages) | ||
47 | { | ||
48 | struct color_ioctl_cmd shm_info; | ||
49 | struct color_ioctl_offset shm_offset; | ||
50 | cacheline_t* arena = NULL; | ||
51 | |||
52 | |||
53 | shm_info.color = 0x0000ffff; | ||
54 | |||
55 | if (cs == 1 || cs == 2) | ||
56 | shm_info.bank = 0x00000020; // hi crit. bank | ||
57 | else if (cs == 3) | ||
58 | shm_info.bank = 0x00000040; // levelC | ||
59 | |||
60 | shm_offset.offset = 0; | ||
61 | shm_offset.lock = 1; | ||
62 | |||
63 | arena = color_mmap(size, shm_info, shm_offset); | ||
64 | if (arena == MAP_FAILED) { | ||
65 | printf("mmap failed.\n"); | ||
66 | return NULL; | ||
67 | } | ||
68 | |||
69 | mlockall(MCL_CURRENT | MCL_FUTURE); | ||
70 | /* finish allocation */ | ||
71 | |||
72 | assert(arena); | ||
73 | |||
74 | return arena; | ||
75 | } | ||
76 | |||
77 | static cacheline_t* alloc_local(size_t size, int use_huge_pages, int use_uncache_pages) | ||
78 | { | ||
79 | int flags = MAP_PRIVATE | MAP_POPULATE; | ||
80 | cacheline_t* arena = NULL; | ||
81 | int fd; | ||
82 | |||
83 | if(use_huge_pages) | ||
84 | flags |= MAP_HUGETLB; | ||
85 | |||
86 | if(use_uncache_pages) { | ||
87 | fd = open(UNCACHE_DEV, O_RDWR|O_SYNC); | ||
88 | if (fd == -1) | ||
89 | bail_out("Failed to open uncache device. Are you running the LITMUS^RT kernel?"); | ||
90 | } | ||
91 | else { | ||
92 | fd = -1; | ||
93 | flags |= MAP_ANONYMOUS; | ||
94 | } | ||
95 | |||
96 | arena = mmap(0, size, PROT_READ | PROT_WRITE, flags, fd, 0); | ||
97 | |||
98 | if(use_uncache_pages) | ||
99 | close(fd); | ||
100 | |||
101 | assert(arena); | ||
102 | |||
103 | return arena; | ||
104 | } | ||
105 | |||
106 | static void dealloc_arena(cacheline_t* arena, size_t size) | ||
107 | { | ||
108 | int ret = munmap((void*)arena, size); | ||
109 | if(ret != 0) | ||
110 | bail_out("munmap() error"); | ||
111 | } | ||
112 | |||
113 | static int randrange(int min, int max) | ||
114 | { | ||
115 | /* generate a random number on the range [min, max) w/o skew */ | ||
116 | int limit = max - min; | ||
117 | int devisor = RAND_MAX/limit; | ||
118 | int retval; | ||
119 | |||
120 | do { | ||
121 | retval = rand() / devisor; | ||
122 | } while(retval == limit); | ||
123 | retval += min; | ||
124 | |||
125 | return retval; | ||
126 | } | ||
127 | |||
128 | static void init_arena(cacheline_t* arena, size_t size) | ||
129 | { | ||
130 | int i; | ||
131 | size_t num_arena_elem = size / sizeof(cacheline_t); | ||
132 | |||
133 | /* Generate a cycle among the cache lines using Sattolo's algorithm. | ||
134 | Every int in the cache line points to the same cache line. | ||
135 | Note: Sequential walk doesn't care about these values. */ | ||
136 | for (i = 0; i < num_arena_elem; i++) { | ||
137 | int j; | ||
138 | for(j = 0; j < INTS_IN_CACHELINE; ++j) | ||
139 | arena[i].line[j] = i; | ||
140 | } | ||
141 | while(1 < i--) { | ||
142 | int j = randrange(0, i); | ||
143 | cacheline_t temp = arena[j]; | ||
144 | arena[j] = arena[i]; | ||
145 | arena[i] = temp; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | /* Random walk around the arena in cacheline-sized chunks. | ||
150 | Cacheline-sized chucks ensures the same utilization of each | ||
151 | hit line as sequential read. (Otherwise, our utilization | ||
152 | would only be 1/INTS_IN_CACHELINE.) */ | ||
153 | static int random_walk(cacheline_t *mem, int wss, int write_cycle) | ||
154 | { | ||
155 | /* a random cycle among the cache lines was set up by init_arena(). */ | ||
156 | int sum, i, next, j; | ||
157 | |||
158 | int numlines = wss * CACHELINES_IN_1KB; | ||
159 | |||
160 | sum = 0; | ||
161 | |||
162 | /* contents of arena is structured s.t. offsets are all | ||
163 | w.r.t. to start of arena, so compute the initial offset */ | ||
164 | next = mem - arena; | ||
165 | |||
166 | if (write_cycle == 0) { | ||
167 | for (i = 0; i < numlines; i++) { | ||
168 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
169 | /* every element in the cacheline has the same value */ | ||
170 | //next = arena[next].line[j]; | ||
171 | local_buf[next].line[j] = arena[next].line[j]; | ||
172 | //sum += next; | ||
173 | //local_buf[next].line[j] = next; | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | else { | ||
179 | int w, which_line; | ||
180 | for (i = 0, w = 0; i < numlines; i++) { | ||
181 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
182 | which_line = next; | ||
183 | next = local_buf[next].line[j]; | ||
184 | ((volatile cacheline_t*)arena)[which_line].line[j] = next; | ||
185 | //sum += next; | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | return sum; | ||
190 | } | ||
191 | |||
192 | static cacheline_t* random_start(int wss) | ||
193 | { | ||
194 | return arena + randrange(0, ((wss * 1024)/sizeof(cacheline_t))); | ||
195 | } | ||
196 | |||
197 | static int sequential_walk(cacheline_t *mem, int wss, int write_cycle) | ||
198 | { | ||
199 | int sum = 0, i, j; | ||
200 | //int* mem = (int*)_mem; /* treat as raw buffer of ints */ | ||
201 | int num_ints = wss * CACHELINES_IN_1KB; | ||
202 | |||
203 | if (write_cycle > 0) { | ||
204 | for (i = 0; i < num_ints; i++) { | ||
205 | //if (i % write_cycle == (write_cycle - 1)) { | ||
206 | //mem[i]++; | ||
207 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
208 | //sum += local_buf[i].line[j]; | ||
209 | mem[i].line[j] = local_buf[i].line[j];; | ||
210 | } | ||
211 | //} | ||
212 | //else { | ||
213 | // sum += mem[i]; | ||
214 | //} | ||
215 | } | ||
216 | } else { | ||
217 | /* sequential access, pure read */ | ||
218 | for (i = 0; i < num_ints; i++) { | ||
219 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
220 | //sum += mem[i]; | ||
221 | local_buf[i].line[j] = mem[i].line[j]; | ||
222 | //sum += mem[i]; | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | return sum; | ||
227 | } | ||
228 | |||
229 | static cacheline_t* sequential_start(int wss) | ||
230 | { | ||
231 | return arena; | ||
232 | /* static int pos = 0; | ||
233 | |||
234 | int num_cachelines = wss * CACHELINES_IN_1KB; | ||
235 | size_t num_arena_elem = wss * 1024 / sizeof(cacheline_t); | ||
236 | cacheline_t *mem; | ||
237 | */ | ||
238 | |||
239 | /* Don't allow re-use between allocations. | ||
240 | * At most half of the arena may be used | ||
241 | * at any one time. | ||
242 | */ | ||
243 | /* if (num_cachelines * 2 > num_arena_elem) | ||
244 | bail_out("static memory arena too small"); | ||
245 | |||
246 | if (pos + num_cachelines > num_arena_elem) { | ||
247 | mem = arena; | ||
248 | pos = num_cachelines; | ||
249 | } else { | ||
250 | mem = arena + pos; | ||
251 | pos += num_cachelines; | ||
252 | } | ||
253 | |||
254 | return mem;*/ | ||
255 | } | ||
256 | |||
257 | static volatile int dont_optimize_me = 0; | ||
258 | |||
259 | static void usage(char *error) { | ||
260 | fprintf(stderr, "Error: %s\n", error); | ||
261 | fprintf(stderr, | ||
262 | "Usage:\n" | ||
263 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
264 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
265 | " rt_spin -l\n" | ||
266 | "\n" | ||
267 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
268 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-m CRITICALITY LEVEL]\n" | ||
269 | " [-k WSS] [-l LOOPS] [-b BUDGET]\n" | ||
270 | "\n" | ||
271 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n"); | ||
272 | exit(EXIT_FAILURE); | ||
273 | } | ||
274 | |||
275 | static int loop_once(int cs, int wss, unsigned int iter) | ||
276 | { | ||
277 | //cacheline_t *mem; | ||
278 | //int temp; | ||
279 | |||
280 | //mem = random_start(wss); | ||
281 | //temp = random_walk(mem, wss, 1); | ||
282 | |||
283 | //mem = sequential_start(wss); | ||
284 | //temp = sequential_walk(arena, wss, 1); | ||
285 | run_bench(cs, wss, arena, local_buf, &exectime[iter]); | ||
286 | dont_optimize_me = (int)exectime[iter]; | ||
287 | |||
288 | return dont_optimize_me; | ||
289 | } | ||
290 | |||
291 | static int job(int cs, int wss, double exec_time, double program_end) | ||
292 | { | ||
293 | if (wctime() > program_end) | ||
294 | return 0; | ||
295 | else { | ||
296 | register unsigned long t; | ||
297 | register unsigned int iter = 0; | ||
298 | //t = get_cyclecount(); | ||
299 | //gettimeofday(&t1, NULL); | ||
300 | while(iter < loops) { | ||
301 | loop_once(cs, wss, iter++); | ||
302 | } | ||
303 | //gettimeofday(&t2, NULL); | ||
304 | //printf("%ld cycles\n", get_cyclecount() - t); | ||
305 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
306 | sleep_next_period(); | ||
307 | return 1; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | #define OPTSTR "p:wl:m:i:b:k:c:" | ||
312 | int main(int argc, char** argv) | ||
313 | { | ||
314 | int ret, i; | ||
315 | lt_t wcet, period, budget; | ||
316 | double wcet_ms, period_ms, budget_ms; | ||
317 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
318 | int migrate = 0; | ||
319 | int cluster = 0; | ||
320 | int opt; | ||
321 | int wait = 0; | ||
322 | double duration = 0, start = 0; | ||
323 | struct rt_task param; | ||
324 | struct mc2_task mc2_param; | ||
325 | struct reservation_config config; | ||
326 | int res_type = PERIODIC_POLLING; | ||
327 | size_t arena_sz; | ||
328 | int wss, cs; | ||
329 | |||
330 | /* default for reservation */ | ||
331 | config.id = 0; | ||
332 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
333 | config.cpu = -1; | ||
334 | |||
335 | mc2_param.crit = CRIT_LEVEL_C; | ||
336 | |||
337 | budget_ms = 1000; | ||
338 | |||
339 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
340 | switch (opt) { | ||
341 | case 'w': | ||
342 | wait = 1; | ||
343 | break; | ||
344 | case 'p': | ||
345 | cluster = atoi(optarg); | ||
346 | migrate = 1; | ||
347 | config.cpu = cluster; | ||
348 | break; | ||
349 | case 'l': | ||
350 | loops = atoi(optarg); | ||
351 | break; | ||
352 | case 'k': | ||
353 | wss = atoi(optarg); | ||
354 | break; | ||
355 | case 'm': | ||
356 | mc2_param.crit = atoi(optarg); | ||
357 | if ((mc2_param.crit >= CRIT_LEVEL_A) && (mc2_param.crit <= CRIT_LEVEL_C)) { | ||
358 | res_type = PERIODIC_POLLING; | ||
359 | } | ||
360 | else | ||
361 | usage("Invalid criticality level."); | ||
362 | break; | ||
363 | case 'b': | ||
364 | budget_ms = atof(optarg); | ||
365 | break; | ||
366 | case 'i': | ||
367 | config.priority = atoi(optarg); | ||
368 | break; | ||
369 | case 'c': | ||
370 | cs = atoi(optarg); | ||
371 | break; | ||
372 | case ':': | ||
373 | usage("Argument missing."); | ||
374 | break; | ||
375 | case '?': | ||
376 | default: | ||
377 | usage("Bad argument."); | ||
378 | break; | ||
379 | } | ||
380 | } | ||
381 | srand(getpid()); | ||
382 | |||
383 | /* | ||
384 | * We need three parameters | ||
385 | */ | ||
386 | if (argc - optind < 3) | ||
387 | usage("Arguments missing."); | ||
388 | |||
389 | wcet_ms = atof(argv[optind + 0]); | ||
390 | period_ms = atof(argv[optind + 1]); | ||
391 | |||
392 | wcet = ms2ns(wcet_ms); | ||
393 | period = ms2ns(period_ms); | ||
394 | budget = ms2ns(budget_ms); | ||
395 | if (wcet <= 0) | ||
396 | usage("The worst-case execution time must be a " | ||
397 | "positive number."); | ||
398 | if (period <= 0) | ||
399 | usage("The period must be a positive number."); | ||
400 | if (wcet > period) { | ||
401 | usage("The worst-case execution time must not " | ||
402 | "exceed the period."); | ||
403 | } | ||
404 | |||
405 | duration = atof(argv[optind + 2]); | ||
406 | |||
407 | if (migrate) { | ||
408 | ret = be_migrate_to_domain(cluster); | ||
409 | if (ret < 0) | ||
410 | bail_out("could not migrate to target partition or cluster."); | ||
411 | } | ||
412 | |||
413 | /* reservation config */ | ||
414 | config.id = gettid(); | ||
415 | config.polling_params.budget = budget; | ||
416 | config.polling_params.period = period; | ||
417 | config.polling_params.offset = 0; | ||
418 | config.polling_params.relative_deadline = 0; | ||
419 | |||
420 | if (config.polling_params.budget > config.polling_params.period) { | ||
421 | usage("The budget must not exceed the period."); | ||
422 | } | ||
423 | |||
424 | /* create a reservation */ | ||
425 | ret = reservation_create(res_type, &config); | ||
426 | if (ret < 0) { | ||
427 | bail_out("failed to create reservation."); | ||
428 | } | ||
429 | |||
430 | init_rt_task_param(¶m); | ||
431 | param.exec_cost = wcet; | ||
432 | param.period = period; | ||
433 | param.priority = priority; | ||
434 | param.cls = RT_CLASS_HARD; | ||
435 | param.release_policy = TASK_PERIODIC; | ||
436 | param.budget_policy = NO_ENFORCEMENT; | ||
437 | if (migrate) { | ||
438 | param.cpu = gettid(); | ||
439 | } | ||
440 | ret = set_rt_task_param(gettid(), ¶m); | ||
441 | if (ret < 0) | ||
442 | bail_out("could not setup rt task params"); | ||
443 | |||
444 | mc2_param.res_id = gettid(); | ||
445 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
446 | if (ret < 0) | ||
447 | bail_out("could not setup mc2 task params"); | ||
448 | |||
449 | |||
450 | arena_sz = wss*1024; | ||
451 | |||
452 | arena = alloc_shm(cs, arena_sz, 0, 0); | ||
453 | if (!arena) | ||
454 | bail_out("alloc_shm failed.\n"); | ||
455 | init_arena(arena, arena_sz); | ||
456 | |||
457 | local_buf = alloc_local(arena_sz, 0, 0); | ||
458 | if (!local_buf) | ||
459 | bail_out("alloc_local failed.\n"); | ||
460 | init_arena(local_buf, arena_sz); | ||
461 | |||
462 | ret = init_litmus(); | ||
463 | if (ret != 0) | ||
464 | bail_out("init_litmus() failed\n"); | ||
465 | |||
466 | start = wctime(); | ||
467 | ret = task_mode(LITMUS_RT_TASK); | ||
468 | if (ret != 0) | ||
469 | bail_out("could not become RT task"); | ||
470 | |||
471 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
472 | set_page_color(-1); | ||
473 | else | ||
474 | set_page_color(config.cpu); | ||
475 | |||
476 | mlockall(MCL_CURRENT | MCL_FUTURE); | ||
477 | // init_arena(local_buf, arena_sz); | ||
478 | // test_call(1); | ||
479 | // init_arena(arena, arena_sz); | ||
480 | // test_call(2); | ||
481 | |||
482 | if (wait) { | ||
483 | ret = wait_for_ts_release(); | ||
484 | if (ret != 0) | ||
485 | bail_out("wait_for_ts_release()"); | ||
486 | start = wctime(); | ||
487 | } | ||
488 | |||
489 | //while (job(wss, wcet_ms * 0.001, start + duration)) {}; | ||
490 | job(cs, wss, wcet_ms * 0.001, start + duration); | ||
491 | |||
492 | ret = task_mode(BACKGROUND_TASK); | ||
493 | if (ret != 0) | ||
494 | bail_out("could not become regular task (huh?)"); | ||
495 | |||
496 | reservation_destroy(gettid(), config.cpu); | ||
497 | dealloc_arena(arena, arena_sz); | ||
498 | dealloc_arena(local_buf, arena_sz); | ||
499 | printf("%s finished.\n", argv[0]); | ||
500 | for (i = 0; i<loops; i++) | ||
501 | printf("%llu\n", exectime[i]); | ||
502 | return 0; | ||
503 | } | ||
diff --git a/bin/mc2shm.c b/bin/mc2shm.c new file mode 100644 index 0000000..4cc974a --- /dev/null +++ b/bin/mc2shm.c | |||
@@ -0,0 +1,502 @@ | |||
1 | #include <sys/time.h> | ||
2 | #include <sys/mman.h> | ||
3 | |||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <unistd.h> | ||
7 | #include <time.h> | ||
8 | #include <string.h> | ||
9 | #include <assert.h> | ||
10 | #include <limits.h> | ||
11 | #include <fcntl.h> | ||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "color_shm.h" | ||
16 | |||
17 | #define PAGE_SIZE (4096) | ||
18 | #define CACHELINE_SIZE 32 | ||
19 | #define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) | ||
20 | #define CACHELINES_IN_1KB (1024 / sizeof(cacheline_t)) | ||
21 | #define INTS_IN_1KB (1024 / sizeof(int)) | ||
22 | #define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) | ||
23 | |||
24 | //typedef struct cacheline | ||
25 | //{ | ||
26 | // int line[INTS_IN_CACHELINE]; | ||
27 | //} __attribute__((aligned(CACHELINE_SIZE))) cacheline_t; | ||
28 | |||
29 | static int loops = 10; | ||
30 | static cacheline_t* arena = NULL; | ||
31 | static cacheline_t* local_buf = NULL; | ||
32 | |||
33 | struct timeval t1,t2; | ||
34 | |||
35 | inline unsigned long get_cyclecount (void) | ||
36 | { | ||
37 | unsigned long value; | ||
38 | // Read CCNT Register | ||
39 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
40 | return value; | ||
41 | } | ||
42 | |||
43 | #define UNCACHE_DEV "/dev/litmus/uncache" | ||
44 | |||
45 | static cacheline_t* alloc_shm(size_t size, int use_huge_pages, int use_uncache_pages) | ||
46 | { | ||
47 | int ret, fd; | ||
48 | struct color_ioctl_cmd shm_info; | ||
49 | cacheline_t* arena = NULL; | ||
50 | |||
51 | /* allocate shm */ | ||
52 | fd = open("/dev/litmus/color_shm", O_RDWR); | ||
53 | if (fd < 0) { | ||
54 | printf("Device open error.\n"); | ||
55 | return NULL; | ||
56 | } | ||
57 | |||
58 | shm_info.color = 0x00000f00; | ||
59 | //shm_info.bank = 0x00000020; // hi crit. bank | ||
60 | shm_info.bank = 0x00000040; // levelC | ||
61 | |||
62 | ret = ioctl(fd, SET_COLOR_SHM_CMD, &shm_info); | ||
63 | if (ret < 0) { | ||
64 | printf("ioctl failed.\n"); | ||
65 | return NULL; | ||
66 | } | ||
67 | |||
68 | arena = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||
69 | if (arena == MAP_FAILED) { | ||
70 | printf("mmap failed.\n"); | ||
71 | return NULL; | ||
72 | } | ||
73 | close(fd); | ||
74 | |||
75 | mlockall(MCL_CURRENT | MCL_FUTURE); | ||
76 | /* finish allocation */ | ||
77 | |||
78 | assert(arena); | ||
79 | |||
80 | return arena; | ||
81 | } | ||
82 | |||
83 | static cacheline_t* alloc_local(size_t size, int use_huge_pages, int use_uncache_pages) | ||
84 | { | ||
85 | int flags = MAP_PRIVATE | MAP_POPULATE; | ||
86 | cacheline_t* arena = NULL; | ||
87 | int fd; | ||
88 | |||
89 | if(use_huge_pages) | ||
90 | flags |= MAP_HUGETLB; | ||
91 | |||
92 | if(use_uncache_pages) { | ||
93 | fd = open(UNCACHE_DEV, O_RDWR|O_SYNC); | ||
94 | if (fd == -1) | ||
95 | bail_out("Failed to open uncache device. Are you running the LITMUS^RT kernel?"); | ||
96 | } | ||
97 | else { | ||
98 | fd = -1; | ||
99 | flags |= MAP_ANONYMOUS; | ||
100 | } | ||
101 | |||
102 | arena = mmap(0, size, PROT_READ | PROT_WRITE, flags, fd, 0); | ||
103 | |||
104 | if(use_uncache_pages) | ||
105 | close(fd); | ||
106 | |||
107 | assert(arena); | ||
108 | |||
109 | return arena; | ||
110 | } | ||
111 | |||
112 | static void dealloc_arena(cacheline_t* arena, size_t size) | ||
113 | { | ||
114 | int ret = munmap((void*)arena, size); | ||
115 | if(ret != 0) | ||
116 | bail_out("munmap() error"); | ||
117 | } | ||
118 | |||
119 | static int randrange(int min, int max) | ||
120 | { | ||
121 | /* generate a random number on the range [min, max) w/o skew */ | ||
122 | int limit = max - min; | ||
123 | int devisor = RAND_MAX/limit; | ||
124 | int retval; | ||
125 | |||
126 | do { | ||
127 | retval = rand() / devisor; | ||
128 | } while(retval == limit); | ||
129 | retval += min; | ||
130 | |||
131 | return retval; | ||
132 | } | ||
133 | |||
134 | static void init_arena(cacheline_t* arena, size_t size) | ||
135 | { | ||
136 | int i; | ||
137 | size_t num_arena_elem = size / sizeof(cacheline_t); | ||
138 | |||
139 | /* Generate a cycle among the cache lines using Sattolo's algorithm. | ||
140 | Every int in the cache line points to the same cache line. | ||
141 | Note: Sequential walk doesn't care about these values. */ | ||
142 | for (i = 0; i < num_arena_elem; i++) { | ||
143 | int j; | ||
144 | for(j = 0; j < INTS_IN_CACHELINE; ++j) | ||
145 | arena[i].line[j] = i; | ||
146 | } | ||
147 | while(1 < i--) { | ||
148 | int j = randrange(0, i); | ||
149 | cacheline_t temp = arena[j]; | ||
150 | arena[j] = arena[i]; | ||
151 | arena[i] = temp; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* Random walk around the arena in cacheline-sized chunks. | ||
156 | Cacheline-sized chucks ensures the same utilization of each | ||
157 | hit line as sequential read. (Otherwise, our utilization | ||
158 | would only be 1/INTS_IN_CACHELINE.) */ | ||
159 | static int random_walk(cacheline_t *mem, int wss, int write_cycle) | ||
160 | { | ||
161 | /* a random cycle among the cache lines was set up by init_arena(). */ | ||
162 | int sum, i, next, j; | ||
163 | |||
164 | int numlines = wss * CACHELINES_IN_1KB; | ||
165 | |||
166 | sum = 0; | ||
167 | |||
168 | /* contents of arena is structured s.t. offsets are all | ||
169 | w.r.t. to start of arena, so compute the initial offset */ | ||
170 | next = mem - arena; | ||
171 | |||
172 | if (write_cycle == 0) { | ||
173 | for (i = 0; i < numlines; i++) { | ||
174 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
175 | /* every element in the cacheline has the same value */ | ||
176 | //next = arena[next].line[j]; | ||
177 | local_buf[next].line[j] = arena[next].line[j]; | ||
178 | //sum += next; | ||
179 | //local_buf[next].line[j] = next; | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | |||
184 | else { | ||
185 | int w, which_line; | ||
186 | for (i = 0, w = 0; i < numlines; i++) { | ||
187 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
188 | which_line = next; | ||
189 | next = local_buf[next].line[j]; | ||
190 | ((volatile cacheline_t*)arena)[which_line].line[j] = next; | ||
191 | //sum += next; | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | return sum; | ||
196 | } | ||
197 | |||
198 | static cacheline_t* random_start(int wss) | ||
199 | { | ||
200 | return arena + randrange(0, ((wss * 1024)/sizeof(cacheline_t))); | ||
201 | } | ||
202 | |||
203 | static int sequential_walk(cacheline_t *mem, int wss, int write_cycle) | ||
204 | { | ||
205 | int sum = 0, i, j; | ||
206 | //int* mem = (int*)_mem; /* treat as raw buffer of ints */ | ||
207 | int num_ints = wss * CACHELINES_IN_1KB; | ||
208 | |||
209 | if (write_cycle > 0) { | ||
210 | for (i = 0; i < num_ints; i++) { | ||
211 | //if (i % write_cycle == (write_cycle - 1)) { | ||
212 | //mem[i]++; | ||
213 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
214 | //sum += local_buf[i].line[j]; | ||
215 | mem[i].line[j] = local_buf[i].line[j];; | ||
216 | } | ||
217 | //} | ||
218 | //else { | ||
219 | // sum += mem[i]; | ||
220 | //} | ||
221 | } | ||
222 | } else { | ||
223 | /* sequential access, pure read */ | ||
224 | for (i = 0; i < num_ints; i++) { | ||
225 | for (j = 0; j < INTS_IN_CACHELINE; j++) { | ||
226 | //sum += mem[i]; | ||
227 | local_buf[i].line[j] = mem[i].line[j]; | ||
228 | //sum += mem[i]; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | return sum; | ||
233 | } | ||
234 | |||
235 | static cacheline_t* sequential_start(int wss) | ||
236 | { | ||
237 | return arena; | ||
238 | /* static int pos = 0; | ||
239 | |||
240 | int num_cachelines = wss * CACHELINES_IN_1KB; | ||
241 | size_t num_arena_elem = wss * 1024 / sizeof(cacheline_t); | ||
242 | cacheline_t *mem; | ||
243 | */ | ||
244 | |||
245 | /* Don't allow re-use between allocations. | ||
246 | * At most half of the arena may be used | ||
247 | * at any one time. | ||
248 | */ | ||
249 | /* if (num_cachelines * 2 > num_arena_elem) | ||
250 | bail_out("static memory arena too small"); | ||
251 | |||
252 | if (pos + num_cachelines > num_arena_elem) { | ||
253 | mem = arena; | ||
254 | pos = num_cachelines; | ||
255 | } else { | ||
256 | mem = arena + pos; | ||
257 | pos += num_cachelines; | ||
258 | } | ||
259 | |||
260 | return mem;*/ | ||
261 | } | ||
262 | |||
263 | static volatile int dont_optimize_me = 0; | ||
264 | |||
265 | static void usage(char *error) { | ||
266 | fprintf(stderr, "Error: %s\n", error); | ||
267 | fprintf(stderr, | ||
268 | "Usage:\n" | ||
269 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
270 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
271 | " rt_spin -l\n" | ||
272 | "\n" | ||
273 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
274 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-m CRITICALITY LEVEL]\n" | ||
275 | " [-k WSS] [-l LOOPS] [-b BUDGET]\n" | ||
276 | "\n" | ||
277 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n"); | ||
278 | exit(EXIT_FAILURE); | ||
279 | } | ||
280 | |||
281 | static int loop_once(int wss) | ||
282 | { | ||
283 | cacheline_t *mem; | ||
284 | int temp; | ||
285 | |||
286 | mem = random_start(wss); | ||
287 | temp = random_walk(mem, wss, 1); | ||
288 | |||
289 | //mem = sequential_start(wss); | ||
290 | //temp = sequential_walk(arena, wss, 1); | ||
291 | dont_optimize_me = temp; | ||
292 | |||
293 | return dont_optimize_me; | ||
294 | } | ||
295 | |||
296 | static int job(int wss, double exec_time, double program_end) | ||
297 | { | ||
298 | if (wctime() > program_end) | ||
299 | return 0; | ||
300 | else { | ||
301 | register unsigned long t; | ||
302 | register unsigned int iter = 0; | ||
303 | //t = get_cyclecount(); | ||
304 | //gettimeofday(&t1, NULL); | ||
305 | while(iter++ < loops) { | ||
306 | loop_once(wss); | ||
307 | } | ||
308 | //gettimeofday(&t2, NULL); | ||
309 | //printf("%ld cycles\n", get_cyclecount() - t); | ||
310 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
311 | sleep_next_period(); | ||
312 | return 1; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | #define OPTSTR "p:wl:m:i:b:k:" | ||
317 | int main(int argc, char** argv) | ||
318 | { | ||
319 | int ret; | ||
320 | lt_t wcet, period, budget; | ||
321 | double wcet_ms, period_ms, budget_ms; | ||
322 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
323 | int migrate = 0; | ||
324 | int cluster = 0; | ||
325 | int opt; | ||
326 | int wait = 0; | ||
327 | double duration = 0, start = 0; | ||
328 | struct rt_task param; | ||
329 | struct mc2_task mc2_param; | ||
330 | struct reservation_config config; | ||
331 | int res_type = PERIODIC_POLLING; | ||
332 | size_t arena_sz; | ||
333 | int wss; | ||
334 | |||
335 | /* default for reservation */ | ||
336 | config.id = 0; | ||
337 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
338 | config.cpu = -1; | ||
339 | |||
340 | mc2_param.crit = CRIT_LEVEL_C; | ||
341 | |||
342 | budget_ms = 1000; | ||
343 | |||
344 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
345 | switch (opt) { | ||
346 | case 'w': | ||
347 | wait = 1; | ||
348 | break; | ||
349 | case 'p': | ||
350 | cluster = atoi(optarg); | ||
351 | migrate = 1; | ||
352 | config.cpu = cluster; | ||
353 | break; | ||
354 | case 'l': | ||
355 | loops = atoi(optarg); | ||
356 | break; | ||
357 | case 'k': | ||
358 | wss = atoi(optarg); | ||
359 | break; | ||
360 | case 'm': | ||
361 | mc2_param.crit = atoi(optarg); | ||
362 | if ((mc2_param.crit >= CRIT_LEVEL_A) && (mc2_param.crit <= CRIT_LEVEL_C)) { | ||
363 | res_type = PERIODIC_POLLING; | ||
364 | } | ||
365 | else | ||
366 | usage("Invalid criticality level."); | ||
367 | break; | ||
368 | case 'b': | ||
369 | budget_ms = atof(optarg); | ||
370 | break; | ||
371 | case 'i': | ||
372 | config.priority = atoi(optarg); | ||
373 | break; | ||
374 | case ':': | ||
375 | usage("Argument missing."); | ||
376 | break; | ||
377 | case '?': | ||
378 | default: | ||
379 | usage("Bad argument."); | ||
380 | break; | ||
381 | } | ||
382 | } | ||
383 | srand(getpid()); | ||
384 | |||
385 | /* | ||
386 | * We need three parameters | ||
387 | */ | ||
388 | if (argc - optind < 3) | ||
389 | usage("Arguments missing."); | ||
390 | |||
391 | wcet_ms = atof(argv[optind + 0]); | ||
392 | period_ms = atof(argv[optind + 1]); | ||
393 | |||
394 | wcet = ms2ns(wcet_ms); | ||
395 | period = ms2ns(period_ms); | ||
396 | budget = ms2ns(budget_ms); | ||
397 | if (wcet <= 0) | ||
398 | usage("The worst-case execution time must be a " | ||
399 | "positive number."); | ||
400 | if (period <= 0) | ||
401 | usage("The period must be a positive number."); | ||
402 | if (wcet > period) { | ||
403 | usage("The worst-case execution time must not " | ||
404 | "exceed the period."); | ||
405 | } | ||
406 | |||
407 | duration = atof(argv[optind + 2]); | ||
408 | |||
409 | if (migrate) { | ||
410 | ret = be_migrate_to_domain(cluster); | ||
411 | if (ret < 0) | ||
412 | bail_out("could not migrate to target partition or cluster."); | ||
413 | } | ||
414 | |||
415 | /* reservation config */ | ||
416 | config.id = gettid(); | ||
417 | config.polling_params.budget = budget; | ||
418 | config.polling_params.period = period; | ||
419 | config.polling_params.offset = 0; | ||
420 | config.polling_params.relative_deadline = 0; | ||
421 | |||
422 | if (config.polling_params.budget > config.polling_params.period) { | ||
423 | usage("The budget must not exceed the period."); | ||
424 | } | ||
425 | |||
426 | /* create a reservation */ | ||
427 | ret = reservation_create(res_type, &config); | ||
428 | if (ret < 0) { | ||
429 | bail_out("failed to create reservation."); | ||
430 | } | ||
431 | |||
432 | init_rt_task_param(¶m); | ||
433 | param.exec_cost = wcet; | ||
434 | param.period = period; | ||
435 | param.priority = priority; | ||
436 | param.cls = RT_CLASS_HARD; | ||
437 | param.release_policy = TASK_PERIODIC; | ||
438 | param.budget_policy = NO_ENFORCEMENT; | ||
439 | if (migrate) { | ||
440 | param.cpu = gettid(); | ||
441 | } | ||
442 | ret = set_rt_task_param(gettid(), ¶m); | ||
443 | if (ret < 0) | ||
444 | bail_out("could not setup rt task params"); | ||
445 | |||
446 | mc2_param.res_id = gettid(); | ||
447 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
448 | if (ret < 0) | ||
449 | bail_out("could not setup mc2 task params"); | ||
450 | |||
451 | |||
452 | arena_sz = wss*1024; | ||
453 | |||
454 | arena = alloc_shm(arena_sz, 0, 0); | ||
455 | if (!arena) | ||
456 | bail_out("alloc_shm failed.\n"); | ||
457 | init_arena(arena, arena_sz); | ||
458 | |||
459 | local_buf = alloc_local(arena_sz, 0, 0); | ||
460 | if (!local_buf) | ||
461 | bail_out("alloc_local failed.\n"); | ||
462 | init_arena(local_buf, arena_sz); | ||
463 | |||
464 | ret = init_litmus(); | ||
465 | if (ret != 0) | ||
466 | bail_out("init_litmus() failed\n"); | ||
467 | |||
468 | start = wctime(); | ||
469 | ret = task_mode(LITMUS_RT_TASK); | ||
470 | if (ret != 0) | ||
471 | bail_out("could not become RT task"); | ||
472 | |||
473 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
474 | set_page_color(-1); | ||
475 | else | ||
476 | set_page_color(config.cpu); | ||
477 | |||
478 | mlockall(MCL_CURRENT | MCL_FUTURE); | ||
479 | // init_arena(local_buf, arena_sz); | ||
480 | // test_call(1); | ||
481 | // init_arena(arena, arena_sz); | ||
482 | // test_call(2); | ||
483 | |||
484 | if (wait) { | ||
485 | ret = wait_for_ts_release(); | ||
486 | if (ret != 0) | ||
487 | bail_out("wait_for_ts_release()"); | ||
488 | start = wctime(); | ||
489 | } | ||
490 | |||
491 | while (job(wss, wcet_ms * 0.001, start + duration)) {}; | ||
492 | |||
493 | ret = task_mode(BACKGROUND_TASK); | ||
494 | if (ret != 0) | ||
495 | bail_out("could not become regular task (huh?)"); | ||
496 | |||
497 | reservation_destroy(gettid(), config.cpu); | ||
498 | dealloc_arena(arena, arena_sz); | ||
499 | dealloc_arena(local_buf, arena_sz); | ||
500 | printf("%s finished.\n", argv[0]); | ||
501 | return 0; | ||
502 | } | ||
diff --git a/bin/mttest.c b/bin/mtdag.c index d502778..adf6d8d 100644 --- a/bin/mttest.c +++ b/bin/mtdag.c | |||
@@ -26,6 +26,7 @@ | |||
26 | /* Include the LITMUS^RT API.*/ | 26 | /* Include the LITMUS^RT API.*/ |
27 | #include "litmus.h" | 27 | #include "litmus.h" |
28 | #include "color_shm.h" | 28 | #include "color_shm.h" |
29 | #include "asm/cycles.h" | ||
29 | 30 | ||
30 | #define PERIOD 100 | 31 | #define PERIOD 100 |
31 | #define RELATIVE_DEADLINE 100 | 32 | #define RELATIVE_DEADLINE 100 |
@@ -41,7 +42,9 @@ struct thread_context { | |||
41 | int id; | 42 | int id; |
42 | int cpu; | 43 | int cpu; |
43 | int job_no; | 44 | int job_no; |
44 | char* shm; | 45 | char* shm1; |
46 | char* shm2; | ||
47 | char* shm3; | ||
45 | }; | 48 | }; |
46 | 49 | ||
47 | /* The real-time thread program. Doesn't have to be the same for | 50 | /* The real-time thread program. Doesn't have to be the same for |
@@ -73,11 +76,14 @@ int job(struct thread_context *tcx); | |||
73 | */ | 76 | */ |
74 | int main(int argc, char** argv) | 77 | int main(int argc, char** argv) |
75 | { | 78 | { |
76 | int i, ret, fd; | 79 | int i; |
77 | struct thread_context ctx[NUM_THREADS]; | 80 | struct thread_context ctx[NUM_THREADS]; |
78 | pthread_t task[NUM_THREADS]; | 81 | pthread_t task[NUM_THREADS]; |
79 | char *shm; | 82 | char *shm1; |
83 | char *shm2; | ||
84 | char *shm3; | ||
80 | struct color_ioctl_cmd shm_info; | 85 | struct color_ioctl_cmd shm_info; |
86 | struct color_ioctl_offset shm_offset; | ||
81 | /* The task is in background mode upon startup. */ | 87 | /* The task is in background mode upon startup. */ |
82 | 88 | ||
83 | 89 | ||
@@ -91,27 +97,31 @@ int main(int argc, char** argv) | |||
91 | * 2) Work environment (e.g., global data structures, file data, etc.) would | 97 | * 2) Work environment (e.g., global data structures, file data, etc.) would |
92 | * be setup here. | 98 | * be setup here. |
93 | */ | 99 | */ |
94 | fd = open("/dev/litmus/color_shm", O_RDWR); | ||
95 | if (fd < 0) { | ||
96 | printf("Device open error.\n"); | ||
97 | return -1; | ||
98 | } | ||
99 | |||
100 | shm_info.color = 0x0000cccc; | ||
101 | shm_info.bank = 0x000000ac; | ||
102 | 100 | ||
103 | ret = ioctl(fd, SET_COLOR_SHM_CMD, &shm_info); | 101 | shm_info.color = 0x00000001; |
104 | if (ret < 0) { | 102 | shm_info.bank = 0x00000020; |
105 | printf("ioctl failed.\n"); | 103 | shm_offset.offset = 0; |
106 | return -1; | 104 | shm_offset.lock = 1; |
105 | |||
106 | shm1 = (char*)color_mmap(1024, shm_info, shm_offset); | ||
107 | if (!shm1) { | ||
108 | printf("color mmap failed.\n"); | ||
109 | exit(-1); | ||
107 | } | 110 | } |
108 | 111 | else { | |
109 | shm = mmap(NULL, 6000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | 112 | printf("Mapped vaddr = %p\n", shm1); |
110 | if (shm == MAP_FAILED) { | 113 | } |
111 | printf("mmap failed.\n"); | 114 | |
112 | return -1; | 115 | shm_info.color = 0x00000003; |
116 | shm_offset.offset = 1024; | ||
117 | shm2 = (char*)color_mmap(4096, shm_info, shm_offset); | ||
118 | if (!shm2) { | ||
119 | printf("color mmap failed.\n"); | ||
120 | exit(-1); | ||
121 | } | ||
122 | else { | ||
123 | printf("Mapped vaddr = %p\n", shm2); | ||
113 | } | 124 | } |
114 | close(fd); | ||
115 | 125 | ||
116 | mlockall(MCL_CURRENT | MCL_FUTURE); | 126 | mlockall(MCL_CURRENT | MCL_FUTURE); |
117 | /***** | 127 | /***** |
@@ -128,7 +138,9 @@ int main(int argc, char** argv) | |||
128 | ctx[i].id = i; | 138 | ctx[i].id = i; |
129 | ctx[i].cpu = 0; | 139 | ctx[i].cpu = 0; |
130 | ctx[i].job_no = 0; | 140 | ctx[i].job_no = 0; |
131 | ctx[i].shm = shm; | 141 | ctx[i].shm1 = shm1; |
142 | ctx[i].shm3 = shm2; | ||
143 | ctx[i].shm2 = shm3; | ||
132 | pthread_create(task + i, NULL, rt_thread, (void *) (ctx + i)); | 144 | pthread_create(task + i, NULL, rt_thread, (void *) (ctx + i)); |
133 | } | 145 | } |
134 | 146 | ||
@@ -253,24 +265,22 @@ void* rt_thread(void *tcontext) | |||
253 | int job(struct thread_context *tcx) | 265 | int job(struct thread_context *tcx) |
254 | { | 266 | { |
255 | int i; | 267 | int i; |
256 | char* buf = tcx->shm; | 268 | char* buf1 = tcx->shm1; |
269 | char* buf2 = tcx->shm2; | ||
270 | char* buf3 = tcx->shm3; | ||
271 | char tmp = 0; | ||
257 | /* Do real-time calculation. */ | 272 | /* Do real-time calculation. */ |
258 | printf("Task %d Job %d executinig\n", tcx->id, tcx->job_no); | 273 | printf("Task %d Job %d executinig\n", tcx->id, tcx->job_no); |
259 | 274 | ||
260 | if (tcx->id == 0) { | 275 | if (tcx->id == 0) { |
261 | printf("WRITE\n"); | ||
262 | for (i=0; i<600; i++) { | ||
263 | buf[i] = rand()%255; | ||
264 | printf("%x ",buf[i]); | ||
265 | } | ||
266 | printf("\n"); | ||
267 | } else if (tcx->id == 1) { | ||
268 | printf("READ\n"); | 276 | printf("READ\n"); |
269 | for (i=0; i<600; i++) { | 277 | for (i=0; i<600; i++) { |
270 | char t = buf[i]; | 278 | char t = buf1[i]; |
271 | printf("%x ", t); | 279 | printf("%x ", t); |
272 | } | 280 | } |
273 | printf("\n"); | 281 | printf("\n"); |
282 | |||
283 | ; | ||
274 | } | 284 | } |
275 | //test_call(0); | 285 | //test_call(0); |
276 | tcx->job_no++; | 286 | tcx->job_no++; |
diff --git a/bin/test1.c b/bin/test1.c new file mode 100644 index 0000000..a38d402 --- /dev/null +++ b/bin/test1.c | |||
@@ -0,0 +1,453 @@ | |||
1 | #include <sys/time.h> | ||
2 | |||
3 | #include <stdio.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <unistd.h> | ||
6 | #include <time.h> | ||
7 | #include <string.h> | ||
8 | #include <assert.h> | ||
9 | #include <limits.h> | ||
10 | #include <sys/mman.h> | ||
11 | #include <sys/types.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <fcntl.h> | ||
14 | |||
15 | #include "litmus.h" | ||
16 | #include "common.h" | ||
17 | |||
18 | |||
19 | |||
20 | static void usage(char *error) { | ||
21 | fprintf(stderr, "Error: %s\n", error); | ||
22 | fprintf(stderr, | ||
23 | "Usage:\n" | ||
24 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
25 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
26 | " rt_spin -l\n" | ||
27 | "\n" | ||
28 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
29 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS]\n" | ||
30 | " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]" | ||
31 | "\n" | ||
32 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n" | ||
33 | "CRITICAL SECTION LENGTH is in milliseconds.\n"); | ||
34 | exit(EXIT_FAILURE); | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * returns the character that made processing stop, newline or EOF | ||
39 | */ | ||
40 | static int skip_to_next_line(FILE *fstream) | ||
41 | { | ||
42 | int ch; | ||
43 | for (ch = fgetc(fstream); ch != EOF && ch != '\n'; ch = fgetc(fstream)); | ||
44 | return ch; | ||
45 | } | ||
46 | |||
47 | static void skip_comments(FILE *fstream) | ||
48 | { | ||
49 | int ch; | ||
50 | for (ch = fgetc(fstream); ch == '#'; ch = fgetc(fstream)) | ||
51 | skip_to_next_line(fstream); | ||
52 | ungetc(ch, fstream); | ||
53 | } | ||
54 | |||
55 | static void get_exec_times(const char *file, const int column, | ||
56 | int *num_jobs, double **exec_times) | ||
57 | { | ||
58 | FILE *fstream; | ||
59 | int cur_job, cur_col, ch; | ||
60 | *num_jobs = 0; | ||
61 | |||
62 | fstream = fopen(file, "r"); | ||
63 | if (!fstream) | ||
64 | bail_out("could not open execution time file"); | ||
65 | |||
66 | /* figure out the number of jobs */ | ||
67 | do { | ||
68 | skip_comments(fstream); | ||
69 | ch = skip_to_next_line(fstream); | ||
70 | if (ch != EOF) | ||
71 | ++(*num_jobs); | ||
72 | } while (ch != EOF); | ||
73 | |||
74 | if (-1 == fseek(fstream, 0L, SEEK_SET)) | ||
75 | bail_out("rewinding file failed"); | ||
76 | |||
77 | /* allocate space for exec times */ | ||
78 | *exec_times = calloc(*num_jobs, sizeof(*exec_times)); | ||
79 | if (!*exec_times) | ||
80 | bail_out("couldn't allocate memory"); | ||
81 | |||
82 | for (cur_job = 0; cur_job < *num_jobs && !feof(fstream); ++cur_job) { | ||
83 | |||
84 | skip_comments(fstream); | ||
85 | |||
86 | for (cur_col = 1; cur_col < column; ++cur_col) { | ||
87 | /* discard input until we get to the column we want */ | ||
88 | int unused __attribute__ ((unused)) = fscanf(fstream, "%*s,"); | ||
89 | } | ||
90 | |||
91 | /* get the desired exec. time */ | ||
92 | if (1 != fscanf(fstream, "%lf", (*exec_times)+cur_job)) { | ||
93 | fprintf(stderr, "invalid execution time near line %d\n", | ||
94 | cur_job); | ||
95 | exit(EXIT_FAILURE); | ||
96 | } | ||
97 | |||
98 | skip_to_next_line(fstream); | ||
99 | } | ||
100 | |||
101 | assert(cur_job == *num_jobs); | ||
102 | fclose(fstream); | ||
103 | } | ||
104 | |||
105 | #define NUMS 4096 | ||
106 | static int num[NUMS]; | ||
107 | static char* progname; | ||
108 | static char* smem; | ||
109 | static int access_type; /* 0: read 1: write */ | ||
110 | |||
111 | static int loop_once(void) | ||
112 | { | ||
113 | int i, j = 0; | ||
114 | for (i = 0; i < NUMS; i++) { | ||
115 | j += num[i]++; | ||
116 | if (access_type == 1) { | ||
117 | smem[i] = j%255; | ||
118 | printf("Write %d at [%d]\n", smem[i], i); | ||
119 | } else { | ||
120 | char tmp = smem[i]; | ||
121 | printf("Read %d at [%d]\n", tmp, i); | ||
122 | } | ||
123 | } | ||
124 | return j; | ||
125 | } | ||
126 | |||
127 | static int loop_for(double exec_time, double emergency_exit) | ||
128 | { | ||
129 | double last_loop = 0, loop_start; | ||
130 | int tmp = 0; | ||
131 | |||
132 | double start = cputime(); | ||
133 | double now = cputime(); | ||
134 | |||
135 | while (now + last_loop < start + exec_time) { | ||
136 | loop_start = now; | ||
137 | tmp += loop_once(); | ||
138 | now = cputime(); | ||
139 | last_loop = now - loop_start; | ||
140 | if (emergency_exit && wctime() > emergency_exit) { | ||
141 | /* Oops --- this should only be possible if the execution time tracking | ||
142 | * is broken in the LITMUS^RT kernel. */ | ||
143 | fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); | ||
144 | fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | return tmp; | ||
150 | } | ||
151 | |||
152 | |||
153 | static void debug_delay_loop(void) | ||
154 | { | ||
155 | double start, end, delay; | ||
156 | |||
157 | while (1) { | ||
158 | for (delay = 0.5; delay > 0.01; delay -= 0.01) { | ||
159 | start = wctime(); | ||
160 | loop_for(delay, 0); | ||
161 | end = wctime(); | ||
162 | printf("%6.4fs: looped for %10.8fs, delta=%11.8fs, error=%7.4f%%\n", | ||
163 | delay, | ||
164 | end - start, | ||
165 | end - start - delay, | ||
166 | 100 * (end - start - delay) / delay); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | static int job(double exec_time, double program_end, int lock_od, double cs_length) | ||
172 | { | ||
173 | double chunk1, chunk2; | ||
174 | |||
175 | if (wctime() > program_end) | ||
176 | return 0; | ||
177 | else { | ||
178 | if (lock_od >= 0) { | ||
179 | /* simulate critical section somewhere in the middle */ | ||
180 | chunk1 = drand48() * (exec_time - cs_length); | ||
181 | chunk2 = exec_time - cs_length - chunk1; | ||
182 | |||
183 | /* non-critical section */ | ||
184 | loop_for(chunk1, program_end + 1); | ||
185 | |||
186 | /* critical section */ | ||
187 | litmus_lock(lock_od); | ||
188 | loop_for(cs_length, program_end + 1); | ||
189 | litmus_unlock(lock_od); | ||
190 | |||
191 | /* non-critical section */ | ||
192 | loop_for(chunk2, program_end + 2); | ||
193 | } else { | ||
194 | //loop_for(exec_time, program_end + 1); | ||
195 | loop_once(); | ||
196 | } | ||
197 | sleep_next_period(); | ||
198 | return 1; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | #define OPTSTR "p:c:wlveo:f:s:q:r:X:L:Q:vt:" | ||
203 | int main(int argc, char** argv) | ||
204 | { | ||
205 | int ret; | ||
206 | lt_t wcet; | ||
207 | lt_t period; | ||
208 | double wcet_ms, period_ms; | ||
209 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
210 | int migrate = 0; | ||
211 | int cluster = 0; | ||
212 | int reservation = -1; | ||
213 | int opt; | ||
214 | int wait = 0; | ||
215 | int test_loop = 0; | ||
216 | int column = 1; | ||
217 | const char *file = NULL; | ||
218 | int want_enforcement = 0; | ||
219 | double duration = 0, start = 0; | ||
220 | double *exec_times = NULL; | ||
221 | double scale = 1.0; | ||
222 | task_class_t class = RT_CLASS_HARD; | ||
223 | int cur_job = 0, num_jobs = 0; | ||
224 | struct rt_task param; | ||
225 | |||
226 | int verbose = 0; | ||
227 | unsigned int job_no; | ||
228 | |||
229 | /* locking */ | ||
230 | int lock_od = -1; | ||
231 | int resource_id = 0; | ||
232 | const char *lock_namespace = "./rtspin-locks"; | ||
233 | int protocol = -1; | ||
234 | double cs_length = 1; /* millisecond */ | ||
235 | int fd; | ||
236 | |||
237 | progname = argv[0]; | ||
238 | |||
239 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
240 | switch (opt) { | ||
241 | case 'w': | ||
242 | wait = 1; | ||
243 | break; | ||
244 | case 'p': | ||
245 | cluster = atoi(optarg); | ||
246 | migrate = 1; | ||
247 | break; | ||
248 | case 'r': | ||
249 | reservation = atoi(optarg); | ||
250 | break; | ||
251 | case 'q': | ||
252 | priority = atoi(optarg); | ||
253 | if (!litmus_is_valid_fixed_prio(priority)) | ||
254 | usage("Invalid priority."); | ||
255 | break; | ||
256 | case 'c': | ||
257 | class = str2class(optarg); | ||
258 | if (class == -1) | ||
259 | usage("Unknown task class."); | ||
260 | break; | ||
261 | case 'e': | ||
262 | want_enforcement = 1; | ||
263 | break; | ||
264 | case 'l': | ||
265 | test_loop = 1; | ||
266 | break; | ||
267 | case 'o': | ||
268 | column = atoi(optarg); | ||
269 | break; | ||
270 | case 'f': | ||
271 | file = optarg; | ||
272 | break; | ||
273 | case 's': | ||
274 | scale = atof(optarg); | ||
275 | break; | ||
276 | case 'X': | ||
277 | protocol = lock_protocol_for_name(optarg); | ||
278 | if (protocol < 0) | ||
279 | usage("Unknown locking protocol specified."); | ||
280 | break; | ||
281 | case 'L': | ||
282 | cs_length = atof(optarg); | ||
283 | if (cs_length <= 0) | ||
284 | usage("Invalid critical section length."); | ||
285 | break; | ||
286 | case 'Q': | ||
287 | resource_id = atoi(optarg); | ||
288 | if (resource_id <= 0 && strcmp(optarg, "0")) | ||
289 | usage("Invalid resource ID."); | ||
290 | break; | ||
291 | case 'v': | ||
292 | verbose = 1; | ||
293 | break; | ||
294 | case 't': | ||
295 | access_type = atoi(optarg); | ||
296 | if (access_type != 0 && access_type != 1) | ||
297 | usage("Wrong SHM access type."); | ||
298 | break; | ||
299 | case ':': | ||
300 | usage("Argument missing."); | ||
301 | break; | ||
302 | case '?': | ||
303 | default: | ||
304 | usage("Bad argument."); | ||
305 | break; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | if (test_loop) { | ||
310 | debug_delay_loop(); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | srand(getpid()); | ||
315 | |||
316 | if (file) { | ||
317 | get_exec_times(file, column, &num_jobs, &exec_times); | ||
318 | |||
319 | if (argc - optind < 2) | ||
320 | usage("Arguments missing."); | ||
321 | |||
322 | for (cur_job = 0; cur_job < num_jobs; ++cur_job) { | ||
323 | /* convert the execution time to seconds */ | ||
324 | duration += exec_times[cur_job] * 0.001; | ||
325 | } | ||
326 | } else { | ||
327 | /* | ||
328 | * if we're not reading from the CSV file, then we need | ||
329 | * three parameters | ||
330 | */ | ||
331 | if (argc - optind < 3) | ||
332 | usage("Arguments missing."); | ||
333 | } | ||
334 | |||
335 | wcet_ms = atof(argv[optind + 0]); | ||
336 | period_ms = atof(argv[optind + 1]); | ||
337 | |||
338 | wcet = ms2ns(wcet_ms); | ||
339 | period = ms2ns(period_ms); | ||
340 | if (wcet <= 0) | ||
341 | usage("The worst-case execution time must be a " | ||
342 | "positive number."); | ||
343 | if (period <= 0) | ||
344 | usage("The period must be a positive number."); | ||
345 | if (!file && wcet > period) { | ||
346 | usage("The worst-case execution time must not " | ||
347 | "exceed the period."); | ||
348 | } | ||
349 | |||
350 | if (!file) | ||
351 | duration = atof(argv[optind + 2]); | ||
352 | else if (file && num_jobs > 1) | ||
353 | duration += period_ms * 0.001 * (num_jobs - 1); | ||
354 | |||
355 | if (migrate) { | ||
356 | ret = be_migrate_to_domain(cluster); | ||
357 | if (ret < 0) | ||
358 | bail_out("could not migrate to target partition or cluster."); | ||
359 | } | ||
360 | |||
361 | |||
362 | /* allocate shared memory */ | ||
363 | fd = open("/dev/shm/region1", O_CREAT|O_RDWR|O_TRUNC, 0666); | ||
364 | if (fd == -1) | ||
365 | bail_out("could not open /dev/shm."); | ||
366 | |||
367 | fallocate(fd, 0, 0, 4096); | ||
368 | smem = NULL; | ||
369 | if (access_type == 1) { | ||
370 | printf("open write mmap now.\n"); | ||
371 | smem = (char*) mmap(NULL, 4096, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); | ||
372 | if (smem == MAP_FAILED) | ||
373 | bail_out("mmap error."); | ||
374 | close(fd); | ||
375 | } | ||
376 | else { | ||
377 | printf("open read mmap now.\n"); | ||
378 | smem = (char*) mmap(NULL, 4096, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0); | ||
379 | if (smem == MAP_FAILED) | ||
380 | bail_out("mmap error."); | ||
381 | close(fd); | ||
382 | } | ||
383 | printf("smem addr = %p\n", smem); | ||
384 | init_rt_task_param(¶m); | ||
385 | param.exec_cost = wcet; | ||
386 | param.period = period; | ||
387 | param.priority = priority; | ||
388 | param.cls = class; | ||
389 | param.budget_policy = (want_enforcement) ? | ||
390 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
391 | if (migrate) { | ||
392 | if (reservation >= 0) | ||
393 | param.cpu = reservation; | ||
394 | else | ||
395 | param.cpu = domain_to_first_cpu(cluster); | ||
396 | } | ||
397 | ret = set_rt_task_param(gettid(), ¶m); | ||
398 | if (ret < 0) | ||
399 | bail_out("could not setup rt task params"); | ||
400 | |||
401 | init_litmus(); | ||
402 | //test_call(0); | ||
403 | start = wctime(); | ||
404 | ret = task_mode(LITMUS_RT_TASK); | ||
405 | if (ret != 0) | ||
406 | bail_out("could not become RT task"); | ||
407 | |||
408 | if (protocol >= 0) { | ||
409 | /* open reference to semaphore */ | ||
410 | lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster); | ||
411 | if (lock_od < 0) { | ||
412 | perror("litmus_open_lock"); | ||
413 | usage("Could not open lock."); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | |||
418 | if (wait) { | ||
419 | ret = wait_for_ts_release(); | ||
420 | if (ret != 0) | ||
421 | bail_out("wait_for_ts_release()"); | ||
422 | start = wctime(); | ||
423 | } | ||
424 | |||
425 | if (file) { | ||
426 | /* use times read from the CSV file */ | ||
427 | for (cur_job = 0; cur_job < num_jobs; ++cur_job) { | ||
428 | /* convert job's length to seconds */ | ||
429 | job(exec_times[cur_job] * 0.001 * scale, | ||
430 | start + duration, | ||
431 | lock_od, cs_length * 0.001); | ||
432 | } | ||
433 | } else { | ||
434 | do { | ||
435 | if (verbose) { | ||
436 | get_job_no(&job_no); | ||
437 | printf("rtspin/%d:%u @ %.4fms\n", gettid(), | ||
438 | job_no, (wctime() - start) * 1000); | ||
439 | } | ||
440 | /* convert to seconds and scale */ | ||
441 | } while (job(wcet_ms * 0.001 * scale, start + duration, | ||
442 | lock_od, cs_length * 0.001)); | ||
443 | } | ||
444 | |||
445 | ret = task_mode(BACKGROUND_TASK); | ||
446 | if (ret != 0) | ||
447 | bail_out("could not become regular task (huh?)"); | ||
448 | |||
449 | if (file) | ||
450 | free(exec_times); | ||
451 | |||
452 | return 0; | ||
453 | } | ||
diff --git a/include/color_shm.h b/include/color_shm.h index ffa90dd..449ec9d 100644 --- a/include/color_shm.h +++ b/include/color_shm.h | |||
@@ -18,4 +18,3 @@ struct color_ioctl_offset { | |||
18 | #define SET_COLOR_SHM_OFFSET _IOW(SHM_MAJOR, 0x2, struct color_ioctl_offset) | 18 | #define SET_COLOR_SHM_OFFSET _IOW(SHM_MAJOR, 0x2, struct color_ioctl_offset) |
19 | 19 | ||
20 | void* color_mmap(size_t size, struct color_ioctl_cmd cmd, struct color_ioctl_offset offset); | 20 | void* color_mmap(size_t size, struct color_ioctl_cmd cmd, struct color_ioctl_offset offset); |
21 | |||
diff --git a/include/litmus.h b/include/litmus.h index 4a4ea39..7229a38 100644 --- a/include/litmus.h +++ b/include/litmus.h | |||
@@ -46,7 +46,7 @@ extern "C" { | |||
46 | * @private | 46 | * @private |
47 | * Number of semaphore protocol object types | 47 | * Number of semaphore protocol object types |
48 | */ | 48 | */ |
49 | #define SCHED_LITMUS 7 | 49 | #define SCHED_LITMUS 6 |
50 | 50 | ||
51 | #define CACHELINE_SIZE 32 | 51 | #define CACHELINE_SIZE 32 |
52 | #define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) | 52 | #define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) |
diff --git a/src/kernel_iface.c b/src/kernel_iface.c index 49cef2a..a2c2104 100644 --- a/src/kernel_iface.c +++ b/src/kernel_iface.c | |||
@@ -140,62 +140,6 @@ int requested_to_preempt(void) | |||
140 | return (likely(ctrl_page != NULL) && ctrl_page->sched.np.preempt); | 140 | return (likely(ctrl_page != NULL) && ctrl_page->sched.np.preempt); |
141 | } | 141 | } |
142 | 142 | ||
143 | void enter_pgm_wait(void) | ||
144 | { | ||
145 | if (likely(ctrl_page != NULL) || init_kernel_iface() == 0) { | ||
146 | assert(!ctrl_page->pgm_waiting); | ||
147 | ctrl_page->pgm_waiting = 1; | ||
148 | __sync_synchronize(); | ||
149 | } | ||
150 | else { | ||
151 | fprintf(stderr, "enter_pgm_wait: control page not mapped!\n"); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | void exit_pgm_wait(void) | ||
156 | { | ||
157 | if (likely(ctrl_page != NULL)) { | ||
158 | assert(ctrl_page->pgm_waiting); | ||
159 | ctrl_page->pgm_waiting = 0; | ||
160 | __sync_synchronize(); | ||
161 | } | ||
162 | else { | ||
163 | fprintf(stderr, "exit_pgm_wait: control page not mapped!\n"); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | void enter_pgm_send(void) | ||
168 | { | ||
169 | if (likely(ctrl_page != NULL) || init_kernel_iface() == 0) { | ||
170 | assert(!ctrl_page->pgm_sending); | ||
171 | ctrl_page->pgm_sending = 1; /* we will become boosted if | ||
172 | anyone tries to preempt us. */ | ||
173 | __sync_synchronize(); | ||
174 | } | ||
175 | else { | ||
176 | fprintf(stderr, "enter_pgm_send: control page not mapped!\n"); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | void exit_pgm_send(void) | ||
181 | { | ||
182 | if (likely(ctrl_page != NULL)) { | ||
183 | assert(ctrl_page->pgm_sending); | ||
184 | |||
185 | ctrl_page->pgm_satisfied = 1; | ||
186 | __sync_synchronize(); | ||
187 | |||
188 | /* re-eval priority. Should clear pgm_sending and pgm_satisfied. */ | ||
189 | sched_yield(); | ||
190 | |||
191 | /* double check that Litmus is doing its job */ | ||
192 | assert(!ctrl_page->pgm_sending && !ctrl_page->pgm_satisfied); | ||
193 | } | ||
194 | else { | ||
195 | fprintf(stderr, "exit_pgm_send: control page not mapped!\n"); | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /* init and return a ptr to the control page for | 143 | /* init and return a ptr to the control page for |
200 | * preemption and migration overhead analysis | 144 | * preemption and migration overhead analysis |
201 | * | 145 | * |
diff --git a/src/syscalls.c b/src/syscalls.c index a4cec67..6ec0cd9 100644 --- a/src/syscalls.c +++ b/src/syscalls.c | |||
@@ -107,11 +107,6 @@ int set_page_color(int cpu) | |||
107 | return syscall(__NR_set_page_color, cpu); | 107 | return syscall(__NR_set_page_color, cpu); |
108 | } | 108 | } |
109 | 109 | ||
110 | int test_call(unsigned int param) | ||
111 | { | ||
112 | return syscall(__NR_test_call, param); | ||
113 | } | ||
114 | |||
115 | int run_bench(int type, int wss, cacheline_t *src, cacheline_t *dst, lt_t *ts) | 110 | int run_bench(int type, int wss, cacheline_t *src, cacheline_t *dst, lt_t *ts) |
116 | { | 111 | { |
117 | return syscall(__NR_run_test, type, wss, src, dst, ts); | 112 | return syscall(__NR_run_test, type, wss, src, dst, ts); |