From 010690950e295802405f2d538be859ef21bec155 Mon Sep 17 00:00:00 2001 From: leochanj105 Date: Fri, 23 Oct 2020 03:46:12 -0400 Subject: wip wip wip wip --- SD-VBS/benchmarks/stitch/src/c/script_stitch.c | 12 +- SD-VBS/common/c/extra.h | 239 ++++++++++++++----------- SD-VBS/common/makefiles/Makefile.common | 5 +- 3 files changed, 143 insertions(+), 113 deletions(-) (limited to 'SD-VBS') diff --git a/SD-VBS/benchmarks/stitch/src/c/script_stitch.c b/SD-VBS/benchmarks/stitch/src/c/script_stitch.c index b7611f1..9310048 100644 --- a/SD-VBS/benchmarks/stitch/src/c/script_stitch.c +++ b/SD-VBS/benchmarks/stitch/src/c/script_stitch.c @@ -23,6 +23,12 @@ int main(int argc, char* argv[]) cols = Icur->width; for_each_job { + iFreeHandle(Icur); + fFreeHandle(v); + fFreeHandle(interestPnts); + fFreeHandle(int1); + fFreeHandle(int2); + fFreeHandle(Fcur); v = harris(Icur); interestPnts = getANMS(v, 24); int1 = fMallocHandle(interestPnts->height, 1); @@ -49,12 +55,6 @@ int main(int argc, char* argv[]) printf("Error in Stitch\n"); } #endif - iFreeHandle(Icur); - fFreeHandle(v); - fFreeHandle(interestPnts); - fFreeHandle(int1); - fFreeHandle(int2); - fFreeHandle(Fcur); WRITE_TO_FILE return 0; } diff --git a/SD-VBS/common/c/extra.h b/SD-VBS/common/c/extra.h index 8c67b33..9c72064 100644 --- a/SD-VBS/common/c/extra.h +++ b/SD-VBS/common/c/extra.h @@ -29,8 +29,8 @@ extern int sched_getcpu(); #include #endif +// This is a proxy for "case study mode" now #define LITMUS 1 -#define MC2 0 #define MMDC_PROF 0 #if LITMUS @@ -41,18 +41,6 @@ extern int sched_getcpu(); #include "/media/speedy/litmus/tools/mmdc/mmdc.h" #endif -#if LITMUS -#define SET_UP LOAD_PARAMS SETUP_LITMUS -#else -#define SET_UP LOAD_PARAMS -#endif - -#if MMDC_PROF -#define LOAD_PARAMS LOAD_PARAMS_ITRL SETUP_MMDC -#else -#define LOAD_PARAMS LOAD_PARAMS_ITRL -#endif - // Store state globally so that the job can be outside main() // Arrays use float as a comprimise between overflow and size // Paired arrays use long longs as precision is more important for those times @@ -82,50 +70,72 @@ char *_rt_other_core; char *_rt_barrier; sem_t *_rt_first_sem, *_rt_second_sem; int _rt_lock_id; +#define _ID_SZ 128 +char _rt_sem1_name[_ID_SZ] = "/_libextra_first_sem-"; +char _rt_sem2_name[_ID_SZ] = "/_libextra_second_sem-"; +char _rt_shm_name[_ID_SZ] = "/_libextra_barrier-"; +#endif /* PAIRED */ + +#if LITMUS +long unsigned int _rt_period; #endif static void _rt_load_params_itrl(int argc, char **argv) { #ifdef PAIRED - if (argc != 8) { - fprintf(stderr, "Usage: %s ", argv[0]); - fprintf(stderr, " string for logging. Name of this task.\n"); - fprintf(stderr, " integer number of iterations. -1 for infinite.\n"); - fprintf(stderr, " UNUSED. Core is now auto-detected.\n"); - fprintf(stderr, " integer for logging. Core of paired task.\n"); - fprintf(stderr, " string for logging. Name of paired task.\n"); - fprintf(stderr, " string to append with .txt to yield output file name.\n"); - fprintf(stderr, " 1 to indicate this is pair member 1, otherwise pair member 2.\n"); - exit(1); - } + if (argc != (8 + LITMUS*2) && argc != (9 + LITMUS*2)) { + fprintf(stderr, "Usage: %s ", argv[0]); #else - if (argc != 6) { + if (argc != (6 + LITMUS*2)) { fprintf(stderr, "Usage: %s \n", argv[0]); +#endif /* PAIRED */ fprintf(stderr, " string for logging. Name of this task.\n"); fprintf(stderr, " integer number of iterations. -1 for infinite.\n"); - fprintf(stderr, " UNUSED. Core is now auto-detected.\n"); + fprintf(stderr, " integer core number. Only used for LITMUS-RT.\n"); +#ifdef PAIRED + fprintf(stderr, " integer for logging. Core of paired task.\n"); + fprintf(stderr, " string for logging. Name of paired task.\n"); +#endif /* PAIRED */ fprintf(stderr, " string to append with .txt to yield output file name.\n"); fprintf(stderr, " 1 to save results, 0 to discard.\n"); +#ifdef PAIRED + fprintf(stderr, " (optional).\n"); +#endif +#if LITMUS + fprintf(stderr, " in ms\n"); + fprintf(stderr, " 0 for Level-A, 1 for Level-B, 2 for Level-C\n"); +#endif /* LITMUS */ exit(1); } -#endif _rt_our_prog_name = argv[1]; _rt_max_jobs = atol(argv[2]); +#if !LITMUS _rt_core = sched_getcpu(); +#else + _rt_core = atoi(argv[3]); +#endif #ifdef PAIRED _rt_other_core = argv[4]; _rt_other_prog_name = argv[5]; _rt_run_id = argv[6]; - _rt_lock_id = atoi(argv[7]); - // The paired version doesn't support disabling output (legacy compatibility) - _rt_will_output = 1; + _rt_will_output = atoi(argv[7]); + char *pairId; + int end; + if (argc > 8) { + pairId = argv[8]; + end = 8; + } else { + pairId = "none"; + end = 9; + } #else _rt_other_core = "none"; _rt_other_prog_name = "none"; _rt_run_id = argv[4]; _rt_will_output = atoi(argv[5]); + int end = 6; #endif /* PAIRED */ if (_rt_max_jobs < 0 && _rt_will_output != 0) { - fprintf(stderr, "Infinite loops only supported when _rt_will_output is disabled!\n"); + fprintf(stderr, "Infinite loops only supported when output is disabled!\n"); exit(1); } if (strlen(_rt_run_id) + 5 > _RT_FILENAME_LEN) { @@ -133,32 +143,54 @@ static void _rt_load_params_itrl(int argc, char **argv) { exit(1); } #ifdef PAIRED + // __rt_sem2_name happens to be the longest + if (strlen(pairId) + strlen(_rt_sem2_name) > _ID_SZ) { + fprintf(stderr, "PairID is too long! Maximum length is %ld characters.\n", _ID_SZ - strlen(_rt_sem2_name)); + exit(1); + } _rt_start_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(long long)); _rt_end_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(long long)); if (!_rt_end_time || !_rt_start_time) { perror("Unable to allocate buffers for execution times"); exit(1); } - _rt_first_sem = sem_open("/_libextra_first_sem", O_CREAT, 644, 0); - _rt_second_sem = sem_open("/_libextra_second_sem", O_CREAT, 644, 0); + // Use PairID to create unique semaphore and shared memory paths + strcat(_rt_sem1_name, pairId); + strcat(_rt_sem2_name, pairId); + strcat(_rt_shm_name, pairId); + _rt_first_sem = sem_open(_rt_sem1_name, O_CREAT, 644, 0); + _rt_second_sem = sem_open(_rt_sem2_name, O_CREAT, 644, 0); if (_rt_first_sem == SEM_FAILED || _rt_second_sem == SEM_FAILED) { perror("Error while creating semaphores"); exit(1); } - int barrier_file = shm_open("/_libextra_barrier", O_CREAT | O_RDWR, 644); + // Create shared memory for barrier synchronization and infer lock ID + int barrier_file = shm_open(_rt_shm_name, O_CREAT | O_RDWR | O_EXCL, 644); + if (barrier_file == -1) { + // File already existed - we're the 2nd program and thus lock ID 2 + _rt_lock_id = 2; + barrier_file = shm_open(_rt_shm_name, O_CREAT | O_RDWR, 644); + } else { + _rt_lock_id = 1; + } if (barrier_file == -1) { perror("Error while creating shared memory for barrier synchronization"); exit(1); } - if (ftruncate(barrier_file, 1) == -1) { + if (ftruncate(barrier_file, 2) == -1) { perror("Error while setting size of shared memory for barrier synchronization"); exit(1); } - _rt_barrier = mmap(NULL, 1, PROT_WRITE, MAP_SHARED, barrier_file, 0); + _rt_barrier = mmap(NULL, 2, PROT_WRITE, MAP_SHARED, barrier_file, 0); if (_rt_barrier == MAP_FAILED) { perror("Error while mapping shared memory for barrier synchronization"); exit(1); } + // If we're the 2nd user of this barrier, mark it as in-use + if (_rt_lock_id == 2 && !__sync_bool_compare_and_swap(_rt_barrier+1, 0, 1)) { + fprintf(stderr, "Pair ID already in use!\n"); + exit(1); + } *_rt_barrier = 0; #else _rt_exec_time = calloc(_rt_max_jobs * _rt_will_output, sizeof(float)); @@ -169,8 +201,47 @@ static void _rt_load_params_itrl(int argc, char **argv) { #endif /* PAIRED */ _rt_jobs_complete = 0; mlockall(MCL_CURRENT || MCL_FUTURE); +#if LITMUS + _rt_period = strtoul(argv[end], NULL, 10); + unsigned int crit = atoi(argv[end+1]); + unsigned int wait = 1; + if (be_migrate_to_domain(_rt_core) < 0) { + perror("Unable to migrate to specified CPU"); + exit(1); + } + struct rt_task rt_param; + init_rt_task_param(&rt_param); + // Fake exec cost - this value ignored by the MC^2 scheduler + rt_param.exec_cost = _rt_period; + rt_param.period = ms2ns(_rt_period); + rt_param.relative_deadline = 0; + rt_param.phase = 0; + rt_param.priority = LITMUS_LOWEST_PRIORITY; + rt_param.cls = crit; + rt_param.release_policy = TASK_PERIODIC; + rt_param.budget_policy = NO_ENFORCEMENT; + rt_param.cpu = _rt_core; + if (set_rt_task_param(gettid(), &rt_param) < 0) { + perror("Unable to set real-time parameters"); + exit(1); + } + if (init_litmus() != 0) { + perror("init_litmus failed"); + exit(1); + } + if (task_mode(LITMUS_RT_TASK) != 0) { + perror("Unable to become real-time task"); + exit(1); + } + if (wait && wait_for_ts_release() != 0) { + perror("Unable to wait for taskset release"); + exit(1); + } +#endif /* LITMUS */ +#if MMDC_PROF + SETUP_MMDC +#endif } -#define LOAD_PARAMS_ITRL _rt_load_params_itrl(argc, argv); #define SETUP_MMDC \ _rt_mmdc_read = calloc(_rt_max_jobs * _rt_will_output, sizeof(float));\ @@ -194,54 +265,6 @@ static void _rt_load_params_itrl(int argc, char **argv) { mmdc->madpcr1 = axi_arm1;\ msync(&(mmdc->madpcr1),4,MS_SYNC); -#define SETUP_LITMUS \ - unsigned int wait = 0; \ - if (be_migrate_to_domain(_rt_core) < 0) { \ - perror("Unable to migrate to specified CPU"); \ - exit(1); \ - } \ - struct rt_task rt_param; \ - init_rt_task_param(&rt_param); \ - /* Supposedly the next two parameters are irrelevant when reservations are enabled, but I'm leaving them anyway... */ \ - rt_param.exec_cost = ms2ns(999); \ - rt_param.period = ms2ns(1000); \ - rt_param.priority = LITMUS_HIGHEST_PRIORITY; \ - rt_param.cls = RT_CLASS_HARD; \ - rt_param.release_policy = TASK_PERIODIC; \ - rt_param.budget_policy = NO_ENFORCEMENT; \ - rt_param.cpu = _rt_core; \ - if (set_rt_task_param(gettid(), &rt_param) < 0) { \ - perror("Unable to set real-time parameters"); \ - exit(1); \ - } \ - if (init_litmus() != 0) { \ - perror("init_litmus failed"); \ - exit(1); \ - } \ - MC2_SETUP \ - if (task_mode(LITMUS_RT_TASK) != 0) { \ - perror("Unable to become real-time task"); \ - exit(1); \ - } \ - if (wait && wait_for_ts_release() != 0) { \ - perror("Unable to wait for taskset release"); \ - exit(1); \ - } - -#if MC2 -#define MC2_SETUP \ - - set_page_color(rt_param.cpu); -#else -#define MC2_SETUP -#endif - -#define CLEANUP_LITMUS \ - if (task_mode(BACKGROUND_TASK) != 0) { \ - perror("Unable to become a real-time task"); \ - exit(1); \ - } \ - #if __arm__ // On ARM, manually flush the cache #define FLUSH_CACHES \ @@ -305,28 +328,28 @@ static void _rt_load_params_itrl(int argc, char **argv) { // Buffer timing result from a single job static void _rt_save_job_result() { + if (!_rt_will_output) + return; if (_rt_jobs_complete >= _rt_max_jobs) { fprintf(stderr, "Max jobs setting too small! Trying to record job #%ld when we only have space for %ld jobs. Exiting...\n", _rt_jobs_complete, _rt_max_jobs); exit(1); } - if (_rt_jobs_complete > -1 && _rt_will_output) { #ifdef PAIRED - _rt_start_time[_rt_jobs_complete] = _rt_start.tv_sec; - _rt_start_time[_rt_jobs_complete] *= _BILLION; - _rt_start_time[_rt_jobs_complete] += _rt_start.tv_nsec; - _rt_end_time[_rt_jobs_complete] = _rt_end.tv_sec; - _rt_end_time[_rt_jobs_complete] *= _BILLION; - _rt_end_time[_rt_jobs_complete] += _rt_end.tv_nsec; + _rt_start_time[_rt_jobs_complete] = _rt_start.tv_sec; + _rt_start_time[_rt_jobs_complete] *= _BILLION; + _rt_start_time[_rt_jobs_complete] += _rt_start.tv_nsec; + _rt_end_time[_rt_jobs_complete] = _rt_end.tv_sec; + _rt_end_time[_rt_jobs_complete] *= _BILLION; + _rt_end_time[_rt_jobs_complete] += _rt_end.tv_nsec; #else - _rt_exec_time[_rt_jobs_complete] = _rt_end.tv_sec - _rt_start.tv_sec; - _rt_exec_time[_rt_jobs_complete] *= _BILLION; - _rt_exec_time[_rt_jobs_complete] += _rt_end.tv_nsec - _rt_start.tv_nsec; + _rt_exec_time[_rt_jobs_complete] = _rt_end.tv_sec - _rt_start.tv_sec; + _rt_exec_time[_rt_jobs_complete] *= _BILLION; + _rt_exec_time[_rt_jobs_complete] += _rt_end.tv_nsec - _rt_start.tv_nsec; #endif /* PAIRED */ #if MMDC_PROF - _rt_mmdc_read[_rt_jobs_complete] = mmdc_res.read_bytes; - _rt_mmdc_write[_rt_jobs_complete] = mmdc_res.write_bytes; -#endif - } + _rt_mmdc_read[_rt_jobs_complete] = mmdc_res.read_bytes; + _rt_mmdc_write[_rt_jobs_complete] = mmdc_res.write_bytes; +#endif /* MMDC_PROF */ } // Save all buffered timing results to disk @@ -365,13 +388,16 @@ static void _rt_write_to_file() { fclose(fp); out: #if LITMUS - CLEANUP_LITMUS + if (task_mode(BACKGROUND_TASK) != 0) { + perror("Unable to become a real-time task"); + exit(1); + } #endif /* LITMUS */ #ifdef PAIRED - munmap(_rt_barrier, 1); - shm_unlink("/_libextra_barrier"); - sem_unlink("/_libextra_first_sem"); - sem_unlink("/_libextra_second_sem"); + munmap(_rt_barrier, 2); + sem_unlink(_rt_sem1_name); + sem_unlink(_rt_sem2_name); + shm_unlink(_rt_shm_name); free(_rt_start_time); free(_rt_end_time); #else @@ -396,7 +422,9 @@ static void _rt_start_loop() { FIRST_UNLOCK FIRST_LOCK #endif /* PAIRED */ +#if !LITMUS FLUSH_CACHES +#endif #ifdef PAIRED BARRIER_SYNC #endif /* PAIRED */ @@ -444,7 +472,7 @@ static void _rt_stop_loop() { * result. We use this to call our void function from inside a comparison. */ #define for_each_job \ - for (; _rt_jobs_complete < _rt_max_jobs && (_rt_start_loop(),1); \ + for (; (_rt_max_jobs == -1 || _rt_jobs_complete < _rt_max_jobs) && (_rt_start_loop(),1); \ _rt_stop_loop()) /****** Legacy API ****** @@ -466,6 +494,7 @@ static void _rt_stop_loop() { * able to read them. */ static int jobsComplete = 0; +#define SET_UP _rt_load_params_itrl(argc, argv); #define START_LOOP _rt_start_loop(); #define STOP_LOOP _rt_stop_loop(); #define WRITE_TO_FILE _rt_write_to_file(); diff --git a/SD-VBS/common/makefiles/Makefile.common b/SD-VBS/common/makefiles/Makefile.common index 964ece6..2080e2a 100644 --- a/SD-VBS/common/makefiles/Makefile.common +++ b/SD-VBS/common/makefiles/Makefile.common @@ -28,9 +28,10 @@ PRELOAD_TIMES_DIR := $(TOP_DIR)/preload-times/$(BMARK) MTIMING_DIR := $(TOP_DIR)/cycles/$(BMARK) BMARK_DIR := $(TOP_DIR)/benchmarks/$(BMARK) TOOL_DIR := $(TOP_DIR)/tools -LIBLITMUS ?= /home/litmus/liblitmus +LIBLITMUS ?= /playpen/mc2/liblitmus +LIBEXTRA ?= $(TOP_DIR)/../ ifneq ($(shell grep "define LITMUS 1" ../../../../../extra.h),) - override CFLAGS += -I${LIBLITMUS}/include -I${LIBLITMUS}/arch/arm/include + override CFLAGS += -I${LIBLITMUS}/include -I${LIBLITMUS}/arch/arm/include -I${LIBEXTRA} override LDFLAGS += -L${LIBLITMUS} -llitmus endif #The options set below and specific to each benchmark. Disparity takes 2 input images, whereas Tracking can take any >1 input images =. -- cgit v1.2.2