summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2019-10-19 10:50:23 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2019-10-19 10:50:23 -0400
commit4f1aa00f177646b5129304a7d587658aad949946 (patch)
tree925a103d779bd7ae2f6568907051f8ce43b868b4
parent7e6ceb16b53fdbdb2a27cf3ade15d32177ff811f (diff)
Support LITMUS, MC^2, and alternate benchmarks
-rw-r--r--baseline/source/extra.h230
1 files changed, 193 insertions, 37 deletions
diff --git a/baseline/source/extra.h b/baseline/source/extra.h
index ca92812..df8164f 100644
--- a/baseline/source/extra.h
+++ b/baseline/source/extra.h
@@ -1,3 +1,8 @@
1/**
2 * Copyright 2019 Sims Hill Osborne and Joshua Bakita
3 *
4 * This header provides facilities by which to separably run and time TACLeBench
5 **/
1#include <time.h> 6#include <time.h>
2#include <sys/mman.h> 7#include <sys/mman.h>
3#include <stdlib.h> 8#include <stdlib.h>
@@ -5,12 +10,47 @@
5#include <string.h> 10#include <string.h>
6#include <signal.h> 11#include <signal.h>
7#include <limits.h> 12#include <limits.h>
13#include <fcntl.h>
8 14
9#define L3_CACHE_SIZE (11264*1024) 15// These constants correspond to the imx6q-sabredb platform
16#define LINE_SIZE 32
17#define L2_SIZE 16*2048*32
10 18
19#if __arm__
20#include <unistd.h>
21#include <sys/syscall.h>
22#endif
11 23
24#define LITMUS 1
25#define MC2 1
26#define MMDC_PROF 1
12 27
13#define SET_UP char *thisProgram=argv[1];\ 28#if LITMUS
29#include <litmus.h>
30#endif
31
32#if MMDC_PROF
33#include "/media/speedy/litmus/tools/mmdc/mmdc.h"
34#endif
35
36#if LITMUS
37#define SET_UP LOAD_PARAMS SETUP_LITMUS
38#else
39#define SET_UP LOAD_PARAMS
40#endif
41
42#if MMDC_PROF
43#define LOAD_PARAMS LOAD_PARAMS_ITRL SETUP_MMDC
44#else
45#define LOAD_PARAMS LOAD_PARAMS_ITRL
46#endif
47
48#define LOAD_PARAMS_ITRL \
49 if (argc < 9) { \
50 printf("Usage: %s <name> <loops> <my core> <unused> <unused> <runID> <\?\?\?>", argv[0]);\
51 exit(1);\
52 }\
53 char *thisProgram=argv[1];\
14 int maxJobs=atoi(argv[2]);\ 54 int maxJobs=atoi(argv[2]);\
15 char *thisCore=argv[3];\ 55 char *thisCore=argv[3];\
16 char *otherCore=argv[4];\ 56 char *otherCore=argv[4];\
@@ -20,37 +60,152 @@
20 pid_t killMe;\ 60 pid_t killMe;\
21 struct timespec start, end;\ 61 struct timespec start, end;\
22 int jobsComplete;\ 62 int jobsComplete;\
63 int jobs_complete = -1;\
23 long progTime[maxJobs*output];\ 64 long progTime[maxJobs*output];\
65 memset(progTime, 0, sizeof(long)*maxJobs*output);\
24 char fileName[50];\ 66 char fileName[50];\
25 char *bigArray;\ 67 char *bigArray;\
26 int wasteCount;\ 68 int wasteCount;\
69 unsigned long mmdc_read[maxJobs];\
70 unsigned long mmdc_write[maxJobs];\
71 memset(mmdc_read, 0, sizeof(unsigned long)*maxJobs);\
72 memset(mmdc_write, 0, sizeof(unsigned long)*maxJobs);\
27 strcpy(fileName, runID);\ 73 strcpy(fileName, runID);\
28 strcat(fileName, ".txt");\ 74 strcat(fileName, ".txt");\
29 mlockall(MCL_CURRENT || MCL_FUTURE); 75 mlockall(MCL_CURRENT || MCL_FUTURE);
30 76
77#define SETUP_MMDC \
78 MMDC_PROFILE_RES_t mmdc_res; \
79 memset(&mmdc_res, 0, sizeof(MMDC_PROFILE_RES_t));\
80 int fd = open("/dev/mem", O_RDWR, 0);\
81 if (fd < 0) {\
82 perror("Unable to open /dev/mem");\
83 exit(1);\
84 }\
85 pMMDC_t mmdc = mmap(NULL, 0x4000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MMDC_P0_IPS_BASE_ADDR);\
86 if (mmdc == MAP_FAILED) {\
87 perror("Unable to map MMDC address space");\
88 exit(1);\
89 }\
90 mmdc->madpcr1 = axi_arm1;\
91 msync(&(mmdc->madpcr1),4,MS_SYNC);
92
93#define SETUP_LITMUS \
94 unsigned int cpu = atoi(thisCore); \
95 unsigned int wait = 0; \
96 if (be_migrate_to_domain(cpu) < 0) { \
97 perror("Unable to migrate to specified CPU"); \
98 exit(1); \
99 } \
100 struct reservation_config res; \
101 res.id = gettid(); \
102 res.cpu = cpu; \
103 res.priority = LITMUS_HIGHEST_PRIORITY; \
104 /* we take over half the CPU time (these are ns) */ \
105 res.polling_params.budget = ms2ns(999); \
106 res.polling_params.period = ms2ns(1000); \
107 res.polling_params.offset = 0; \
108 res.polling_params.relative_deadline = ms2ns(999); \
109 /* Not 100% sure that we should use periodic polling */ \
110 if (reservation_create(PERIODIC_POLLING, &res) < 0) { \
111 perror("Unable to create reservation"); \
112 exit(1); \
113 } \
114 struct rt_task rt_param; \
115 init_rt_task_param(&rt_param); \
116 /* Supposedly the next two parameters are irrelevant when reservations are enabled, but I'm leaving them anyway... */ \
117 rt_param.exec_cost = ms2ns(999); \
118 rt_param.period = ms2ns(1000); \
119 rt_param.priority = LITMUS_HIGHEST_PRIORITY; \
120 rt_param.cls = RT_CLASS_HARD; \
121 rt_param.release_policy = TASK_PERIODIC; \
122 rt_param.budget_policy = NO_ENFORCEMENT; \
123 rt_param.cpu = cpu; \
124 if (set_rt_task_param(gettid(), &rt_param) < 0) { \
125 perror("Unable to set real-time parameters"); \
126 exit(1); \
127 } \
128 if (init_litmus() != 0) { \
129 perror("init_litmus failed"); \
130 exit(1); \
131 } \
132 MC2_SETUP \
133 if (task_mode(LITMUS_RT_TASK) != 0) { \
134 perror("Unable to become real-time task"); \
135 exit(1); \
136 } \
137 if (wait && wait_for_ts_release() != 0) { \
138 perror("Unable to wait for taskset release"); \
139 exit(1); \
140 }
141
142#if MC2
143#define MC2_SETUP \
144 struct mc2_task mc2_param; \
145 mc2_param.res_id = gettid(); \
146 mc2_param.crit = CRIT_LEVEL_A; \
147 if (set_mc2_task_param(gettid(), &mc2_param) < 0) { \
148 perror("Unable to set MC^2 task params"); \
149 exit(1); \
150 } \
151 set_page_color(rt_param.cpu);
152#else
153#define MC2_SETUP
154#endif
31 155
32//if output==0, endless loop 156#define CLEANUP_LITMUS \
33//avoids int overflow error with large numbers for background loops 157 if (task_mode(BACKGROUND_TASK) != 0) { \
158 perror("Unable to become a real-time task"); \
159 exit(1); \
160 } \
161 reservation_destroy(gettid(), rt_param.cpu);
34 162
35#define SAVE_RESULTS if(jobsComplete>-1) progTime[jobsComplete]=(end.tv_nsec-start.tv_nsec)+(1000000000*(end.tv_sec-start.tv_sec)); 163#if MMDC_PROF
164#define SAVE_RESULTS \
165 if(jobs_complete>-1) {\
166 progTime[jobs_complete]=(end.tv_nsec-start.tv_nsec)+(1000000000*(end.tv_sec-start.tv_sec));\
167 mmdc_read[jobs_complete] = mmdc_res.read_bytes;\
168 mmdc_write[jobs_complete] = mmdc_res.write_bytes;\
169 }
170#else
171#define SAVE_RESULTS \
172 if(jobs_complete>-1)\
173 progTime[jobs_complete]=(end.tv_nsec-start.tv_nsec)+(1000000000*(end.tv_sec-start.tv_sec));
174#endif
36 175
37#define WRITE_TO_FILE if (output){\ 176
177#if LITMUS
178#define WRITE_TO_FILE WRITE_TO_FILE_ITRNL CLEANUP_LITMUS
179#else
180#define WRITE_TO_FILE WRITE_TO_FILE_ITRNL
181#endif
182
183#define WRITE_TO_FILE_ITRNL if (output){\
38 munlockall();\ 184 munlockall();\
39 FILE *fp=fopen(fileName, "a");\ 185 FILE *fp=fopen(fileName, "a");\
40 if (fp == NULL) {\ 186 if (fp == NULL) {\
41 perror("Error opening file. \n");\ 187 perror("Error opening file. \n");\
42 exit(1);\ 188 exit(1);\
43 }\ 189 }\
44 for(jobsComplete=0; jobsComplete<maxJobs; jobsComplete++){\ 190 for(int i = 0; i <= jobs_complete; i++){\
45 fprintf(fp, "%s %s %s %s %d %ld %s %d \n",\ 191 fprintf(fp, "%s %s %s %s %d %ld %s %d %lu %lu \n",\
46 thisProgram, otherProgram, thisCore, otherCore, maxJobs,\ 192 thisProgram, otherProgram, thisCore, otherCore, maxJobs,\
47 progTime[jobsComplete], runID, jobsComplete);\ 193 progTime[i], runID, i, mmdc_read[i], mmdc_write[i]);\
48 }\ 194 }\
49 fclose(fp);\ 195 fclose(fp);\
50} 196}
51 197
52// Call the wbinvld instruction (it's in a kernel module due to it being ring-0) 198#if __arm__
53#define FLUSH_CACHES FILE *fp = fopen("/proc/wbinvd", "r");\ 199// On ARM, manually flush the cache
200#define FLUSH_CACHES \
201 volatile uint8_t buffer[L2_SIZE * 4]; \
202 for (uint32_t j = 0; j < 4; j++) \
203 for (uint32_t i = 0; i < L2_SIZE * 4; i += LINE_SIZE) \
204 buffer[i]++;
205#else
206// On x86 call the wbinvld instruction (it's in a kernel module due to it being ring-0)
207#define FLUSH_CACHES \
208 FILE *fp = fopen("/proc/wbinvd", "r");\
54 if (fp == NULL) {\ 209 if (fp == NULL) {\
55 perror("Cache flush module interface cannot be opened");\ 210 perror("Cache flush module interface cannot be opened");\
56 exit(1);\ 211 exit(1);\
@@ -61,40 +216,41 @@
61 exit(1);\ 216 exit(1);\
62 }\ 217 }\
63 fclose(fp); 218 fclose(fp);
219#endif
64 220
65//invoke start timer twice, stop timer to make sure timer and vars are in cache 221#if MMDC_PROF
66//#define START_TIMER clock_gettime(CLOCK_MONOTONIC, &start);\ 222#define START_TIMER \
67 clock_gettime(CLOCK_MONOTONIC, &end);\ 223 /* This disables profiling, resets the counters, clears the overflow bit, and enables profiling */ \
68 clock_gettime(CLOCK_MONOTONIC, &start);\ 224 start_mmdc_profiling(mmdc); \
69 225 /*nanosleep(&(struct timespec){0, ms2ns(999)}, NULL);*/ \
226 clock_gettime(CLOCK_MONOTONIC, &start);
227#else
70#define START_TIMER clock_gettime(CLOCK_MONOTONIC, &start); 228#define START_TIMER clock_gettime(CLOCK_MONOTONIC, &start);
229#endif
71 230
231#if MMDC_PROF
232#define STOP_TIMER \
233 clock_gettime(CLOCK_MONOTONIC, &end); \
234 /* This freezes the profiling and makes results available */ \
235 pause_mmdc_profiling(mmdc); \
236 get_mmdc_profiling_results(mmdc, &mmdc_res);
237#else
72#define STOP_TIMER clock_gettime(CLOCK_MONOTONIC, &end); 238#define STOP_TIMER clock_gettime(CLOCK_MONOTONIC, &end);
73 239#endif
74//waste a millisecond
75
76#define WASTE_TIME clock_gettime(CLOCK_MONOTONIC, &start);\
77do{clock_gettime(CLOCK_MONOTONIC, &end);}\
78while( (end.tv_sec*1000000000+end.tv_nsec)-(start.tv_sec*1000000000+start.tv_nsec) < 1000000);
79
80 240
81#define SLEEP nanosleep((const struct timespec[]){{0, 1000000}}, NULL); 241#define SLEEP nanosleep((const struct timespec[]){{0, 1000000}}, NULL);
82 242
83//#define LOOP_WASTE for(wasteCount=0; wasteCount<1000000; wasteCount++){} 243#if LITMUS
84 244#define START_LOOP \
85//at beginning of loop clear cache, waste some time 245 if (sleep_next_period() != 0) { \
86//wasting time allows interfering process to build up some cache presence 246 perror("Unable to sleep for next period"); \
87//using sleep instead of waste time loop causes problems 247 } \
88//both sleeping and spinning give advantage to threaded task 248 FLUSH_CACHES START_TIMER
89//#define START_LOOP if (output) {KILL_CACHE START_TIMER} 249#else
90
91//#define START_LOOP if (output){START_TIMER}
92
93//#define STOP_LOOP if (output) {STOP_TIMER SAVE_RESULTS}
94//if (!output) {jobsComplete--;}
95
96#define START_LOOP FLUSH_CACHES START_TIMER 250#define START_LOOP FLUSH_CACHES START_TIMER
97#define STOP_LOOP STOP_TIMER SAVE_RESULTS 251#endif
252
253#define STOP_LOOP STOP_TIMER SAVE_RESULTS jobs_complete++;
98 254
99 255
100/* 256/*