From 11765fcf37057053065abd3715cf9cb46f2fa4db Mon Sep 17 00:00:00 2001 From: Namhoon Kim Date: Mon, 1 May 2017 20:02:05 +0000 Subject: RTSS17 submit --- Makefile | 49 +-- bin/mc2bench.c | 503 --------------------------- bin/mc2mem.c | 326 +++++++++++++++++ bin/mc2shm.c | 502 -------------------------- bin/mc2spin.c | 83 ++--- bin/mode_request.c | 48 ++- bin/mode_skeleton.c | 256 ++++++++++++++ bin/rt_field.c | 379 -------------------- bin/rt_field_spin.c | 385 -------------------- bin/rt_matrix.c | 851 --------------------------------------------- bin/rt_matrix_spin.c | 833 -------------------------------------------- bin/rt_mode_poll.c | 102 +++--- bin/rt_neighborhood.c | 381 -------------------- bin/rt_neighborhood_spin.c | 337 ------------------ bin/rt_pointer.c | 430 ----------------------- bin/rt_pointer_spin.c | 439 ----------------------- bin/rt_transitive.c | 362 ------------------- bin/rt_update.c | 387 --------------------- bin/rt_update_spin.c | 398 --------------------- bin/test1.c | 453 ------------------------ src/kernel_iface.c | 6 +- 21 files changed, 716 insertions(+), 6794 deletions(-) delete mode 100644 bin/mc2bench.c create mode 100644 bin/mc2mem.c delete mode 100644 bin/mc2shm.c create mode 100644 bin/mode_skeleton.c delete mode 100644 bin/rt_field.c delete mode 100644 bin/rt_field_spin.c delete mode 100644 bin/rt_matrix.c delete mode 100644 bin/rt_matrix_spin.c delete mode 100644 bin/rt_neighborhood.c delete mode 100644 bin/rt_neighborhood_spin.c delete mode 100644 bin/rt_pointer.c delete mode 100644 bin/rt_pointer_spin.c delete mode 100644 bin/rt_transitive.c delete mode 100644 bin/rt_update.c delete mode 100644 bin/rt_update_spin.c delete mode 100644 bin/test1.c diff --git a/Makefile b/Makefile index c2a1105..3e6ee15 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ LITMUS_KERNEL ?= ../litmus-rt # compiler flags flags-debug = -O0 -Wall -g -Wdeclaration-after-statement -flags-api = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE -DCONFIG_PGMRT_SUPPORT +flags-api = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE # architecture-specific flags flags-i386 = -m32 @@ -73,13 +73,14 @@ AR := ${CROSS_COMPILE}${AR} all = lib ${rt-apps} rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ - base_mt_task uncache runtests resctrl mc2spin test1 \ - mc2thrash mc2shm mc2thrash1 mc2thrash2 mc2thrash3 mc2bench\ - mtdag + base_mt_task uncache runtests resctrl mc2mem \ + mc2spin mtdag mode_request rt_mode_poll + +#mc2thrash mc2thrash1 mc2thrash2 mc2thrash3 .PHONY: all lib clean dump-config TAGS tags cscope help doc -all: ${all} inc/config.makefile +all: ${all} inc/config.makefile post-build # Write a distilled version of the flags for clients of the library. Ideally, # this should depend on liblitmus.a, but that requires LIBLITMUS to be a @@ -128,6 +129,7 @@ clean: rm -f inc/config.makefile rm -f tags TAGS cscope.files cscope.out rm -r -f docs + rm -f mc2mem* # Emacs Tags TAGS: @@ -145,6 +147,8 @@ cscope: @find . -type f -and -iname '*.[ch]' | xargs printf "%s\n" > cscope.files @cscope -b +post-build: + # ############################################################################## # Kernel headers. # The kernel does not like being #included directly, so let's @@ -242,38 +246,17 @@ obj-resctrl = resctrl.o obj-mc2spin = mc2spin.o common.o lib-mc2spin = -lrt -static -obj-mc2pollute = mc2pollute.o common.o -lib-mc2pollute = -lrt -static - -obj-mc2syn = mc2syn.o common.o -lib-mc2syn = -lrt -static - -obj-memthrash = memthrash.o -lib-memthrash = -lrt - -obj-test1 = test1.o common.o -lib-test1 = -lrt -static - -obj-mc2thrash = mc2thrash.o common.o -lib-mc2thrash = -lrt -static - -obj-mc2thrash1 = mc2thrash.o common.o -lib-mc2thrash1 = -lrt -static - -obj-mc2thrash2 = mc2thrash.o common.o -lib-mc2thrash2 = -lrt -static - -obj-mc2thrash3 = mc2thrash.o common.o -lib-mc2thrash3 = -lrt -static - -obj-mc2shm = mc2shm.o common.o -lib-mc2shm = -lrt -static +obj-mc2mem = mc2mem.o common.o +lib-mc2mem = -lrt -static obj-mtdag = mtdag.o common.o ldf-mtdag = -lrt -pthread -static -obj-mc2bench = mc2bench.o common.o -lib-mc2bench = -lrt -static +obj-mode_request = mode_request.o common.o +lib-mode_request = -lrt -static + +obj-rt_mode_poll = rt_mode_poll.o common.o +lib-rt_mode_poll = -lrt -static # ############################################################################## # Build everything that depends on liblitmus. diff --git a/bin/mc2bench.c b/bin/mc2bench.c deleted file mode 100644 index dfb4f15..0000000 --- a/bin/mc2bench.c +++ /dev/null @@ -1,503 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "litmus.h" -#include "common.h" -#include "color_shm.h" - -#define PAGE_SIZE (4096) -//#define CACHELINE_SIZE 32 -//#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) -//#define CACHELINES_IN_1KB (1024 / sizeof(cacheline_t)) -#define INTS_IN_1KB (1024 / sizeof(int)) - -//typedef struct cacheline -//{ -// int line[INTS_IN_CACHELINE]; -//} __attribute__((aligned(CACHELINE_SIZE))) cacheline_t; - -static int loops = 100000; -static cacheline_t* arena = NULL; -static cacheline_t* local_buf = NULL; - -struct timeval t1,t2; - -lt_t exectime[100000]; - -inline unsigned long get_cyclecount (void) -{ - unsigned long value; - // Read CCNT Register - asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); - return value; -} - -#define UNCACHE_DEV "/dev/litmus/uncache" - -static cacheline_t* alloc_shm(int cs, size_t size, int use_huge_pages, int use_uncache_pages) -{ - struct color_ioctl_cmd shm_info; - struct color_ioctl_offset shm_offset; - cacheline_t* arena = NULL; - - - shm_info.color = 0x0000ffff; - - if (cs == 1 || cs == 2) - shm_info.bank = 0x00000020; // hi crit. bank - else if (cs == 3) - shm_info.bank = 0x00000040; // levelC - - shm_offset.offset = 0; - shm_offset.lock = 1; - - arena = color_mmap(size, shm_info, shm_offset); - if (arena == MAP_FAILED) { - printf("mmap failed.\n"); - return NULL; - } - - mlockall(MCL_CURRENT | MCL_FUTURE); - /* finish allocation */ - - assert(arena); - - return arena; -} - -static cacheline_t* alloc_local(size_t size, int use_huge_pages, int use_uncache_pages) -{ - int flags = MAP_PRIVATE | MAP_POPULATE; - cacheline_t* arena = NULL; - int fd; - - if(use_huge_pages) - flags |= MAP_HUGETLB; - - if(use_uncache_pages) { - fd = open(UNCACHE_DEV, O_RDWR|O_SYNC); - if (fd == -1) - bail_out("Failed to open uncache device. Are you running the LITMUS^RT kernel?"); - } - else { - fd = -1; - flags |= MAP_ANONYMOUS; - } - - arena = mmap(0, size, PROT_READ | PROT_WRITE, flags, fd, 0); - - if(use_uncache_pages) - close(fd); - - assert(arena); - - return arena; -} - -static void dealloc_arena(cacheline_t* arena, size_t size) -{ - int ret = munmap((void*)arena, size); - if(ret != 0) - bail_out("munmap() error"); -} - -static int randrange(int min, int max) -{ - /* generate a random number on the range [min, max) w/o skew */ - int limit = max - min; - int devisor = RAND_MAX/limit; - int retval; - - do { - retval = rand() / devisor; - } while(retval == limit); - retval += min; - - return retval; -} - -static void init_arena(cacheline_t* arena, size_t size) -{ - int i; - size_t num_arena_elem = size / sizeof(cacheline_t); - - /* Generate a cycle among the cache lines using Sattolo's algorithm. - Every int in the cache line points to the same cache line. - Note: Sequential walk doesn't care about these values. */ - for (i = 0; i < num_arena_elem; i++) { - int j; - for(j = 0; j < INTS_IN_CACHELINE; ++j) - arena[i].line[j] = i; - } - while(1 < i--) { - int j = randrange(0, i); - cacheline_t temp = arena[j]; - arena[j] = arena[i]; - arena[i] = temp; - } -} - -/* Random walk around the arena in cacheline-sized chunks. - Cacheline-sized chucks ensures the same utilization of each - hit line as sequential read. (Otherwise, our utilization - would only be 1/INTS_IN_CACHELINE.) */ -static int random_walk(cacheline_t *mem, int wss, int write_cycle) -{ - /* a random cycle among the cache lines was set up by init_arena(). */ - int sum, i, next, j; - - int numlines = wss * CACHELINES_IN_1KB; - - sum = 0; - - /* contents of arena is structured s.t. offsets are all - w.r.t. to start of arena, so compute the initial offset */ - next = mem - arena; - - if (write_cycle == 0) { - for (i = 0; i < numlines; i++) { - for (j = 0; j < INTS_IN_CACHELINE; j++) { - /* every element in the cacheline has the same value */ - //next = arena[next].line[j]; - local_buf[next].line[j] = arena[next].line[j]; - //sum += next; - //local_buf[next].line[j] = next; - } - } - } - - else { - int w, which_line; - for (i = 0, w = 0; i < numlines; i++) { - for (j = 0; j < INTS_IN_CACHELINE; j++) { - which_line = next; - next = local_buf[next].line[j]; - ((volatile cacheline_t*)arena)[which_line].line[j] = next; - //sum += next; - } - } - } - return sum; -} - -static cacheline_t* random_start(int wss) -{ - return arena + randrange(0, ((wss * 1024)/sizeof(cacheline_t))); -} - -static int sequential_walk(cacheline_t *mem, int wss, int write_cycle) -{ - int sum = 0, i, j; - //int* mem = (int*)_mem; /* treat as raw buffer of ints */ - int num_ints = wss * CACHELINES_IN_1KB; - - if (write_cycle > 0) { - for (i = 0; i < num_ints; i++) { - //if (i % write_cycle == (write_cycle - 1)) { - //mem[i]++; - for (j = 0; j < INTS_IN_CACHELINE; j++) { - //sum += local_buf[i].line[j]; - mem[i].line[j] = local_buf[i].line[j];; - } - //} - //else { - // sum += mem[i]; - //} - } - } else { - /* sequential access, pure read */ - for (i = 0; i < num_ints; i++) { - for (j = 0; j < INTS_IN_CACHELINE; j++) { - //sum += mem[i]; - local_buf[i].line[j] = mem[i].line[j]; - //sum += mem[i]; - } - } - } - return sum; -} - -static cacheline_t* sequential_start(int wss) -{ - return arena; -/* static int pos = 0; - - int num_cachelines = wss * CACHELINES_IN_1KB; - size_t num_arena_elem = wss * 1024 / sizeof(cacheline_t); - cacheline_t *mem; -*/ - - /* Don't allow re-use between allocations. - * At most half of the arena may be used - * at any one time. - */ -/* if (num_cachelines * 2 > num_arena_elem) - bail_out("static memory arena too small"); - - if (pos + num_cachelines > num_arena_elem) { - mem = arena; - pos = num_cachelines; - } else { - mem = arena + pos; - pos += num_cachelines; - } - - return mem;*/ -} - -static volatile int dont_optimize_me = 0; - -static void usage(char *error) { - fprintf(stderr, "Error: %s\n", error); - fprintf(stderr, - "Usage:\n" - " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" - " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" - " rt_spin -l\n" - "\n" - "COMMON-OPTS = [-w] [-s SCALE]\n" - " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-m CRITICALITY LEVEL]\n" - " [-k WSS] [-l LOOPS] [-b BUDGET]\n" - "\n" - "WCET and PERIOD are milliseconds, DURATION is seconds.\n"); - exit(EXIT_FAILURE); -} - -static int loop_once(int cs, int wss, unsigned int iter) -{ - //cacheline_t *mem; - //int temp; - - //mem = random_start(wss); - //temp = random_walk(mem, wss, 1); - - //mem = sequential_start(wss); - //temp = sequential_walk(arena, wss, 1); - run_bench(cs, wss, arena, local_buf, &exectime[iter]); - dont_optimize_me = (int)exectime[iter]; - - return dont_optimize_me; -} - -static int job(int cs, int wss, double exec_time, double program_end) -{ - if (wctime() > program_end) - return 0; - else { - register unsigned long t; - register unsigned int iter = 0; - //t = get_cyclecount(); - //gettimeofday(&t1, NULL); - while(iter < loops) { - loop_once(cs, wss, iter++); - } - //gettimeofday(&t2, NULL); - //printf("%ld cycles\n", get_cyclecount() - t); - //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); - sleep_next_period(); - return 1; - } -} - -#define OPTSTR "p:wl:m:i:b:k:c:" -int main(int argc, char** argv) -{ - int ret, i; - lt_t wcet, period, budget; - double wcet_ms, period_ms, budget_ms; - unsigned int priority = LITMUS_NO_PRIORITY; - int migrate = 0; - int cluster = 0; - int opt; - int wait = 0; - double duration = 0, start = 0; - struct rt_task param; - struct mc2_task mc2_param; - struct reservation_config config; - int res_type = PERIODIC_POLLING; - size_t arena_sz; - int wss, cs; - - /* default for reservation */ - config.id = 0; - config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ - config.cpu = -1; - - mc2_param.crit = CRIT_LEVEL_C; - - budget_ms = 1000; - - while ((opt = getopt(argc, argv, OPTSTR)) != -1) { - switch (opt) { - case 'w': - wait = 1; - break; - case 'p': - cluster = atoi(optarg); - migrate = 1; - config.cpu = cluster; - break; - case 'l': - loops = atoi(optarg); - break; - case 'k': - wss = atoi(optarg); - break; - case 'm': - mc2_param.crit = atoi(optarg); - if ((mc2_param.crit >= CRIT_LEVEL_A) && (mc2_param.crit <= CRIT_LEVEL_C)) { - res_type = PERIODIC_POLLING; - } - else - usage("Invalid criticality level."); - break; - case 'b': - budget_ms = atof(optarg); - break; - case 'i': - config.priority = atoi(optarg); - break; - case 'c': - cs = atoi(optarg); - break; - case ':': - usage("Argument missing."); - break; - case '?': - default: - usage("Bad argument."); - break; - } - } - srand(getpid()); - - /* - * We need three parameters - */ - if (argc - optind < 3) - usage("Arguments missing."); - - wcet_ms = atof(argv[optind + 0]); - period_ms = atof(argv[optind + 1]); - - wcet = ms2ns(wcet_ms); - period = ms2ns(period_ms); - budget = ms2ns(budget_ms); - if (wcet <= 0) - usage("The worst-case execution time must be a " - "positive number."); - if (period <= 0) - usage("The period must be a positive number."); - if (wcet > period) { - usage("The worst-case execution time must not " - "exceed the period."); - } - - duration = atof(argv[optind + 2]); - - if (migrate) { - ret = be_migrate_to_domain(cluster); - if (ret < 0) - bail_out("could not migrate to target partition or cluster."); - } - - /* reservation config */ - config.id = gettid(); - config.polling_params.budget = budget; - config.polling_params.period = period; - config.polling_params.offset = 0; - config.polling_params.relative_deadline = 0; - - if (config.polling_params.budget > config.polling_params.period) { - usage("The budget must not exceed the period."); - } - - /* create a reservation */ - ret = reservation_create(res_type, &config); - if (ret < 0) { - bail_out("failed to create reservation."); - } - - init_rt_task_param(¶m); - param.exec_cost = wcet; - param.period = period; - param.priority = priority; - param.cls = RT_CLASS_HARD; - param.release_policy = TASK_PERIODIC; - param.budget_policy = NO_ENFORCEMENT; - if (migrate) { - param.cpu = gettid(); - } - ret = set_rt_task_param(gettid(), ¶m); - if (ret < 0) - bail_out("could not setup rt task params"); - - mc2_param.res_id = gettid(); - ret = set_mc2_task_param(gettid(), &mc2_param); - if (ret < 0) - bail_out("could not setup mc2 task params"); - - - arena_sz = wss*1024; - - arena = alloc_shm(cs, arena_sz, 0, 0); - if (!arena) - bail_out("alloc_shm failed.\n"); - init_arena(arena, arena_sz); - - local_buf = alloc_local(arena_sz, 0, 0); - if (!local_buf) - bail_out("alloc_local failed.\n"); - init_arena(local_buf, arena_sz); - - ret = init_litmus(); - if (ret != 0) - bail_out("init_litmus() failed\n"); - - start = wctime(); - ret = task_mode(LITMUS_RT_TASK); - if (ret != 0) - bail_out("could not become RT task"); - - if (mc2_param.crit == CRIT_LEVEL_C) - set_page_color(-1); - else - set_page_color(config.cpu); - - mlockall(MCL_CURRENT | MCL_FUTURE); -// init_arena(local_buf, arena_sz); -// test_call(1); -// init_arena(arena, arena_sz); -// test_call(2); - - if (wait) { - ret = wait_for_ts_release(); - if (ret != 0) - bail_out("wait_for_ts_release()"); - start = wctime(); - } - - //while (job(wss, wcet_ms * 0.001, start + duration)) {}; - job(cs, wss, wcet_ms * 0.001, start + duration); - - ret = task_mode(BACKGROUND_TASK); - if (ret != 0) - bail_out("could not become regular task (huh?)"); - - reservation_destroy(gettid(), config.cpu); - dealloc_arena(arena, arena_sz); - dealloc_arena(local_buf, arena_sz); - printf("%s finished.\n", argv[0]); - for (i = 0; i +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "litmus.h" +#include "common.h" +#include "cache_common.h" + +#define PAGE_SIZE (4096) +#define CACHELINE_SIZE 32 +#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) +#define CACHELINES_IN_1KB (1024 / sizeof(cacheline_t)) +#define INTS_IN_1KB (1024 / sizeof(int)) +#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) + +static int loops = 100; +static cacheline_t* arena = NULL; +static int verbose = 0; + +struct timeval t1,t2; + + +#define UNCACHE_DEV "/dev/litmus/uncache" + +/* Random walk around the arena in cacheline-sized chunks. + Cacheline-sized chucks ensures the same utilization of each + hit line as sequential read. (Otherwise, our utilization + would only be 1/INTS_IN_CACHELINE.) */ +static int random_walk(cacheline_t *mem, int wss, int write_cycle) +{ + /* a random cycle among the cache lines was set up by init_arena(). */ + int sum, i, next; + + int numlines = wss * CACHELINES_IN_1KB; + + sum = 0; + + /* contents of arena is structured s.t. offsets are all + w.r.t. to start of arena, so compute the initial offset */ + next = mem - arena; + + if (write_cycle == 0) { + for (i = 0; i < numlines; i++) { + /* every element in the cacheline has the same value */ + next = arena[next].line[0]; + sum += next; + } + } + + else { + int w, which_line; + for (i = 0, w = 0; i < numlines; i++) { + which_line = next; + next = arena[next].line[0]; + if((w % write_cycle) != (write_cycle - 1)) { + sum += next; + } + else { + ((volatile cacheline_t*)arena)[which_line].line[0] = next; + } + } + } + return sum; +} + +static cacheline_t* random_start(int wss) +{ + return arena + randrange(0, ((wss * 1024)/sizeof(cacheline_t))); +} + +static volatile int dont_optimize_me = 0; + +static void usage(char *error) { + fprintf(stderr, "Error: %s\n", error); + fprintf(stderr, + "Usage:\n" + " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" + " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" + " rt_spin -l\n" + "\n" + "COMMON-OPTS = [-w] [-s SCALE]\n" + " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-m CRITICALITY LEVEL]\n" + " [-k WSS] [-l LOOPS] [-b BUDGET]\n" + "\n" + "WCET and PERIOD are milliseconds, DURATION is seconds.\n"); + exit(EXIT_FAILURE); +} + +static int loop_once(int wss) +{ + cacheline_t *mem; + int temp; + + mem = random_start(wss); + temp = random_walk(mem, wss, 1); + + //mem = sequential_start(wss); + //temp = sequential_walk(mem, wss, 0); + dont_optimize_me = temp; + + return dont_optimize_me; +} + +static int job(int wss, double exec_time, double program_end) +{ + if (wctime() > program_end) + return 0; + else { + register unsigned int iter = 0; + register cycles_t t; + t = get_cycles(); + while(iter++ < loops) { + loop_once(wss); + } + t = get_cycles() - t; + if (verbose) + printf("%ld cycles\n", t); + sleep_next_period(); + return 1; + } +} + +#define OPTSTR "p:wl:m:i:b:k:vs:" +int main(int argc, char** argv) +{ + int ret, i; + lt_t wcet, period, budget; + double wcet_ms, period_ms, budget_ms; + unsigned int priority = LITMUS_NO_PRIORITY; + int migrate = 0; + int cluster = 0; + int opt; + int wait = 0; + double duration = 0, start = 0; + struct rt_task param; + struct mc2_task mc2_param; + struct reservation_config config; + int res_type = PERIODIC_POLLING; + size_t arena_sz; + int wss = 1; + uint32_t mode_mask; + + /* default for reservation */ + config.id = 0; + config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ + config.cpu = -1; + + mc2_param.crit = CRIT_LEVEL_C; + + budget_ms = 1000; + + while ((opt = getopt(argc, argv, OPTSTR)) != -1) { + switch (opt) { + case 'w': + wait = 1; + break; + case 'p': + cluster = atoi(optarg); + migrate = 1; + config.cpu = cluster; + break; + case 'l': + loops = atoi(optarg); + break; + case 's': + wss = atoi(optarg); + break; + case 'k': + mode_mask = atoi(optarg); + break; + case 'm': + mc2_param.crit = atoi(optarg); + if ((mc2_param.crit >= CRIT_LEVEL_A) && (mc2_param.crit <= CRIT_LEVEL_C)) { + res_type = PERIODIC_POLLING; + } + else + usage("Invalid criticality level."); + break; + case 'b': + budget_ms = atof(optarg); + break; + case 'i': + config.priority = atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case ':': + usage("Argument missing."); + break; + case '?': + default: + usage("Bad argument."); + break; + } + } + srand(getpid()); + + /* + * We need three parameters + */ + if (argc - optind < 3) + usage("Arguments missing."); + + wcet_ms = atof(argv[optind + 0]); + period_ms = atof(argv[optind + 1]); + + wcet = ms2ns(wcet_ms); + period = ms2ns(period_ms); + budget = ms2ns(budget_ms); + if (wcet <= 0) + usage("The worst-case execution time must be a " + "positive number."); + if (period <= 0) + usage("The period must be a positive number."); + if (wcet > period) { + usage("The worst-case execution time must not " + "exceed the period."); + } + if (wss == 0) { + usage("You need to specify a WSS (-k option)."); + } + + duration = atof(argv[optind + 2]); + + if (migrate) { + ret = be_migrate_to_domain(cluster); + if (ret < 0) + bail_out("could not migrate to target partition or cluster."); + } + + /* reservation config */ + config.id = gettid(); + config.polling_params.budget = budget; + config.polling_params.period = period; + config.polling_params.offset = 0; + config.polling_params.relative_deadline = 0; + + if (config.polling_params.budget > config.polling_params.period) { + usage("The budget must not exceed the period."); + } + + /* create a reservation */ + for(i = 0; i < 32; i++){ + if ( !( (1 << i) & mode_mask) ) + continue; + config.mode = i; + ret = reservation_create(res_type, &config); + if (ret < 0) { + bail_out("failed to create reservation."); + } + } + + init_rt_task_param(¶m); + param.exec_cost = wcet; + param.period = period; + param.priority = priority; + param.cls = RT_CLASS_HARD; + param.release_policy = TASK_PERIODIC; + param.budget_policy = NO_ENFORCEMENT; + if (migrate) { + param.cpu = gettid(); + //param.cpu = config.cpu; + } + ret = set_rt_task_param(gettid(), ¶m); + if (ret < 0) + bail_out("could not setup rt task params"); + + mc2_param.res_id = gettid(); + mc2_param.mode_mask = mode_mask; + ret = set_mc2_task_param(gettid(), &mc2_param); + if (ret < 0) + bail_out("could not setup mc2 task params"); + + arena_sz = wss*1024; + arena = alloc_arena(arena_sz, 0, 0); + init_arena(arena, arena_sz); + + mlockall(MCL_CURRENT | MCL_FUTURE); + + ret = init_litmus(); + if (ret != 0) + bail_out("init_litmus() failed\n"); + + start = wctime(); + ret = task_mode(LITMUS_RT_TASK); + if (ret != 0) + bail_out("could not become RT task"); + + if (mc2_param.crit == CRIT_LEVEL_C) + set_page_color(-1); + else + set_page_color(config.cpu); + + mlockall(MCL_CURRENT | MCL_FUTURE); + + if (wait) { + ret = wait_for_ts_release(); + if (ret != 0) + bail_out("wait_for_ts_release()"); + start = wctime(); + } + + while (job(wss, wcet_ms * 0.001, start + duration)) {}; + +//set_page_color(config.cpu); + //test_call(0); + ret = task_mode(BACKGROUND_TASK); + if (ret != 0) + bail_out("could not become regular task (huh?)"); + + reservation_destroy(gettid(), config.cpu); + dealloc_arena(arena, arena_sz); + printf("%s finished.\n", argv[0]); + //test_call(1); + return 0; +} diff --git a/bin/mc2shm.c b/bin/mc2shm.c deleted file mode 100644 index 4cc974a..0000000 --- a/bin/mc2shm.c +++ /dev/null @@ -1,502 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "litmus.h" -#include "common.h" -#include "color_shm.h" - -#define PAGE_SIZE (4096) -#define CACHELINE_SIZE 32 -#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) -#define CACHELINES_IN_1KB (1024 / sizeof(cacheline_t)) -#define INTS_IN_1KB (1024 / sizeof(int)) -#define INTS_IN_CACHELINE (CACHELINE_SIZE/sizeof(int)) - -//typedef struct cacheline -//{ -// int line[INTS_IN_CACHELINE]; -//} __attribute__((aligned(CACHELINE_SIZE))) cacheline_t; - -static int loops = 10; -static cacheline_t* arena = NULL; -static cacheline_t* local_buf = NULL; - -struct timeval t1,t2; - -inline unsigned long get_cyclecount (void) -{ - unsigned long value; - // Read CCNT Register - asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); - return value; -} - -#define UNCACHE_DEV "/dev/litmus/uncache" - -static cacheline_t* alloc_shm(size_t size, int use_huge_pages, int use_uncache_pages) -{ - int ret, fd; - struct color_ioctl_cmd shm_info; - cacheline_t* arena = NULL; - - /* allocate shm */ - fd = open("/dev/litmus/color_shm", O_RDWR); - if (fd < 0) { - printf("Device open error.\n"); - return NULL; - } - - shm_info.color = 0x00000f00; - //shm_info.bank = 0x00000020; // hi crit. bank - shm_info.bank = 0x00000040; // levelC - - ret = ioctl(fd, SET_COLOR_SHM_CMD, &shm_info); - if (ret < 0) { - printf("ioctl failed.\n"); - return NULL; - } - - arena = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (arena == MAP_FAILED) { - printf("mmap failed.\n"); - return NULL; - } - close(fd); - - mlockall(MCL_CURRENT | MCL_FUTURE); - /* finish allocation */ - - assert(arena); - - return arena; -} - -static cacheline_t* alloc_local(size_t size, int use_huge_pages, int use_uncache_pages) -{ - int flags = MAP_PRIVATE | MAP_POPULATE; - cacheline_t* arena = NULL; - int fd; - - if(use_huge_pages) - flags |= MAP_HUGETLB; - - if(use_uncache_pages) { - fd = open(UNCACHE_DEV, O_RDWR|O_SYNC); - if (fd == -1) - bail_out("Failed to open uncache device. Are you running the LITMUS^RT kernel?"); - } - else { - fd = -1; - flags |= MAP_ANONYMOUS; - } - - arena = mmap(0, size, PROT_READ | PROT_WRITE, flags, fd, 0); - - if(use_uncache_pages) - close(fd); - - assert(arena); - - return arena; -} - -static void dealloc_arena(cacheline_t* arena, size_t size) -{ - int ret = munmap((void*)arena, size); - if(ret != 0) - bail_out("munmap() error"); -} - -static int randrange(int min, int max) -{ - /* generate a random number on the range [min, max) w/o skew */ - int limit = max - min; - int devisor = RAND_MAX/limit; - int retval; - - do { - retval = rand() / devisor; - } while(retval == limit); - retval += min; - - return retval; -} - -static void init_arena(cacheline_t* arena, size_t size) -{ - int i; - size_t num_arena_elem = size / sizeof(cacheline_t); - - /* Generate a cycle among the cache lines using Sattolo's algorithm. - Every int in the cache line points to the same cache line. - Note: Sequential walk doesn't care about these values. */ - for (i = 0; i < num_arena_elem; i++) { - int j; - for(j = 0; j < INTS_IN_CACHELINE; ++j) - arena[i].line[j] = i; - } - while(1 < i--) { - int j = randrange(0, i); - cacheline_t temp = arena[j]; - arena[j] = arena[i]; - arena[i] = temp; - } -} - -/* Random walk around the arena in cacheline-sized chunks. - Cacheline-sized chucks ensures the same utilization of each - hit line as sequential read. (Otherwise, our utilization - would only be 1/INTS_IN_CACHELINE.) */ -static int random_walk(cacheline_t *mem, int wss, int write_cycle) -{ - /* a random cycle among the cache lines was set up by init_arena(). */ - int sum, i, next, j; - - int numlines = wss * CACHELINES_IN_1KB; - - sum = 0; - - /* contents of arena is structured s.t. offsets are all - w.r.t. to start of arena, so compute the initial offset */ - next = mem - arena; - - if (write_cycle == 0) { - for (i = 0; i < numlines; i++) { - for (j = 0; j < INTS_IN_CACHELINE; j++) { - /* every element in the cacheline has the same value */ - //next = arena[next].line[j]; - local_buf[next].line[j] = arena[next].line[j]; - //sum += next; - //local_buf[next].line[j] = next; - } - } - } - - else { - int w, which_line; - for (i = 0, w = 0; i < numlines; i++) { - for (j = 0; j < INTS_IN_CACHELINE; j++) { - which_line = next; - next = local_buf[next].line[j]; - ((volatile cacheline_t*)arena)[which_line].line[j] = next; - //sum += next; - } - } - } - return sum; -} - -static cacheline_t* random_start(int wss) -{ - return arena + randrange(0, ((wss * 1024)/sizeof(cacheline_t))); -} - -static int sequential_walk(cacheline_t *mem, int wss, int write_cycle) -{ - int sum = 0, i, j; - //int* mem = (int*)_mem; /* treat as raw buffer of ints */ - int num_ints = wss * CACHELINES_IN_1KB; - - if (write_cycle > 0) { - for (i = 0; i < num_ints; i++) { - //if (i % write_cycle == (write_cycle - 1)) { - //mem[i]++; - for (j = 0; j < INTS_IN_CACHELINE; j++) { - //sum += local_buf[i].line[j]; - mem[i].line[j] = local_buf[i].line[j];; - } - //} - //else { - // sum += mem[i]; - //} - } - } else { - /* sequential access, pure read */ - for (i = 0; i < num_ints; i++) { - for (j = 0; j < INTS_IN_CACHELINE; j++) { - //sum += mem[i]; - local_buf[i].line[j] = mem[i].line[j]; - //sum += mem[i]; - } - } - } - return sum; -} - -static cacheline_t* sequential_start(int wss) -{ - return arena; -/* static int pos = 0; - - int num_cachelines = wss * CACHELINES_IN_1KB; - size_t num_arena_elem = wss * 1024 / sizeof(cacheline_t); - cacheline_t *mem; -*/ - - /* Don't allow re-use between allocations. - * At most half of the arena may be used - * at any one time. - */ -/* if (num_cachelines * 2 > num_arena_elem) - bail_out("static memory arena too small"); - - if (pos + num_cachelines > num_arena_elem) { - mem = arena; - pos = num_cachelines; - } else { - mem = arena + pos; - pos += num_cachelines; - } - - return mem;*/ -} - -static volatile int dont_optimize_me = 0; - -static void usage(char *error) { - fprintf(stderr, "Error: %s\n", error); - fprintf(stderr, - "Usage:\n" - " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" - " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" - " rt_spin -l\n" - "\n" - "COMMON-OPTS = [-w] [-s SCALE]\n" - " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-m CRITICALITY LEVEL]\n" - " [-k WSS] [-l LOOPS] [-b BUDGET]\n" - "\n" - "WCET and PERIOD are milliseconds, DURATION is seconds.\n"); - exit(EXIT_FAILURE); -} - -static int loop_once(int wss) -{ - cacheline_t *mem; - int temp; - - mem = random_start(wss); - temp = random_walk(mem, wss, 1); - - //mem = sequential_start(wss); - //temp = sequential_walk(arena, wss, 1); - dont_optimize_me = temp; - - return dont_optimize_me; -} - -static int job(int wss, double exec_time, double program_end) -{ - if (wctime() > program_end) - return 0; - else { - register unsigned long t; - register unsigned int iter = 0; - //t = get_cyclecount(); - //gettimeofday(&t1, NULL); - while(iter++ < loops) { - loop_once(wss); - } - //gettimeofday(&t2, NULL); - //printf("%ld cycles\n", get_cyclecount() - t); - //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); - sleep_next_period(); - return 1; - } -} - -#define OPTSTR "p:wl:m:i:b:k:" -int main(int argc, char** argv) -{ - int ret; - lt_t wcet, period, budget; - double wcet_ms, period_ms, budget_ms; - unsigned int priority = LITMUS_NO_PRIORITY; - int migrate = 0; - int cluster = 0; - int opt; - int wait = 0; - double duration = 0, start = 0; - struct rt_task param; - struct mc2_task mc2_param; - struct reservation_config config; - int res_type = PERIODIC_POLLING; - size_t arena_sz; - int wss; - - /* default for reservation */ - config.id = 0; - config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ - config.cpu = -1; - - mc2_param.crit = CRIT_LEVEL_C; - - budget_ms = 1000; - - while ((opt = getopt(argc, argv, OPTSTR)) != -1) { - switch (opt) { - case 'w': - wait = 1; - break; - case 'p': - cluster = atoi(optarg); - migrate = 1; - config.cpu = cluster; - break; - case 'l': - loops = atoi(optarg); - break; - case 'k': - wss = atoi(optarg); - break; - case 'm': - mc2_param.crit = atoi(optarg); - if ((mc2_param.crit >= CRIT_LEVEL_A) && (mc2_param.crit <= CRIT_LEVEL_C)) { - res_type = PERIODIC_POLLING; - } - else - usage("Invalid criticality level."); - break; - case 'b': - budget_ms = atof(optarg); - break; - case 'i': - config.priority = atoi(optarg); - break; - case ':': - usage("Argument missing."); - break; - case '?': - default: - usage("Bad argument."); - break; - } - } - srand(getpid()); - - /* - * We need three parameters - */ - if (argc - optind < 3) - usage("Arguments missing."); - - wcet_ms = atof(argv[optind + 0]); - period_ms = atof(argv[optind + 1]); - - wcet = ms2ns(wcet_ms); - period = ms2ns(period_ms); - budget = ms2ns(budget_ms); - if (wcet <= 0) - usage("The worst-case execution time must be a " - "positive number."); - if (period <= 0) - usage("The period must be a positive number."); - if (wcet > period) { - usage("The worst-case execution time must not " - "exceed the period."); - } - - duration = atof(argv[optind + 2]); - - if (migrate) { - ret = be_migrate_to_domain(cluster); - if (ret < 0) - bail_out("could not migrate to target partition or cluster."); - } - - /* reservation config */ - config.id = gettid(); - config.polling_params.budget = budget; - config.polling_params.period = period; - config.polling_params.offset = 0; - config.polling_params.relative_deadline = 0; - - if (config.polling_params.budget > config.polling_params.period) { - usage("The budget must not exceed the period."); - } - - /* create a reservation */ - ret = reservation_create(res_type, &config); - if (ret < 0) { - bail_out("failed to create reservation."); - } - - init_rt_task_param(¶m); - param.exec_cost = wcet; - param.period = period; - param.priority = priority; - param.cls = RT_CLASS_HARD; - param.release_policy = TASK_PERIODIC; - param.budget_policy = NO_ENFORCEMENT; - if (migrate) { - param.cpu = gettid(); - } - ret = set_rt_task_param(gettid(), ¶m); - if (ret < 0) - bail_out("could not setup rt task params"); - - mc2_param.res_id = gettid(); - ret = set_mc2_task_param(gettid(), &mc2_param); - if (ret < 0) - bail_out("could not setup mc2 task params"); - - - arena_sz = wss*1024; - - arena = alloc_shm(arena_sz, 0, 0); - if (!arena) - bail_out("alloc_shm failed.\n"); - init_arena(arena, arena_sz); - - local_buf = alloc_local(arena_sz, 0, 0); - if (!local_buf) - bail_out("alloc_local failed.\n"); - init_arena(local_buf, arena_sz); - - ret = init_litmus(); - if (ret != 0) - bail_out("init_litmus() failed\n"); - - start = wctime(); - ret = task_mode(LITMUS_RT_TASK); - if (ret != 0) - bail_out("could not become RT task"); - - if (mc2_param.crit == CRIT_LEVEL_C) - set_page_color(-1); - else - set_page_color(config.cpu); - - mlockall(MCL_CURRENT | MCL_FUTURE); -// init_arena(local_buf, arena_sz); -// test_call(1); -// init_arena(arena, arena_sz); -// test_call(2); - - if (wait) { - ret = wait_for_ts_release(); - if (ret != 0) - bail_out("wait_for_ts_release()"); - start = wctime(); - } - - while (job(wss, wcet_ms * 0.001, start + duration)) {}; - - ret = task_mode(BACKGROUND_TASK); - if (ret != 0) - bail_out("could not become regular task (huh?)"); - - reservation_destroy(gettid(), config.cpu); - dealloc_arena(arena, arena_sz); - dealloc_arena(local_buf, arena_sz); - printf("%s finished.\n", argv[0]); - return 0; -} diff --git a/bin/mc2spin.c b/bin/mc2spin.c index 25b1c58..dfb5c80 100644 --- a/bin/mc2spin.c +++ b/bin/mc2spin.c @@ -14,10 +14,6 @@ #include "common.h" #define PAGE_SIZE 4096 -#define NUM_ITEMS 8192 - -int *pages; -unsigned long *access_order; static void usage(char *error) { fprintf(stderr, "Error: %s\n", error); @@ -105,46 +101,16 @@ static void get_exec_times(const char *file, const int column, fclose(fstream); } -#define NUMS 4096 +#define NUMS 16 static int num[NUMS]; static char* progname; -static int randrange(const int max) -{ - return (rand() / (RAND_MAX / max + 1)); -} - -static void sattolo(unsigned long *items, const unsigned long len) -{ - unsigned long i; - /* first set up 0, 1, ..., n - 1 */ - for (i = 0; i < len; i++) - items[i] = i; - /* note: i is now n */ - while (1 < i--) { - /* 0 <= j < i */ - int t, j = randrange(i); - t = items[i]; - items[i] = items[j]; - items[j] = t; - } -} - static int loop_once(void) { int i, j = 0; for (i = 0; i < NUMS; i++) - j += num[i]++; + j += num[i]; return j; -/* - int i, tmp; - for (i = 0; i < NUM_ITEMS; i++) { - tmp = pages[access_order[i]]; - if (access_order[i] % 3 == 0) - pages[access_order[i]] = i+tmp; - } - return 1; -*/ } static int loop_for(double exec_time, double emergency_exit) @@ -275,7 +241,7 @@ struct lt_interval* parse_td_intervals(int num, char* optarg, unsigned int *num_ return slots; } -#define OPTSTR "p:c:wlveo:f:s:q:X:L:Q:vh:m:i:b:" +#define OPTSTR "p:c:wlveo:f:s:q:X:L:Q:vh:m:i:b:k:" int main(int argc, char** argv) { int ret; @@ -302,7 +268,8 @@ int main(int argc, char** argv) struct mc2_task mc2_param; struct reservation_config config; int res_type = PERIODIC_POLLING; - int n_str, num_int = 0; + int i; + uint32_t mode_mask; int verbose = 0; unsigned int job_no; @@ -395,6 +362,9 @@ int main(int argc, char** argv) case 'i': config.priority = atoi(optarg); break; + case 'k': + mode_mask = atoi(optarg); + break; case ':': usage("Argument missing."); break; @@ -410,8 +380,16 @@ int main(int argc, char** argv) return 0; } - if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) + if (mc2_param.crit == CRIT_LEVEL_A && config.priority == LITMUS_NO_PRIORITY) usage("Bad criticailty level or priority"); + if (mc2_param.crit == CRIT_LEVEL_B) { + config.priority = LITMUS_NO_PRIORITY; + } + + if (mc2_param.crit == CRIT_LEVEL_C) { + config.priority = LITMUS_NO_PRIORITY; + config.cpu = -1; + } srand(getpid()); @@ -477,11 +455,15 @@ int main(int argc, char** argv) if (config.polling_params.budget > config.polling_params.period) { usage("The budget must not exceed the period."); } - /* create a reservation */ - ret = reservation_create(res_type, &config); - if (ret < 0) { - bail_out("failed to create reservation."); + for(i = 0; i < 32; i++){ + if ( !( (1 << i) & mode_mask) ) + continue; + config.mode = i; + ret = reservation_create(res_type, &config); + if (ret < 0) { + bail_out("failed to create reservation."); + } } init_rt_task_param(¶m); @@ -501,24 +483,19 @@ int main(int argc, char** argv) bail_out("could not setup rt task params"); mc2_param.res_id = gettid(); + mc2_param.mode_mask = mode_mask; ret = set_mc2_task_param(gettid(), &mc2_param); //printf("SET_MC2_TASK\n"); if (ret < 0) bail_out("could not setup mc2 task params"); - pages = (int*)malloc(sizeof(int)*NUM_ITEMS); - access_order = (unsigned long*)malloc(sizeof(unsigned long)*NUM_ITEMS); - sattolo(access_order, NUM_ITEMS); - init_litmus(); -printf("CALL\n"); - set_page_color(config.cpu); -printf("CALL\n"); //printf("INIT_LITMUS\n"); start = wctime(); ret = task_mode(LITMUS_RT_TASK); //printf("TASK_MODE\n"); + set_page_color(config.cpu); if (ret != 0) bail_out("could not become RT task"); @@ -555,7 +532,6 @@ printf("CALL\n"); } while (job(wcet_ms * 0.001 * scale, start + duration, lock_od, cs_length * 0.001)); } -printf("BEFORE BACK_TASK\n"); ret = task_mode(BACKGROUND_TASK); if (ret != 0) bail_out("could not become regular task (huh?)"); @@ -565,10 +541,5 @@ printf("BEFORE BACK_TASK\n"); reservation_destroy(gettid(), config.cpu); -printf("CALL\n"); - set_page_color(config.cpu); -printf("CALL\n"); - free(pages); - free(access_order); return 0; } diff --git a/bin/mode_request.c b/bin/mode_request.c index a0b3226..010add1 100644 --- a/bin/mode_request.c +++ b/bin/mode_request.c @@ -1,13 +1,49 @@ +#include +#include +#include +#include +#include +#include + #include "litmus.h" #define __NR_request_mode 408 -int main(int argc, char* argv){ - int ret, req_mode; - if (argc < 2){ - return -EINVAL; +static int keep_running; + +void sig_handler(int signum) { + int ret; + + usleep(100000); + ret = syscall(__NR_request_mode, 0); + usleep(1000000); + keep_running = 0; + +} + +int main(int argc, char* argv[]) { + int ret, req_mode = 0; + int interval_ms; + int max_mode = 9; + + signal(SIGINT, sig_handler); + + if (argc == 2) { + max_mode = atoi(argv[1]); + printf("%d\n", max_mode); + } + + keep_running = 1; + usleep(500000); // ms + while (keep_running) { + req_mode = (req_mode%max_mode)+1; + + if (keep_running) + ret = syscall(__NR_request_mode, req_mode); + interval_ms = rand() % 1000 - 500; // ms + usleep(1000*(1000 + interval_ms)); } - req_mode = atoi(argv[1]); - ret = syscall(__NR_request_mode, req_mode); + + return ret; } diff --git a/bin/mode_skeleton.c b/bin/mode_skeleton.c new file mode 100644 index 0000000..cae5851 --- /dev/null +++ b/bin/mode_skeleton.c @@ -0,0 +1,256 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include "litmus.h" +#include "common.h" + +extern int main_job(void); + +static char* progname; +int loops = 10; +//struct timeval t1, t2; + +static void usage(char *error) { + fprintf(stderr, "Error: %s\n", error); + fprintf(stderr, + "Usage:\n" + " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" + " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" + " rt_spin -l\n" + "\n" + "COMMON-OPTS = [-w] [-s SCALE]\n" + " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" + "\n" + "WCET and PERIOD are microseconds, DURATION is seconds.\n"); + exit(EXIT_FAILURE); +} + +inline unsigned long get_cyclecount (void) +{ + unsigned long value; + // Read CCNT Register + asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); + return value; +} + +static int job(double exec_time, double program_end) +{ + if (wctime() > program_end) + return 0; + else { + register int iter = 0; + //register unsigned long t; + //t = get_cyclecount(); + //gettimeofday(&t1, NULL); + while (iter++ < loops) { + main_job(); + } + //t = get_cyclecount() - t; + //printf("%ld cycles\n", t); + //gettimeofday(&t2, NULL); + //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); + sleep_next_period(); + return 1; + } +} + +#define OPTSTR "p:wves:l:m:i:b:k:" +int main(int argc, char** argv) +{ + int ret; + lt_t wcet; + lt_t period; + lt_t budget; + double wcet_us, period_us, budget_us; + unsigned int priority = LITMUS_NO_PRIORITY; + int migrate = 0; + int cluster = 0; + int opt; + int wait = 0; + int want_enforcement = 0; + double duration = 0, start = 0; + double scale = 1.0; + task_class_t class = RT_CLASS_HARD; + struct rt_task param; + struct mc2_task mc2_param; + struct reservation_config config; + int res_type = PERIODIC_POLLING; + uint32_t mode_mask = (1 << 0); + int i; + unsigned int job_no; + + + progname = argv[0]; + + /* default for reservation */ + config.id = 0; + config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ + config.cpu = -1; + + mc2_param.crit = CRIT_LEVEL_C; + + budget_us = 10000; + + while ((opt = getopt(argc, argv, OPTSTR)) != -1) { + switch (opt) { + case 'w': + wait = 1; + break; + case 'p': + cluster = atoi(optarg); + migrate = 1; + config.cpu = cluster; + break; + case 'e': + want_enforcement = 1; + break; + case 's': + scale = atof(optarg); + break; + case 'l': + loops = atoi(optarg); + break; + case 'm': + mc2_param.crit = atoi(optarg); + if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { + usage("Invalid criticality level."); + } + res_type = PERIODIC_POLLING; + break; + case 'b': + budget_us = atof(optarg); + break; + case 'i': + config.priority = atoi(optarg); + break; + case 'k': + mode_mask = atoi(optarg); + case ':': + usage("Argument missing."); + break; + case '?': + default: + usage("Bad argument."); + break; + } + } + + if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) + usage("Bad criticailty level or priority"); + + if (argc - optind < 3) + usage("Arguments missing."); + + wcet_us = atof(argv[optind + 0]); + period_us = atof(argv[optind + 1]); + + wcet = us2ns(wcet_us); + period = us2ns(period_us); + budget = us2ns(budget_us); + + if (wcet <= 0) + usage("The worst-case execution time must be a " + "positive number."); + if (period <= 0) + usage("The period must be a positive number."); + if (wcet > period) { + usage("The worst-case execution time must not " + "exceed the period."); + } + + duration = atof(argv[optind + 2]); + + if (migrate) { + ret = be_migrate_to_domain(cluster); + if (ret < 0) + bail_out("could not migrate to target partition or cluster."); + } + + /* reservation config */ + config.id = gettid(); + + config.polling_params.budget = budget; + config.polling_params.period = period; + config.polling_params.offset = 0; + config.polling_params.relative_deadline = 0; + if (config.polling_params.budget > config.polling_params.period) { + usage("The budget must not exceed the period."); + } + + /* create reservations */ + for(i = 0; i < 32; i++){ + if ( !((1 << i) & mode_mask ) ) + continue; + config.mode = i; + ret = reservation_create(res_type, &config); + if (ret < 0) { + bail_out("failed to create reservation."); + } + } + + init_rt_task_param(¶m); + param.exec_cost = wcet; + param.period = period; + param.priority = priority; + param.cls = class; + param.release_policy = TASK_PERIODIC; + param.budget_policy = (want_enforcement) ? + PRECISE_ENFORCEMENT : NO_ENFORCEMENT; + if (migrate) { + param.cpu = gettid(); + } + ret = set_rt_task_param(gettid(), ¶m); + + if (ret < 0) + bail_out("could not setup rt task params"); + + mc2_param.res_id = gettid(); + mc2_param.mode_mask = mode_mask; + ret = set_mc2_task_param(gettid(), &mc2_param); +//printf("SET_MC2_TASK\n"); + if (ret < 0) + bail_out("could not setup mc2 task params"); + + init_litmus(); +//printf("CALL\n"); + if (mc2_param.crit == CRIT_LEVEL_C) + set_page_color(8); + else if (mc2_param.crit < CRIT_LEVEL_C) + set_page_color(config.cpu*2 + mc2_param.crit); +//printf("CALL\n"); + +//printf("INIT_LITMUS\n"); + start = wctime(); + ret = task_mode(LITMUS_RT_TASK); +//printf("TASK_MODE\n"); + if (ret != 0) + bail_out("could not become RT task"); + + + if (wait) { +//printf("BEFORE WAIT\n"); + ret = wait_for_ts_release(); + if (ret != 0) + bail_out("wait_for_ts_release()"); + start = wctime(); + } + + while (job(wcet_us * 0.000001 * scale, start + duration)) {}; + + ret = task_mode(BACKGROUND_TASK); + if (ret != 0) + bail_out("could not become regular task (huh?)"); + + reservation_destroy(gettid(), config.cpu); + printf("%s/%d finished.\n",progname, gettid()); + return 0; +} diff --git a/bin/rt_field.c b/bin/rt_field.c deleted file mode 100644 index ac79020..0000000 --- a/bin/rt_field.c +++ /dev/null @@ -1,379 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "litmus.h" -#include "common.h" -#include "DISstressmarkRNG.h" - -#define MIN_FIELD_SIZE 16 -#define MAX_FIELD_SIZE 16777216 -#define MIN_SEED -2147483647 -#define MAX_SEED -1 -#define MIN_MOD_OFFSET 0 -#define MAX_MOD_OFFSET 65535 -#define MIN_TOKENS 1 -#define MAX_TOKENS 256 -#define MIN_TOKEN_LENGTH 1 -#define MAX_TOKEN_LENGTH 8 -#define MIN_TOKEN_VALUE 0 -#define MAX_TOKEN_VALUE 255 -#define MAX_SUBFIELDS 256 - -static char* progname; -int loops = 1; - -struct timeval t1, t2; - -struct tokenS{ - unsigned char delimiter[MAX_TOKEN_LENGTH]; - unsigned char length; - struct statisticS{ - unsigned int count; - unsigned char min; - unsigned char sum; - } stat[MAX_SUBFIELDS]; - unsigned char subfields; -} token[MAX_TOKENS]; - -unsigned char *field; -unsigned int f_max; -int seed; -int mod_offset; -unsigned int n_max; - -unsigned char input_token[8] = {0x1, 0x1, 0x22, 0x1, 0xc2, 0x1, 0x2d, 0x0}; - -int init_job(){ - //fscanf(stdin, "%d %d %d %d", &f, &seed, &mod_offset, &n); - f_max = 262144; - seed = -2; - n_max = 128; - - assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); - - if ((field = (unsigned char*)malloc(f_max*sizeof(unsigned char))) == NULL) - return (-1); - - randInit(seed); - - return 0; -} - -int main_job() { - unsigned int l, f, n; - - /* for online */ -/* f = randInt(65536, f_max); - mod_offset = randInt(128, 8192); - n = 20; //randInt(64, n_max); -*/ - - /* for case */ - - f = randInt(64, 18000); - mod_offset = randInt(128, 8192); - n = 1; //randInt(64, n_max); - - - assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE)); - assert((mod_offset >= MIN_MOD_OFFSET) && (mod_offset <= MAX_MOD_OFFSET)); - assert((n >= MIN_TOKENS) && (n <= MAX_TOKENS)); - - for (l=0; l= MIN_TOKEN_VALUE) && (x <= MAX_TOKEN_VALUE)); - token[l].delimiter[index] = (unsigned char )x; - } - token[l].length = index; - } - - for (l =0; l field[index]) - token[l].stat[token[l].subfields].min = field[index]; - } - index++; - } - } - - return 0; -} - -int post_job() { - if (field) { - free(field); - field = NULL; - } - - return(0); -} - -static void usage(char *error) { - fprintf(stderr, "Error: %s\n", error); - fprintf(stderr, - "Usage:\n" - " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" - " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" - " rt_spin -l\n" - "\n" - "COMMON-OPTS = [-w] [-s SCALE]\n" - " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" - "\n" - "WCET and PERIOD are microseconds, DURATION is seconds.\n"); - exit(EXIT_FAILURE); -} - -inline unsigned long get_cyclecount (void) -{ - unsigned long value; - // Read CCNT Register - asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); - return value; -} - -static int job(double exec_time, double program_end) -{ - if (wctime() > program_end) - return 0; - else { - register int iter = 0; - //register unsigned long t; - //t = get_cyclecount(); - //gettimeofday(&t1, NULL); - while (iter++ < loops) { - main_job(); - } - //t = get_cyclecount() - t; - //printf("%ld cycles\n", t); - //gettimeofday(&t2, NULL); - //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); - sleep_next_period(); - return 1; - } -} - -#define OPTSTR "p:wves:l:m:i:b:" -int main(int argc, char** argv) -{ - int ret; - lt_t wcet; - lt_t period; - lt_t budget; - double wcet_ms, period_ms, budget_ms; - unsigned int priority = LITMUS_NO_PRIORITY; - int migrate = 0; - int cluster = 0; - int opt; - int wait = 0; - int want_enforcement = 0; - double duration = 0, start = 0; - double scale = 1.0; - task_class_t class = RT_CLASS_HARD; - struct rt_task param; - struct mc2_task mc2_param; - struct reservation_config config; - int res_type = PERIODIC_POLLING; - - progname = argv[0]; - - /* default for reservation */ - config.id = 0; - config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ - config.cpu = -1; - - mc2_param.crit = CRIT_LEVEL_C; - - budget_ms = 10; - - while ((opt = getopt(argc, argv, OPTSTR)) != -1) { - switch (opt) { - case 'w': - wait = 1; - break; - case 'p': - cluster = atoi(optarg); - migrate = 1; - config.cpu = cluster; - break; - case 'e': - want_enforcement = 1; - break; - case 's': - scale = atof(optarg); - break; - case 'l': - loops = atoi(optarg); - break; - case 'm': - mc2_param.crit = atoi(optarg); - if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { - usage("Invalid criticality level."); - } - res_type = PERIODIC_POLLING; - break; - case 'b': - budget_ms = atof(optarg); - break; - case 'i': - config.priority = atoi(optarg); - break; - case ':': - usage("Argument missing."); - break; - case '?': - default: - usage("Bad argument."); - break; - } - } - - if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) - usage("Bad criticailty level or priority"); - - if (argc - optind < 3) - usage("Arguments missing."); - - wcet_ms = atof(argv[optind + 0]); - period_ms = atof(argv[optind + 1]); - - wcet = ms2ns(wcet_ms); - period = ms2ns(period_ms); - budget = ms2ns(budget_ms); - - if (wcet <= 0) - usage("The worst-case execution time must be a " - "positive number."); - if (period <= 0) - usage("The period must be a positive number."); - if (wcet > period) { - usage("The worst-case execution time must not " - "exceed the period."); - } - - duration = atof(argv[optind + 2]); - - if (migrate) { - ret = be_migrate_to_domain(cluster); - if (ret < 0) - bail_out("could not migrate to target partition or cluster."); - } - - /* reservation config */ - config.id = gettid(); - - config.polling_params.budget = budget; - config.polling_params.period = period; - config.polling_params.offset = 0; - config.polling_params.relative_deadline = 0; - if (config.polling_params.budget > config.polling_params.period) { - usage("The budget must not exceed the period."); - } - - /* create a reservation */ - ret = reservation_create(res_type, &config); - if (ret < 0) { - bail_out("failed to create reservation."); - } - init_job(); - - init_rt_task_param(¶m); - param.exec_cost = wcet; - param.period = period; - param.priority = priority; - param.cls = class; - param.release_policy = TASK_PERIODIC; - param.budget_policy = (want_enforcement) ? - PRECISE_ENFORCEMENT : NO_ENFORCEMENT; - if (migrate) { - param.cpu = gettid(); - } - ret = set_rt_task_param(gettid(), ¶m); - - if (ret < 0) - bail_out("could not setup rt task params"); - - mc2_param.res_id = gettid(); - ret = set_mc2_task_param(gettid(), &mc2_param); -//printf("SET_MC2_TASK\n"); - if (ret < 0) - bail_out("could not setup mc2 task params"); - - init_litmus(); -//printf("CALL\n"); - if (mc2_param.crit == CRIT_LEVEL_C) - set_page_color(-1); - else if (mc2_param.crit < CRIT_LEVEL_C) - set_page_color(config.cpu); -//printf("CALL\n"); - -//printf("INIT_LITMUS\n"); - start = wctime(); - ret = task_mode(LITMUS_RT_TASK); -//printf("TASK_MODE\n"); - if (ret != 0) - bail_out("could not become RT task"); - - - if (wait) { -//printf("BEFORE WAIT\n"); - ret = wait_for_ts_release(); - if (ret != 0) - bail_out("wait_for_ts_release()"); - start = wctime(); - } - - while (job(wcet_ms * 0.001 * scale, start + duration)) {}; - - ret = task_mode(BACKGROUND_TASK); - if (ret != 0) - bail_out("could not become regular task (huh?)"); - - reservation_destroy(gettid(), config.cpu); - post_job(); - printf("%s/%d finished.\n",progname, gettid()); - return 0; -} diff --git a/bin/rt_field_spin.c b/bin/rt_field_spin.c deleted file mode 100644 index 06cabd4..0000000 --- a/bin/rt_field_spin.c +++ /dev/null @@ -1,385 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "litmus.h" -#include "common.h" -#include "DISstressmarkRNG.h" - -#define MIN_FIELD_SIZE 16 -#define MAX_FIELD_SIZE 16777216 -#define MIN_SEED -2147483647 -#define MAX_SEED -1 -#define MIN_MOD_OFFSET 0 -#define MAX_MOD_OFFSET 65535 -#define MIN_TOKENS 1 -#define MAX_TOKENS 256 -#define MIN_TOKEN_LENGTH 1 -#define MAX_TOKEN_LENGTH 8 -#define MIN_TOKEN_VALUE 0 -#define MAX_TOKEN_VALUE 255 -#define MAX_SUBFIELDS 256 - -static char* progname; -int loops = 1; - -struct timeval t1, t2; - -struct tokenS{ - unsigned char delimiter[MAX_TOKEN_LENGTH]; - unsigned char length; - struct statisticS{ - unsigned int count; - unsigned char min; - unsigned char sum; - } stat[MAX_SUBFIELDS]; - unsigned char subfields; -} token[MAX_TOKENS]; - -unsigned char *field; -unsigned int f_max; -int seed; -int mod_offset; -unsigned int n_max; - -unsigned char input_token[8] = {0x1, 0x1, 0x22, 0x1, 0xc2, 0x1, 0x2d, 0x0}; - -int init_job(){ - //fscanf(stdin, "%d %d %d %d", &f, &seed, &mod_offset, &n); - f_max = 262144; - seed = -1; - n_max = 1; - - assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); - - if ((field = (unsigned char*)malloc(f_max*sizeof(unsigned char))) == NULL) - return (-1); - - randInit(seed); - - return 0; -} - -int main_job() { - unsigned int l, f, n; - - f = randInt(16384, f_max); - mod_offset = randInt(128, 8192); - n = n_max; //randInt(128,n_max); - - assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE)); - assert((mod_offset >= MIN_MOD_OFFSET) && (mod_offset <= MAX_MOD_OFFSET)); - assert((n >= MIN_TOKENS) && (n <= MAX_TOKENS)); - - for (l=0; l= MIN_TOKEN_VALUE) && (x <= MAX_TOKEN_VALUE)); - token[l].delimiter[index] = (unsigned char )x; - } - token[l].length = index; - } - - for (l =0; l field[index]) - token[l].stat[token[l].subfields].min = field[index]; - } - index++; - } - } - - return 0; -} - -int post_job() { - if (field) { - free(field); - field = NULL; - } - - return(0); -} - -static void usage(char *error) { - fprintf(stderr, "Error: %s\n", error); - fprintf(stderr, - "Usage:\n" - " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" - " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" - " rt_spin -l\n" - "\n" - "COMMON-OPTS = [-w] [-s SCALE]\n" - " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" - "\n" - "WCET and PERIOD are microseconds, DURATION is seconds.\n"); - exit(EXIT_FAILURE); -} - -inline unsigned long get_cyclecount (void) -{ - unsigned long value; - // Read CCNT Register - asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); - return value; -} - -static int loop_main(double exec_time, double emergency_exit) -{ - double last_loop = 0, loop_start; - int tmp = 0; - - double start = cputime(); - double now = cputime(); - - while (now + last_loop < start + exec_time) { - loop_start = now; - tmp += main_job(); - now = cputime(); - last_loop = now - loop_start; - if (emergency_exit && wctime() > emergency_exit) { - /* Oops --- this should only be possible if the execution time tracking - * is broken in the LITMUS^RT kernel. */ - fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); - fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); - break; - } - } - - return tmp; -} - -static int job(double exec_time, double program_end) -{ - if (wctime() > program_end) - return 0; - else { - loop_main(exec_time, program_end + 1); - sleep_next_period(); - return 1; - } -} - -#define OPTSTR "p:wves:l:m:i:b:" -int main(int argc, char** argv) -{ - int ret; - lt_t wcet; - lt_t period; - lt_t budget; - double wcet_ms, period_ms, budget_ms; - unsigned int priority = LITMUS_NO_PRIORITY; - int migrate = 0; - int cluster = 0; - int opt; - int wait = 0; - int want_enforcement = 0; - double duration = 0, start = 0; - double scale = 1.0; - task_class_t class = RT_CLASS_HARD; - struct rt_task param; - struct mc2_task mc2_param; - struct reservation_config config; - int res_type = PERIODIC_POLLING; - - progname = argv[0]; - - /* default for reservation */ - config.id = 0; - config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ - config.cpu = -1; - -