diff options
author | Stephen Tang <sytang@cs.unc.edu> | 2017-04-03 20:31:46 -0400 |
---|---|---|
committer | Stephen Tang <sytang@cs.unc.edu> | 2017-04-03 20:31:46 -0400 |
commit | bfee87a910560e022b04c81a026b1f88522cd62f (patch) | |
tree | ce618ffafaf8f89971faa75f71cc17dda6878c9d | |
parent | 1ae58b9a30fbacd3ba5a1a62f40cb669cc51559a (diff) |
Added benchmarks and user tasks
-rw-r--r-- | bin/mode_request.c | 13 | ||||
-rw-r--r-- | bin/rt_compress.c | 283 | ||||
-rw-r--r-- | bin/rt_field.c | 379 | ||||
-rw-r--r-- | bin/rt_field_spin.c | 385 | ||||
-rw-r--r-- | bin/rt_matrix.c | 851 | ||||
-rw-r--r-- | bin/rt_matrix_spin.c | 833 | ||||
-rw-r--r-- | bin/rt_mode_poll.c | 235 | ||||
-rw-r--r-- | bin/rt_neighborhood.c | 381 | ||||
-rw-r--r-- | bin/rt_neighborhood_spin.c | 337 | ||||
-rw-r--r-- | bin/rt_pointer.c | 430 | ||||
-rw-r--r-- | bin/rt_pointer_spin.c | 439 | ||||
-rw-r--r-- | bin/rt_skeleton.c | 247 | ||||
-rw-r--r-- | bin/rt_skeleton_ms.c | 282 | ||||
-rw-r--r-- | bin/rt_skeleton_us.c | 282 | ||||
-rw-r--r-- | bin/rt_transitive.c | 362 | ||||
-rw-r--r-- | bin/rt_update.c | 387 | ||||
-rw-r--r-- | bin/rt_update_spin.c | 398 |
17 files changed, 6524 insertions, 0 deletions
diff --git a/bin/mode_request.c b/bin/mode_request.c new file mode 100644 index 0000000..a0b3226 --- /dev/null +++ b/bin/mode_request.c | |||
@@ -0,0 +1,13 @@ | |||
1 | #include "litmus.h" | ||
2 | |||
3 | #define __NR_request_mode 408 | ||
4 | |||
5 | int main(int argc, char* argv){ | ||
6 | int ret, req_mode; | ||
7 | if (argc < 2){ | ||
8 | return -EINVAL; | ||
9 | } | ||
10 | req_mode = atoi(argv[1]); | ||
11 | ret = syscall(__NR_request_mode, req_mode); | ||
12 | return ret; | ||
13 | } | ||
diff --git a/bin/rt_compress.c b/bin/rt_compress.c new file mode 100644 index 0000000..9647854 --- /dev/null +++ b/bin/rt_compress.c | |||
@@ -0,0 +1,283 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | |||
16 | extern int main_job(void); | ||
17 | static char* progname; | ||
18 | |||
19 | static void usage(char *error) { | ||
20 | fprintf(stderr, "Error: %s\n", error); | ||
21 | fprintf(stderr, | ||
22 | "Usage:\n" | ||
23 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
24 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
25 | " rt_spin -l\n" | ||
26 | "\n" | ||
27 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
28 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
29 | " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]\n" | ||
30 | "\n" | ||
31 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n" | ||
32 | "CRITICAL SECTION LENGTH is in milliseconds.\n"); | ||
33 | exit(EXIT_FAILURE); | ||
34 | } | ||
35 | |||
36 | static int job(double exec_time, double program_end, int lock_od, double cs_length) | ||
37 | { | ||
38 | if (wctime() > program_end) | ||
39 | return 0; | ||
40 | else { | ||
41 | main_job(); | ||
42 | sleep_next_period(); | ||
43 | return 1; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | #define OPTSTR "p:c:wves:q:X:L:Q:vh:m:i:b:" | ||
48 | int main(int argc, char** argv) | ||
49 | { | ||
50 | int ret; | ||
51 | lt_t wcet; | ||
52 | lt_t period; | ||
53 | lt_t hyperperiod; | ||
54 | lt_t budget; | ||
55 | double wcet_ms, period_ms, hyperperiod_ms, budget_ms; | ||
56 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
57 | int migrate = 0; | ||
58 | int cluster = 0; | ||
59 | int opt; | ||
60 | int wait = 0; | ||
61 | int want_enforcement = 0; | ||
62 | double duration = 0, start = 0; | ||
63 | double scale = 1.0; | ||
64 | task_class_t class = RT_CLASS_HARD; | ||
65 | struct rt_task param; | ||
66 | struct mc2_task mc2_param; | ||
67 | struct reservation_config config; | ||
68 | int res_type = PERIODIC_POLLING; | ||
69 | |||
70 | int verbose = 0; | ||
71 | unsigned int job_no; | ||
72 | |||
73 | /* locking */ | ||
74 | int lock_od = -1; | ||
75 | int resource_id = 0; | ||
76 | const char *lock_namespace = "./rtspin-locks"; | ||
77 | int protocol = -1; | ||
78 | double cs_length = 1; /* millisecond */ | ||
79 | |||
80 | progname = argv[0]; | ||
81 | |||
82 | /* default for reservation */ | ||
83 | config.id = 0; | ||
84 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
85 | config.cpu = -1; | ||
86 | |||
87 | mc2_param.crit = CRIT_LEVEL_C; | ||
88 | |||
89 | hyperperiod_ms = 1000; | ||
90 | budget_ms = 10; | ||
91 | |||
92 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
93 | switch (opt) { | ||
94 | case 'w': | ||
95 | wait = 1; | ||
96 | break; | ||
97 | case 'p': | ||
98 | cluster = atoi(optarg); | ||
99 | migrate = 1; | ||
100 | config.cpu = cluster; | ||
101 | break; | ||
102 | case 'q': | ||
103 | priority = atoi(optarg); | ||
104 | if (!litmus_is_valid_fixed_prio(priority)) | ||
105 | usage("Invalid priority."); | ||
106 | break; | ||
107 | case 'c': | ||
108 | class = str2class(optarg); | ||
109 | if (class == -1) | ||
110 | usage("Unknown task class."); | ||
111 | break; | ||
112 | case 'e': | ||
113 | want_enforcement = 1; | ||
114 | break; | ||
115 | case 's': | ||
116 | scale = atof(optarg); | ||
117 | break; | ||
118 | case 'X': | ||
119 | protocol = lock_protocol_for_name(optarg); | ||
120 | if (protocol < 0) | ||
121 | usage("Unknown locking protocol specified."); | ||
122 | break; | ||
123 | case 'L': | ||
124 | cs_length = atof(optarg); | ||
125 | if (cs_length <= 0) | ||
126 | usage("Invalid critical section length."); | ||
127 | break; | ||
128 | case 'Q': | ||
129 | resource_id = atoi(optarg); | ||
130 | if (resource_id <= 0 && strcmp(optarg, "0")) | ||
131 | usage("Invalid resource ID."); | ||
132 | break; | ||
133 | case 'v': | ||
134 | verbose = 1; | ||
135 | break; | ||
136 | case 'm': | ||
137 | mc2_param.crit = atoi(optarg); | ||
138 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
139 | usage("Invalid criticality level."); | ||
140 | } | ||
141 | res_type = PERIODIC_POLLING; | ||
142 | break; | ||
143 | case 'h': | ||
144 | hyperperiod_ms = atof(optarg); | ||
145 | break; | ||
146 | case 'b': | ||
147 | budget_ms = atof(optarg); | ||
148 | break; | ||
149 | case 'i': | ||
150 | config.priority = atoi(optarg); | ||
151 | break; | ||
152 | case ':': | ||
153 | usage("Argument missing."); | ||
154 | break; | ||
155 | case '?': | ||
156 | default: | ||
157 | usage("Bad argument."); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
163 | usage("Bad criticailty level or priority"); | ||
164 | |||
165 | if (argc - optind < 3) | ||
166 | usage("Arguments missing."); | ||
167 | |||
168 | wcet_ms = atof(argv[optind + 0]); | ||
169 | period_ms = atof(argv[optind + 1]); | ||
170 | |||
171 | wcet = ms2ns(wcet_ms); | ||
172 | period = ms2ns(period_ms); | ||
173 | budget = ms2ns(budget_ms); | ||
174 | hyperperiod = ms2ns(hyperperiod_ms); | ||
175 | |||
176 | if (wcet <= 0) | ||
177 | usage("The worst-case execution time must be a " | ||
178 | "positive number."); | ||
179 | if (period <= 0) | ||
180 | usage("The period must be a positive number."); | ||
181 | if (wcet > period) { | ||
182 | usage("The worst-case execution time must not " | ||
183 | "exceed the period."); | ||
184 | } | ||
185 | |||
186 | duration = atof(argv[optind + 2]); | ||
187 | |||
188 | if (migrate) { | ||
189 | ret = be_migrate_to_domain(cluster); | ||
190 | if (ret < 0) | ||
191 | bail_out("could not migrate to target partition or cluster."); | ||
192 | } | ||
193 | |||
194 | /* reservation config */ | ||
195 | config.id = gettid(); | ||
196 | |||
197 | if (hyperperiod%period != 0 ) { | ||
198 | ;//bail_out("hyperperiod must be multiple of period"); | ||
199 | } | ||
200 | |||
201 | config.polling_params.budget = budget; | ||
202 | config.polling_params.period = period; | ||
203 | config.polling_params.offset = 0; | ||
204 | config.polling_params.relative_deadline = 0; | ||
205 | if (config.polling_params.budget > config.polling_params.period) { | ||
206 | usage("The budget must not exceed the period."); | ||
207 | } | ||
208 | |||
209 | /* create a reservation */ | ||
210 | ret = reservation_create(res_type, &config); | ||
211 | if (ret < 0) { | ||
212 | bail_out("failed to create reservation."); | ||
213 | } | ||
214 | |||
215 | init_rt_task_param(¶m); | ||
216 | param.exec_cost = wcet; | ||
217 | param.period = period; | ||
218 | param.priority = priority; | ||
219 | param.cls = class; | ||
220 | param.release_policy = TASK_PERIODIC; | ||
221 | param.budget_policy = (want_enforcement) ? | ||
222 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
223 | if (migrate) { | ||
224 | param.cpu = gettid(); | ||
225 | } | ||
226 | ret = set_rt_task_param(gettid(), ¶m); | ||
227 | |||
228 | if (ret < 0) | ||
229 | bail_out("could not setup rt task params"); | ||
230 | |||
231 | mc2_param.res_id = gettid(); | ||
232 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
233 | //printf("SET_MC2_TASK\n"); | ||
234 | if (ret < 0) | ||
235 | bail_out("could not setup mc2 task params"); | ||
236 | |||
237 | init_litmus(); | ||
238 | //printf("CALL\n"); | ||
239 | //set_page_color(config.cpu); | ||
240 | //printf("CALL\n"); | ||
241 | |||
242 | //printf("INIT_LITMUS\n"); | ||
243 | start = wctime(); | ||
244 | ret = task_mode(LITMUS_RT_TASK); | ||
245 | //printf("TASK_MODE\n"); | ||
246 | if (ret != 0) | ||
247 | bail_out("could not become RT task"); | ||
248 | |||
249 | if (protocol >= 0) { | ||
250 | lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster); | ||
251 | if (lock_od < 0) { | ||
252 | perror("litmus_open_lock"); | ||
253 | usage("Could not open lock."); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | if (wait) { | ||
259 | //printf("BEFORE WAIT\n"); | ||
260 | ret = wait_for_ts_release(); | ||
261 | if (ret != 0) | ||
262 | bail_out("wait_for_ts_release()"); | ||
263 | start = wctime(); | ||
264 | } | ||
265 | |||
266 | do { | ||
267 | if (verbose) { | ||
268 | get_job_no(&job_no); | ||
269 | printf("rtspin/%d:%u @ %.4fms\n", gettid(), | ||
270 | job_no, (wctime() - start) * 1000); | ||
271 | } | ||
272 | } while (job(wcet_ms * 0.001 * scale, start + duration, | ||
273 | lock_od, cs_length * 0.001)); | ||
274 | |||
275 | printf("BEFORE BACK_TASK\n"); | ||
276 | ret = task_mode(BACKGROUND_TASK); | ||
277 | if (ret != 0) | ||
278 | bail_out("could not become regular task (huh?)"); | ||
279 | |||
280 | reservation_destroy(gettid(), config.cpu); | ||
281 | |||
282 | return 0; | ||
283 | } | ||
diff --git a/bin/rt_field.c b/bin/rt_field.c new file mode 100644 index 0000000..ac79020 --- /dev/null +++ b/bin/rt_field.c | |||
@@ -0,0 +1,379 @@ | |||
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 | |||
12 | #include "litmus.h" | ||
13 | #include "common.h" | ||
14 | #include "DISstressmarkRNG.h" | ||
15 | |||
16 | #define MIN_FIELD_SIZE 16 | ||
17 | #define MAX_FIELD_SIZE 16777216 | ||
18 | #define MIN_SEED -2147483647 | ||
19 | #define MAX_SEED -1 | ||
20 | #define MIN_MOD_OFFSET 0 | ||
21 | #define MAX_MOD_OFFSET 65535 | ||
22 | #define MIN_TOKENS 1 | ||
23 | #define MAX_TOKENS 256 | ||
24 | #define MIN_TOKEN_LENGTH 1 | ||
25 | #define MAX_TOKEN_LENGTH 8 | ||
26 | #define MIN_TOKEN_VALUE 0 | ||
27 | #define MAX_TOKEN_VALUE 255 | ||
28 | #define MAX_SUBFIELDS 256 | ||
29 | |||
30 | static char* progname; | ||
31 | int loops = 1; | ||
32 | |||
33 | struct timeval t1, t2; | ||
34 | |||
35 | struct tokenS{ | ||
36 | unsigned char delimiter[MAX_TOKEN_LENGTH]; | ||
37 | unsigned char length; | ||
38 | struct statisticS{ | ||
39 | unsigned int count; | ||
40 | unsigned char min; | ||
41 | unsigned char sum; | ||
42 | } stat[MAX_SUBFIELDS]; | ||
43 | unsigned char subfields; | ||
44 | } token[MAX_TOKENS]; | ||
45 | |||
46 | unsigned char *field; | ||
47 | unsigned int f_max; | ||
48 | int seed; | ||
49 | int mod_offset; | ||
50 | unsigned int n_max; | ||
51 | |||
52 | unsigned char input_token[8] = {0x1, 0x1, 0x22, 0x1, 0xc2, 0x1, 0x2d, 0x0}; | ||
53 | |||
54 | int init_job(){ | ||
55 | //fscanf(stdin, "%d %d %d %d", &f, &seed, &mod_offset, &n); | ||
56 | f_max = 262144; | ||
57 | seed = -2; | ||
58 | n_max = 128; | ||
59 | |||
60 | assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
61 | |||
62 | if ((field = (unsigned char*)malloc(f_max*sizeof(unsigned char))) == NULL) | ||
63 | return (-1); | ||
64 | |||
65 | randInit(seed); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | int main_job() { | ||
71 | unsigned int l, f, n; | ||
72 | |||
73 | /* for online */ | ||
74 | /* f = randInt(65536, f_max); | ||
75 | mod_offset = randInt(128, 8192); | ||
76 | n = 20; //randInt(64, n_max); | ||
77 | */ | ||
78 | |||
79 | /* for case */ | ||
80 | |||
81 | f = randInt(64, 18000); | ||
82 | mod_offset = randInt(128, 8192); | ||
83 | n = 1; //randInt(64, n_max); | ||
84 | |||
85 | |||
86 | assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE)); | ||
87 | assert((mod_offset >= MIN_MOD_OFFSET) && (mod_offset <= MAX_MOD_OFFSET)); | ||
88 | assert((n >= MIN_TOKENS) && (n <= MAX_TOKENS)); | ||
89 | |||
90 | for (l=0; l<n; l++){ | ||
91 | int index; | ||
92 | for (index = 0; index<MAX_TOKEN_LENGTH; index++) { | ||
93 | unsigned char x = input_token[index]; | ||
94 | assert((x >= MIN_TOKEN_VALUE) && (x <= MAX_TOKEN_VALUE)); | ||
95 | token[l].delimiter[index] = (unsigned char )x; | ||
96 | } | ||
97 | token[l].length = index; | ||
98 | } | ||
99 | |||
100 | for (l =0; l<f; l++){ | ||
101 | field[l] = randInt(MIN_TOKEN_VALUE, MAX_TOKEN_VALUE); | ||
102 | } | ||
103 | |||
104 | for (l =0; l<n; l++){ | ||
105 | unsigned int index; | ||
106 | |||
107 | token[l].subfields = 0; | ||
108 | token[l].stat[0].count = 0; | ||
109 | token[l].stat[0].sum = 0; | ||
110 | token[l].stat[0].min = MAX_TOKEN_VALUE; | ||
111 | |||
112 | index = 0; | ||
113 | while ((index < f) && (token[l].subfields < MAX_SUBFIELDS)){ | ||
114 | unsigned char offset; | ||
115 | offset = 0; | ||
116 | while ((field[index+offset] == token[l].delimiter[offset]) && | ||
117 | (offset < token[l].length)){ | ||
118 | offset++; | ||
119 | } | ||
120 | |||
121 | if (offset == token[l].length){ | ||
122 | for (offset=0; offset<token[l].length; offset++){ | ||
123 | field[index+offset] = (field[index+offset] + | ||
124 | field[(index+offset+mod_offset) % f]) | ||
125 | %(MAX_TOKEN_VALUE+1); | ||
126 | } | ||
127 | index += token[l].length-1; | ||
128 | token[l].subfields++; | ||
129 | token[l].stat[token[l].subfields].count = 0; | ||
130 | token[l].stat[token[l].subfields].sum = 0; | ||
131 | token[l].stat[token[l].subfields].min = MAX_TOKEN_VALUE; | ||
132 | } | ||
133 | else { | ||
134 | token[l].stat[token[l].subfields].count++; | ||
135 | token[l].stat[token[l].subfields].sum += field[index]; | ||
136 | if (token[l].stat[token[l].subfields].min > field[index]) | ||
137 | token[l].stat[token[l].subfields].min = field[index]; | ||
138 | } | ||
139 | index++; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | int post_job() { | ||
147 | if (field) { | ||
148 | free(field); | ||
149 | field = NULL; | ||
150 | } | ||
151 | |||
152 | return(0); | ||
153 | } | ||
154 | |||
155 | static void usage(char *error) { | ||
156 | fprintf(stderr, "Error: %s\n", error); | ||
157 | fprintf(stderr, | ||
158 | "Usage:\n" | ||
159 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
160 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
161 | " rt_spin -l\n" | ||
162 | "\n" | ||
163 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
164 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
165 | "\n" | ||
166 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
167 | exit(EXIT_FAILURE); | ||
168 | } | ||
169 | |||
170 | inline unsigned long get_cyclecount (void) | ||
171 | { | ||
172 | unsigned long value; | ||
173 | // Read CCNT Register | ||
174 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
175 | return value; | ||
176 | } | ||
177 | |||
178 | static int job(double exec_time, double program_end) | ||
179 | { | ||
180 | if (wctime() > program_end) | ||
181 | return 0; | ||
182 | else { | ||
183 | register int iter = 0; | ||
184 | //register unsigned long t; | ||
185 | //t = get_cyclecount(); | ||
186 | //gettimeofday(&t1, NULL); | ||
187 | while (iter++ < loops) { | ||
188 | main_job(); | ||
189 | } | ||
190 | //t = get_cyclecount() - t; | ||
191 | //printf("%ld cycles\n", t); | ||
192 | //gettimeofday(&t2, NULL); | ||
193 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
194 | sleep_next_period(); | ||
195 | return 1; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | #define OPTSTR "p:wves:l:m:i:b:" | ||
200 | int main(int argc, char** argv) | ||
201 | { | ||
202 | int ret; | ||
203 | lt_t wcet; | ||
204 | lt_t period; | ||
205 | lt_t budget; | ||
206 | double wcet_ms, period_ms, budget_ms; | ||
207 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
208 | int migrate = 0; | ||
209 | int cluster = 0; | ||
210 | int opt; | ||
211 | int wait = 0; | ||
212 | int want_enforcement = 0; | ||
213 | double duration = 0, start = 0; | ||
214 | double scale = 1.0; | ||
215 | task_class_t class = RT_CLASS_HARD; | ||
216 | struct rt_task param; | ||
217 | struct mc2_task mc2_param; | ||
218 | struct reservation_config config; | ||
219 | int res_type = PERIODIC_POLLING; | ||
220 | |||
221 | progname = argv[0]; | ||
222 | |||
223 | /* default for reservation */ | ||
224 | config.id = 0; | ||
225 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
226 | config.cpu = -1; | ||
227 | |||
228 | mc2_param.crit = CRIT_LEVEL_C; | ||
229 | |||
230 | budget_ms = 10; | ||
231 | |||
232 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
233 | switch (opt) { | ||
234 | case 'w': | ||
235 | wait = 1; | ||
236 | break; | ||
237 | case 'p': | ||
238 | cluster = atoi(optarg); | ||
239 | migrate = 1; | ||
240 | config.cpu = cluster; | ||
241 | break; | ||
242 | case 'e': | ||
243 | want_enforcement = 1; | ||
244 | break; | ||
245 | case 's': | ||
246 | scale = atof(optarg); | ||
247 | break; | ||
248 | case 'l': | ||
249 | loops = atoi(optarg); | ||
250 | break; | ||
251 | case 'm': | ||
252 | mc2_param.crit = atoi(optarg); | ||
253 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
254 | usage("Invalid criticality level."); | ||
255 | } | ||
256 | res_type = PERIODIC_POLLING; | ||
257 | break; | ||
258 | case 'b': | ||
259 | budget_ms = atof(optarg); | ||
260 | break; | ||
261 | case 'i': | ||
262 | config.priority = atoi(optarg); | ||
263 | break; | ||
264 | case ':': | ||
265 | usage("Argument missing."); | ||
266 | break; | ||
267 | case '?': | ||
268 | default: | ||
269 | usage("Bad argument."); | ||
270 | break; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
275 | usage("Bad criticailty level or priority"); | ||
276 | |||
277 | if (argc - optind < 3) | ||
278 | usage("Arguments missing."); | ||
279 | |||
280 | wcet_ms = atof(argv[optind + 0]); | ||
281 | period_ms = atof(argv[optind + 1]); | ||
282 | |||
283 | wcet = ms2ns(wcet_ms); | ||
284 | period = ms2ns(period_ms); | ||
285 | budget = ms2ns(budget_ms); | ||
286 | |||
287 | if (wcet <= 0) | ||
288 | usage("The worst-case execution time must be a " | ||
289 | "positive number."); | ||
290 | if (period <= 0) | ||
291 | usage("The period must be a positive number."); | ||
292 | if (wcet > period) { | ||
293 | usage("The worst-case execution time must not " | ||
294 | "exceed the period."); | ||
295 | } | ||
296 | |||
297 | duration = atof(argv[optind + 2]); | ||
298 | |||
299 | if (migrate) { | ||
300 | ret = be_migrate_to_domain(cluster); | ||
301 | if (ret < 0) | ||
302 | bail_out("could not migrate to target partition or cluster."); | ||
303 | } | ||
304 | |||
305 | /* reservation config */ | ||
306 | config.id = gettid(); | ||
307 | |||
308 | config.polling_params.budget = budget; | ||
309 | config.polling_params.period = period; | ||
310 | config.polling_params.offset = 0; | ||
311 | config.polling_params.relative_deadline = 0; | ||
312 | if (config.polling_params.budget > config.polling_params.period) { | ||
313 | usage("The budget must not exceed the period."); | ||
314 | } | ||
315 | |||
316 | /* create a reservation */ | ||
317 | ret = reservation_create(res_type, &config); | ||
318 | if (ret < 0) { | ||
319 | bail_out("failed to create reservation."); | ||
320 | } | ||
321 | init_job(); | ||
322 | |||
323 | init_rt_task_param(¶m); | ||
324 | param.exec_cost = wcet; | ||
325 | param.period = period; | ||
326 | param.priority = priority; | ||
327 | param.cls = class; | ||
328 | param.release_policy = TASK_PERIODIC; | ||
329 | param.budget_policy = (want_enforcement) ? | ||
330 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
331 | if (migrate) { | ||
332 | param.cpu = gettid(); | ||
333 | } | ||
334 | ret = set_rt_task_param(gettid(), ¶m); | ||
335 | |||
336 | if (ret < 0) | ||
337 | bail_out("could not setup rt task params"); | ||
338 | |||
339 | mc2_param.res_id = gettid(); | ||
340 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
341 | //printf("SET_MC2_TASK\n"); | ||
342 | if (ret < 0) | ||
343 | bail_out("could not setup mc2 task params"); | ||
344 | |||
345 | init_litmus(); | ||
346 | //printf("CALL\n"); | ||
347 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
348 | set_page_color(-1); | ||
349 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
350 | set_page_color(config.cpu); | ||
351 | //printf("CALL\n"); | ||
352 | |||
353 | //printf("INIT_LITMUS\n"); | ||
354 | start = wctime(); | ||
355 | ret = task_mode(LITMUS_RT_TASK); | ||
356 | //printf("TASK_MODE\n"); | ||
357 | if (ret != 0) | ||
358 | bail_out("could not become RT task"); | ||
359 | |||
360 | |||
361 | if (wait) { | ||
362 | //printf("BEFORE WAIT\n"); | ||
363 | ret = wait_for_ts_release(); | ||
364 | if (ret != 0) | ||
365 | bail_out("wait_for_ts_release()"); | ||
366 | start = wctime(); | ||
367 | } | ||
368 | |||
369 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
370 | |||
371 | ret = task_mode(BACKGROUND_TASK); | ||
372 | if (ret != 0) | ||
373 | bail_out("could not become regular task (huh?)"); | ||
374 | |||
375 | reservation_destroy(gettid(), config.cpu); | ||
376 | post_job(); | ||
377 | printf("%s/%d finished.\n",progname, gettid()); | ||
378 | return 0; | ||
379 | } | ||
diff --git a/bin/rt_field_spin.c b/bin/rt_field_spin.c new file mode 100644 index 0000000..06cabd4 --- /dev/null +++ b/bin/rt_field_spin.c | |||
@@ -0,0 +1,385 @@ | |||
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 | |||
12 | #include "litmus.h" | ||
13 | #include "common.h" | ||
14 | #include "DISstressmarkRNG.h" | ||
15 | |||
16 | #define MIN_FIELD_SIZE 16 | ||
17 | #define MAX_FIELD_SIZE 16777216 | ||
18 | #define MIN_SEED -2147483647 | ||
19 | #define MAX_SEED -1 | ||
20 | #define MIN_MOD_OFFSET 0 | ||
21 | #define MAX_MOD_OFFSET 65535 | ||
22 | #define MIN_TOKENS 1 | ||
23 | #define MAX_TOKENS 256 | ||
24 | #define MIN_TOKEN_LENGTH 1 | ||
25 | #define MAX_TOKEN_LENGTH 8 | ||
26 | #define MIN_TOKEN_VALUE 0 | ||
27 | #define MAX_TOKEN_VALUE 255 | ||
28 | #define MAX_SUBFIELDS 256 | ||
29 | |||
30 | static char* progname; | ||
31 | int loops = 1; | ||
32 | |||
33 | struct timeval t1, t2; | ||
34 | |||
35 | struct tokenS{ | ||
36 | unsigned char delimiter[MAX_TOKEN_LENGTH]; | ||
37 | unsigned char length; | ||
38 | struct statisticS{ | ||
39 | unsigned int count; | ||
40 | unsigned char min; | ||
41 | unsigned char sum; | ||
42 | } stat[MAX_SUBFIELDS]; | ||
43 | unsigned char subfields; | ||
44 | } token[MAX_TOKENS]; | ||
45 | |||
46 | unsigned char *field; | ||
47 | unsigned int f_max; | ||
48 | int seed; | ||
49 | int mod_offset; | ||
50 | unsigned int n_max; | ||
51 | |||
52 | unsigned char input_token[8] = {0x1, 0x1, 0x22, 0x1, 0xc2, 0x1, 0x2d, 0x0}; | ||
53 | |||
54 | int init_job(){ | ||
55 | //fscanf(stdin, "%d %d %d %d", &f, &seed, &mod_offset, &n); | ||
56 | f_max = 262144; | ||
57 | seed = -1; | ||
58 | n_max = 1; | ||
59 | |||
60 | assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
61 | |||
62 | if ((field = (unsigned char*)malloc(f_max*sizeof(unsigned char))) == NULL) | ||
63 | return (-1); | ||
64 | |||
65 | randInit(seed); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | int main_job() { | ||
71 | unsigned int l, f, n; | ||
72 | |||
73 | f = randInt(16384, f_max); | ||
74 | mod_offset = randInt(128, 8192); | ||
75 | n = n_max; //randInt(128,n_max); | ||
76 | |||
77 | assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE)); | ||
78 | assert((mod_offset >= MIN_MOD_OFFSET) && (mod_offset <= MAX_MOD_OFFSET)); | ||
79 | assert((n >= MIN_TOKENS) && (n <= MAX_TOKENS)); | ||
80 | |||
81 | for (l=0; l<n; l++){ | ||
82 | int index; | ||
83 | for (index = 0; index<MAX_TOKEN_LENGTH; index++) { | ||
84 | unsigned char x = input_token[index]; | ||
85 | assert((x >= MIN_TOKEN_VALUE) && (x <= MAX_TOKEN_VALUE)); | ||
86 | token[l].delimiter[index] = (unsigned char )x; | ||
87 | } | ||
88 | token[l].length = index; | ||
89 | } | ||
90 | |||
91 | for (l =0; l<f; l++){ | ||
92 | field[l] = randInt(MIN_TOKEN_VALUE, MAX_TOKEN_VALUE); | ||
93 | } | ||
94 | |||
95 | for (l =0; l<n; l++){ | ||
96 | unsigned int index; | ||
97 | |||
98 | token[l].subfields = 0; | ||
99 | token[l].stat[0].count = 0; | ||
100 | token[l].stat[0].sum = 0; | ||
101 | token[l].stat[0].min = MAX_TOKEN_VALUE; | ||
102 | |||
103 | index = 0; | ||
104 | while ((index < f) && (token[l].subfields < MAX_SUBFIELDS)){ | ||
105 | unsigned char offset; | ||
106 | offset = 0; | ||
107 | while ((field[index+offset] == token[l].delimiter[offset]) && | ||
108 | (offset < token[l].length)){ | ||
109 | offset++; | ||
110 | } | ||
111 | |||
112 | if (offset == token[l].length){ | ||
113 | for (offset=0; offset<token[l].length; offset++){ | ||
114 | field[index+offset] = (field[index+offset] + | ||
115 | field[(index+offset+mod_offset) % f]) | ||
116 | %(MAX_TOKEN_VALUE+1); | ||
117 | } | ||
118 | index += token[l].length-1; | ||
119 | token[l].subfields++; | ||
120 | token[l].stat[token[l].subfields].count = 0; | ||
121 | token[l].stat[token[l].subfields].sum = 0; | ||
122 | token[l].stat[token[l].subfields].min = MAX_TOKEN_VALUE; | ||
123 | } | ||
124 | else { | ||
125 | token[l].stat[token[l].subfields].count++; | ||
126 | token[l].stat[token[l].subfields].sum += field[index]; | ||
127 | if (token[l].stat[token[l].subfields].min > field[index]) | ||
128 | token[l].stat[token[l].subfields].min = field[index]; | ||
129 | } | ||
130 | index++; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | int post_job() { | ||
138 | if (field) { | ||
139 | free(field); | ||
140 | field = NULL; | ||
141 | } | ||
142 | |||
143 | return(0); | ||
144 | } | ||
145 | |||
146 | static void usage(char *error) { | ||
147 | fprintf(stderr, "Error: %s\n", error); | ||
148 | fprintf(stderr, | ||
149 | "Usage:\n" | ||
150 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
151 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
152 | " rt_spin -l\n" | ||
153 | "\n" | ||
154 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
155 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
156 | "\n" | ||
157 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
158 | exit(EXIT_FAILURE); | ||
159 | } | ||
160 | |||
161 | inline unsigned long get_cyclecount (void) | ||
162 | { | ||
163 | unsigned long value; | ||
164 | // Read CCNT Register | ||
165 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
166 | return value; | ||
167 | } | ||
168 | |||
169 | static int loop_main(double exec_time, double emergency_exit) | ||
170 | { | ||
171 | double last_loop = 0, loop_start; | ||
172 | int tmp = 0; | ||
173 | |||
174 | double start = cputime(); | ||
175 | double now = cputime(); | ||
176 | |||
177 | while (now + last_loop < start + exec_time) { | ||
178 | loop_start = now; | ||
179 | tmp += main_job(); | ||
180 | now = cputime(); | ||
181 | last_loop = now - loop_start; | ||
182 | if (emergency_exit && wctime() > emergency_exit) { | ||
183 | /* Oops --- this should only be possible if the execution time tracking | ||
184 | * is broken in the LITMUS^RT kernel. */ | ||
185 | fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); | ||
186 | fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | return tmp; | ||
192 | } | ||
193 | |||
194 | static int job(double exec_time, double program_end) | ||
195 | { | ||
196 | if (wctime() > program_end) | ||
197 | return 0; | ||
198 | else { | ||
199 | loop_main(exec_time, program_end + 1); | ||
200 | sleep_next_period(); | ||
201 | return 1; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | #define OPTSTR "p:wves:l:m:i:b:" | ||
206 | int main(int argc, char** argv) | ||
207 | { | ||
208 | int ret; | ||
209 | lt_t wcet; | ||
210 | lt_t period; | ||
211 | lt_t budget; | ||
212 | double wcet_ms, period_ms, budget_ms; | ||
213 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
214 | int migrate = 0; | ||
215 | int cluster = 0; | ||
216 | int opt; | ||
217 | int wait = 0; | ||
218 | int want_enforcement = 0; | ||
219 | double duration = 0, start = 0; | ||
220 | double scale = 1.0; | ||
221 | task_class_t class = RT_CLASS_HARD; | ||
222 | struct rt_task param; | ||
223 | struct mc2_task mc2_param; | ||
224 | struct reservation_config config; | ||
225 | int res_type = PERIODIC_POLLING; | ||
226 | |||
227 | progname = argv[0]; | ||
228 | |||
229 | /* default for reservation */ | ||
230 | config.id = 0; | ||
231 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
232 | config.cpu = -1; | ||
233 | |||
234 | mc2_param.crit = CRIT_LEVEL_C; | ||
235 | |||
236 | budget_ms = 10; | ||
237 | |||
238 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
239 | switch (opt) { | ||
240 | case 'w': | ||
241 | wait = 1; | ||
242 | break; | ||
243 | case 'p': | ||
244 | cluster = atoi(optarg); | ||
245 | migrate = 1; | ||
246 | config.cpu = cluster; | ||
247 | break; | ||
248 | case 'e': | ||
249 | want_enforcement = 1; | ||
250 | break; | ||
251 | case 's': | ||
252 | scale = atof(optarg); | ||
253 | break; | ||
254 | case 'l': | ||
255 | loops = atoi(optarg); | ||
256 | break; | ||
257 | case 'm': | ||
258 | mc2_param.crit = atoi(optarg); | ||
259 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
260 | usage("Invalid criticality level."); | ||
261 | } | ||
262 | res_type = PERIODIC_POLLING; | ||
263 | break; | ||
264 | case 'b': | ||
265 | budget_ms = atof(optarg); | ||
266 | break; | ||
267 | case 'i': | ||
268 | config.priority = atoi(optarg); | ||
269 | break; | ||
270 | case ':': | ||
271 | usage("Argument missing."); | ||
272 | break; | ||
273 | case '?': | ||
274 | default: | ||
275 | usage("Bad argument."); | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
281 | usage("Bad criticailty level or priority"); | ||
282 | |||
283 | if (argc - optind < 3) | ||
284 | usage("Arguments missing."); | ||
285 | |||
286 | wcet_ms = atof(argv[optind + 0]); | ||
287 | period_ms = atof(argv[optind + 1]); | ||
288 | |||
289 | wcet = ms2ns(wcet_ms); | ||
290 | period = ms2ns(period_ms); | ||
291 | budget = ms2ns(budget_ms); | ||
292 | |||
293 | if (wcet <= 0) | ||
294 | usage("The worst-case execution time must be a " | ||
295 | "positive number."); | ||
296 | if (period <= 0) | ||
297 | usage("The period must be a positive number."); | ||
298 | if (wcet > period) { | ||
299 | usage("The worst-case execution time must not " | ||
300 | "exceed the period."); | ||
301 | } | ||
302 | |||
303 | duration = atof(argv[optind + 2]); | ||
304 | |||
305 | if (migrate) { | ||
306 | ret = be_migrate_to_domain(cluster); | ||
307 | if (ret < 0) | ||
308 | bail_out("could not migrate to target partition or cluster."); | ||
309 | } | ||
310 | |||
311 | /* reservation config */ | ||
312 | config.id = gettid(); | ||
313 | |||
314 | config.polling_params.budget = budget; | ||
315 | config.polling_params.period = period; | ||
316 | config.polling_params.offset = 0; | ||
317 | config.polling_params.relative_deadline = 0; | ||
318 | if (config.polling_params.budget > config.polling_params.period) { | ||
319 | usage("The budget must not exceed the period."); | ||
320 | } | ||
321 | |||
322 | /* create a reservation */ | ||
323 | ret = reservation_create(res_type, &config); | ||
324 | if (ret < 0) { | ||
325 | bail_out("failed to create reservation."); | ||
326 | } | ||
327 | init_job(); | ||
328 | |||
329 | init_rt_task_param(¶m); | ||
330 | param.exec_cost = wcet; | ||
331 | param.period = period; | ||
332 | param.priority = priority; | ||
333 | param.cls = class; | ||
334 | param.release_policy = TASK_PERIODIC; | ||
335 | param.budget_policy = (want_enforcement) ? | ||
336 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
337 | if (migrate) { | ||
338 | param.cpu = gettid(); | ||
339 | } | ||
340 | ret = set_rt_task_param(gettid(), ¶m); | ||
341 | |||
342 | if (ret < 0) | ||
343 | bail_out("could not setup rt task params"); | ||
344 | |||
345 | mc2_param.res_id = gettid(); | ||
346 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
347 | //printf("SET_MC2_TASK\n"); | ||
348 | if (ret < 0) | ||
349 | bail_out("could not setup mc2 task params"); | ||
350 | |||
351 | init_litmus(); | ||
352 | //printf("CALL\n"); | ||
353 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
354 | set_page_color(-1); | ||
355 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
356 | set_page_color(config.cpu); | ||
357 | //printf("CALL\n"); | ||
358 | |||
359 | //printf("INIT_LITMUS\n"); | ||
360 | start = wctime(); | ||
361 | ret = task_mode(LITMUS_RT_TASK); | ||
362 | //printf("TASK_MODE\n"); | ||
363 | if (ret != 0) | ||
364 | bail_out("could not become RT task"); | ||
365 | |||
366 | |||
367 | if (wait) { | ||
368 | //printf("BEFORE WAIT\n"); | ||
369 | ret = wait_for_ts_release(); | ||
370 | if (ret != 0) | ||
371 | bail_out("wait_for_ts_release()"); | ||
372 | start = wctime(); | ||
373 | } | ||
374 | |||
375 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
376 | |||
377 | ret = task_mode(BACKGROUND_TASK); | ||
378 | if (ret != 0) | ||
379 | bail_out("could not become regular task (huh?)"); | ||
380 | |||
381 | reservation_destroy(gettid(), config.cpu); | ||
382 | post_job(); | ||
383 | //printf("%s/%d finished.\n",progname, gettid()); | ||
384 | return 0; | ||
385 | } | ||
diff --git a/bin/rt_matrix.c b/bin/rt_matrix.c new file mode 100644 index 0000000..d3fa62c --- /dev/null +++ b/bin/rt_matrix.c | |||
@@ -0,0 +1,851 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | |||
17 | #define MIN_SEED -2147483647 | ||
18 | #define MAX_SEED -1 | ||
19 | #define MIN_DIM 1 | ||
20 | #define MAX_DIM 32768 | ||
21 | #define MAX_ITERATIONS 65536 | ||
22 | #define MIN_TOLERANCE 0.000007 | ||
23 | #define MAX_TOLERANCE 0.5 | ||
24 | #define MIN_NUMBER -3.4e10/dim | ||
25 | #define MAX_NUMBER 3.4e10/dim | ||
26 | #define EPSI 1.0e-10 | ||
27 | #define MIN_DIG_NUMBER 1.0e-10 | ||
28 | #define MAX_DIG_NUMBER 3.4e10 | ||
29 | |||
30 | static char* progname; | ||
31 | int loops = 1; | ||
32 | struct timeval t1, t2; | ||
33 | |||
34 | /* | ||
35 | * External variable, dimension | ||
36 | */ | ||
37 | |||
38 | int max_dim; | ||
39 | double *vectorP, *vectorR, *nextVectorR; | ||
40 | double *matrixA = NULL; | ||
41 | double *vectorB = NULL; | ||
42 | double *vectorX = NULL; | ||
43 | double *value = NULL; | ||
44 | int *col_ind = NULL; | ||
45 | int *row_start = NULL; | ||
46 | double *tmpVector1, *tmpVector2, *tmpVector3; | ||
47 | |||
48 | /* | ||
49 | * matrix * vector | ||
50 | */ | ||
51 | |||
52 | void matrixMulvector(double *value, | ||
53 | int *col_ind, | ||
54 | int *row_start, | ||
55 | double *vector, | ||
56 | double *out, | ||
57 | int dim) | ||
58 | { | ||
59 | int l, ll; | ||
60 | int tmp_rs, tmp_re; | ||
61 | |||
62 | for (l=0; l<dim; l++){ | ||
63 | *(out + l) = 0; | ||
64 | tmp_rs = row_start[l]; | ||
65 | |||
66 | if (tmp_rs != -1){ | ||
67 | tmp_re = row_start[l+1]; /* | ||
68 | *get the start and ending elements of | ||
69 | * each row | ||
70 | */ | ||
71 | for (ll=tmp_rs; ll<tmp_re; ll++){ | ||
72 | *(out + l) += value[ll]*vector[col_ind[ll]]; | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | return; | ||
77 | } | ||
78 | |||
79 | |||
80 | /* | ||
81 | * vector1 - vector2 | ||
82 | */ | ||
83 | |||
84 | void vectorSub(double *vector1, double *vector2, double *vector, int dim){ | ||
85 | |||
86 | int l; | ||
87 | |||
88 | for (l=0; l<dim; l++){ | ||
89 | *(vector + l) = *(vector1 + l) - *(vector2 + l); | ||
90 | } | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | |||
95 | /* | ||
96 | * vector1 + vector2 | ||
97 | */ | ||
98 | |||
99 | void vectorAdd(double *vector1, double *vector2, double *vector, int dim){ | ||
100 | |||
101 | int l; | ||
102 | |||
103 | for (l=0; l<dim; l++){ | ||
104 | *(vector + l) = *(vector1 + l) + *(vector2 + l); | ||
105 | } | ||
106 | return; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * vector1 * vector2 | ||
111 | */ | ||
112 | |||
113 | double vectorMul(double *vector1, double *vector2, int dim){ | ||
114 | |||
115 | int l; | ||
116 | double product; | ||
117 | |||
118 | product = 0; | ||
119 | |||
120 | for (l=0; l<dim; l++){ | ||
121 | product += (*(vector1 + l))*(*(vector2 + l)); | ||
122 | |||
123 | } | ||
124 | return product; | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * /vector/ | ||
129 | */ | ||
130 | |||
131 | double vectorValue(double *vector, int dim){ | ||
132 | |||
133 | double value; | ||
134 | int l; | ||
135 | |||
136 | value = 0; | ||
137 | |||
138 | for (l=0; l<dim; l++){ | ||
139 | value += (*(vector + l)) * (*(vector + l)); | ||
140 | } | ||
141 | |||
142 | return (sqrt(value)); | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * transpose(vector) | ||
147 | * In fact, we return the original vector here | ||
148 | */ | ||
149 | |||
150 | void transpose(double *vector, double *vect){ | ||
151 | |||
152 | int l; | ||
153 | |||
154 | for (l=0; l<max_dim; l++){ | ||
155 | *(vect+l) = *(vector+l); | ||
156 | } | ||
157 | return; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * value * <vector> | ||
162 | */ | ||
163 | void valueMulvector(double value, double *vector, double *vect){ | ||
164 | |||
165 | int l; | ||
166 | |||
167 | for (l=0; l<max_dim; l++){ | ||
168 | *(vect + l) = *(vector + l) * value; | ||
169 | } | ||
170 | return; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * generate the data distributed sparsely in matrix | ||
175 | */ | ||
176 | |||
177 | void initMatrix(double *matrix, int dim, int numberNonzero){ | ||
178 | |||
179 | int k, l, ll; | ||
180 | int i, j; | ||
181 | |||
182 | int lll; | ||
183 | double sum; | ||
184 | |||
185 | for (k=0; k< dim*dim; k++){ | ||
186 | *(matrix + k) = 0; | ||
187 | } | ||
188 | |||
189 | for (l=0; l<numberNonzero/2; l++){ | ||
190 | |||
191 | i = randomUInt(1, dim-1); | ||
192 | j = randomUInt(0, i-1); | ||
193 | |||
194 | while (*(matrix + i*dim + j) != 0){ | ||
195 | |||
196 | i++; | ||
197 | if (i == dim){ | ||
198 | j++; | ||
199 | if (j == dim-1){ | ||
200 | j = 0; | ||
201 | i = 1; | ||
202 | } | ||
203 | else{ | ||
204 | i = j+1; | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | |||
209 | if (*(matrix + i*dim + j) == 0){ | ||
210 | *(matrix + i*dim + j) = (double )randomNonZeroFloat(MIN_NUMBER, | ||
211 | MAX_NUMBER, | ||
212 | EPSI); | ||
213 | *(matrix + j*dim + i) = *(matrix + i*dim + j); | ||
214 | } | ||
215 | } | ||
216 | |||
217 | for (ll=0; ll<dim; ll++){ | ||
218 | |||
219 | |||
220 | |||
221 | *(matrix + ll*dim + ll) = (double )randomNonZeroFloat(-MAX_DIG_NUMBER, | ||
222 | MAX_DIG_NUMBER, | ||
223 | MIN_DIG_NUMBER); | ||
224 | |||
225 | sum = 0; | ||
226 | |||
227 | for (lll=0; lll<dim; lll++){ | ||
228 | if (lll != ll){ | ||
229 | sum += *(matrix + lll*dim + ll); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | if (*(matrix + ll*dim + ll) < sum ){ | ||
234 | *(matrix + ll*dim + ll) += sum; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | return; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * generate the data value in the vectors | ||
243 | */ | ||
244 | |||
245 | void initVector(double *vector, int dim){ | ||
246 | |||
247 | int l; | ||
248 | |||
249 | for (l=0; l<dim; l++){ | ||
250 | *(vector + l) = (double )randomFloat (MIN_NUMBER, MAX_NUMBER); | ||
251 | } | ||
252 | |||
253 | return; | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * make a vector contains value of zero | ||
258 | */ | ||
259 | |||
260 | void zeroVector(double *vector, int dim){ | ||
261 | int l; | ||
262 | |||
263 | for (l=0; l<dim; l++){ | ||
264 | *(vector + l) = 0; | ||
265 | } | ||
266 | return; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * return a vector which is the copy of the vect | ||
271 | */ | ||
272 | |||
273 | void equalVector(double *vect, double *vect1){ | ||
274 | |||
275 | int l; | ||
276 | |||
277 | for (l=0; l<max_dim; l++){ | ||
278 | *(vect1+l) = *(vect+l); | ||
279 | } | ||
280 | return; | ||
281 | } | ||
282 | |||
283 | |||
284 | |||
285 | void biConjugateGradient(double *value, | ||
286 | int *col_ind, | ||
287 | int *row_start, | ||
288 | double *vectorB, | ||
289 | double *vectorX, | ||
290 | double errorTolerance, | ||
291 | int maxIterations, | ||
292 | double *actualError, | ||
293 | int *actualIteration, | ||
294 | int dim) | ||
295 | /* | ||
296 | * in the code, we use a lot of temparary vectors and variables | ||
297 | * this is just for simple and clear | ||
298 | * you can optimize these temporary variables and vectors | ||
299 | * based on your need | ||
300 | * | ||
301 | */ | ||
302 | { | ||
303 | double error; | ||
304 | int iteration; | ||
305 | double alpha, beta; | ||
306 | |||
307 | double tmpValue1, tmpValue2; | ||
308 | int l; | ||
309 | int ll; | ||
310 | |||
311 | alpha = 0; | ||
312 | beta = 0; | ||
313 | |||
314 | /* | ||
315 | * vectorR = vectorB - matrixA*vectorX | ||
316 | */ | ||
317 | matrixMulvector(value,col_ind, row_start, vectorX, tmpVector1, dim); | ||
318 | |||
319 | vectorSub(vectorB, tmpVector1, vectorR, dim); | ||
320 | |||
321 | /* | ||
322 | * vectorP = vectorR | ||
323 | */ | ||
324 | |||
325 | equalVector(vectorR, vectorP); | ||
326 | |||
327 | /* | ||
328 | * error = |matrixA * vectorX - vectorB| / |vectorB| | ||
329 | */ | ||
330 | vectorSub(tmpVector1, vectorB, tmpVector1, dim); | ||
331 | |||
332 | error = vectorValue(tmpVector1,dim)/vectorValue(vectorB,dim); | ||
333 | |||
334 | iteration = 0; | ||
335 | |||
336 | while ((iteration < maxIterations) && (error > errorTolerance)){ | ||
337 | |||
338 | /* | ||
339 | * alpha = (transpose(vectorR) * vectorR) / | ||
340 | * (transpose(vectorP) * (matrixA * vectorP) | ||
341 | */ | ||
342 | |||
343 | matrixMulvector(value, col_ind, row_start, vectorP, tmpVector1, dim); | ||
344 | transpose(vectorR, tmpVector2); | ||
345 | transpose(vectorP, tmpVector3); | ||
346 | tmpValue1 = vectorMul(tmpVector3, tmpVector1, dim); | ||
347 | tmpValue2 = vectorMul(tmpVector2, vectorR, dim); | ||
348 | alpha = tmpValue2/tmpValue1; | ||
349 | |||
350 | /* | ||
351 | * nextVectorR = vectorR - alpha*(matrixA * vectorP) | ||
352 | */ | ||
353 | |||
354 | valueMulvector(alpha, tmpVector1, tmpVector2); | ||
355 | vectorSub(vectorR, tmpVector2, tmpVector1, dim); | ||
356 | equalVector(tmpVector1, nextVectorR); | ||
357 | |||
358 | /* | ||
359 | * beta = (transpose(nextVectorR) * nextVectorR) / | ||
360 | * (transpose(vectorR) * vectorR) | ||
361 | */ | ||
362 | |||
363 | transpose(nextVectorR, tmpVector3); | ||
364 | tmpValue1 = vectorMul(tmpVector3, nextVectorR, dim); | ||
365 | transpose(vectorR, tmpVector2); | ||
366 | tmpValue2 = vectorMul(tmpVector2, vectorR, dim); | ||
367 | beta = tmpValue1/tmpValue2; | ||
368 | |||
369 | /* | ||
370 | * vectorX = vectorX + alpha * vectorP | ||
371 | */ | ||
372 | valueMulvector(alpha, vectorP, tmpVector1); | ||
373 | vectorAdd(vectorX,tmpVector1, vectorX, dim); | ||
374 | |||
375 | /* | ||
376 | *vectorP = nextVectorR + beta*vectorP | ||
377 | */ | ||
378 | valueMulvector(beta, vectorP, tmpVector1); | ||
379 | vectorAdd(nextVectorR, tmpVector1, tmpVector1, dim); | ||
380 | |||
381 | for (ll=0; ll<dim; ll++){ | ||
382 | *(vectorP + ll) = *(tmpVector1 + ll); | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * vectorR = nextVectorR | ||
387 | */ | ||
388 | |||
389 | for (l=0; l<dim; l++){ | ||
390 | *(vectorR+l) = *(nextVectorR+l); | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * error = |matrixA * vectorX - vectorB| / |vectorB| | ||
395 | */ | ||
396 | matrixMulvector(value, col_ind,row_start, vectorX, tmpVector1, dim); | ||
397 | vectorSub(tmpVector1,vectorB,tmpVector1,dim); | ||
398 | error = vectorValue(tmpVector1,dim)/vectorValue(vectorB,dim); | ||
399 | |||
400 | iteration++; | ||
401 | } | ||
402 | |||
403 | *actualError = error; | ||
404 | *actualIteration = iteration; | ||
405 | |||
406 | |||
407 | return; | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * This is the function to transfer the data from the matrix of dense storage | ||
412 | * to Compact Row Storage | ||
413 | */ | ||
414 | void create_CRS(double *matrixA, | ||
415 | double *value, | ||
416 | int *col_ind, | ||
417 | int *row_start, | ||
418 | int dim, | ||
419 | int numberNonzero) | ||
420 | { | ||
421 | |||
422 | int i, j, k; | ||
423 | int cnt; | ||
424 | double tmp; | ||
425 | |||
426 | /* | ||
427 | *initialize the row_start | ||
428 | */ | ||
429 | |||
430 | for(k=0; k<dim; k++){ | ||
431 | row_start[k] = -1; | ||
432 | } | ||
433 | |||
434 | /* | ||
435 | * make the end of the last row to be numberNonzero + dim. | ||
436 | */ | ||
437 | |||
438 | row_start[dim] = numberNonzero+dim; | ||
439 | |||
440 | /* | ||
441 | * initialize the col_ind | ||
442 | */ | ||
443 | |||
444 | for (k=0; k<numberNonzero+dim; k++){ | ||
445 | col_ind[k] = -1; | ||
446 | } | ||
447 | |||
448 | |||
449 | cnt = 0; | ||
450 | |||
451 | for (i=0; (cnt<numberNonzero+dim)&&(i<dim); i++){ | ||
452 | for (j=0; (cnt<numberNonzero+dim)&&(j<dim); j++){ | ||
453 | |||
454 | tmp = *(matrixA + i*dim + j); | ||
455 | |||
456 | if (tmp!=0){ | ||
457 | |||
458 | value[cnt] = tmp; | ||
459 | col_ind[cnt] = j; | ||
460 | |||
461 | if (row_start[i] == -1) | ||
462 | row_start[i] = cnt; | ||
463 | |||
464 | cnt += 1; | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | row_start[i] = cnt; | ||
469 | |||
470 | return; | ||
471 | } | ||
472 | |||
473 | int seed; | ||
474 | int max_numberNonzero; | ||
475 | int maxIterations; | ||
476 | float errorTolerance; | ||
477 | int k; | ||
478 | |||
479 | //fscanf(stdin, "%d %d %d %d %f", | ||
480 | // &seed, &dim, &numberNonzero,&maxIterations,&errorTolerance); | ||
481 | int init_job() { | ||
482 | //seed = -2; | ||
483 | //randInit(seed); | ||
484 | |||
485 | max_dim = 300; | ||
486 | //max_dim = 100; | ||
487 | max_numberNonzero = max_dim*max_dim/2+1; | ||
488 | |||
489 | //maxIterations = 65535; | ||
490 | |||
491 | //dim = randInt(100, 500); | ||
492 | //numberNonzero = randInt(dim+1, dim*dim/2); | ||
493 | //maxIterations = randInt(10240, 32768); | ||
494 | |||
495 | errorTolerance = 0.02734; | ||
496 | |||
497 | //printf("%d %d %d\n",dim,numberNonzero,maxIterations); | ||
498 | //assert((seed > MIN_SEED) && (seed < MAX_SEED)); | ||
499 | assert((max_dim > MIN_DIM) && (max_dim < MAX_DIM)); | ||
500 | assert((max_numberNonzero > max_dim) && (max_numberNonzero < max_dim*max_dim)); | ||
501 | //assert((maxIterations > 0) && (maxIterations < MAX_ITERATIONS)); | ||
502 | assert((errorTolerance > MIN_TOLERANCE) && (errorTolerance < MAX_TOLERANCE)); | ||
503 | |||
504 | matrixA = (double *)malloc(max_dim*max_dim*sizeof(double )); | ||
505 | vectorB = (double *)malloc(max_dim*sizeof(double)); | ||
506 | vectorX = (double *)malloc(max_dim*sizeof(double)); | ||
507 | |||
508 | value = (double *)malloc((max_numberNonzero+max_dim)*sizeof(double)); | ||
509 | col_ind = (int *)malloc((max_numberNonzero+max_dim)*sizeof(int)); | ||
510 | row_start = (int *)malloc((max_dim+1)*sizeof(int)); | ||
511 | |||
512 | |||
513 | //initMatrix(matrixA, dim, numberNonzero); | ||
514 | |||
515 | //create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero); | ||
516 | |||
517 | //initVector(vectorB, dim); | ||
518 | //zeroVector(vectorX, dim); | ||
519 | |||
520 | vectorP = (double *)malloc(max_dim*sizeof(double)); | ||
521 | vectorR = (double *)malloc(max_dim*sizeof(double)); | ||
522 | nextVectorR = (double *)malloc(max_dim*sizeof(double)); | ||
523 | |||
524 | tmpVector1 = (double *)malloc(max_dim*sizeof(double)); | ||
525 | tmpVector2 = (double *)malloc(max_dim*sizeof(double)); | ||
526 | tmpVector3 = (double *)malloc(max_dim*sizeof(double)); | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | int main_job() { | ||
532 | int sum, dim, numberNonzero; | ||
533 | double actualError; | ||
534 | int actualIteration; | ||
535 | |||
536 | /* for online */ | ||
537 | /* dim = randInt(100, max_dim); | ||
538 | numberNonzero = randInt(dim+1, dim*dim/2); | ||
539 | maxIterations = randInt(1024, 8192); | ||
540 | */ | ||
541 | |||
542 | /* for case */ | ||
543 | dim = randInt(4, 50); | ||
544 | numberNonzero = randInt(dim+1, dim*dim/2); | ||
545 | maxIterations = randInt(1, 10); //randInt(32, 512); | ||
546 | |||
547 | |||
548 | initMatrix(matrixA, dim, numberNonzero); | ||
549 | create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero); | ||
550 | |||
551 | initVector(vectorB, dim); | ||
552 | zeroVector(vectorX, dim); | ||
553 | |||
554 | actualError = 0; | ||
555 | actualIteration = 0; | ||
556 | |||
557 | biConjugateGradient(value, col_ind, row_start, vectorB, vectorX, errorTolerance, | ||
558 | maxIterations, | ||
559 | &actualError, &actualIteration, dim); | ||
560 | |||
561 | sum = 0; | ||
562 | for (k=1; k<dim; k++){ | ||
563 | sum += sum + *(vectorX + k); | ||
564 | } | ||
565 | |||
566 | //fprintf(stdout, "sum = %d, actualError = %e, actualIteration = %d\n", sum, actualError, actualIteration); | ||
567 | //fprintf(stdout, "total time = %u sec. \n", (unsigned int)endTime); | ||
568 | |||
569 | return(0); | ||
570 | } | ||
571 | |||
572 | int post_job() { | ||
573 | if (matrixA) { | ||
574 | free(matrixA); | ||
575 | matrixA = NULL; | ||
576 | } | ||
577 | if (vectorB) { | ||
578 | free(vectorB); | ||
579 | vectorB = NULL; | ||
580 | } | ||
581 | if (vectorX) { | ||
582 | free(vectorX); | ||
583 | vectorX = NULL; | ||
584 | } | ||
585 | if (value) { | ||
586 | free(value); | ||
587 | value = NULL; | ||
588 | } | ||
589 | if (col_ind) { | ||
590 | free(col_ind); | ||
591 | col_ind = NULL; | ||
592 | } | ||
593 | if (row_start) { | ||
594 | free(row_start); | ||
595 | row_start = NULL; | ||
596 | } | ||
597 | if (vectorP) { | ||
598 | free(vectorP); | ||
599 | vectorP = NULL; | ||
600 | } | ||
601 | if (vectorR) { | ||
602 | free(vectorR); | ||
603 | vectorR = NULL; | ||
604 | } | ||
605 | if (nextVectorR) { | ||
606 | free(nextVectorR); | ||
607 | nextVectorR = NULL; | ||
608 | } | ||
609 | if (tmpVector1) { | ||
610 | free(tmpVector1); | ||
611 | tmpVector1 = NULL; | ||
612 | } | ||
613 | if (tmpVector2) { | ||
614 | free(tmpVector2); | ||
615 | tmpVector2 = NULL; | ||
616 | } | ||
617 | if (tmpVector3) { | ||
618 | free(tmpVector3); | ||
619 | tmpVector3 = NULL; | ||
620 | } | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static void usage(char *error) { | ||
626 | fprintf(stderr, "Error: %s\n", error); | ||
627 | fprintf(stderr, | ||
628 | "Usage:\n" | ||
629 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
630 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
631 | " rt_spin -l\n" | ||
632 | "\n" | ||
633 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
634 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
635 | "\n" | ||
636 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
637 | exit(EXIT_FAILURE); | ||
638 | } | ||
639 | |||
640 | inline unsigned long get_cyclecount (void) | ||
641 | { | ||
642 | unsigned long value; | ||
643 | // Read CCNT Register | ||
644 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
645 | return value; | ||
646 | } | ||
647 | |||
648 | static int job(double exec_time, double program_end) | ||
649 | { | ||
650 | if (wctime() > program_end) | ||
651 | return 0; | ||
652 | else { | ||
653 | //register int iter = 0; | ||
654 | //register unsigned long t; | ||
655 | //t = get_cyclecount(); | ||
656 | //gettimeofday(&t1, NULL); | ||
657 | //while (iter++ < loops) { | ||
658 | main_job(); | ||
659 | //} | ||
660 | //t = get_cyclecount() - t; | ||
661 | //printf("%ld cycles\n", t); | ||
662 | //gettimeofday(&t2, NULL); | ||
663 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
664 | sleep_next_period(); | ||
665 | return 1; | ||
666 | } | ||
667 | } | ||
668 | |||
669 | #define OPTSTR "p:wves:l:m:i:b:" | ||
670 | int main(int argc, char** argv) | ||
671 | { | ||
672 | int ret; | ||
673 | lt_t wcet; | ||
674 | lt_t period; | ||
675 | lt_t budget; | ||
676 | double wcet_ms, period_ms, budget_ms; | ||
677 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
678 | int migrate = 0; | ||
679 | int cluster = 0; | ||
680 | int opt; | ||
681 | int wait = 0; | ||
682 | int want_enforcement = 0; | ||
683 | double duration = 0, start = 0; | ||
684 | double scale = 1.0; | ||
685 | task_class_t class = RT_CLASS_HARD; | ||
686 | struct rt_task param; | ||
687 | struct mc2_task mc2_param; | ||
688 | struct reservation_config config; | ||
689 | int res_type = PERIODIC_POLLING; | ||
690 | |||
691 | progname = argv[0]; | ||
692 | |||
693 | /* default for reservation */ | ||
694 | config.id = 0; | ||
695 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
696 | config.cpu = -1; | ||
697 | |||
698 | mc2_param.crit = CRIT_LEVEL_C; | ||
699 | |||
700 | budget_ms = 10; | ||
701 | |||
702 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
703 | switch (opt) { | ||
704 | case 'w': | ||
705 | wait = 1; | ||
706 | break; | ||
707 | case 'p': | ||
708 | cluster = atoi(optarg); | ||
709 | migrate = 1; | ||
710 | config.cpu = cluster; | ||
711 | break; | ||
712 | case 'e': | ||
713 | want_enforcement = 1; | ||
714 | break; | ||
715 | case 's': | ||
716 | scale = atof(optarg); | ||
717 | break; | ||
718 | case 'l': | ||
719 | loops = atoi(optarg); | ||
720 | break; | ||
721 | case 'm': | ||
722 | mc2_param.crit = atoi(optarg); | ||
723 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
724 | usage("Invalid criticality level."); | ||
725 | } | ||
726 | res_type = PERIODIC_POLLING; | ||
727 | break; | ||
728 | case 'b': | ||
729 | budget_ms = atof(optarg); | ||
730 | break; | ||
731 | case 'i': | ||
732 | config.priority = atoi(optarg); | ||
733 | break; | ||
734 | case ':': | ||
735 | usage("Argument missing."); | ||
736 | break; | ||
737 | case '?': | ||
738 | default: | ||
739 | usage("Bad argument."); | ||
740 | break; | ||
741 | } | ||
742 | } | ||
743 | |||
744 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
745 | usage("Bad criticailty level or priority"); | ||
746 | |||
747 | if (argc - optind < 3) | ||
748 | usage("Arguments missing."); | ||
749 | |||
750 | wcet_ms = atof(argv[optind + 0]); | ||
751 | period_ms = atof(argv[optind + 1]); | ||
752 | |||
753 | wcet = ms2ns(wcet_ms); | ||
754 | period = ms2ns(period_ms); | ||
755 | budget = ms2ns(budget_ms); | ||
756 | |||
757 | if (wcet <= 0) | ||
758 | usage("The worst-case execution time must be a " | ||
759 | "positive number."); | ||
760 | if (period <= 0) | ||
761 | usage("The period must be a positive number."); | ||
762 | if (wcet > period) { | ||
763 | usage("The worst-case execution time must not " | ||
764 | "exceed the period."); | ||
765 | } | ||
766 | |||
767 | duration = atof(argv[optind + 2]); | ||
768 | |||
769 | if (migrate) { | ||
770 | ret = be_migrate_to_domain(cluster); | ||
771 | if (ret < 0) | ||
772 | bail_out("could not migrate to target partition or cluster."); | ||
773 | } | ||
774 | |||
775 | /* reservation config */ | ||
776 | config.id = gettid(); | ||
777 | |||
778 | config.polling_params.budget = budget; | ||
779 | config.polling_params.period = period; | ||
780 | config.polling_params.offset = 0; | ||
781 | config.polling_params.relative_deadline = 0; | ||
782 | if (config.polling_params.budget > config.polling_params.period) { | ||
783 | usage("The budget must not exceed the period."); | ||
784 | } | ||
785 | |||
786 | /* create a reservation */ | ||
787 | ret = reservation_create(res_type, &config); | ||
788 | if (ret < 0) { | ||
789 | bail_out("failed to create reservation."); | ||
790 | } | ||
791 | //srand (time(NULL)); | ||
792 | |||
793 | seed = -2; | ||
794 | randInit(seed); | ||
795 | |||
796 | init_job(); | ||
797 | |||
798 | init_rt_task_param(¶m); | ||
799 | param.exec_cost = wcet; | ||
800 | param.period = period; | ||
801 | param.priority = priority; | ||
802 | param.cls = class; | ||
803 | param.release_policy = TASK_PERIODIC; | ||
804 | param.budget_policy = (want_enforcement) ? | ||
805 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
806 | if (migrate) { | ||
807 | param.cpu = gettid(); | ||
808 | } | ||
809 | ret = set_rt_task_param(gettid(), ¶m); | ||
810 | |||
811 | if (ret < 0) | ||
812 | bail_out("could not setup rt task params"); | ||
813 | |||
814 | mc2_param.res_id = gettid(); | ||
815 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
816 | |||
817 | if (ret < 0) | ||
818 | bail_out("could not setup mc2 task params"); | ||
819 | |||
820 | init_litmus(); | ||
821 | |||
822 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
823 | set_page_color(-1); | ||
824 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
825 | set_page_color(config.cpu); | ||
826 | |||
827 | start = wctime(); | ||
828 | ret = task_mode(LITMUS_RT_TASK); | ||
829 | |||
830 | if (ret != 0) | ||
831 | bail_out("could not become RT task"); | ||
832 | |||
833 | |||
834 | if (wait) { | ||
835 | ret = wait_for_ts_release(); | ||
836 | if (ret != 0) | ||
837 | bail_out("wait_for_ts_release()"); | ||
838 | start = wctime(); | ||
839 | } | ||
840 | |||
841 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
842 | |||
843 | ret = task_mode(BACKGROUND_TASK); | ||
844 | if (ret != 0) | ||
845 | bail_out("could not become regular task (huh?)"); | ||
846 | |||
847 | reservation_destroy(gettid(), config.cpu); | ||
848 | post_job(); | ||
849 | printf("%s/%d finished.\n",progname, gettid()); | ||
850 | return 0; | ||
851 | } | ||
diff --git a/bin/rt_matrix_spin.c b/bin/rt_matrix_spin.c new file mode 100644 index 0000000..142576c --- /dev/null +++ b/bin/rt_matrix_spin.c | |||
@@ -0,0 +1,833 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | |||
17 | #define MIN_SEED -2147483647 | ||
18 | #define MAX_SEED -1 | ||
19 | #define MIN_DIM 1 | ||
20 | #define MAX_DIM 32768 | ||
21 | #define MAX_ITERATIONS 65536 | ||
22 | #define MIN_TOLERANCE 0.000007 | ||
23 | #define MAX_TOLERANCE 0.5 | ||
24 | #define MIN_NUMBER -3.4e10/dim | ||
25 | #define MAX_NUMBER 3.4e10/dim | ||
26 | #define EPSI 1.0e-10 | ||
27 | #define MIN_DIG_NUMBER 1.0e-10 | ||
28 | #define MAX_DIG_NUMBER 3.4e10 | ||
29 | |||
30 | static char* progname; | ||
31 | int loops = 1; | ||
32 | //struct timeval t1, t2; | ||
33 | |||
34 | /* | ||
35 | * External variable, dimension | ||
36 | */ | ||
37 | |||
38 | static int dim; | ||
39 | |||
40 | /* | ||
41 | * matrix * vector | ||
42 | */ | ||
43 | |||
44 | void matrixMulvector(double *value, | ||
45 | int *col_ind, | ||
46 | int *row_start, | ||
47 | double *vector, | ||
48 | double *out) | ||
49 | { | ||
50 | int l, ll; | ||
51 | double sum; | ||
52 | int tmp_rs, tmp_re; | ||
53 | |||
54 | for (l=0; l<dim; l++){ | ||
55 | *(out + l) = 0; | ||
56 | tmp_rs = row_start[l]; | ||
57 | |||
58 | if (tmp_rs != -1){ | ||
59 | tmp_re = row_start[l+1]; /* | ||
60 | *get the start and ending elements of | ||
61 | * each row | ||
62 | */ | ||
63 | for (ll=tmp_rs; ll<tmp_re; ll++){ | ||
64 | *(out + l) += value[ll]*vector[col_ind[ll]]; | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | return; | ||
69 | } | ||
70 | |||
71 | |||
72 | /* | ||
73 | * vector1 - vector2 | ||
74 | */ | ||
75 | |||
76 | void vectorSub(double *vector1, double *vector2, double *vector){ | ||
77 | |||
78 | int l; | ||
79 | |||
80 | for (l=0; l<dim; l++){ | ||
81 | *(vector + l) = *(vector1 + l) - *(vector2 + l); | ||
82 | } | ||
83 | return; | ||
84 | } | ||
85 | |||
86 | |||
87 | /* | ||
88 | * vector1 + vector2 | ||
89 | */ | ||
90 | |||
91 | void vectorAdd(double *vector1, double *vector2, double *vector){ | ||
92 | |||
93 | int l; | ||
94 | |||
95 | for (l=0; l<dim; l++){ | ||
96 | *(vector + l) = *(vector1 + l) + *(vector2 + l); | ||
97 | } | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * vector1 * vector2 | ||
103 | */ | ||
104 | |||
105 | double vectorMul(double *vector1, double *vector2){ | ||
106 | |||
107 | int l; | ||
108 | double product; | ||
109 | |||
110 | product = 0; | ||
111 | |||
112 | for (l=0; l<dim; l++){ | ||
113 | product += (*(vector1 + l))*(*(vector2 + l)); | ||
114 | |||
115 | } | ||
116 | return product; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * /vector/ | ||
121 | */ | ||
122 | |||
123 | double vectorValue(double *vector){ | ||
124 | |||
125 | double value; | ||
126 | int l; | ||
127 | |||
128 | value = 0; | ||
129 | |||
130 | for (l=0; l<dim; l++){ | ||
131 | value += (*(vector + l)) * (*(vector + l)); | ||
132 | } | ||
133 | |||
134 | return (sqrt(value)); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * transpose(vector) | ||
139 | * In fact, we return the original vector here | ||
140 | */ | ||
141 | |||
142 | void transpose(double *vector, double *vect){ | ||
143 | |||
144 | int l; | ||
145 | |||
146 | for (l=0; l<dim; l++){ | ||
147 | *(vect+l) = *(vector+l); | ||
148 | } | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * value * <vector> | ||
154 | */ | ||
155 | void valueMulvector(double value, double *vector, double *vect){ | ||
156 | |||
157 | int l; | ||
158 | int lll, i; | ||
159 | double tmp; | ||
160 | |||
161 | for (l=0; l<dim; l++){ | ||
162 | *(vect + l) = *(vector + l) * value; | ||
163 | } | ||
164 | return; | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * generate the data distributed sparsely in matrix | ||
169 | */ | ||
170 | |||
171 | void initMatrix(double *matrix, int dim, int numberNonzero){ | ||
172 | |||
173 | int k, l, ll; | ||
174 | int i, j; | ||
175 | |||
176 | int lll; | ||
177 | double sum; | ||
178 | |||
179 | for (k=0; k< dim*dim; k++){ | ||
180 | *(matrix + k) = 0; | ||
181 | } | ||
182 | |||
183 | for (l=0; l<numberNonzero/2; l++){ | ||
184 | |||
185 | i = randomUInt(1, dim-1); | ||
186 | j = randomUInt(0, i-1); | ||
187 | |||
188 | while (*(matrix + i*dim + j) != 0){ | ||
189 | |||
190 | i++; | ||
191 | if (i == dim){ | ||
192 | j++; | ||
193 | if (j == dim-1){ | ||
194 | j = 0; | ||
195 | i = 1; | ||
196 | } | ||
197 | else{ | ||
198 | i = j+1; | ||
199 | } | ||
200 | } | ||
201 | } | ||
202 | |||
203 | if (*(matrix + i*dim + j) == 0){ | ||
204 | *(matrix + i*dim + j) = (double )randomNonZeroFloat(MIN_NUMBER, | ||
205 | MAX_NUMBER, | ||
206 | EPSI); | ||
207 | *(matrix + j*dim + i) = *(matrix + i*dim + j); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | for (ll=0; ll<dim; ll++){ | ||
212 | |||
213 | |||
214 | |||
215 | *(matrix + ll*dim + ll) = (double )randomNonZeroFloat(-MAX_DIG_NUMBER, | ||
216 | MAX_DIG_NUMBER, | ||
217 | MIN_DIG_NUMBER); | ||
218 | |||
219 | sum = 0; | ||
220 | |||
221 | for (lll=0; lll<dim; lll++){ | ||
222 | if (lll != ll){ | ||
223 | sum += *(matrix + lll*dim + ll); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | if (*(matrix + ll*dim + ll) < sum ){ | ||
228 | *(matrix + ll*dim + ll) += sum; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | return; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * generate the data value in the vectors | ||
237 | */ | ||
238 | |||
239 | void initVector(double *vector, int dim){ | ||
240 | |||
241 | int l; | ||
242 | |||
243 | for (l=0; l<dim; l++){ | ||
244 | *(vector + l) = (double )randomFloat (MIN_NUMBER, MAX_NUMBER); | ||
245 | } | ||
246 | |||
247 | return; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * make a vector contains value of zero | ||
252 | */ | ||
253 | |||
254 | void zeroVector(double *vector, int dim){ | ||
255 | int l; | ||
256 | |||
257 | for (l=0; l<dim; l++){ | ||
258 | *(vector + l) = 0; | ||
259 | } | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * return a vector which is the copy of the vect | ||
265 | */ | ||
266 | |||
267 | void equalVector(double *vect, double *vect1){ | ||
268 | |||
269 | int l; | ||
270 | |||
271 | for (l=0; l<dim; l++){ | ||
272 | *(vect1+l) = *(vect+l); | ||
273 | } | ||
274 | return; | ||
275 | } | ||
276 | |||
277 | |||
278 | |||
279 | void biConjugateGradient(double *value, | ||
280 | int *col_ind, | ||
281 | int *row_start, | ||
282 | double *vectorB, | ||
283 | double *vectorX, | ||
284 | double errorTolerance, | ||
285 | int maxIterations, | ||
286 | double *actualError, | ||
287 | int *actualIteration, | ||
288 | int dim) | ||
289 | /* | ||
290 | * in the code, we use a lot of temparary vectors and variables | ||
291 | * this is just for simple and clear | ||
292 | * you can optimize these temporary variables and vectors | ||
293 | * based on your need | ||
294 | * | ||
295 | */ | ||
296 | { | ||
297 | double *vectorR; | ||
298 | double *vectorP, *matrixAvectorP, *nextVectorR; | ||
299 | double error; | ||
300 | int iteration; | ||
301 | double alpha, beta; | ||
302 | |||
303 | double *tmpVector1, *tmpVector2, *tmpVector3; | ||
304 | double tmpValue1, tmpValue2; | ||
305 | int i; | ||
306 | int l; | ||
307 | int ll; | ||
308 | |||
309 | alpha = 0; | ||
310 | beta = 0; | ||
311 | |||
312 | vectorP = (double *)malloc(dim*sizeof(double)); | ||
313 | vectorR = (double *)malloc(dim*sizeof(double)); | ||
314 | nextVectorR = (double *)malloc(dim*sizeof(double)); | ||
315 | vectorX = (double *)malloc(dim*sizeof(double)); | ||
316 | |||
317 | tmpVector1 = (double *)malloc(dim*sizeof(double)); | ||
318 | tmpVector2 = (double *)malloc(dim*sizeof(double)); | ||
319 | tmpVector3 = (double *)malloc(dim*sizeof(double)); | ||
320 | |||
321 | /* | ||
322 | * vectorR = vectorB - matrixA*vectorX | ||
323 | */ | ||
324 | matrixMulvector(value,col_ind, row_start, vectorX, tmpVector1); | ||
325 | |||
326 | vectorSub(vectorB, tmpVector1, vectorR); | ||
327 | |||
328 | /* | ||
329 | * vectorP = vectorR | ||
330 | */ | ||
331 | |||
332 | equalVector(vectorR, vectorP); | ||
333 | |||
334 | /* | ||
335 | * error = |matrixA * vectorX - vectorB| / |vectorB| | ||
336 | */ | ||
337 | vectorSub(tmpVector1, vectorB, tmpVector1); | ||
338 | |||
339 | error = vectorValue(tmpVector1)/vectorValue(vectorB); | ||
340 | |||
341 | iteration = 0; | ||
342 | |||
343 | while ((iteration < maxIterations) && (error > errorTolerance)){ | ||
344 | |||
345 | /* | ||
346 | * alpha = (transpose(vectorR) * vectorR) / | ||
347 | * (transpose(vectorP) * (matrixA * vectorP) | ||
348 | */ | ||
349 | |||
350 | matrixMulvector(value, col_ind, row_start, vectorP, tmpVector1); | ||
351 | transpose(vectorR, tmpVector2); | ||
352 | transpose(vectorP, tmpVector3); | ||
353 | tmpValue1 = vectorMul(tmpVector3, tmpVector1); | ||
354 | tmpValue2 = vectorMul(tmpVector2, vectorR); | ||
355 | alpha = tmpValue2/tmpValue1; | ||
356 | |||
357 | /* | ||
358 | * nextVectorR = vectorR - alpha*(matrixA * vectorP) | ||
359 | */ | ||
360 | |||
361 | valueMulvector(alpha, tmpVector1, tmpVector2); | ||
362 | vectorSub(vectorR, tmpVector2, tmpVector1); | ||
363 | equalVector(tmpVector1, nextVectorR); | ||
364 | |||
365 | /* | ||
366 | * beta = (transpose(nextVectorR) * nextVectorR) / | ||
367 | * (transpose(vectorR) * vectorR) | ||
368 | */ | ||
369 | |||
370 | transpose(nextVectorR, tmpVector3); | ||
371 | tmpValue1 = vectorMul(tmpVector3, nextVectorR); | ||
372 | transpose(vectorR, tmpVector2); | ||
373 | tmpValue2 = vectorMul(tmpVector2, vectorR); | ||
374 | beta = tmpValue1/tmpValue2; | ||
375 | |||
376 | /* | ||
377 | * vectorX = vectorX + alpha * vectorP | ||
378 | */ | ||
379 | valueMulvector(alpha, vectorP, tmpVector1); | ||
380 | vectorAdd(vectorX,tmpVector1, vectorX); | ||
381 | |||
382 | /* | ||
383 | *vectorP = nextVectorR + beta*vectorP | ||
384 | */ | ||
385 | valueMulvector(beta, vectorP, tmpVector1); | ||
386 | vectorAdd(nextVectorR, tmpVector1, tmpVector1); | ||
387 | |||
388 | for (ll=0; ll<dim; ll++){ | ||
389 | *(vectorP + ll) = *(tmpVector1 + ll); | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * vectorR = nextVectorR | ||
394 | */ | ||
395 | |||
396 | for (l=0; l<dim; l++){ | ||
397 | *(vectorR+l) = *(nextVectorR+l); | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * error = |matrixA * vectorX - vectorB| / |vectorB| | ||
402 | */ | ||
403 | matrixMulvector(value, col_ind,row_start, vectorX, tmpVector1); | ||
404 | vectorSub(tmpVector1,vectorB,tmpVector1); | ||
405 | error = vectorValue(tmpVector1)/vectorValue(vectorB); | ||
406 | |||
407 | iteration++; | ||
408 | } | ||
409 | |||
410 | *actualError = error; | ||
411 | *actualIteration = iteration; | ||
412 | |||
413 | free(tmpVector1); | ||
414 | free(tmpVector2); | ||
415 | free(tmpVector3); | ||
416 | |||
417 | free(vectorR); | ||
418 | free(vectorP); | ||
419 | |||
420 | return; | ||
421 | } | ||
422 | |||
423 | /* | ||
424 | * This is the function to transfer the data from the matrix of dense storage | ||
425 | * to Compact Row Storage | ||
426 | */ | ||
427 | void create_CRS(double *matrixA, | ||
428 | double *value, | ||
429 | int *col_ind, | ||
430 | int *row_start, | ||
431 | int dim, | ||
432 | int numberNonzero) | ||
433 | { | ||
434 | |||
435 | int i, j, k; | ||
436 | int cnt; | ||
437 | double tmp; | ||
438 | |||
439 | /* | ||
440 | *initialize the row_start | ||
441 | */ | ||
442 | |||
443 | for(k=0; k<dim; k++){ | ||
444 | row_start[k] = -1; | ||
445 | } | ||
446 | |||
447 | /* | ||
448 | * make the end of the last row to be numberNonzero + dim. | ||
449 | */ | ||
450 | |||
451 | row_start[dim] = numberNonzero+dim; | ||
452 | |||
453 | /* | ||
454 | * initialize the col_ind | ||
455 | */ | ||
456 | |||
457 | for (k=0; k<numberNonzero+dim; k++){ | ||
458 | col_ind[k] = -1; | ||
459 | } | ||
460 | |||
461 | |||
462 | cnt = 0; | ||
463 | |||
464 | for (i=0; (cnt<numberNonzero+dim)&&(i<dim); i++){ | ||
465 | for (j=0; (cnt<numberNonzero+dim)&&(j<dim); j++){ | ||
466 | |||
467 | tmp = *(matrixA + i*dim + j); | ||
468 | |||
469 | if (tmp!=0){ | ||
470 | |||
471 | value[cnt] = tmp; | ||
472 | col_ind[cnt] = j; | ||
473 | |||
474 | if (row_start[i] == -1) | ||
475 | row_start[i] = cnt; | ||
476 | |||
477 | cnt += 1; | ||
478 | } | ||
479 | } | ||
480 | } | ||
481 | row_start[i] = cnt; | ||
482 | |||
483 | return; | ||
484 | } | ||
485 | |||
486 | int seed; | ||
487 | int numberNonzero; | ||
488 | int maxIterations; | ||
489 | float errorTolerance; | ||
490 | double actualError; | ||
491 | int actualIteration; | ||
492 | |||
493 | |||
494 | double *matrixA; | ||
495 | double *vectorB; | ||
496 | double *vectorX; | ||
497 | |||
498 | double *value; | ||
499 | int *col_ind; | ||
500 | int *row_start; | ||
501 | int sum; | ||
502 | int k; | ||
503 | |||
504 | //fscanf(stdin, "%d %d %d %d %f", | ||
505 | // &seed, &dim, &numberNonzero,&maxIterations,&errorTolerance); | ||
506 | int init_job() { | ||
507 | |||
508 | seed = -2; | ||
509 | //dim = 500; | ||
510 | //numberNonzero = 20000; | ||
511 | dim = randInt(100,300); | ||
512 | numberNonzero = randInt(dim+1, dim*dim/4); | ||
513 | maxIterations = 32; | ||
514 | errorTolerance = 0.002734; | ||
515 | |||
516 | assert((seed > MIN_SEED) && (seed < MAX_SEED)); | ||
517 | assert((dim > MIN_DIM) && (dim < MAX_DIM)); | ||
518 | assert((numberNonzero > dim) && (numberNonzero < dim*dim)); | ||
519 | assert((maxIterations > 0) && (maxIterations < MAX_ITERATIONS)); | ||
520 | assert((errorTolerance > MIN_TOLERANCE) && (errorTolerance < MAX_TOLERANCE)); | ||
521 | |||
522 | matrixA = (double *)malloc(dim*dim*sizeof(double )); | ||
523 | vectorB = (double *)malloc(dim*sizeof(double)); | ||
524 | vectorX = (double *)malloc(dim*sizeof(double)); | ||
525 | |||
526 | value = (double *)malloc((numberNonzero+dim)*sizeof(double)); | ||
527 | col_ind = (int *)malloc((numberNonzero+dim)*sizeof(int)); | ||
528 | row_start = (int *)malloc((dim+1)*sizeof(int)); | ||
529 | |||
530 | //randInit(seed); | ||
531 | |||
532 | initMatrix(matrixA, dim, numberNonzero); | ||
533 | |||
534 | create_CRS(matrixA, value, col_ind, row_start, dim, numberNonzero); | ||
535 | |||
536 | initVector(vectorB, dim); | ||
537 | zeroVector(vectorX, dim); | ||
538 | |||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | int main_job() { | ||
543 | initVector(vectorB, dim); | ||
544 | zeroVector(vectorX, dim); | ||
545 | |||
546 | actualError = 0; | ||
547 | actualIteration = 0; | ||
548 | |||
549 | biConjugateGradient(value, col_ind, row_start, vectorB, vectorX, errorTolerance, | ||
550 | maxIterations, | ||
551 | &actualError, &actualIteration, dim); | ||
552 | |||
553 | sum = 0; | ||
554 | for (k=1; k<dim; k++){ | ||
555 | sum += sum + *(vectorX + k); | ||
556 | } | ||
557 | |||
558 | //fprintf(stdout, "sum = %d, actualError = %e, actualIteration = %d\n", sum, actualError, actualIteration); | ||
559 | //fprintf(stdout, "total time = %u sec. \n", (unsigned int)endTime); | ||
560 | |||
561 | return(0); | ||
562 | } | ||
563 | |||
564 | int post_job() { | ||
565 | free(matrixA); | ||
566 | free(vectorB); | ||
567 | free(vectorX); | ||
568 | free(value); | ||
569 | free(col_ind); | ||
570 | free(row_start); | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static void usage(char *error) { | ||
575 | fprintf(stderr, "Error: %s\n", error); | ||
576 | fprintf(stderr, | ||
577 | "Usage:\n" | ||
578 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
579 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
580 | " rt_spin -l\n" | ||
581 | "\n" | ||
582 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
583 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
584 | "\n" | ||
585 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
586 | exit(EXIT_FAILURE); | ||
587 | } | ||
588 | |||
589 | inline unsigned long get_cyclecount (void) | ||
590 | { | ||
591 | unsigned long value; | ||
592 | // Read CCNT Register | ||
593 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
594 | return value; | ||
595 | } | ||
596 | |||
597 | static int loop_main(double exec_time, double emergency_exit) | ||
598 | { | ||
599 | double last_loop = 0, loop_start; | ||
600 | int tmp = 0; | ||
601 | |||
602 | double start = cputime(); | ||
603 | double now = cputime(); | ||
604 | |||
605 | while (now + last_loop < start + exec_time) { | ||
606 | loop_start = now; | ||
607 | init_job(); | ||
608 | tmp += main_job(); | ||
609 | post_job(); | ||
610 | now = cputime(); | ||
611 | last_loop = now - loop_start; | ||
612 | if (emergency_exit && wctime() > emergency_exit) { | ||
613 | /* Oops --- this should only be possible if the execution time tracking | ||
614 | * is broken in the LITMUS^RT kernel. */ | ||
615 | fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); | ||
616 | fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); | ||
617 | break; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | return tmp; | ||
622 | } | ||
623 | |||
624 | static int job(double exec_time, double program_end) | ||
625 | { | ||
626 | if (wctime() > program_end) | ||
627 | return 0; | ||
628 | else { | ||
629 | register int iter = 0; | ||
630 | //register unsigned long t; | ||
631 | //t = get_cyclecount(); | ||
632 | //gettimeofday(&t1, NULL); | ||
633 | //while (iter++ < loops) { | ||
634 | loop_main(exec_time, program_end + 1); | ||
635 | //} | ||
636 | //t = get_cyclecount() - t; | ||
637 | //printf("%ld cycles\n", t); | ||
638 | //gettimeofday(&t2, NULL); | ||
639 | //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
640 | sleep_next_period(); | ||
641 | return 1; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | #define OPTSTR "p:wves:l:m:i:b:" | ||
646 | int main(int argc, char** argv) | ||
647 | { | ||
648 | int ret; | ||
649 | lt_t wcet; | ||
650 | lt_t period; | ||
651 | lt_t budget; | ||
652 | double wcet_ms, period_ms, budget_ms; | ||
653 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
654 | int migrate = 0; | ||
655 | int cluster = 0; | ||
656 | int opt; | ||
657 | int wait = 0; | ||
658 | int want_enforcement = 0; | ||
659 | double duration = 0, start = 0; | ||
660 | double scale = 1.0; | ||
661 | task_class_t class = RT_CLASS_HARD; | ||
662 | struct rt_task param; | ||
663 | struct mc2_task mc2_param; | ||
664 | struct reservation_config config; | ||
665 | int res_type = PERIODIC_POLLING; | ||
666 | |||
667 | unsigned int job_no; | ||
668 | |||
669 | |||
670 | progname = argv[0]; | ||
671 | |||
672 | /* default for reservation */ | ||
673 | config.id = 0; | ||
674 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
675 | config.cpu = -1; | ||
676 | |||
677 | mc2_param.crit = CRIT_LEVEL_C; | ||
678 | |||
679 | budget_ms = 0; | ||
680 | |||
681 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
682 | switch (opt) { | ||
683 | case 'w': | ||
684 | wait = 1; | ||
685 | break; | ||
686 | case 'p': | ||
687 | cluster = atoi(optarg); | ||
688 | migrate = 1; | ||
689 | config.cpu = cluster; | ||
690 | break; | ||
691 | case 'e': | ||
692 | want_enforcement = 1; | ||
693 | break; | ||
694 | case 's': | ||
695 | scale = atof(optarg); | ||
696 | break; | ||
697 | case 'l': | ||
698 | loops = atoi(optarg); | ||
699 | break; | ||
700 | case 'm': | ||
701 | mc2_param.crit = atoi(optarg); | ||
702 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
703 | usage("Invalid criticality level."); | ||
704 | } | ||
705 | res_type = PERIODIC_POLLING; | ||
706 | break; | ||
707 | case 'b': | ||
708 | budget_ms = atof(optarg); | ||
709 | break; | ||
710 | case 'i': | ||
711 | config.priority = atoi(optarg); | ||
712 | break; | ||
713 | case ':': | ||
714 | usage("Argument missing."); | ||
715 | break; | ||
716 | case '?': | ||
717 | default: | ||
718 | usage("Bad argument."); | ||
719 | break; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
724 | usage("Bad criticailty level or priority"); | ||
725 | |||
726 | if (argc - optind < 3) | ||
727 | usage("Arguments missing."); | ||
728 | |||
729 | wcet_ms = atof(argv[optind + 0]); | ||
730 | period_ms = atof(argv[optind + 1]); | ||
731 | |||
732 | wcet = ms2ns(wcet_ms); | ||
733 | period = ms2ns(period_ms); | ||
734 | if (budget_ms == 0) | ||
735 | budget_ms = wcet_ms; | ||
736 | budget = ms2ns(budget_ms); | ||
737 | |||
738 | if (wcet <= 0) | ||
739 | usage("The worst-case execution time must be a " | ||
740 | "positive number."); | ||
741 | if (period <= 0) | ||
742 | usage("The period must be a positive number."); | ||
743 | if (wcet > period) { | ||
744 | usage("The worst-case execution time must not " | ||
745 | "exceed the period."); | ||
746 | } | ||
747 | |||
748 | duration = atof(argv[optind + 2]); | ||
749 | |||
750 | if (migrate) { | ||
751 | ret = be_migrate_to_domain(cluster); | ||
752 | if (ret < 0) | ||
753 | bail_out("could not migrate to target partition or cluster."); | ||
754 | } | ||
755 | |||
756 | /* reservation config */ | ||
757 | config.id = gettid(); | ||
758 | |||
759 | config.polling_params.budget = budget; | ||
760 | config.polling_params.period = period; | ||
761 | config.polling_params.offset = 0; | ||
762 | config.polling_params.relative_deadline = 0; | ||
763 | if (config.polling_params.budget > config.polling_params.period) { | ||
764 | usage("The budget must not exceed the period."); | ||
765 | } | ||
766 | |||
767 | /* create a reservation */ | ||
768 | ret = reservation_create(res_type, &config); | ||
769 | if (ret < 0) { | ||
770 | bail_out("failed to create reservation."); | ||
771 | } | ||
772 | //init_job(); | ||
773 | srand (time(NULL)); | ||
774 | randInit(-rand()%65535); | ||
775 | |||
776 | init_rt_task_param(¶m); | ||
777 | param.exec_cost = wcet; | ||
778 | param.period = period; | ||
779 | param.priority = priority; | ||
780 | param.cls = class; | ||
781 | param.release_policy = TASK_PERIODIC; | ||
782 | param.budget_policy = (want_enforcement) ? | ||
783 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
784 | if (migrate) { | ||
785 | param.cpu = gettid(); | ||
786 | } | ||
787 | ret = set_rt_task_param(gettid(), ¶m); | ||
788 | |||
789 | if (ret < 0) | ||
790 | bail_out("could not setup rt task params"); | ||
791 | |||
792 | mc2_param.res_id = gettid(); | ||
793 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
794 | //printf("SET_MC2_TASK\n"); | ||
795 | if (ret < 0) | ||
796 | bail_out("could not setup mc2 task params"); | ||
797 | |||
798 | init_litmus(); | ||
799 | //printf("CALL\n"); | ||
800 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
801 | set_page_color(-1); | ||
802 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
803 | set_page_color(config.cpu); | ||
804 | //printf("CALL\n"); | ||
805 | |||
806 | //printf("INIT_LITMUS\n"); | ||
807 | start = wctime(); | ||
808 | ret = task_mode(LITMUS_RT_TASK); | ||
809 | //printf("TASK_MODE\n"); | ||
810 | if (ret != 0) | ||
811 | bail_out("could not become RT task"); | ||
812 | |||
813 | |||
814 | if (wait) { | ||
815 | //printf("BEFORE WAIT\n"); | ||
816 | ret = wait_for_ts_release(); | ||
817 | if (ret != 0) | ||
818 | bail_out("wait_for_ts_release()"); | ||
819 | start = wctime(); | ||
820 | } | ||
821 | |||
822 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
823 | |||
824 | ret = task_mode(BACKGROUND_TASK); | ||
825 | if (ret != 0) | ||
826 | bail_out("could not become regular task (huh?)"); | ||
827 | |||
828 | reservation_destroy(gettid(), config.cpu); | ||
829 | //post_job(); | ||
830 | // printf("%s/%d finished.\n",progname, gettid()); | ||
831 | return 0; | ||
832 | } | ||
833 | |||
diff --git a/bin/rt_mode_poll.c b/bin/rt_mode_poll.c new file mode 100644 index 0000000..08e9490 --- /dev/null +++ b/bin/rt_mode_poll.c | |||
@@ -0,0 +1,235 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | |||
16 | #define __NR_enact_mode 409 | ||
17 | |||
18 | int main_job(void){ | ||
19 | syscall(__NR_enact_mode); | ||
20 | } | ||
21 | |||
22 | static char* progname; | ||
23 | int loops = 1; | ||
24 | //struct timeval t1, t2; | ||
25 | |||
26 | static void usage(char *error) { | ||
27 | fprintf(stderr, "Error: %s\n", error); | ||
28 | fprintf(stderr, | ||
29 | "Usage:\n" | ||
30 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
31 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
32 | " rt_spin -l\n" | ||
33 | "\n" | ||
34 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
35 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
36 | "\n" | ||
37 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
38 | exit(EXIT_FAILURE); | ||
39 | } | ||
40 | |||
41 | inline unsigned long get_cyclecount (void) | ||
42 | { | ||
43 | unsigned long value; | ||
44 | // Read CCNT Register | ||
45 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
46 | return value; | ||
47 | } | ||
48 | |||
49 | static int job(double exec_time, double program_end) | ||
50 | { | ||
51 | if (wctime() > program_end) | ||
52 | return 0; | ||
53 | else { | ||
54 | main_job(); | ||
55 | sleep_next_period(); | ||
56 | return 1; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | #define OPTSTR "p:wves:l:m:i:b:" | ||
61 | int main(int argc, char** argv) | ||
62 | { | ||
63 | int ret; | ||
64 | lt_t wcet; | ||
65 | lt_t period; | ||
66 | lt_t budget; | ||
67 | double wcet_us, period_us, budget_us; | ||
68 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
69 | int migrate = 0; | ||
70 | int cluster = 0; | ||
71 | int opt; | ||
72 | int wait = 0; | ||
73 | int want_enforcement = 0; | ||
74 | double duration = 0, start = 0; | ||
75 | double scale = 1.0; | ||
76 | task_class_t class = RT_CLASS_HARD; | ||
77 | struct rt_task param; | ||
78 | struct mc2_task mc2_param; | ||
79 | struct reservation_config config; | ||
80 | int res_type = PERIODIC_POLLING; | ||
81 | |||
82 | unsigned int job_no; | ||
83 | |||
84 | |||
85 | progname = argv[0]; | ||
86 | |||
87 | /* default for reservation */ | ||
88 | config.id = 0; | ||
89 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
90 | config.cpu = -1; | ||
91 | |||
92 | mc2_param.crit = CRIT_LEVEL_C; | ||
93 | |||
94 | budget_us = 10000; | ||
95 | |||
96 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
97 | switch (opt) { | ||
98 | case 'w': | ||
99 | wait = 1; | ||
100 | break; | ||
101 | case 'p': | ||
102 | cluster = atoi(optarg); | ||
103 | migrate = 1; | ||
104 | config.cpu = cluster; | ||
105 | break; | ||
106 | case 'e': | ||
107 | want_enforcement = 1; | ||
108 | break; | ||
109 | case 's': | ||
110 | scale = atof(optarg); | ||
111 | break; | ||
112 | case 'l': | ||
113 | loops = atoi(optarg); | ||
114 | break; | ||
115 | case 'm': | ||
116 | mc2_param.crit = atoi(optarg); | ||
117 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
118 | usage("Invalid criticality level."); | ||
119 | } | ||
120 | res_type = PERIODIC_POLLING; | ||
121 | break; | ||
122 | case 'b': | ||
123 | budget_us = atof(optarg); | ||
124 | break; | ||
125 | case 'i': | ||
126 | config.priority = atoi(optarg); | ||
127 | break; | ||
128 | case ':': | ||
129 | usage("Argument missing."); | ||
130 | break; | ||
131 | case '?': | ||
132 | default: | ||
133 | usage("Bad argument."); | ||
134 | break; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
139 | usage("Bad criticailty level or priority"); | ||
140 | |||
141 | if (argc - optind < 3) | ||
142 | usage("Arguments missing."); | ||
143 | |||
144 | wcet_us = atof(argv[optind + 0]); | ||
145 | period_us = atof(argv[optind + 1]); | ||
146 | |||
147 | wcet = us2ns(wcet_us); | ||
148 | period = us2ns(period_us); | ||
149 | budget = us2ns(budget_us); | ||
150 | |||
151 | if (wcet <= 0) | ||
152 | usage("The worst-case execution time must be a " | ||
153 | "positive number."); | ||
154 | if (period <= 0) | ||
155 | usage("The period must be a positive number."); | ||
156 | if (wcet > period) { | ||
157 | usage("The worst-case execution time must not " | ||
158 | "exceed the period."); | ||
159 | } | ||
160 | |||
161 | duration = atof(argv[optind + 2]); | ||
162 | |||
163 | if (migrate) { | ||
164 | ret = be_migrate_to_domain(cluster); | ||
165 | if (ret < 0) | ||
166 | bail_out("could not migrate to target partition or cluster."); | ||
167 | } | ||
168 | |||
169 | /* reservation config */ | ||
170 | config.id = gettid(); | ||
171 | |||
172 | config.polling_params.budget = budget; | ||
173 | config.polling_params.period = period; | ||
174 | config.polling_params.offset = 0; | ||
175 | config.polling_params.relative_deadline = 0; | ||
176 | if (config.polling_params.budget > config.polling_params.period) { | ||
177 | usage("The budget must not exceed the period."); | ||
178 | } | ||
179 | |||
180 | /* create a reservation */ | ||
181 | ret = reservation_create(res_type, &config); | ||
182 | if (ret < 0) { | ||
183 | bail_out("failed to create reservation."); | ||
184 | } | ||
185 | |||
186 | init_rt_task_param(¶m); | ||
187 | param.exec_cost = wcet; | ||
188 | param.period = period; | ||
189 | param.priority = priority; | ||
190 | param.cls = class; | ||
191 | param.release_policy = TASK_PERIODIC; | ||
192 | param.budget_policy = (want_enforcement) ? | ||
193 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
194 | if (migrate) { | ||
195 | param.cpu = gettid(); | ||
196 | } | ||
197 | ret = set_rt_task_param(gettid(), ¶m); | ||
198 | |||
199 | if (ret < 0) | ||
200 | bail_out("could not setup rt task params"); | ||
201 | |||
202 | mc2_param.res_id = gettid(); | ||
203 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
204 | if (ret < 0) | ||
205 | bail_out("could not setup mc2 task params"); | ||
206 | |||
207 | init_litmus(); | ||
208 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
209 | set_page_color(8); | ||
210 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
211 | set_page_color(config.cpu*2 + mc2_param.crit); | ||
212 | |||
213 | start = wctime(); | ||
214 | ret = task_mode(LITMUS_RT_TASK); | ||
215 | if (ret != 0) | ||
216 | bail_out("could not become RT task"); | ||
217 | |||
218 | |||
219 | if (wait) { | ||
220 | ret = wait_for_ts_release(); | ||
221 | if (ret != 0) | ||
222 | bail_out("wait_for_ts_release()"); | ||
223 | start = wctime(); | ||
224 | } | ||
225 | |||
226 | while (job(wcet_us * 0.000001 * scale, start + duration)) {}; | ||
227 | |||
228 | ret = task_mode(BACKGROUND_TASK); | ||
229 | if (ret != 0) | ||
230 | bail_out("could not become regular task (huh?)"); | ||
231 | |||
232 | reservation_destroy(gettid(), config.cpu); | ||
233 | printf("%s/%d finished.\n",progname, gettid()); | ||
234 | return 0; | ||
235 | } | ||
diff --git a/bin/rt_neighborhood.c b/bin/rt_neighborhood.c new file mode 100644 index 0000000..8679cfb --- /dev/null +++ b/bin/rt_neighborhood.c | |||
@@ -0,0 +1,381 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | #include "utili.h" | ||
17 | |||
18 | #define MIN_PIXEL 0 | ||
19 | |||
20 | static char* progname; | ||
21 | int loops = 1; | ||
22 | struct timeval t1, t2; | ||
23 | |||
24 | long int seed; | ||
25 | int max_dimension; | ||
26 | int numberLines; | ||
27 | int minThickness; | ||
28 | int maxThickness; | ||
29 | int distanceShort; | ||
30 | int distanceLong; | ||
31 | int bitDepth; | ||
32 | int maxPixel; | ||
33 | Pixel *image; | ||
34 | Neighborhood values; | ||
35 | int *sumHist, *diffHist; | ||
36 | int numBins; | ||
37 | |||
38 | int init_job() { | ||
39 | //fscanf(stdin, "%ld %d %d %d %d %d %d %d", | ||
40 | // &seed, &bitDepth, &dimension, &numberLines, | ||
41 | // &minThickness, &maxThickness, | ||
42 | // &distanceShort, &distanceLong); | ||
43 | |||
44 | seed = -2; | ||
45 | bitDepth = 8; | ||
46 | /* | ||
47 | dimension = 1501; | ||
48 | numberLines = 10000; | ||
49 | minThickness = 10; | ||
50 | maxThickness = 1000; | ||
51 | distanceShort = 100; | ||
52 | distanceLong = 1000; | ||
53 | */ | ||
54 | /* for online */ | ||
55 | max_dimension = 501; | ||
56 | numberLines = randInt(200,600); | ||
57 | minThickness = randInt(1,max_dimension/2); | ||
58 | maxThickness = randInt(minThickness+1,max_dimension-1); | ||
59 | distanceShort = 10; | ||
60 | distanceLong = randInt(20, max_dimension-1); | ||
61 | |||
62 | |||
63 | /* for case | ||
64 | max_dimension = 301; | ||
65 | //max_dimension = 1501; | ||
66 | numberLines = randInt(2000,6000); | ||
67 | minThickness = randInt(1,max_dimension/2); | ||
68 | maxThickness = randInt(minThickness+1,max_dimension-1); | ||
69 | distanceShort = 10; | ||
70 | distanceLong = randInt(20, max_dimension-1); | ||
71 | */ | ||
72 | |||
73 | assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
74 | assert((max_dimension > 0) && (max_dimension <= MAX_DIMENSION)); | ||
75 | assert((numberLines > 0) && (numberLines <= MAX_NUMBER_LINES)); | ||
76 | assert((minThickness > 0) && (minThickness < max_dimension)); | ||
77 | assert((maxThickness >= minThickness) && (maxThickness < max_dimension)); | ||
78 | assert((distanceShort > 0) && (distanceShort < max_dimension)); | ||
79 | assert((distanceLong > 0) && (distanceLong < max_dimension)); | ||
80 | assert((bitDepth >= MIN_BIT_DEPTH) && (bitDepth <= MAX_BIT_DEPTH)); | ||
81 | |||
82 | //randInit(seed); | ||
83 | maxPixel = (1 << bitDepth) - 1; | ||
84 | //image = createImage(dimension, maxPixel, numberLines, | ||
85 | // minThickness, maxThickness); | ||
86 | //assert (image != NULL); | ||
87 | |||
88 | image = (Pixel *)malloc(sizeof(Pixel) * max_dimension * max_dimension); | ||
89 | assert (image != NULL); | ||
90 | |||
91 | numBins = (2 * (maxPixel - MIN_PIXEL + 1) -1); | ||
92 | sumHist = (int *) malloc(numBins * sizeof(int)); | ||
93 | assert (sumHist != NULL); | ||
94 | diffHist = (int *)malloc(numBins * sizeof(int)); | ||
95 | assert(diffHist != NULL); | ||
96 | |||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | |||
102 | int main_job() { | ||
103 | int dimension; | ||
104 | |||
105 | /* online */ | ||
106 | /* dimension = randInt(101, 501); | ||
107 | numberLines = randInt(10,150); | ||
108 | minThickness = randInt(1,dimension/2); | ||
109 | maxThickness = randInt(minThickness+1,dimension-1); | ||
110 | distanceShort = 10; | ||
111 | distanceLong = randInt(20, dimension-1); | ||
112 | */ | ||
113 | /* case */ | ||
114 | dimension = randInt(11, 151); | ||
115 | numberLines = randInt(5,100); | ||
116 | minThickness = randInt(1,dimension/2); | ||
117 | maxThickness = randInt(minThickness+1,dimension-1); | ||
118 | distanceShort = 10; | ||
119 | distanceLong = randInt(5, dimension-1); | ||
120 | |||
121 | |||
122 | |||
123 | image = createImage(image, dimension, maxPixel, numberLines, minThickness, maxThickness); | ||
124 | |||
125 | //assert (image != NULL); | ||
126 | |||
127 | neighborhoodCalculation(image, dimension, distanceShort, distanceLong, &values, maxPixel, sumHist, diffHist); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | int post_job() { | ||
133 | if (image) { | ||
134 | free((Pixel *)image); | ||
135 | image = NULL; | ||
136 | } | ||
137 | if (sumHist) { | ||
138 | free(sumHist); | ||
139 | sumHist = NULL; | ||
140 | } | ||
141 | if (diffHist) { | ||
142 | free(diffHist); | ||
143 | diffHist = NULL; | ||
144 | } | ||
145 | |||
146 | return (0); | ||
147 | } | ||
148 | |||
149 | static void usage(char *error) { | ||
150 | fprintf(stderr, "Error: %s\n", error); | ||
151 | fprintf(stderr, | ||
152 | "Usage:\n" | ||
153 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
154 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
155 | " rt_spin -l\n" | ||
156 | "\n" | ||
157 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
158 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
159 | "\n" | ||
160 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
161 | exit(EXIT_FAILURE); | ||
162 | } | ||
163 | |||
164 | inline unsigned long get_cyclecount (void) | ||
165 | { | ||
166 | unsigned long value; | ||
167 | // Read CCNT Register | ||
168 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
169 | return value; | ||
170 | } | ||
171 | |||
172 | static int job(double exec_time, double program_end) | ||
173 | { | ||
174 | if (wctime() > program_end) | ||
175 | return 0; | ||
176 | else { | ||
177 | register int iter = 0; | ||
178 | //register unsigned long t; | ||
179 | //t = get_cyclecount(); | ||
180 | //init_job(); | ||
181 | //gettimeofday(&t1, NULL); | ||
182 | while (iter++ < loops) { | ||
183 | main_job(); | ||
184 | } | ||
185 | //t = get_cyclecount() - t; | ||
186 | //printf("%ld cycles\n", t); | ||
187 | //gettimeofday(&t2, NULL); | ||
188 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
189 | //post_job(); | ||
190 | sleep_next_period(); | ||
191 | return 1; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | #define OPTSTR "p:wves:l:m:i:b:" | ||
196 | int main(int argc, char** argv) | ||
197 | { | ||
198 | int ret; | ||
199 | lt_t wcet; | ||
200 | lt_t period; | ||
201 | lt_t budget; | ||
202 | double wcet_ms, period_ms, budget_ms; | ||
203 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
204 | int migrate = 0; | ||
205 | int cluster = 0; | ||
206 | int opt; | ||
207 | int wait = 0; | ||
208 | int want_enforcement = 0; | ||
209 | double duration = 0, start = 0; | ||
210 | double scale = 1.0; | ||
211 | task_class_t class = RT_CLASS_HARD; | ||
212 | struct rt_task param; | ||
213 | struct mc2_task mc2_param; | ||
214 | struct reservation_config config; | ||
215 | int res_type = PERIODIC_POLLING; | ||
216 | |||
217 | unsigned int job_no; | ||
218 | |||
219 | |||
220 | progname = argv[0]; | ||
221 | |||
222 | /* default for reservation */ | ||
223 | config.id = 0; | ||
224 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
225 | config.cpu = -1; | ||
226 | |||
227 | mc2_param.crit = CRIT_LEVEL_C; | ||
228 | |||
229 | budget_ms = 10; | ||
230 | |||
231 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
232 | switch (opt) { | ||
233 | case 'w': | ||
234 | wait = 1; | ||
235 | break; | ||
236 | case 'p': | ||
237 | cluster = atoi(optarg); | ||
238 | migrate = 1; | ||
239 | config.cpu = cluster; | ||
240 | break; | ||
241 | case 'e': | ||
242 | want_enforcement = 1; | ||
243 | break; | ||
244 | case 's': | ||
245 | scale = atof(optarg); | ||
246 | break; | ||
247 | case 'l': | ||
248 | loops = atoi(optarg); | ||
249 | break; | ||
250 | case 'm': | ||
251 | mc2_param.crit = atoi(optarg); | ||
252 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
253 | usage("Invalid criticality level."); | ||
254 | } | ||
255 | res_type = PERIODIC_POLLING; | ||
256 | break; | ||
257 | case 'b': | ||
258 | budget_ms = atof(optarg); | ||
259 | break; | ||
260 | case 'i': | ||
261 | config.priority = atoi(optarg); | ||
262 | break; | ||
263 | case ':': | ||
264 | usage("Argument missing."); | ||
265 | break; | ||
266 | case '?': | ||
267 | default: | ||
268 | usage("Bad argument."); | ||
269 | break; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
274 | usage("Bad criticailty level or priority"); | ||
275 | |||
276 | if (argc - optind < 3) | ||
277 | usage("Arguments missing."); | ||
278 | |||
279 | wcet_ms = atof(argv[optind + 0]); | ||
280 | period_ms = atof(argv[optind + 1]); | ||
281 | |||
282 | wcet = ms2ns(wcet_ms); | ||
283 | period = ms2ns(period_ms); | ||
284 | budget = ms2ns(budget_ms); | ||
285 | |||
286 | if (wcet <= 0) | ||
287 | usage("The worst-case execution time must be a " | ||
288 | "positive number."); | ||
289 | if (period <= 0) | ||
290 | usage("The period must be a positive number."); | ||
291 | if (wcet > period) { | ||
292 | usage("The worst-case execution time must not " | ||
293 | "exceed the period."); | ||
294 | } | ||
295 | |||
296 | duration = atof(argv[optind + 2]); | ||
297 | |||
298 | if (migrate) { | ||
299 | ret = be_migrate_to_domain(cluster); | ||
300 | if (ret < 0) | ||
301 | bail_out("could not migrate to target partition or cluster."); | ||
302 | } | ||
303 | |||
304 | /* reservation config */ | ||
305 | config.id = gettid(); | ||
306 | |||
307 | config.polling_params.budget = budget; | ||
308 | config.polling_params.period = period; | ||
309 | config.polling_params.offset = 0; | ||
310 | config.polling_params.relative_deadline = 0; | ||
311 | if (config.polling_params.budget > config.polling_params.period) { | ||
312 | usage("The budget must not exceed the period."); | ||
313 | } | ||
314 | |||
315 | /* create a reservation */ | ||
316 | ret = reservation_create(res_type, &config); | ||
317 | if (ret < 0) { | ||
318 | bail_out("failed to create reservation."); | ||
319 | } | ||
320 | |||
321 | randInit(-2); | ||
322 | init_job(); | ||
323 | |||
324 | |||
325 | init_rt_task_param(¶m); | ||
326 | param.exec_cost = wcet; | ||
327 | param.period = period; | ||
328 | param.priority = priority; | ||
329 | param.cls = class; | ||
330 | param.release_policy = TASK_PERIODIC; | ||
331 | param.budget_policy = (want_enforcement) ? | ||
332 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
333 | if (migrate) { | ||
334 | param.cpu = gettid(); | ||
335 | } | ||
336 | ret = set_rt_task_param(gettid(), ¶m); | ||
337 | |||
338 | if (ret < 0) | ||
339 | bail_out("could not setup rt task params"); | ||
340 | |||
341 | mc2_param.res_id = gettid(); | ||
342 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
343 | //printf("SET_MC2_TASK\n"); | ||
344 | if (ret < 0) | ||
345 | bail_out("could not setup mc2 task params"); | ||
346 | |||
347 | init_litmus(); | ||
348 | //printf("CALL\n"); | ||
349 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
350 | set_page_color(-1); | ||
351 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
352 | set_page_color(config.cpu); | ||
353 | //printf("CALL\n"); | ||
354 | |||
355 | //printf("INIT_LITMUS\n"); | ||
356 | start = wctime(); | ||
357 | ret = task_mode(LITMUS_RT_TASK); | ||
358 | //printf("TASK_MODE\n"); | ||
359 | if (ret != 0) | ||
360 | bail_out("could not become RT task"); | ||
361 | |||
362 | |||
363 | if (wait) { | ||
364 | //printf("BEFORE WAIT\n"); | ||
365 | ret = wait_for_ts_release(); | ||
366 | if (ret != 0) | ||
367 | bail_out("wait_for_ts_release()"); | ||
368 | start = wctime(); | ||
369 | } | ||
370 | |||
371 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
372 | |||
373 | ret = task_mode(BACKGROUND_TASK); | ||
374 | if (ret != 0) | ||
375 | bail_out("could not become regular task (huh?)"); | ||
376 | |||
377 | reservation_destroy(gettid(), config.cpu); | ||
378 | post_job(); | ||
379 | printf("%s/%d finished.\n",progname, gettid()); | ||
380 | return 0; | ||
381 | } | ||
diff --git a/bin/rt_neighborhood_spin.c b/bin/rt_neighborhood_spin.c new file mode 100644 index 0000000..67b1b7e --- /dev/null +++ b/bin/rt_neighborhood_spin.c | |||
@@ -0,0 +1,337 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | #include "utili.h" | ||
17 | |||
18 | static char* progname; | ||
19 | int loops = 1; | ||
20 | struct timeval t1, t2; | ||
21 | |||
22 | long int seed; | ||
23 | int dimension; | ||
24 | int numberLines; | ||
25 | int minThickness; | ||
26 | int maxThickness; | ||
27 | int distanceShort; | ||
28 | int distanceLong; | ||
29 | int bitDepth; | ||
30 | int maxPixel; | ||
31 | Pixel *image; | ||
32 | Neighborhood values; | ||
33 | |||
34 | int init_job() { | ||
35 | //fscanf(stdin, "%ld %d %d %d %d %d %d %d", | ||
36 | // &seed, &bitDepth, &dimension, &numberLines, | ||
37 | // &minThickness, &maxThickness, | ||
38 | // &distanceShort, &distanceLong); | ||
39 | |||
40 | seed = -2; | ||
41 | bitDepth = 8; | ||
42 | /* | ||
43 | dimension = 1501; | ||
44 | numberLines = 10000; | ||
45 | minThickness = 10; | ||
46 | maxThickness = 1000; | ||
47 | distanceShort = 100; | ||
48 | distanceLong = 1000; | ||
49 | */ | ||
50 | dimension = randInt(100,501); | ||
51 | numberLines = randInt(200,1000); | ||
52 | minThickness = randInt(1,dimension/2); | ||
53 | maxThickness = randInt(minThickness+1,dimension-1); | ||
54 | distanceShort = 10; | ||
55 | distanceLong = randInt(20, dimension-1); | ||
56 | |||
57 | assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
58 | assert((dimension > 0) && (dimension <= MAX_DIMENSION)); | ||
59 | assert((numberLines > 0) && (numberLines <= MAX_NUMBER_LINES)); | ||
60 | assert((minThickness > 0) && (minThickness < dimension)); | ||
61 | assert((maxThickness >= minThickness) && (maxThickness < dimension)); | ||
62 | assert((distanceShort > 0) && (distanceShort < dimension)); | ||
63 | assert((distanceLong > 0) && (distanceLong < dimension)); | ||
64 | assert((bitDepth >= MIN_BIT_DEPTH) && (bitDepth <= MAX_BIT_DEPTH)); | ||
65 | |||
66 | //randInit(seed); | ||
67 | maxPixel = (1 << bitDepth) - 1; | ||
68 | image = createImage(dimension, maxPixel, numberLines, | ||
69 | minThickness, maxThickness); | ||
70 | assert (image != NULL); | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | int main_job() { | ||
76 | neighborhoodCalculation(image, dimension, | ||
77 | distanceShort, distanceLong, &values, maxPixel); | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | int post_job() { | ||
83 | if (image) { | ||
84 | free((Pixel *)image); | ||
85 | image = NULL; | ||
86 | } | ||
87 | return (0); | ||
88 | } | ||
89 | |||
90 | static void usage(char *error) { | ||
91 | fprintf(stderr, "Error: %s\n", error); | ||
92 | fprintf(stderr, | ||
93 | "Usage:\n" | ||
94 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
95 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
96 | " rt_spin -l\n" | ||
97 | "\n" | ||
98 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
99 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
100 | "\n" | ||
101 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
102 | exit(EXIT_FAILURE); | ||
103 | } | ||
104 | |||
105 | inline unsigned long get_cyclecount (void) | ||
106 | { | ||
107 | unsigned long value; | ||
108 | // Read CCNT Register | ||
109 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
110 | return value; | ||
111 | } | ||
112 | |||
113 | |||
114 | static int loop_main(double exec_time, double emergency_exit) | ||
115 | { | ||
116 | double last_loop = 0, loop_start; | ||
117 | int tmp = 0; | ||
118 | |||
119 | double start = cputime(); | ||
120 | double now = cputime(); | ||
121 | |||
122 | while (now + last_loop < start + exec_time) { | ||
123 | loop_start = now; | ||
124 | tmp += main_job(); | ||
125 | now = cputime(); | ||
126 | last_loop = now - loop_start; | ||
127 | if (emergency_exit && wctime() > emergency_exit) { | ||
128 | /* Oops --- this should only be possible if the execution time tracking | ||
129 | * is broken in the LITMUS^RT kernel. */ | ||
130 | fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); | ||
131 | fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | return tmp; | ||
137 | } | ||
138 | |||
139 | static int job(double exec_time, double program_end) | ||
140 | { | ||
141 | if (wctime() > program_end) | ||
142 | return 0; | ||
143 | else { | ||
144 | init_job(); | ||
145 | //gettimeofday(&t1, NULL); | ||
146 | loop_main(exec_time, program_end + 1); | ||
147 | //gettimeofday(&t2, NULL); | ||
148 | //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
149 | post_job(); | ||
150 | sleep_next_period(); | ||
151 | return 1; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | #define OPTSTR "p:wves:l:m:i:b:" | ||
156 | int main(int argc, char** argv) | ||
157 | { | ||
158 | int ret; | ||
159 | lt_t wcet; | ||
160 | lt_t period; | ||
161 | lt_t budget; | ||
162 | double wcet_ms, period_ms, budget_ms; | ||
163 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
164 | int migrate = 0; | ||
165 | int cluster = 0; | ||
166 | int opt; | ||
167 | int wait = 0; | ||
168 | int want_enforcement = 0; | ||
169 | double duration = 0, start = 0; | ||
170 | double scale = 1.0; | ||
171 | task_class_t class = RT_CLASS_HARD; | ||
172 | struct rt_task param; | ||
173 | struct mc2_task mc2_param; | ||
174 | struct reservation_config config; | ||
175 | int res_type = PERIODIC_POLLING; | ||
176 | |||
177 | unsigned int job_no; | ||
178 | |||
179 | |||
180 | progname = argv[0]; | ||
181 | |||
182 | /* default for reservation */ | ||
183 | config.id = 0; | ||
184 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
185 | config.cpu = -1; | ||
186 | |||
187 | mc2_param.crit = CRIT_LEVEL_C; | ||
188 | |||
189 | budget_ms = 10; | ||
190 | |||
191 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
192 | switch (opt) { | ||
193 | case 'w': | ||
194 | wait = 1; | ||
195 | break; | ||
196 | case 'p': | ||
197 | cluster = atoi(optarg); | ||
198 | migrate = 1; | ||
199 | config.cpu = cluster; | ||
200 | break; | ||
201 | case 'e': | ||
202 | want_enforcement = 1; | ||
203 | break; | ||
204 | case 's': | ||
205 | scale = atof(optarg); | ||
206 | break; | ||
207 | case 'l': | ||
208 | loops = atoi(optarg); | ||
209 | break; | ||
210 | case 'm': | ||
211 | mc2_param.crit = atoi(optarg); | ||
212 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
213 | usage("Invalid criticality level."); | ||
214 | } | ||
215 | res_type = PERIODIC_POLLING; | ||
216 | break; | ||
217 | case 'b': | ||
218 | budget_ms = atof(optarg); | ||
219 | break; | ||
220 | case 'i': | ||
221 | config.priority = atoi(optarg); | ||
222 | break; | ||
223 | case ':': | ||
224 | usage("Argument missing."); | ||
225 | break; | ||
226 | case '?': | ||
227 | default: | ||
228 | usage("Bad argument."); | ||
229 | break; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
234 | usage("Bad criticailty level or priority"); | ||
235 | |||
236 | if (argc - optind < 3) | ||
237 | usage("Arguments missing."); | ||
238 | |||
239 | wcet_ms = atof(argv[optind + 0]); | ||
240 | period_ms = atof(argv[optind + 1]); | ||
241 | |||
242 | wcet = ms2ns(wcet_ms); | ||
243 | period = ms2ns(period_ms); | ||
244 | budget = ms2ns(budget_ms); | ||
245 | |||
246 | if (wcet <= 0) | ||
247 | usage("The worst-case execution time must be a " | ||
248 | "positive number."); | ||
249 | if (period <= 0) | ||
250 | usage("The period must be a positive number."); | ||
251 | if (wcet > period) { | ||
252 | usage("The worst-case execution time must not " | ||
253 | "exceed the period."); | ||
254 | } | ||
255 | |||
256 | duration = atof(argv[optind + 2]); | ||
257 | |||
258 | if (migrate) { | ||
259 | ret = be_migrate_to_domain(cluster); | ||
260 | if (ret < 0) | ||
261 | bail_out("could not migrate to target partition or cluster."); | ||
262 | } | ||
263 | |||
264 | /* reservation config */ | ||
265 | config.id = gettid(); | ||
266 | |||
267 | config.polling_params.budget = budget; | ||
268 | config.polling_params.period = period; | ||
269 | config.polling_params.offset = 0; | ||
270 | config.polling_params.relative_deadline = 0; | ||
271 | if (config.polling_params.budget > config.polling_params.period) { | ||
272 | usage("The budget must not exceed the period."); | ||
273 | } | ||
274 | |||
275 | /* create a reservation */ | ||
276 | ret = reservation_create(res_type, &config); | ||
277 | if (ret < 0) { | ||
278 | bail_out("failed to create reservation."); | ||
279 | } | ||
280 | //init_job(); | ||
281 | randInit(-2); | ||
282 | |||
283 | init_rt_task_param(¶m); | ||
284 | param.exec_cost = wcet; | ||
285 | param.period = period; | ||
286 | param.priority = priority; | ||
287 | param.cls = class; | ||
288 | param.release_policy = TASK_PERIODIC; | ||
289 | param.budget_policy = (want_enforcement) ? | ||
290 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
291 | if (migrate) { | ||
292 | param.cpu = gettid(); | ||
293 | } | ||
294 | ret = set_rt_task_param(gettid(), ¶m); | ||
295 | |||
296 | if (ret < 0) | ||
297 | bail_out("could not setup rt task params"); | ||
298 | |||
299 | mc2_param.res_id = gettid(); | ||
300 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
301 | |||
302 | if (ret < 0) | ||
303 | bail_out("could not setup mc2 task params"); | ||
304 | |||
305 | init_litmus(); | ||
306 | |||
307 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
308 | set_page_color(-1); | ||
309 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
310 | set_page_color(config.cpu); | ||
311 | |||
312 | start = wctime(); | ||
313 | ret = task_mode(LITMUS_RT_TASK); | ||
314 | |||
315 | if (ret != 0) | ||
316 | bail_out("could not become RT task"); | ||
317 | |||
318 | |||
319 | if (wait) { | ||
320 | |||
321 | ret = wait_for_ts_release(); | ||
322 | if (ret != 0) | ||
323 | bail_out("wait_for_ts_release()"); | ||
324 | start = wctime(); | ||
325 | } | ||
326 | |||
327 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
328 | |||
329 | ret = task_mode(BACKGROUND_TASK); | ||
330 | if (ret != 0) | ||
331 | bail_out("could not become regular task (huh?)"); | ||
332 | |||
333 | reservation_destroy(gettid(), config.cpu); | ||
334 | //post_job(); | ||
335 | //printf("%s/%d finished.\n",progname, gettid()); | ||
336 | return 0; | ||
337 | } | ||
diff --git a/bin/rt_pointer.c b/bin/rt_pointer.c new file mode 100644 index 0000000..bfd9fec --- /dev/null +++ b/bin/rt_pointer.c | |||
@@ -0,0 +1,430 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | |||
17 | #define MIN_FIELD_SIZE 16 | ||
18 | #define MAX_FIELD_SIZE 16777216 | ||
19 | #define MIN_WINDOW_SIZE 1 | ||
20 | #define MAX_WINDOW_SIZE 15 | ||
21 | #define MIN_HOP_LIMIT 1 | ||
22 | |||
23 | #define MAX_HOP_LIMIT 4294967295U | ||
24 | |||
25 | #define MIN_SEED -2147483647 | ||
26 | #define MAX_SEED -1 | ||
27 | #define MIN_THREADS 1 | ||
28 | #define MAX_THREADS 256 | ||
29 | |||
30 | static char* progname; | ||
31 | int loops = 1; | ||
32 | struct timeval t1, t2; | ||
33 | |||
34 | unsigned int *field; | ||
35 | unsigned int f_max; | ||
36 | unsigned short int w; | ||
37 | unsigned int maxhops; | ||
38 | int seed = -2; | ||
39 | unsigned int n_max; | ||
40 | |||
41 | clock_t startTime; | ||
42 | |||
43 | struct threadS{ | ||
44 | unsigned int initial; | ||
45 | unsigned int minStop; | ||
46 | unsigned int maxStop; | ||
47 | unsigned int hops; | ||
48 | }*thread; | ||
49 | |||
50 | int init_job() { | ||
51 | //fscanf(stdin, "%lu %u %lu %ld %u", | ||
52 | // &f, &l, &maxhops, &seed, &n); | ||
53 | |||
54 | //f_max = 102400; //1048570; | ||
55 | f_max = 409600; | ||
56 | //f_max = 240000; // case study | ||
57 | maxhops = 512000; | ||
58 | //n_max = 50; | ||
59 | n_max = 10; | ||
60 | |||
61 | assert ((f_max >= MIN_FIELD_SIZE) && (f_max <= MAX_FIELD_SIZE)); | ||
62 | assert ((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT)); | ||
63 | assert ((n_max >= MIN_THREADS) && (n_max <= MAX_THREADS)); | ||
64 | if ((thread = (struct threadS *)malloc(n_max*sizeof(struct threadS))) == NULL) | ||
65 | return (-1); | ||
66 | |||
67 | /*for (l=0; l<n; l++){ | ||
68 | //fscanf(stdin, "%lu %lu %lu", | ||
69 | //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop)); | ||
70 | thread[l].initial = 10; | ||
71 | thread[l].minStop = f - thread[l].initial; | ||
72 | thread[l].maxStop = f - thread[l].initial; | ||
73 | |||
74 | assert ((thread[l].initial >= 0) && (thread[l].initial < f)); | ||
75 | assert ((thread[l].minStop >= 0) && (thread[l].minStop < f)); | ||
76 | assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f)); | ||
77 | } | ||
78 | */ | ||
79 | if ((field = (unsigned int *)malloc(f_max*sizeof(int))) == NULL) | ||
80 | return (-1); | ||
81 | |||
82 | //randInit(seed); | ||
83 | /* | ||
84 | for (l=0; l<f; l++){ | ||
85 | field[l] = randInt(0, f-w); | ||
86 | } | ||
87 | */ | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | int main_job() { | ||
92 | unsigned int l; | ||
93 | unsigned int f, n; | ||
94 | unsigned short int w; | ||
95 | |||
96 | /* online appendix setting */ | ||
97 | |||
98 | f = randInt(2048,f_max); | ||
99 | w = 1; //randInt(0,4)*2 + 1; | ||
100 | maxhops = 204800; //4096; | ||
101 | n = randInt(1,20); | ||
102 | |||
103 | |||
104 | /* case-study */ | ||
105 | /* | ||
106 | f = randInt(1024,240000); //409600); | ||
107 | w = 1; //randInt(0,4)*2 + 1; | ||
108 | maxhops = 1024; //4096; | ||
109 | n = 1; //randInt(4,30); | ||
110 | */ | ||
111 | |||
112 | assert ((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE)); | ||
113 | assert (w % 2 == 1); | ||
114 | assert (f > w); | ||
115 | |||
116 | for (l=0; l<n; l++){ | ||
117 | //fscanf(stdin, "%lu %lu %lu", | ||
118 | //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop)); | ||
119 | thread[l].initial = 1; | ||
120 | thread[l].minStop = f - thread[l].initial; | ||
121 | thread[l].maxStop = f - thread[l].initial; | ||
122 | |||
123 | assert ((thread[l].initial >= 0) && (thread[l].initial < f)); | ||
124 | assert ((thread[l].minStop >= 0) && (thread[l].minStop < f)); | ||
125 | assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f)); | ||
126 | } | ||
127 | |||
128 | for (l=0; l<f; l++){ | ||
129 | field[l] = randInt(0, f-w); | ||
130 | } | ||
131 | |||
132 | for (l=0; l<n; l++) { | ||
133 | unsigned int index; | ||
134 | unsigned int minStop, maxStop; | ||
135 | unsigned int hops; | ||
136 | |||
137 | hops = 0; | ||
138 | minStop = thread[l].minStop; | ||
139 | maxStop = thread[l].maxStop; | ||
140 | index = thread[l].initial; | ||
141 | while ((hops < maxhops) && | ||
142 | (!((index >= minStop) && | ||
143 | (index < maxStop)))){ | ||
144 | |||
145 | unsigned int ll, lll; | ||
146 | unsigned int max, min; | ||
147 | unsigned int partition; | ||
148 | unsigned int high; | ||
149 | |||
150 | partition = field[index]; | ||
151 | max = MAX_FIELD_SIZE; | ||
152 | min = 0; | ||
153 | high = 0; | ||
154 | |||
155 | for (ll=0; ll<w; ll++){ | ||
156 | unsigned int balance; | ||
157 | unsigned int x; | ||
158 | x = field[index+ll]; | ||
159 | |||
160 | if (x > max) high++; | ||
161 | else if (x > min){ /* start else* */ | ||
162 | partition = x; | ||
163 | balance = 0; | ||
164 | for (lll=ll+1; lll<w; lll++){ | ||
165 | if (field[index+lll] > partition) balance++; | ||
166 | }/* end for loop */ | ||
167 | |||
168 | if (balance+high == w/2) break; | ||
169 | else if (balance+high > w/2){ | ||
170 | min = partition; | ||
171 | }/* end if */ | ||
172 | else { | ||
173 | max = partition; | ||
174 | high++; | ||
175 | }/* end else */ | ||
176 | } | ||
177 | if (min == max) break; | ||
178 | } /* end else* */ | ||
179 | index = (partition+hops)%(f-w); | ||
180 | hops++; | ||
181 | }/* end loop ll */ | ||
182 | thread[l].hops = hops; | ||
183 | } /* end while */ | ||
184 | |||
185 | return(0); | ||
186 | } | ||
187 | |||
188 | int post_job() { | ||
189 | if (field) { | ||
190 | free(field); | ||
191 | field = NULL; | ||
192 | } | ||
193 | if (thread) { | ||
194 | free(thread); | ||
195 | thread = NULL; | ||
196 | } | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static void usage(char *error) { | ||
201 | fprintf(stderr, "Error: %s\n", error); | ||
202 | fprintf(stderr, | ||
203 | "Usage:\n" | ||
204 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
205 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
206 | " rt_spin -l\n" | ||
207 | "\n" | ||
208 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
209 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
210 | "\n" | ||
211 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
212 | exit(EXIT_FAILURE); | ||
213 | } | ||
214 | |||
215 | inline unsigned long get_cyclecount (void) | ||
216 | { | ||
217 | unsigned long value; | ||
218 | // Read CCNT Register | ||
219 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
220 | return value; | ||
221 | } | ||
222 | |||
223 | static int job(double exec_time, double program_end) | ||
224 | { | ||
225 | if (wctime() > program_end) | ||
226 | return 0; | ||
227 | else { | ||
228 | register int iter = 0; | ||
229 | //register unsigned long t; | ||
230 | //t = get_cyclecount(); | ||
231 | //init_job(); | ||
232 | //gettimeofday(&t1, NULL); | ||
233 | //while (iter++ < loops) { | ||
234 | main_job(); | ||
235 | //} | ||
236 | //t = get_cyclecount() - t; | ||
237 | //printf("%ld cycles\n", t); | ||
238 | //gettimeofday(&t2, NULL); | ||
239 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
240 | //post_job(); | ||
241 | sleep_next_period(); | ||
242 | return 1; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | #define OPTSTR "p:wves:l:m:i:b:" | ||
247 | int main(int argc, char** argv) | ||
248 | { | ||
249 | int ret; | ||
250 | lt_t wcet; | ||
251 | lt_t period; | ||
252 | lt_t budget; | ||
253 | double wcet_ms, period_ms, budget_ms; | ||
254 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
255 | int migrate = 0; | ||
256 | int cluster = 0; | ||
257 | int opt; | ||
258 | int wait = 0; | ||
259 | int want_enforcement = 0; | ||
260 | double duration = 0, start = 0; | ||
261 | double scale = 1.0; | ||
262 | task_class_t class = RT_CLASS_HARD; | ||
263 | struct rt_task param; | ||
264 | struct mc2_task mc2_param; | ||
265 | struct reservation_config config; | ||
266 | int res_type = PERIODIC_POLLING; | ||
267 | |||
268 | progname = argv[0]; | ||
269 | |||
270 | /* default for reservation */ | ||
271 | config.id = 0; | ||
272 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
273 | config.cpu = -1; | ||
274 | |||
275 | mc2_param.crit = CRIT_LEVEL_C; | ||
276 | |||
277 | budget_ms = 10; | ||
278 | |||
279 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
280 | switch (opt) { | ||
281 | case 'w': | ||
282 | wait = 1; | ||
283 | break; | ||
284 | case 'p': | ||
285 | cluster = atoi(optarg); | ||
286 | migrate = 1; | ||
287 | config.cpu = cluster; | ||
288 | break; | ||
289 | case 'e': | ||
290 | want_enforcement = 1; | ||
291 | break; | ||
292 | case 's': | ||
293 | scale = atof(optarg); | ||
294 | break; | ||
295 | case 'l': | ||
296 | loops = atoi(optarg); | ||
297 | break; | ||
298 | case 'm': | ||
299 | mc2_param.crit = atoi(optarg); | ||
300 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
301 | usage("Invalid criticality level."); | ||
302 | } | ||
303 | res_type = PERIODIC_POLLING; | ||
304 | break; | ||
305 | case 'b': | ||
306 | budget_ms = atof(optarg); | ||
307 | break; | ||
308 | case 'i': | ||
309 | config.priority = atoi(optarg); | ||
310 | break; | ||
311 | case ':': | ||
312 | usage("Argument missing."); | ||
313 | break; | ||
314 | case '?': | ||
315 | default: | ||
316 | usage("Bad argument."); | ||
317 | break; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
322 | usage("Bad criticailty level or priority"); | ||
323 | |||
324 | if (argc - optind < 3) | ||
325 | usage("Arguments missing."); | ||
326 | |||
327 | wcet_ms = atof(argv[optind + 0]); | ||
328 | period_ms = atof(argv[optind + 1]); | ||
329 | |||
330 | wcet = ms2ns(wcet_ms); | ||
331 | period = ms2ns(period_ms); | ||
332 | budget = ms2ns(budget_ms); | ||
333 | |||
334 | if (wcet <= 0) | ||
335 | usage("The worst-case execution time must be a " | ||
336 | "positive number."); | ||
337 | if (period <= 0) | ||
338 | usage("The period must be a positive number."); | ||
339 | if (wcet > period) { | ||
340 | usage("The worst-case execution time must not " | ||
341 | "exceed the period."); | ||
342 | } | ||
343 | |||
344 | duration = atof(argv[optind + 2]); | ||
345 | |||
346 | if (migrate) { | ||
347 | ret = be_migrate_to_domain(cluster); | ||
348 | if (ret < 0) | ||
349 | bail_out("could not migrate to target partition or cluster."); | ||
350 | } | ||
351 | |||
352 | /* reservation config */ | ||
353 | config.id = gettid(); | ||
354 | |||
355 | config.polling_params.budget = budget; | ||
356 | config.polling_params.period = period; | ||
357 | config.polling_params.offset = 0; | ||
358 | config.polling_params.relative_deadline = 0; | ||
359 | if (config.polling_params.budget > config.polling_params.period) { | ||
360 | usage("The budget must not exceed the period."); | ||
361 | } | ||
362 | |||
363 | /* create a reservation */ | ||
364 | ret = reservation_create(res_type, &config); | ||
365 | if (ret < 0) { | ||
366 | bail_out("failed to create reservation."); | ||
367 | } | ||
368 | //srand (time(NULL)); | ||
369 | //randInit((-rand()%65535)-2); | ||
370 | randInit(-2); | ||
371 | |||
372 | init_job(); | ||
373 | |||
374 | init_rt_task_param(¶m); | ||
375 | param.exec_cost = wcet; | ||
376 | param.period = period; | ||
377 | param.priority = priority; | ||
378 | param.cls = class; | ||
379 | param.release_policy = TASK_PERIODIC; | ||
380 | param.budget_policy = (want_enforcement) ? | ||
381 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
382 | if (migrate) { | ||
383 | param.cpu = gettid(); | ||
384 | } | ||
385 | ret = set_rt_task_param(gettid(), ¶m); | ||
386 | |||
387 | if (ret < 0) | ||
388 | bail_out("could not setup rt task params"); | ||
389 | |||
390 | mc2_param.res_id = gettid(); | ||
391 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
392 | //printf("SET_MC2_TASK\n"); | ||
393 | if (ret < 0) | ||
394 | bail_out("could not setup mc2 task params"); | ||
395 | |||
396 | init_litmus(); | ||
397 | //printf("CALL\n"); | ||
398 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
399 | set_page_color(-1); | ||
400 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
401 | set_page_color(config.cpu); | ||
402 | //printf("CALL\n"); | ||
403 | |||
404 | //printf("INIT_LITMUS\n"); | ||
405 | start = wctime(); | ||
406 | ret = task_mode(LITMUS_RT_TASK); | ||
407 | //printf("TASK_MODE\n"); | ||
408 | if (ret != 0) | ||
409 | bail_out("could not become RT task"); | ||
410 | |||
411 | |||
412 | if (wait) { | ||
413 | //printf("BEFORE WAIT\n"); | ||
414 | ret = wait_for_ts_release(); | ||
415 | if (ret != 0) | ||
416 | bail_out("wait_for_ts_release()"); | ||
417 | start = wctime(); | ||
418 | } | ||
419 | |||
420 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
421 | |||
422 | ret = task_mode(BACKGROUND_TASK); | ||
423 | if (ret != 0) | ||
424 | bail_out("could not become regular task (huh?)"); | ||
425 | |||
426 | reservation_destroy(gettid(), config.cpu); | ||
427 | //post_job(); | ||
428 | printf("%s/%d finished.\n",progname, gettid()); | ||
429 | return 0; | ||
430 | } | ||
diff --git a/bin/rt_pointer_spin.c b/bin/rt_pointer_spin.c new file mode 100644 index 0000000..73e7b1d --- /dev/null +++ b/bin/rt_pointer_spin.c | |||
@@ -0,0 +1,439 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | |||
17 | #define MIN_FIELD_SIZE 16 | ||
18 | #define MAX_FIELD_SIZE 16777216 | ||
19 | #define MIN_WINDOW_SIZE 1 | ||
20 | #define MAX_WINDOW_SIZE 15 | ||
21 | #define MIN_HOP_LIMIT 1 | ||
22 | |||
23 | #define MAX_HOP_LIMIT 4294967295U | ||
24 | |||
25 | #define MIN_SEED -2147483647 | ||
26 | #define MAX_SEED -1 | ||
27 | #define MIN_THREADS 1 | ||
28 | #define MAX_THREADS 256 | ||
29 | |||
30 | static char* progname; | ||
31 | int loops = 1; | ||
32 | struct timeval t1, t2; | ||
33 | |||
34 | unsigned int *field; | ||
35 | unsigned int f; | ||
36 | unsigned short int w; | ||
37 | unsigned int maxhops; | ||
38 | int seed = -2; | ||
39 | unsigned int n; | ||
40 | |||
41 | clock_t startTime; | ||
42 | |||
43 | struct threadS{ | ||
44 | unsigned int initial; | ||
45 | unsigned int minStop; | ||
46 | unsigned int maxStop; | ||
47 | unsigned int hops; | ||
48 | }*thread; | ||
49 | |||
50 | unsigned int l; | ||
51 | |||
52 | int init_job() { | ||
53 | //fscanf(stdin, "%lu %u %lu %ld %u", | ||
54 | // &f, &l, &maxhops, &seed, &n); | ||
55 | |||
56 | f = 1048570; | ||
57 | l = 15; | ||
58 | maxhops = 5120000; | ||
59 | n = 1; | ||
60 | |||
61 | assert ((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE)); | ||
62 | w = (unsigned int) l; | ||
63 | assert ((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE)); | ||
64 | assert (w % 2 == 1); | ||
65 | assert (f > w); | ||
66 | assert ((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT)); | ||
67 | assert ((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
68 | |||
69 | assert ((n >= MIN_THREADS) && (n <= MAX_THREADS)); | ||
70 | if ((thread = (struct threadS *)malloc(n*sizeof(struct threadS))) == NULL) | ||
71 | return (-1); | ||
72 | |||
73 | /*for (l=0; l<n; l++){ | ||
74 | //fscanf(stdin, "%lu %lu %lu", | ||
75 | //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop)); | ||
76 | thread[l].initial = 10; | ||
77 | thread[l].minStop = f - thread[l].initial; | ||
78 | thread[l].maxStop = f - thread[l].initial; | ||
79 | |||
80 | assert ((thread[l].initial >= 0) && (thread[l].initial < f)); | ||
81 | assert ((thread[l].minStop >= 0) && (thread[l].minStop < f)); | ||
82 | assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f)); | ||
83 | } | ||
84 | */ | ||
85 | if ((field = (unsigned int *)malloc(f*sizeof(int))) == NULL) | ||
86 | return (-1); | ||
87 | |||
88 | //randInit(seed); | ||
89 | /* | ||
90 | for (l=0; l<f; l++){ | ||
91 | field[l] = randInt(0, f-w); | ||
92 | } | ||
93 | */ | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | int main_job() { | ||
98 | f = randInt(16,65536); | ||
99 | w = randInt(0,7)*2 + 1; | ||
100 | maxhops = 32768; | ||
101 | n = 1; | ||
102 | for (l=0; l<n; l++){ | ||
103 | //fscanf(stdin, "%lu %lu %lu", | ||
104 | //&(thread[l].initial), &(thread[l].minStop), &(thread[l].maxStop)); | ||
105 | thread[l].initial = 10; | ||
106 | thread[l].minStop = f - thread[l].initial; | ||
107 | thread[l].maxStop = f - thread[l].initial; | ||
108 | |||
109 | assert ((thread[l].initial >= 0) && (thread[l].initial < f)); | ||
110 | assert ((thread[l].minStop >= 0) && (thread[l].minStop < f)); | ||
111 | assert ((thread[l].maxStop >= 0) && (thread[l].maxStop < f)); | ||
112 | } | ||
113 | |||
114 | for (l=0; l<f; l++){ | ||
115 | field[l] = randInt(0, f-w); | ||
116 | } | ||
117 | |||
118 | for (l=0; l<n; l++) { | ||
119 | unsigned int index; | ||
120 | unsigned int minStop, maxStop; | ||
121 | unsigned int hops; | ||
122 | |||
123 | hops = 0; | ||
124 | minStop = thread[l].minStop; | ||
125 | maxStop = thread[l].maxStop; | ||
126 | index = thread[l].initial; | ||
127 | while ((hops < maxhops) && | ||
128 | (!((index >= minStop) && | ||
129 | (index < maxStop)))){ | ||
130 | |||
131 | unsigned int ll, lll; | ||
132 | unsigned int max, min; | ||
133 | unsigned int partition; | ||
134 | unsigned int high; | ||
135 | |||
136 | partition = field[index]; | ||
137 | max = MAX_FIELD_SIZE; | ||
138 | min = 0; | ||
139 | high = 0; | ||
140 | |||
141 | for (ll=0; ll<w; ll++){ | ||
142 | unsigned int balance; | ||
143 | unsigned int x; | ||
144 | x = field[index+ll]; | ||
145 | |||
146 | if (x > max) high++; | ||
147 | else if (x > min){ /* start else* */ | ||
148 | partition = x; | ||
149 | balance = 0; | ||
150 | for (lll=ll+1; lll<w; lll++){ | ||
151 | if (field[index+lll] > partition) balance++; | ||
152 | }/* end for loop */ | ||
153 | |||
154 | if (balance+high == w/2) break; | ||
155 | else if (balance+high > w/2){ | ||
156 | min = partition; | ||
157 | }/* end if */ | ||
158 | else { | ||
159 | max = partition; | ||
160 | high++; | ||
161 | }/* end else */ | ||
162 | } | ||
163 | if (min == max) break; | ||
164 | } /* end else* */ | ||
165 | index = (partition+hops)%(f-w); | ||
166 | hops++; | ||
167 | }/* end loop ll */ | ||
168 | thread[l].hops = hops; | ||
169 | } /* end while */ | ||
170 | |||
171 | return(0); | ||
172 | } | ||
173 | |||
174 | int post_job() { | ||
175 | if (field) { | ||
176 | free(field); | ||
177 | field = NULL; | ||
178 | } | ||
179 | if (thread) { | ||
180 | free(thread); | ||
181 | thread = NULL; | ||
182 | } | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static void usage(char *error) { | ||
187 | fprintf(stderr, "Error: %s\n", error); | ||
188 | fprintf(stderr, | ||
189 | "Usage:\n" | ||
190 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
191 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
192 | " rt_spin -l\n" | ||
193 | "\n" | ||
194 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
195 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
196 | "\n" | ||
197 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
198 | exit(EXIT_FAILURE); | ||
199 | } | ||
200 | |||
201 | inline unsigned long get_cyclecount (void) | ||
202 | { | ||
203 | unsigned long value; | ||
204 | // Read CCNT Register | ||
205 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
206 | return value; | ||
207 | } | ||
208 | |||
209 | static int loop_main(double exec_time, double emergency_exit) | ||
210 | { | ||
211 | double last_loop = 0, loop_start; | ||
212 | int tmp = 0; | ||
213 | |||
214 | double start = cputime(); | ||
215 | double now = cputime(); | ||
216 | |||
217 | while (now + last_loop < start + exec_time) { | ||
218 | loop_start = now; | ||
219 | tmp += main_job(); | ||
220 | now = cputime(); | ||
221 | last_loop = now - loop_start; | ||
222 | if (emergency_exit && wctime() > emergency_exit) { | ||
223 | /* Oops --- this should only be possible if the execution time tracking | ||
224 | * is broken in the LITMUS^RT kernel. */ | ||
225 | fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); | ||
226 | fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); | ||
227 | break; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | return tmp; | ||
232 | } | ||
233 | |||
234 | static int job(double exec_time, double program_end) | ||
235 | { | ||
236 | if (wctime() > program_end) | ||
237 | return 0; | ||
238 | else { | ||
239 | register int iter = 0; | ||
240 | //register unsigned long t; | ||
241 | //t = get_cyclecount(); | ||
242 | //init_job(); | ||
243 | //gettimeofday(&t1, NULL); | ||
244 | loop_main(exec_time, program_end + 1); | ||
245 | //t = get_cyclecount() - t; | ||
246 | //printf("%ld cycles\n", t); | ||
247 | //gettimeofday(&t2, NULL); | ||
248 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
249 | //post_job(); | ||
250 | sleep_next_period(); | ||
251 | return 1; | ||
252 | } | ||
253 | } | ||
254 | |||
255 | #define OPTSTR "p:wves:l:m:i:b:" | ||
256 | int main(int argc, char** argv) | ||
257 | { | ||
258 | int ret; | ||
259 | lt_t wcet; | ||
260 | lt_t period; | ||
261 | lt_t budget; | ||
262 | double wcet_ms, period_ms, budget_ms; | ||
263 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
264 | int migrate = 0; | ||
265 | int cluster = 0; | ||
266 | int opt; | ||
267 | int wait = 0; | ||
268 | int want_enforcement = 0; | ||
269 | double duration = 0, start = 0; | ||
270 | double scale = 1.0; | ||
271 | task_class_t class = RT_CLASS_HARD; | ||
272 | struct rt_task param; | ||
273 | struct mc2_task mc2_param; | ||
274 | struct reservation_config config; | ||
275 | int res_type = PERIODIC_POLLING; | ||
276 | |||
277 | progname = argv[0]; | ||
278 | |||
279 | /* default for reservation */ | ||
280 | config.id = 0; | ||
281 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
282 | config.cpu = -1; | ||
283 | |||
284 | mc2_param.crit = CRIT_LEVEL_C; | ||
285 | |||
286 | budget_ms = 10; | ||
287 | |||
288 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
289 | switch (opt) { | ||
290 | case 'w': | ||
291 | wait = 1; | ||
292 | break; | ||
293 | case 'p': | ||
294 | cluster = atoi(optarg); | ||
295 | migrate = 1; | ||
296 | config.cpu = cluster; | ||
297 | break; | ||
298 | case 'e': | ||
299 | want_enforcement = 1; | ||
300 | break; | ||
301 | case 's': | ||
302 | scale = atof(optarg); | ||
303 | break; | ||
304 | case 'l': | ||
305 | loops = atoi(optarg); | ||
306 | break; | ||
307 | case 'm': | ||
308 | mc2_param.crit = atoi(optarg); | ||
309 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
310 | usage("Invalid criticality level."); | ||
311 | } | ||
312 | res_type = PERIODIC_POLLING; | ||
313 | break; | ||
314 | case 'b': | ||
315 | budget_ms = atof(optarg); | ||
316 | break; | ||
317 | case 'i': | ||
318 | config.priority = atoi(optarg); | ||
319 | break; | ||
320 | case ':': | ||
321 | usage("Argument missing."); | ||
322 | break; | ||
323 | case '?': | ||
324 | default: | ||
325 | usage("Bad argument."); | ||
326 | break; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
331 | usage("Bad criticailty level or priority"); | ||
332 | |||
333 | if (argc - optind < 3) | ||
334 | usage("Arguments missing."); | ||
335 | |||
336 | wcet_ms = atof(argv[optind + 0]); | ||
337 | period_ms = atof(argv[optind + 1]); | ||
338 | |||
339 | wcet = ms2ns(wcet_ms); | ||
340 | period = ms2ns(period_ms); | ||
341 | budget = ms2ns(budget_ms); | ||
342 | |||
343 | if (wcet <= 0) | ||
344 | usage("The worst-case execution time must be a " | ||
345 | "positive number."); | ||
346 | if (period <= 0) | ||
347 | usage("The period must be a positive number."); | ||
348 | if (wcet > period) { | ||
349 | usage("The worst-case execution time must not " | ||
350 | "exceed the period."); | ||
351 | } | ||
352 | |||
353 | duration = atof(argv[optind + 2]); | ||
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 | /* reservation config */ | ||
362 | config.id = gettid(); | ||
363 | |||
364 | config.polling_params.budget = budget; | ||
365 | config.polling_params.period = period; | ||
366 | config.polling_params.offset = 0; | ||
367 | config.polling_params.relative_deadline = 0; | ||
368 | if (config.polling_params.budget > config.polling_params.period) { | ||
369 | usage("The budget must not exceed the period."); | ||
370 | } | ||
371 | |||
372 | /* create a reservation */ | ||
373 | ret = reservation_create(res_type, &config); | ||
374 | if (ret < 0) { | ||
375 | bail_out("failed to create reservation."); | ||
376 | } | ||
377 | //srand (time(NULL)); | ||
378 | //randInit((-rand()%65535)-2); | ||
379 | randInit(-2); | ||
380 | |||
381 | init_job(); | ||
382 | |||
383 | init_rt_task_param(¶m); | ||
384 | param.exec_cost = wcet; | ||
385 | param.period = period; | ||
386 | param.priority = priority; | ||
387 | param.cls = class; | ||
388 | param.release_policy = TASK_PERIODIC; | ||
389 | param.budget_policy = (want_enforcement) ? | ||
390 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
391 | if (migrate) { | ||
392 | param.cpu = gettid(); | ||
393 | } | ||
394 | ret = set_rt_task_param(gettid(), ¶m); | ||
395 | |||
396 | if (ret < 0) | ||
397 | bail_out("could not setup rt task params"); | ||
398 | |||
399 | mc2_param.res_id = gettid(); | ||
400 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
401 | //printf("SET_MC2_TASK\n"); | ||
402 | if (ret < 0) | ||
403 | bail_out("could not setup mc2 task params"); | ||
404 | |||
405 | init_litmus(); | ||
406 | //printf("CALL\n"); | ||
407 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
408 | set_page_color(-1); | ||
409 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
410 | set_page_color(config.cpu); | ||
411 | //printf("CALL\n"); | ||
412 | |||
413 | //printf("INIT_LITMUS\n"); | ||
414 | start = wctime(); | ||
415 | ret = task_mode(LITMUS_RT_TASK); | ||
416 | //printf("TASK_MODE\n"); | ||
417 | if (ret != 0) | ||
418 | bail_out("could not become RT task"); | ||
419 | |||
420 | |||
421 | if (wait) { | ||
422 | //printf("BEFORE WAIT\n"); | ||
423 | ret = wait_for_ts_release(); | ||
424 | if (ret != 0) | ||
425 | bail_out("wait_for_ts_release()"); | ||
426 | start = wctime(); | ||
427 | } | ||
428 | |||
429 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
430 | |||
431 | ret = task_mode(BACKGROUND_TASK); | ||
432 | if (ret != 0) | ||
433 | bail_out("could not become regular task (huh?)"); | ||
434 | |||
435 | reservation_destroy(gettid(), config.cpu); | ||
436 | post_job(); | ||
437 | //printf("%s/%d finished.\n",progname, gettid()); | ||
438 | return 0; | ||
439 | } | ||
diff --git a/bin/rt_skeleton.c b/bin/rt_skeleton.c new file mode 100644 index 0000000..16e189a --- /dev/null +++ b/bin/rt_skeleton.c | |||
@@ -0,0 +1,247 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | |||
16 | extern int main_job(void); | ||
17 | |||
18 | static char* progname; | ||
19 | int loops = 10; | ||
20 | //struct timeval t1, t2; | ||
21 | |||
22 | static void usage(char *error) { | ||
23 | fprintf(stderr, "Error: %s\n", error); | ||
24 | fprintf(stderr, | ||
25 | "Usage:\n" | ||
26 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
27 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
28 | " rt_spin -l\n" | ||
29 | "\n" | ||
30 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
31 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
32 | "\n" | ||
33 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
34 | exit(EXIT_FAILURE); | ||
35 | } | ||
36 | |||
37 | inline unsigned long get_cyclecount (void) | ||
38 | { | ||
39 | unsigned long value; | ||
40 | // Read CCNT Register | ||
41 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
42 | return value; | ||
43 | } | ||
44 | |||
45 | static int job(double exec_time, double program_end) | ||
46 | { | ||
47 | if (wctime() > program_end) | ||
48 | return 0; | ||
49 | else { | ||
50 | register int iter = 0; | ||
51 | //register unsigned long t; | ||
52 | //t = get_cyclecount(); | ||
53 | //gettimeofday(&t1, NULL); | ||
54 | while (iter++ < loops) { | ||
55 | main_job(); | ||
56 | } | ||
57 | //t = get_cyclecount() - t; | ||
58 | //printf("%ld cycles\n", t); | ||
59 | //gettimeofday(&t2, NULL); | ||
60 | //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
61 | sleep_next_period(); | ||
62 | return 1; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | #define OPTSTR "p:wves:l:m:i:b:" | ||
67 | int main(int argc, char** argv) | ||
68 | { | ||
69 | int ret; | ||
70 | lt_t wcet; | ||
71 | lt_t period; | ||
72 | lt_t budget; | ||
73 | double wcet_us, period_us, budget_us; | ||
74 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
75 | int migrate = 0; | ||
76 | int cluster = 0; | ||
77 | int opt; | ||
78 | int wait = 0; | ||
79 | int want_enforcement = 0; | ||
80 | double duration = 0, start = 0; | ||
81 | double scale = 1.0; | ||
82 | task_class_t class = RT_CLASS_HARD; | ||
83 | struct rt_task param; | ||
84 | struct mc2_task mc2_param; | ||
85 | struct reservation_config config; | ||
86 | int res_type = PERIODIC_POLLING; | ||
87 | |||
88 | unsigned int job_no; | ||
89 | |||
90 | |||
91 | progname = argv[0]; | ||
92 | |||
93 | /* default for reservation */ | ||
94 | config.id = 0; | ||
95 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
96 | config.cpu = -1; | ||
97 | |||
98 | mc2_param.crit = CRIT_LEVEL_C; | ||
99 | |||
100 | budget_us = 10000; | ||
101 | |||
102 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
103 | switch (opt) { | ||
104 | case 'w': | ||
105 | wait = 1; | ||
106 | break; | ||
107 | case 'p': | ||
108 | cluster = atoi(optarg); | ||
109 | migrate = 1; | ||
110 | config.cpu = cluster; | ||
111 | break; | ||
112 | case 'e': | ||
113 | want_enforcement = 1; | ||
114 | break; | ||
115 | case 's': | ||
116 | scale = atof(optarg); | ||
117 | break; | ||
118 | case 'l': | ||
119 | loops = atoi(optarg); | ||
120 | break; | ||
121 | case 'm': | ||
122 | mc2_param.crit = atoi(optarg); | ||
123 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
124 | usage("Invalid criticality level."); | ||
125 | } | ||
126 | res_type = PERIODIC_POLLING; | ||
127 | break; | ||
128 | case 'b': | ||
129 | budget_us = atof(optarg); | ||
130 | break; | ||
131 | case 'i': | ||
132 | config.priority = atoi(optarg); | ||
133 | break; | ||
134 | case ':': | ||
135 | usage("Argument missing."); | ||
136 | break; | ||
137 | case '?': | ||
138 | default: | ||
139 | usage("Bad argument."); | ||
140 | break; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
145 | usage("Bad criticailty level or priority"); | ||
146 | |||
147 | if (argc - optind < 3) | ||
148 | usage("Arguments missing."); | ||
149 | |||
150 | wcet_us = atof(argv[optind + 0]); | ||
151 | period_us = atof(argv[optind + 1]); | ||
152 | |||
153 | wcet = us2ns(wcet_us); | ||
154 | period = us2ns(period_us); | ||
155 | budget = us2ns(budget_us); | ||
156 | |||
157 | if (wcet <= 0) | ||
158 | usage("The worst-case execution time must be a " | ||
159 | "positive number."); | ||
160 | if (period <= 0) | ||
161 | usage("The period must be a positive number."); | ||
162 | if (wcet > period) { | ||
163 | usage("The worst-case execution time must not " | ||
164 | "exceed the period."); | ||
165 | } | ||
166 | |||
167 | duration = atof(argv[optind + 2]); | ||
168 | |||
169 | if (migrate) { | ||
170 | ret = be_migrate_to_domain(cluster); | ||
171 | if (ret < 0) | ||
172 | bail_out("could not migrate to target partition or cluster."); | ||
173 | } | ||
174 | |||
175 | /* reservation config */ | ||
176 | config.id = gettid(); | ||
177 | |||
178 | config.polling_params.budget = budget; | ||
179 | config.polling_params.period = period; | ||
180 | config.polling_params.offset = 0; | ||
181 | config.polling_params.relative_deadline = 0; | ||
182 | if (config.polling_params.budget > config.polling_params.period) { | ||
183 | usage("The budget must not exceed the period."); | ||
184 | } | ||
185 | |||
186 | /* create a reservation */ | ||
187 | ret = reservation_create(res_type, &config); | ||
188 | if (ret < 0) { | ||
189 | bail_out("failed to create reservation."); | ||
190 | } | ||
191 | |||
192 | init_rt_task_param(¶m); | ||
193 | param.exec_cost = wcet; | ||
194 | param.period = period; | ||
195 | param.priority = priority; | ||
196 | param.cls = class; | ||
197 | param.release_policy = TASK_PERIODIC; | ||
198 | param.budget_policy = (want_enforcement) ? | ||
199 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
200 | if (migrate) { | ||
201 | param.cpu = gettid(); | ||
202 | } | ||
203 | ret = set_rt_task_param(gettid(), ¶m); | ||
204 | |||
205 | if (ret < 0) | ||
206 | bail_out("could not setup rt task params"); | ||
207 | |||
208 | mc2_param.res_id = gettid(); | ||
209 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
210 | //printf("SET_MC2_TASK\n"); | ||
211 | if (ret < 0) | ||
212 | bail_out("could not setup mc2 task params"); | ||
213 | |||
214 | init_litmus(); | ||
215 | //printf("CALL\n"); | ||
216 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
217 | set_page_color(8); | ||
218 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
219 | set_page_color(config.cpu*2 + mc2_param.crit); | ||
220 | //printf("CALL\n"); | ||
221 | |||
222 | //printf("INIT_LITMUS\n"); | ||
223 | start = wctime(); | ||
224 | ret = task_mode(LITMUS_RT_TASK); | ||
225 | //printf("TASK_MODE\n"); | ||
226 | if (ret != 0) | ||
227 | bail_out("could not become RT task"); | ||
228 | |||
229 | |||
230 | if (wait) { | ||
231 | //printf("BEFORE WAIT\n"); | ||
232 | ret = wait_for_ts_release(); | ||
233 | if (ret != 0) | ||
234 | bail_out("wait_for_ts_release()"); | ||
235 | start = wctime(); | ||
236 | } | ||
237 | |||
238 | while (job(wcet_us * 0.000001 * scale, start + duration)) {}; | ||
239 | |||
240 | ret = task_mode(BACKGROUND_TASK); | ||
241 | if (ret != 0) | ||
242 | bail_out("could not become regular task (huh?)"); | ||
243 | |||
244 | reservation_destroy(gettid(), config.cpu); | ||
245 | printf("%s/%d finished.\n",progname, gettid()); | ||
246 | return 0; | ||
247 | } | ||
diff --git a/bin/rt_skeleton_ms.c b/bin/rt_skeleton_ms.c new file mode 100644 index 0000000..d545635 --- /dev/null +++ b/bin/rt_skeleton_ms.c | |||
@@ -0,0 +1,282 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | |||
16 | extern int main_job(void); | ||
17 | static char* progname; | ||
18 | |||
19 | static void usage(char *error) { | ||
20 | fprintf(stderr, "Error: %s\n", error); | ||
21 | fprintf(stderr, | ||
22 | "Usage:\n" | ||
23 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
24 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
25 | " rt_spin -l\n" | ||
26 | "\n" | ||
27 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
28 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
29 | " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]\n" | ||
30 | "\n" | ||
31 | "WCET and PERIOD are milliseconds, DURATION is seconds.\n" | ||
32 | "CRITICAL SECTION LENGTH is in milliseconds.\n"); | ||
33 | exit(EXIT_FAILURE); | ||
34 | } | ||
35 | |||
36 | static int job(double exec_time, double program_end, int lock_od, double cs_length) | ||
37 | { | ||
38 | if (wctime() > program_end) | ||
39 | return 0; | ||
40 | else { | ||
41 | main_job(); | ||
42 | sleep_next_period(); | ||
43 | return 1; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | #define OPTSTR "p:c:wves:q:X:L:Q:vh:m:i:b:" | ||
48 | int main(int argc, char** argv) | ||
49 | { | ||
50 | int ret; | ||
51 | lt_t wcet; | ||
52 | lt_t period; | ||
53 | lt_t hyperperiod; | ||
54 | lt_t budget; | ||
55 | double wcet_ms, period_ms, hyperperiod_ms, budget_ms; | ||
56 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
57 | int migrate = 0; | ||
58 | int cluster = 0; | ||
59 | int opt; | ||
60 | int wait = 0; | ||
61 | int want_enforcement = 0; | ||
62 | double duration = 0, start = 0; | ||
63 | double scale = 1.0; | ||
64 | task_class_t class = RT_CLASS_HARD; | ||
65 | struct rt_task param; | ||
66 | struct mc2_task mc2_param; | ||
67 | struct reservation_config config; | ||
68 | int res_type = PERIODIC_POLLING; | ||
69 | |||
70 | int verbose = 0; | ||
71 | unsigned int job_no; | ||
72 | |||
73 | /* locking */ | ||
74 | int lock_od = -1; | ||
75 | int resource_id = 0; | ||
76 | const char *lock_namespace = "./rtspin-locks"; | ||
77 | int protocol = -1; | ||
78 | double cs_length = 1; /* millisecond */ | ||
79 | |||
80 | progname = argv[0]; | ||
81 | |||
82 | /* default for reservation */ | ||
83 | config.id = 0; | ||
84 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
85 | config.cpu = -1; | ||
86 | |||
87 | mc2_param.crit = CRIT_LEVEL_C; | ||
88 | |||
89 | hyperperiod_ms = 1000; | ||
90 | budget_ms = 10; | ||
91 | |||
92 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
93 | switch (opt) { | ||
94 | case 'w': | ||
95 | wait = 1; | ||
96 | break; | ||
97 | case 'p': | ||
98 | cluster = atoi(optarg); | ||
99 | migrate = 1; | ||
100 | config.cpu = cluster; | ||
101 | break; | ||
102 | case 'q': | ||
103 | priority = atoi(optarg); | ||
104 | if (!litmus_is_valid_fixed_prio(priority)) | ||
105 | usage("Invalid priority."); | ||
106 | break; | ||
107 | case 'c': | ||
108 | class = str2class(optarg); | ||
109 | if (class == -1) | ||
110 | usage("Unknown task class."); | ||
111 | break; | ||
112 | case 'e': | ||
113 | want_enforcement = 1; | ||
114 | break; | ||
115 | case 's': | ||
116 | scale = atof(optarg); | ||
117 | break; | ||
118 | case 'X': | ||
119 | protocol = lock_protocol_for_name(optarg); | ||
120 | if (protocol < 0) | ||
121 | usage("Unknown locking protocol specified."); | ||
122 | break; | ||
123 | case 'L': | ||
124 | cs_length = atof(optarg); | ||
125 | if (cs_length <= 0) | ||
126 | usage("Invalid critical section length."); | ||
127 | break; | ||
128 | case 'Q': | ||
129 | resource_id = atoi(optarg); | ||
130 | if (resource_id <= 0 && strcmp(optarg, "0")) | ||
131 | usage("Invalid resource ID."); | ||
132 | break; | ||
133 | case 'v': | ||
134 | verbose = 1; | ||
135 | break; | ||
136 | case 'm': | ||
137 | mc2_param.crit = atoi(optarg); | ||
138 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
139 | usage("Invalid criticality level."); | ||
140 | } | ||
141 | res_type = PERIODIC_POLLING; | ||
142 | break; | ||
143 | case 'h': | ||
144 | hyperperiod_ms = atof(optarg); | ||
145 | break; | ||
146 | case 'b': | ||
147 | budget_ms = atof(optarg); | ||
148 | break; | ||
149 | case 'i': | ||
150 | config.priority = atoi(optarg); | ||
151 | break; | ||
152 | case ':': | ||
153 | usage("Argument missing."); | ||
154 | break; | ||
155 | case '?': | ||
156 | default: | ||
157 | usage("Bad argument."); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
163 | usage("Bad criticailty level or priority"); | ||
164 | |||
165 | if (argc - optind < 3) | ||
166 | usage("Arguments missing."); | ||
167 | |||
168 | wcet_ms = atof(argv[optind + 0]); | ||
169 | period_ms = atof(argv[optind + 1]); | ||
170 | |||
171 | wcet = ms2ns(wcet_ms); | ||
172 | period = ms2ns(period_ms); | ||
173 | budget = ms2ns(budget_ms); | ||
174 | hyperperiod = ms2ns(hyperperiod_ms); | ||
175 | |||
176 | if (wcet <= 0) | ||
177 | usage("The worst-case execution time must be a " | ||
178 | "positive number."); | ||
179 | if (period <= 0) | ||
180 | usage("The period must be a positive number."); | ||
181 | if (wcet > period) { | ||
182 | usage("The worst-case execution time must not " | ||
183 | "exceed the period."); | ||
184 | } | ||
185 | |||
186 | duration = atof(argv[optind + 2]); | ||
187 | |||
188 | if (migrate) { | ||
189 | ret = be_migrate_to_domain(cluster); | ||
190 | if (ret < 0) | ||
191 | bail_out("could not migrate to target partition or cluster."); | ||
192 | } | ||
193 | |||
194 | /* reservation config */ | ||
195 | config.id = gettid(); | ||
196 | |||
197 | if (hyperperiod%period != 0 ) { | ||
198 | ;//bail_out("hyperperiod must be multiple of period"); | ||
199 | } | ||
200 | |||
201 | config.polling_params.budget = budget; | ||
202 | config.polling_params.period = period; | ||
203 | config.polling_params.offset = 0; | ||
204 | config.polling_params.relative_deadline = 0; | ||
205 | if (config.polling_params.budget > config.polling_params.period) { | ||
206 | usage("The budget must not exceed the period."); | ||
207 | } | ||
208 | |||
209 | /* create a reservation */ | ||
210 | ret = reservation_create(res_type, &config); | ||
211 | if (ret < 0) { | ||
212 | bail_out("failed to create reservation."); | ||
213 | } | ||
214 | |||
215 | init_rt_task_param(¶m); | ||
216 | param.exec_cost = wcet; | ||
217 | param.period = period; | ||
218 | param.priority = priority; | ||
219 | param.cls = class; | ||
220 | param.release_policy = TASK_PERIODIC; | ||
221 | param.budget_policy = (want_enforcement) ? | ||
222 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
223 | if (migrate) { | ||
224 | param.cpu = gettid(); | ||
225 | } | ||
226 | ret = set_rt_task_param(gettid(), ¶m); | ||
227 | |||
228 | if (ret < 0) | ||
229 | bail_out("could not setup rt task params"); | ||
230 | |||
231 | mc2_param.res_id = gettid(); | ||
232 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
233 | //printf("SET_MC2_TASK\n"); | ||
234 | if (ret < 0) | ||
235 | bail_out("could not setup mc2 task params"); | ||
236 | |||
237 | init_litmus(); | ||
238 | //printf("CALL\n"); | ||
239 | set_page_color(config.cpu); | ||
240 | //printf("CALL\n"); | ||
241 | |||
242 | //printf("INIT_LITMUS\n"); | ||
243 | start = wctime(); | ||
244 | ret = task_mode(LITMUS_RT_TASK); | ||
245 | //printf("TASK_MODE\n"); | ||
246 | if (ret != 0) | ||
247 | bail_out("could not become RT task"); | ||
248 | |||
249 | if (protocol >= 0) { | ||
250 | lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster); | ||
251 | if (lock_od < 0) { | ||
252 | perror("litmus_open_lock"); | ||
253 | usage("Could not open lock."); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | if (wait) { | ||
259 | //printf("BEFORE WAIT\n"); | ||
260 | ret = wait_for_ts_release(); | ||
261 | if (ret != 0) | ||
262 | bail_out("wait_for_ts_release()"); | ||
263 | start = wctime(); | ||
264 | } | ||
265 | |||
266 | do { | ||
267 | if (verbose) { | ||
268 | get_job_no(&job_no); | ||
269 | printf("rtspin/%d:%u @ %.4fms\n", gettid(), | ||
270 | job_no, (wctime() - start) * 1000); | ||
271 | } | ||
272 | } while (job(wcet_ms * 0.001 * scale, start + duration, | ||
273 | lock_od, cs_length * 0.001)); | ||
274 | |||
275 | ret = task_mode(BACKGROUND_TASK); | ||
276 | if (ret != 0) | ||
277 | bail_out("could not become regular task (huh?)"); | ||
278 | |||
279 | reservation_destroy(gettid(), config.cpu); | ||
280 | printf("%s/%d finished.\n",progname, gettid()); | ||
281 | return 0; | ||
282 | } | ||
diff --git a/bin/rt_skeleton_us.c b/bin/rt_skeleton_us.c new file mode 100644 index 0000000..ecf3ed8 --- /dev/null +++ b/bin/rt_skeleton_us.c | |||
@@ -0,0 +1,282 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | |||
16 | extern int main_job(void); | ||
17 | static char* progname; | ||
18 | |||
19 | static void usage(char *error) { | ||
20 | fprintf(stderr, "Error: %s\n", error); | ||
21 | fprintf(stderr, | ||
22 | "Usage:\n" | ||
23 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
24 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
25 | " rt_spin -l\n" | ||
26 | "\n" | ||
27 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
28 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
29 | " [-X LOCKING-PROTOCOL] [-L CRITICAL SECTION LENGTH] [-Q RESOURCE-ID]\n" | ||
30 | "\n" | ||
31 | "WCET and PERIOD are microseconds, DURATION is seconds.\n" | ||
32 | "CRITICAL SECTION LENGTH is in microseconds.\n"); | ||
33 | exit(EXIT_FAILURE); | ||
34 | } | ||
35 | |||
36 | static int job(double exec_time, double program_end, int lock_od, double cs_length) | ||
37 | { | ||
38 | if (wctime() > program_end) | ||
39 | return 0; | ||
40 | else { | ||
41 | main_job(); | ||
42 | sleep_next_period(); | ||
43 | return 1; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | #define OPTSTR "p:c:wves:q:X:L:Q:vh:m:i:b:" | ||
48 | int main(int argc, char** argv) | ||
49 | { | ||
50 | int ret; | ||
51 | lt_t wcet; | ||
52 | lt_t period; | ||
53 | lt_t hyperperiod; | ||
54 | lt_t budget; | ||
55 | double wcet_us, period_us, hyperperiod_us, budget_us; | ||
56 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
57 | int migrate = 0; | ||
58 | int cluster = 0; | ||
59 | int opt; | ||
60 | int wait = 0; | ||
61 | int want_enforcement = 0; | ||
62 | double duration = 0, start = 0; | ||
63 | double scale = 1.0; | ||
64 | task_class_t class = RT_CLASS_HARD; | ||
65 | struct rt_task param; | ||
66 | struct mc2_task mc2_param; | ||
67 | struct reservation_config config; | ||
68 | int res_type = PERIODIC_POLLING; | ||
69 | |||
70 | int verbose = 0; | ||
71 | unsigned int job_no; | ||
72 | |||
73 | /* locking */ | ||
74 | int lock_od = -1; | ||
75 | int resource_id = 0; | ||
76 | const char *lock_namespace = "./rtspin-locks"; | ||
77 | int protocol = -1; | ||
78 | double cs_length = 1; /* millisecond */ | ||
79 | |||
80 | progname = argv[0]; | ||
81 | |||
82 | /* default for reservation */ | ||
83 | config.id = 0; | ||
84 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
85 | config.cpu = -1; | ||
86 | |||
87 | mc2_param.crit = CRIT_LEVEL_C; | ||
88 | |||
89 | hyperperiod_us = 1000000; | ||
90 | budget_us = 10000; | ||
91 | |||
92 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
93 | switch (opt) { | ||
94 | case 'w': | ||
95 | wait = 1; | ||
96 | break; | ||
97 | case 'p': | ||
98 | cluster = atoi(optarg); | ||
99 | migrate = 1; | ||
100 | config.cpu = cluster; | ||
101 | break; | ||
102 | case 'q': | ||
103 | priority = atoi(optarg); | ||
104 | if (!litmus_is_valid_fixed_prio(priority)) | ||
105 | usage("Invalid priority."); | ||
106 | break; | ||
107 | case 'c': | ||
108 | class = str2class(optarg); | ||
109 | if (class == -1) | ||
110 | usage("Unknown task class."); | ||
111 | break; | ||
112 | case 'e': | ||
113 | want_enforcement = 1; | ||
114 | break; | ||
115 | case 's': | ||
116 | scale = atof(optarg); | ||
117 | break; | ||
118 | case 'X': | ||
119 | protocol = lock_protocol_for_name(optarg); | ||
120 | if (protocol < 0) | ||
121 | usage("Unknown locking protocol specified."); | ||
122 | break; | ||
123 | case 'L': | ||
124 | cs_length = atof(optarg); | ||
125 | if (cs_length <= 0) | ||
126 | usage("Invalid critical section length."); | ||
127 | break; | ||
128 | case 'Q': | ||
129 | resource_id = atoi(optarg); | ||
130 | if (resource_id <= 0 && strcmp(optarg, "0")) | ||
131 | usage("Invalid resource ID."); | ||
132 | break; | ||
133 | case 'v': | ||
134 | verbose = 1; | ||
135 | break; | ||
136 | case 'm': | ||
137 | mc2_param.crit = atoi(optarg); | ||
138 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
139 | usage("Invalid criticality level."); | ||
140 | } | ||
141 | res_type = PERIODIC_POLLING; | ||
142 | break; | ||
143 | case 'h': | ||
144 | hyperperiod_us = atof(optarg); | ||
145 | break; | ||
146 | case 'b': | ||
147 | budget_us = atof(optarg); | ||
148 | break; | ||
149 | case 'i': | ||
150 | config.priority = atoi(optarg); | ||
151 | break; | ||
152 | case ':': | ||
153 | usage("Argument missing."); | ||
154 | break; | ||
155 | case '?': | ||
156 | default: | ||
157 | usage("Bad argument."); | ||
158 | break; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
163 | usage("Bad criticailty level or priority"); | ||
164 | |||
165 | if (argc - optind < 3) | ||
166 | usage("Arguments missing."); | ||
167 | |||
168 | wcet_us = atof(argv[optind + 0]); | ||
169 | period_us = atof(argv[optind + 1]); | ||
170 | |||
171 | wcet = us2ns(wcet_us); | ||
172 | period = us2ns(period_us); | ||
173 | budget = us2ns(budget_us); | ||
174 | hyperperiod = us2ns(hyperperiod_us); | ||
175 | |||
176 | if (wcet <= 0) | ||
177 | usage("The worst-case execution time must be a " | ||
178 | "positive number."); | ||
179 | if (period <= 0) | ||
180 | usage("The period must be a positive number."); | ||
181 | if (wcet > period) { | ||
182 | usage("The worst-case execution time must not " | ||
183 | "exceed the period."); | ||
184 | } | ||
185 | |||
186 | duration = atof(argv[optind + 2]); | ||
187 | |||
188 | if (migrate) { | ||
189 | ret = be_migrate_to_domain(cluster); | ||
190 | if (ret < 0) | ||
191 | bail_out("could not migrate to target partition or cluster."); | ||
192 | } | ||
193 | |||
194 | /* reservation config */ | ||
195 | config.id = gettid(); | ||
196 | |||
197 | if (hyperperiod%period != 0 ) { | ||
198 | ;//bail_out("hyperperiod must be multiple of period"); | ||
199 | } | ||
200 | |||
201 | config.polling_params.budget = budget; | ||
202 | config.polling_params.period = period; | ||
203 | config.polling_params.offset = 0; | ||
204 | config.polling_params.relative_deadline = 0; | ||
205 | if (config.polling_params.budget > config.polling_params.period) { | ||
206 | usage("The budget must not exceed the period."); | ||
207 | } | ||
208 | |||
209 | /* create a reservation */ | ||
210 | ret = reservation_create(res_type, &config); | ||
211 | if (ret < 0) { | ||
212 | bail_out("failed to create reservation."); | ||
213 | } | ||
214 | |||
215 | init_rt_task_param(¶m); | ||
216 | param.exec_cost = wcet; | ||
217 | param.period = period; | ||
218 | param.priority = priority; | ||
219 | param.cls = class; | ||
220 | param.release_policy = TASK_PERIODIC; | ||
221 | param.budget_policy = (want_enforcement) ? | ||
222 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
223 | if (migrate) { | ||
224 | param.cpu = gettid(); | ||
225 | } | ||
226 | ret = set_rt_task_param(gettid(), ¶m); | ||
227 | |||
228 | if (ret < 0) | ||
229 | bail_out("could not setup rt task params"); | ||
230 | |||
231 | mc2_param.res_id = gettid(); | ||
232 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
233 | //printf("SET_MC2_TASK\n"); | ||
234 | if (ret < 0) | ||
235 | bail_out("could not setup mc2 task params"); | ||
236 | |||
237 | init_litmus(); | ||
238 | //printf("CALL\n"); | ||
239 | set_page_color(config.cpu); | ||
240 | //printf("CALL\n"); | ||
241 | |||
242 | //printf("INIT_LITMUS\n"); | ||
243 | start = wctime(); | ||
244 | ret = task_mode(LITMUS_RT_TASK); | ||
245 | //printf("TASK_MODE\n"); | ||
246 | if (ret != 0) | ||
247 | bail_out("could not become RT task"); | ||
248 | |||
249 | if (protocol >= 0) { | ||
250 | lock_od = litmus_open_lock(protocol, resource_id, lock_namespace, &cluster); | ||
251 | if (lock_od < 0) { | ||
252 | perror("litmus_open_lock"); | ||
253 | usage("Could not open lock."); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | |||
258 | if (wait) { | ||
259 | //printf("BEFORE WAIT\n"); | ||
260 | ret = wait_for_ts_release(); | ||
261 | if (ret != 0) | ||
262 | bail_out("wait_for_ts_release()"); | ||
263 | start = wctime(); | ||
264 | } | ||
265 | |||
266 | do { | ||
267 | if (verbose) { | ||
268 | get_job_no(&job_no); | ||
269 | printf("rtspin/%d:%u @ %.4fms\n", gettid(), | ||
270 | job_no, (wctime() - start) * 1000); | ||
271 | } | ||
272 | } while (job(wcet_us * 0.000001 * scale, start + duration, | ||
273 | lock_od, cs_length * 0.000001)); | ||
274 | |||
275 | ret = task_mode(BACKGROUND_TASK); | ||
276 | if (ret != 0) | ||
277 | bail_out("could not become regular task (huh?)"); | ||
278 | |||
279 | reservation_destroy(gettid(), config.cpu); | ||
280 | printf("%s/%d finished.\n",progname, gettid()); | ||
281 | return 0; | ||
282 | } | ||
diff --git a/bin/rt_transitive.c b/bin/rt_transitive.c new file mode 100644 index 0000000..dfad0da --- /dev/null +++ b/bin/rt_transitive.c | |||
@@ -0,0 +1,362 @@ | |||
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 | |||
12 | #include "litmus.h" | ||
13 | #include "common.h" | ||
14 | #include "DISstressmarkRNG.h" | ||
15 | |||
16 | #define MIN_VERTICES 8 | ||
17 | #define MAX_VERTICES 16384 | ||
18 | #define MIN_EDGES 0 | ||
19 | #define MAX_EDGES 268435456 | ||
20 | #define MIN_SEED -2147483647 | ||
21 | #define MAX_SEED -1 | ||
22 | #define NO_PATH 2147483647 | ||
23 | |||
24 | #define MIN_EDGS 0 | ||
25 | #define MAX_EDGE 255 | ||
26 | |||
27 | |||
28 | static char* progname; | ||
29 | int loops = 1; | ||
30 | |||
31 | struct timeval t1, t2; | ||
32 | |||
33 | unsigned int *din, *dout; | ||
34 | unsigned int n, n_max; | ||
35 | unsigned int m, m_max; | ||
36 | int seed; | ||
37 | |||
38 | int init_job(){ | ||
39 | //fscanf(stdin,"%d %d %d", &n, &m, &seed); | ||
40 | n_max = 100; | ||
41 | m_max = 400; | ||
42 | //n_max = 100; | ||
43 | //m_max = 1000; | ||
44 | seed = -2; | ||
45 | |||
46 | assert((n_max >= MIN_VERTICES) && (n_max <= MAX_VERTICES)); | ||
47 | assert((m_max >= MIN_EDGES) && (m_max <= MAX_EDGES)); | ||
48 | assert (m_max <= n_max*n_max); | ||
49 | assert ((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
50 | |||
51 | if ((din = (unsigned int *)malloc(n_max*n_max*sizeof(unsigned int))) == NULL) | ||
52 | return (-1); | ||
53 | if ((dout = (unsigned int *)malloc(n_max*n_max*sizeof(unsigned int))) == NULL) | ||
54 | return (-1); | ||
55 | |||
56 | |||
57 | |||
58 | //srand (time(NULL)); | ||
59 | randInit(seed); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | int main_job() { | ||
65 | unsigned int i, j, k; | ||
66 | unsigned int sum; | ||
67 | |||
68 | /* online */ | ||
69 | /* n = randInt(10, n_max); | ||
70 | m = randInt(100, m_max); | ||
71 | */ | ||
72 | |||
73 | /* case */ | ||
74 | n = randInt(5, 50); | ||
75 | m = randInt(10, 100); | ||
76 | |||
77 | for (i=0; i<n_max*n_max; i++){ | ||
78 | *(din + i) = NO_PATH; | ||
79 | *(dout + i) = NO_PATH; | ||
80 | } | ||
81 | |||
82 | for (k=0; k<m; k++){ | ||
83 | i = randInt(0, n); | ||
84 | j = randInt(0, n); | ||
85 | *(din + j*n + i) = randInt(MIN_EDGES, MAX_EDGES); | ||
86 | } | ||
87 | |||
88 | for (k=0; k<n; k++){ | ||
89 | unsigned int old; | ||
90 | unsigned int new1; | ||
91 | unsigned int *dtemp; | ||
92 | |||
93 | for (i=0; i<n; i++){ | ||
94 | for (j=0; j<n; j++){ | ||
95 | old = *(din + j*n + i); | ||
96 | new1 = *(din + j*n + k) + *(din + k*n + i); | ||
97 | *(dout + j*n + i) = (new1 < old ? new1: old); | ||
98 | assert (*(dout + j*n + i) <= NO_PATH); | ||
99 | assert (*(dout + j*n + i) <= *(din + j*n + i)); | ||
100 | } | ||
101 | } | ||
102 | dtemp = dout; | ||
103 | dout = din; | ||
104 | din = dtemp; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | for (j=0; j<n; j++){ | ||
109 | sum = 0; | ||
110 | for (i=0; i<n; i++){ | ||
111 | if (*(din + j*n + i) != NO_PATH) | ||
112 | sum += *(din + j*n + i); | ||
113 | } | ||
114 | } | ||
115 | for (i=0; i<n; i++){ | ||
116 | sum = 0; | ||
117 | for (j=0; j<n; j++){ | ||
118 | if (*(din + j*n + i) != NO_PATH) | ||
119 | sum += *(din+j*n+i); | ||
120 | } | ||
121 | } | ||
122 | */ | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | int post_job() { | ||
127 | if (din) { | ||
128 | //free(din); | ||
129 | din = NULL; | ||
130 | } | ||
131 | if (dout) { | ||
132 | //free(dout); | ||
133 | dout = NULL; | ||
134 | } | ||
135 | return(0); | ||
136 | } | ||
137 | |||
138 | static void usage(char *error) { | ||
139 | fprintf(stderr, "Error: %s\n", error); | ||
140 | fprintf(stderr, | ||
141 | "Usage:\n" | ||
142 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
143 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
144 | " rt_spin -l\n" | ||
145 | "\n" | ||
146 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
147 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
148 | "\n" | ||
149 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
150 | exit(EXIT_FAILURE); | ||
151 | } | ||
152 | |||
153 | inline unsigned long get_cyclecount (void) | ||
154 | { | ||
155 | unsigned long value; | ||
156 | // Read CCNT Register | ||
157 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
158 | return value; | ||
159 | } | ||
160 | |||
161 | static int job(double exec_time, double program_end) | ||
162 | { | ||
163 | if (wctime() > program_end) | ||
164 | return 0; | ||
165 | else { | ||
166 | register int iter = 0; | ||
167 | //register unsigned long t; | ||
168 | //t = get_cyclecount(); | ||
169 | gettimeofday(&t1, NULL); | ||
170 | while (iter++ < loops) { | ||
171 | main_job(); | ||
172 | } | ||
173 | //t = get_cyclecount() - t; | ||
174 | //printf("%ld cycles\n", t); | ||
175 | gettimeofday(&t2, NULL); | ||
176 | printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
177 | sleep_next_period(); | ||
178 | return 1; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | #define OPTSTR "p:wves:l:m:i:b:" | ||
183 | int main(int argc, char** argv) | ||
184 | { | ||
185 | int ret; | ||
186 | lt_t wcet; | ||
187 | lt_t period; | ||
188 | lt_t budget; | ||
189 | double wcet_ms, period_ms, budget_ms; | ||
190 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
191 | int migrate = 0; | ||
192 | int cluster = 0; | ||
193 | int opt; | ||
194 | int wait = 0; | ||
195 | int want_enforcement = 0; | ||
196 | double duration = 0, start = 0; | ||
197 | double scale = 1.0; | ||
198 | task_class_t class = RT_CLASS_HARD; | ||
199 | struct rt_task param; | ||
200 | struct mc2_task mc2_param; | ||
201 | struct reservation_config config; | ||
202 | int res_type = PERIODIC_POLLING; | ||
203 | |||
204 | progname = argv[0]; | ||
205 | |||
206 | /* default for reservation */ | ||
207 | config.id = 0; | ||
208 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
209 | config.cpu = -1; | ||
210 | |||
211 | mc2_param.crit = CRIT_LEVEL_C; | ||
212 | |||
213 | budget_ms = 10; | ||
214 | |||
215 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
216 | switch (opt) { | ||
217 | case 'w': | ||
218 | wait = 1; | ||
219 | break; | ||
220 | case 'p': | ||
221 | cluster = atoi(optarg); | ||
222 | migrate = 1; | ||
223 | config.cpu = cluster; | ||
224 | break; | ||
225 | case 'e': | ||
226 | want_enforcement = 1; | ||
227 | break; | ||
228 | case 's': | ||
229 | scale = atof(optarg); | ||
230 | break; | ||
231 | case 'l': | ||
232 | loops = atoi(optarg); | ||
233 | break; | ||
234 | case 'm': | ||
235 | mc2_param.crit = atoi(optarg); | ||
236 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
237 | usage("Invalid criticality level."); | ||
238 | } | ||
239 | res_type = PERIODIC_POLLING; | ||
240 | break; | ||
241 | case 'b': | ||
242 | budget_ms = atof(optarg); | ||
243 | break; | ||
244 | case 'i': | ||
245 | config.priority = atoi(optarg); | ||
246 | break; | ||
247 | case ':': | ||
248 | usage("Argument missing."); | ||
249 | break; | ||
250 | case '?': | ||
251 | default: | ||
252 | usage("Bad argument."); | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
258 | usage("Bad criticailty level or priority"); | ||
259 | |||
260 | if (argc - optind < 3) | ||
261 | usage("Arguments missing."); | ||
262 | |||
263 | wcet_ms = atof(argv[optind + 0]); | ||
264 | period_ms = atof(argv[optind + 1]); | ||
265 | |||
266 | wcet = ms2ns(wcet_ms); | ||
267 | period = ms2ns(period_ms); | ||
268 | budget = ms2ns(budget_ms); | ||
269 | |||
270 | if (wcet <= 0) | ||
271 | usage("The worst-case execution time must be a " | ||
272 | "positive number."); | ||
273 | if (period <= 0) | ||
274 | usage("The period must be a positive number."); | ||
275 | if (wcet > period) { | ||
276 | usage("The worst-case execution time must not " | ||
277 | "exceed the period."); | ||
278 | } | ||
279 | |||
280 | duration = atof(argv[optind + 2]); | ||
281 | |||
282 | if (migrate) { | ||
283 | ret = be_migrate_to_domain(cluster); | ||
284 | if (ret < 0) | ||
285 | bail_out("could not migrate to target partition or cluster."); | ||
286 | } | ||
287 | |||
288 | /* reservation config */ | ||
289 | config.id = gettid(); | ||
290 | |||
291 | config.polling_params.budget = budget; | ||
292 | config.polling_params.period = period; | ||
293 | config.polling_params.offset = 0; | ||
294 | config.polling_params.relative_deadline = 0; | ||
295 | if (config.polling_params.budget > config.polling_params.period) { | ||
296 | usage("The budget must not exceed the period."); | ||
297 | } | ||
298 | |||
299 | /* create a reservation */ | ||
300 | ret = reservation_create(res_type, &config); | ||
301 | if (ret < 0) { | ||
302 | bail_out("failed to create reservation."); | ||
303 | } | ||
304 | init_job(); | ||
305 | |||
306 | init_rt_task_param(¶m); | ||
307 | param.exec_cost = wcet; | ||
308 | param.period = period; | ||
309 | param.priority = priority; | ||
310 | param.cls = class; | ||
311 | param.release_policy = TASK_PERIODIC; | ||
312 | param.budget_policy = (want_enforcement) ? | ||
313 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
314 | if (migrate) { | ||
315 | param.cpu = gettid(); | ||
316 | } | ||
317 | ret = set_rt_task_param(gettid(), ¶m); | ||
318 | |||
319 | if (ret < 0) | ||
320 | bail_out("could not setup rt task params"); | ||
321 | |||
322 | mc2_param.res_id = gettid(); | ||
323 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
324 | //printf("SET_MC2_TASK\n"); | ||
325 | if (ret < 0) | ||
326 | bail_out("could not setup mc2 task params"); | ||
327 | |||
328 | init_litmus(); | ||
329 | //printf("CALL\n"); | ||
330 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
331 | set_page_color(-1); | ||
332 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
333 | set_page_color(config.cpu); | ||
334 | //printf("CALL\n"); | ||
335 | |||
336 | //printf("INIT_LITMUS\n"); | ||
337 | start = wctime(); | ||
338 | ret = task_mode(LITMUS_RT_TASK); | ||
339 | //printf("TASK_MODE\n"); | ||
340 | if (ret != 0) | ||
341 | bail_out("could not become RT task"); | ||
342 | |||
343 | |||
344 | if (wait) { | ||
345 | //printf("BEFORE WAIT\n"); | ||
346 | ret = wait_for_ts_release(); | ||
347 | if (ret != 0) | ||
348 | bail_out("wait_for_ts_release()"); | ||
349 | start = wctime(); | ||
350 | } | ||
351 | |||
352 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
353 | |||
354 | ret = task_mode(BACKGROUND_TASK); | ||
355 | if (ret != 0) | ||
356 | bail_out("could not become regular task (huh?)"); | ||
357 | |||
358 | reservation_destroy(gettid(), config.cpu); | ||
359 | post_job(); | ||
360 | printf("%s/%d finished.\n",progname, gettid()); | ||
361 | return 0; | ||
362 | } | ||
diff --git a/bin/rt_update.c b/bin/rt_update.c new file mode 100644 index 0000000..4995071 --- /dev/null +++ b/bin/rt_update.c | |||
@@ -0,0 +1,387 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | |||
17 | #define MIN_FIELD_SIZE 16 | ||
18 | #define MAX_FIELD_SIZE 16777216 | ||
19 | #define MIN_WINDOW_SIZE 1 | ||
20 | #define MAX_WINDOW_SIZE 15 | ||
21 | #define MIN_HOP_LIMIT 1 | ||
22 | #define MAX_HOP_LIMIT 4294967295U | ||
23 | #define MIN_SEED -2147483647 | ||
24 | #define MAX_SEED -1 | ||
25 | |||
26 | |||
27 | static char* progname; | ||
28 | int loops = 1; | ||
29 | |||
30 | struct timeval t1, t2; | ||
31 | |||
32 | unsigned int *field; | ||
33 | unsigned int f_max; | ||
34 | unsigned int idx; | ||
35 | unsigned short int w; | ||
36 | unsigned int maxhops; | ||
37 | int seed; | ||
38 | unsigned int initial; | ||
39 | unsigned int minStop; | ||
40 | unsigned int maxStop; | ||
41 | unsigned int hops; | ||
42 | |||
43 | int init_job(){ | ||
44 | //fscanf(stdin, "%u %u %u %d %u %u %u", &f, &l, &maxhops, &seed, &initial, &minStop, &maxStop); | ||
45 | //f_max = 819200; | ||
46 | f_max = 409600; | ||
47 | //f_max = 120000; // for case study | ||
48 | maxhops = 1024000; | ||
49 | seed = -2; | ||
50 | initial = 10; | ||
51 | minStop = f_max - 1; | ||
52 | maxStop = minStop; | ||
53 | |||
54 | assert((f_max >= MIN_FIELD_SIZE) && (f_max <= MAX_FIELD_SIZE)); | ||
55 | |||
56 | |||
57 | assert((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT)); | ||
58 | assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
59 | assert((initial >= 0) && (initial < f_max)); | ||
60 | assert((minStop >= 0) && (minStop < f_max)); | ||
61 | assert((maxStop >= 0) && (maxStop < f_max)); | ||
62 | |||
63 | if ((field = (unsigned int *)malloc(f_max*sizeof(int))) == NULL) | ||
64 | return (-1); | ||
65 | srand (time(NULL)); | ||
66 | //randInit(-rand()%65535); | ||
67 | randInit(seed); | ||
68 | //randInit(seed); | ||
69 | /*for (l=0; l<f; l++){ | ||
70 | field[l] = randInt(0, f-w); | ||
71 | } | ||
72 | */ | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | int main_job() { | ||
77 | unsigned int f; | ||
78 | unsigned int l; | ||
79 | |||
80 | /* for online-appendix */ | ||
81 | f = randInt(65536, f_max); | ||
82 | //w = randInt(1,7); | ||
83 | //w = w*2 + 1; | ||
84 | w = 3; | ||
85 | maxhops = randInt(80000, 409600); | ||
86 | minStop = f - 10; | ||
87 | maxStop = f - 1; | ||
88 | |||
89 | /* for case-study */ | ||
90 | /* f = randInt(1024,120000); //409600); | ||
91 | w = 1; | ||
92 | maxhops = 1024; //4096; | ||
93 | minStop = f - 1; | ||
94 | maxStop = minStop; | ||
95 | */ | ||
96 | |||
97 | initial = 1; | ||
98 | |||
99 | assert((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE)); | ||
100 | assert(w%2 == 1); | ||
101 | assert(f > w); | ||
102 | |||
103 | for (l=0; l<f; l++){ | ||
104 | field[l] = randInt(0, f-w); | ||
105 | } | ||
106 | |||
107 | hops = 0; | ||
108 | idx = initial; | ||
109 | |||
110 | while ((hops < maxhops) && | ||
111 | (!((idx >= minStop) && | ||
112 | (idx < maxStop)))){ | ||
113 | int sum; | ||
114 | |||
115 | unsigned int ll, lll; | ||
116 | unsigned int max, min; | ||
117 | unsigned int partition; | ||
118 | unsigned int high; | ||
119 | max = MAX_FIELD_SIZE; | ||
120 | min = 0; | ||
121 | high = 0; | ||
122 | sum = 0; | ||
123 | |||
124 | for (ll=0; ll<w; ll++){ | ||
125 | unsigned int balance; | ||
126 | unsigned int x; | ||
127 | x = field[idx+ll]; | ||
128 | sum += x; | ||
129 | |||
130 | if (x > max) high++; | ||
131 | else if (x >min){ /* start else* */ | ||
132 | partition = x; | ||
133 | balance = 0; | ||
134 | for (lll=ll+1; lll<w; lll++){ | ||
135 | if (field[idx+lll] > partition) balance++; | ||
136 | } | ||
137 | if (balance+high == w/2) break; | ||
138 | else if (balance+high>w/2){ | ||
139 | min = partition; | ||
140 | }/* end if */ | ||
141 | else{ | ||
142 | max = partition; | ||
143 | high++; | ||
144 | } /* end else */ | ||
145 | } | ||
146 | if (min == max) break; | ||
147 | }/* end else* */ | ||
148 | field[idx] = sum % (f-w); | ||
149 | idx = (partition+hops)%(f-w); | ||
150 | hops++; | ||
151 | }/* end for loop */ | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | int post_job() { | ||
156 | free(field); | ||
157 | return(1); | ||
158 | } | ||
159 | |||
160 | static void usage(char *error) { | ||
161 | fprintf(stderr, "Error: %s\n", error); | ||
162 | fprintf(stderr, | ||
163 | "Usage:\n" | ||
164 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
165 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
166 | " rt_spin -l\n" | ||
167 | "\n" | ||
168 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
169 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
170 | "\n" | ||
171 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
172 | exit(EXIT_FAILURE); | ||
173 | } | ||
174 | |||
175 | inline unsigned long get_cyclecount (void) | ||
176 | { | ||
177 | unsigned long value; | ||
178 | // Read CCNT Register | ||
179 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
180 | return value; | ||
181 | } | ||
182 | |||
183 | static int job(double exec_time, double program_end) | ||
184 | { | ||
185 | if (wctime() > program_end) | ||
186 | return 0; | ||
187 | else { | ||
188 | //register int iter = 0; | ||
189 | //register unsigned long t; | ||
190 | //t = get_cyclecount(); | ||
191 | //gettimeofday(&t1, NULL); | ||
192 | //while (iter++ < loops) { | ||
193 | main_job(); | ||
194 | //} | ||
195 | //t = get_cyclecount() - t; | ||
196 | //printf("%ld cycles\n", t); | ||
197 | //gettimeofday(&t2, NULL); | ||
198 | //printf("%ld\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
199 | sleep_next_period(); | ||
200 | return 1; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | #define OPTSTR "p:wves:l:m:i:b:" | ||
205 | int main(int argc, char** argv) | ||
206 | { | ||
207 | int ret; | ||
208 | lt_t wcet; | ||
209 | lt_t period; | ||
210 | lt_t budget; | ||
211 | double wcet_ms, period_ms, budget_ms; | ||
212 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
213 | int migrate = 0; | ||
214 | int cluster = 0; | ||
215 | int opt; | ||
216 | int wait = 0; | ||
217 | int want_enforcement = 0; | ||
218 | double duration = 0, start = 0; | ||
219 | double scale = 1.0; | ||
220 | task_class_t class = RT_CLASS_HARD; | ||
221 | struct rt_task param; | ||
222 | struct mc2_task mc2_param; | ||
223 | struct reservation_config config; | ||
224 | int res_type = PERIODIC_POLLING; | ||
225 | |||
226 | unsigned int job_no; | ||
227 | |||
228 | |||
229 | progname = argv[0]; | ||
230 | |||
231 | /* default for reservation */ | ||
232 | config.id = 0; | ||
233 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
234 | config.cpu = -1; | ||
235 | |||
236 | mc2_param.crit = CRIT_LEVEL_C; | ||
237 | |||
238 | budget_ms = 10; | ||
239 | |||
240 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
241 | switch (opt) { | ||
242 | case 'w': | ||
243 | wait = 1; | ||
244 | break; | ||
245 | case 'p': | ||
246 | cluster = atoi(optarg); | ||
247 | migrate = 1; | ||
248 | config.cpu = cluster; | ||
249 | break; | ||
250 | case 'e': | ||
251 | want_enforcement = 1; | ||
252 | break; | ||
253 | case 's': | ||
254 | scale = atof(optarg); | ||
255 | break; | ||
256 | case 'l': | ||
257 | loops = atoi(optarg); | ||
258 | break; | ||
259 | case 'm': | ||
260 | mc2_param.crit = atoi(optarg); | ||
261 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
262 | usage("Invalid criticality level."); | ||
263 | } | ||
264 | res_type = PERIODIC_POLLING; | ||
265 | break; | ||
266 | case 'b': | ||
267 | budget_ms = atof(optarg); | ||
268 | break; | ||
269 | case 'i': | ||
270 | config.priority = atoi(optarg); | ||
271 | break; | ||
272 | case ':': | ||
273 | usage("Argument missing."); | ||
274 | break; | ||
275 | case '?': | ||
276 | default: | ||
277 | usage("Bad argument."); | ||
278 | break; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
283 | usage("Bad criticailty level or priority"); | ||
284 | |||
285 | if (argc - optind < 3) | ||
286 | usage("Arguments missing."); | ||
287 | |||
288 | wcet_ms = atof(argv[optind + 0]); | ||
289 | period_ms = atof(argv[optind + 1]); | ||
290 | |||
291 | wcet = ms2ns(wcet_ms); | ||
292 | period = ms2ns(period_ms); | ||
293 | budget = ms2ns(budget_ms); | ||
294 | |||
295 | if (wcet <= 0) | ||
296 | usage("The worst-case execution time must be a " | ||
297 | "positive number."); | ||
298 | if (period <= 0) | ||
299 | usage("The period must be a positive number."); | ||
300 | if (wcet > period) { | ||
301 | usage("The worst-case execution time must not " | ||
302 | "exceed the period."); | ||
303 | } | ||
304 | |||
305 | duration = atof(argv[optind + 2]); | ||
306 | |||
307 | if (migrate) { | ||
308 | ret = be_migrate_to_domain(cluster); | ||
309 | if (ret < 0) | ||
310 | bail_out("could not migrate to target partition or cluster."); | ||
311 | } | ||
312 | |||
313 | /* reservation config */ | ||
314 | config.id = gettid(); | ||
315 | |||
316 | config.polling_params.budget = budget; | ||
317 | config.polling_params.period = period; | ||
318 | config.polling_params.offset = 0; | ||
319 | config.polling_params.relative_deadline = 0; | ||
320 | if (config.polling_params.budget > config.polling_params.period) { | ||
321 | usage("The budget must not exceed the period."); | ||
322 | } | ||
323 | |||
324 | /* create a reservation */ | ||
325 | ret = reservation_create(res_type, &config); | ||
326 | if (ret < 0) { | ||
327 | bail_out("failed to create reservation."); | ||
328 | } | ||
329 | init_job(); | ||
330 | |||
331 | init_rt_task_param(¶m); | ||
332 | param.exec_cost = wcet; | ||
333 | param.period = period; | ||
334 | param.priority = priority; | ||
335 | param.cls = class; | ||
336 | param.release_policy = TASK_PERIODIC; | ||
337 | param.budget_policy = (want_enforcement) ? | ||
338 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
339 | if (migrate) { | ||
340 | param.cpu = gettid(); | ||
341 | } | ||
342 | ret = set_rt_task_param(gettid(), ¶m); | ||
343 | |||
344 | if (ret < 0) | ||
345 | bail_out("could not setup rt task params"); | ||
346 | |||
347 | mc2_param.res_id = gettid(); | ||
348 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
349 | //printf("SET_MC2_TASK\n"); | ||
350 | if (ret < 0) | ||
351 | bail_out("could not setup mc2 task params"); | ||
352 | |||
353 | init_litmus(); | ||
354 | //printf("CALL\n"); | ||
355 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
356 | set_page_color(-1); | ||
357 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
358 | set_page_color(config.cpu); | ||
359 | //printf("CALL\n"); | ||
360 | |||
361 | //printf("INIT_LITMUS\n"); | ||
362 | start = wctime(); | ||
363 | ret = task_mode(LITMUS_RT_TASK); | ||
364 | //printf("TASK_MODE\n"); | ||
365 | if (ret != 0) | ||
366 | bail_out("could not become RT task"); | ||
367 | |||
368 | |||
369 | if (wait) { | ||
370 | //printf("BEFORE WAIT\n"); | ||
371 | ret = wait_for_ts_release(); | ||
372 | if (ret != 0) | ||
373 | bail_out("wait_for_ts_release()"); | ||
374 | start = wctime(); | ||
375 | } | ||
376 | |||
377 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
378 | |||
379 | ret = task_mode(BACKGROUND_TASK); | ||
380 | if (ret != 0) | ||
381 | bail_out("could not become regular task (huh?)"); | ||
382 | |||
383 | reservation_destroy(gettid(), config.cpu); | ||
384 | post_job(); | ||
385 | printf("%s/%d finished.\n",progname, gettid()); | ||
386 | return 0; | ||
387 | } | ||
diff --git a/bin/rt_update_spin.c b/bin/rt_update_spin.c new file mode 100644 index 0000000..259b03f --- /dev/null +++ b/bin/rt_update_spin.c | |||
@@ -0,0 +1,398 @@ | |||
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 | |||
12 | |||
13 | #include "litmus.h" | ||
14 | #include "common.h" | ||
15 | #include "DISstressmarkRNG.h" | ||
16 | |||
17 | #define MIN_FIELD_SIZE 16 | ||
18 | #define MAX_FIELD_SIZE 16777216 | ||
19 | #define MIN_WINDOW_SIZE 1 | ||
20 | #define MAX_WINDOW_SIZE 15 | ||
21 | #define MIN_HOP_LIMIT 1 | ||
22 | #define MAX_HOP_LIMIT 4294967295U | ||
23 | #define MIN_SEED -2147483647 | ||
24 | #define MAX_SEED -1 | ||
25 | |||
26 | |||
27 | static char* progname; | ||
28 | int loops = 1; | ||
29 | |||
30 | //struct timeval t1, t2; | ||
31 | |||
32 | unsigned int *field; | ||
33 | unsigned int f; | ||
34 | unsigned int idx; | ||
35 | unsigned short int w; | ||
36 | unsigned int maxhops; | ||
37 | int seed; | ||
38 | unsigned int initial; | ||
39 | unsigned int minStop; | ||
40 | unsigned int maxStop; | ||
41 | unsigned int hops; | ||
42 | unsigned int l; | ||
43 | |||
44 | int init_job(){ | ||
45 | //fscanf(stdin, "%u %u %u %d %u %u %u", &f, &l, &maxhops, &seed, &initial, &minStop, &maxStop); | ||
46 | f = 262145; | ||
47 | l = 15; | ||
48 | maxhops = 102400; | ||
49 | seed = -2; | ||
50 | initial = 10; | ||
51 | minStop = f - 1; | ||
52 | maxStop = minStop; | ||
53 | |||
54 | assert((f >= MIN_FIELD_SIZE) && (f <= MAX_FIELD_SIZE)); | ||
55 | w = (unsigned int )l; | ||
56 | assert((w >= MIN_WINDOW_SIZE) && (w <= MAX_WINDOW_SIZE)); | ||
57 | assert(w%2 == 1); | ||
58 | assert(f > w); | ||
59 | assert((maxhops >= MIN_HOP_LIMIT) && (maxhops <= MAX_HOP_LIMIT)); | ||
60 | assert((seed >= MIN_SEED) && (seed <= MAX_SEED)); | ||
61 | assert((initial >= 0) && (initial < f)); | ||
62 | assert((minStop >= 0) && (minStop < f)); | ||
63 | assert((maxStop >= 0) && (maxStop < f)); | ||
64 | |||
65 | if ((field = (unsigned int *)malloc(f*sizeof(int))) == NULL) | ||
66 | return (-1); | ||
67 | |||
68 | srand (time(NULL)); | ||
69 | randInit(-rand()%65535); | ||
70 | /* randInit(seed); | ||
71 | for (l=0; l<f; l++){ | ||
72 | field[l] = randInt(0, f-w); | ||
73 | } | ||
74 | */ | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | int main_job() { | ||
79 | f = randInt(1024, 262145); | ||
80 | l = randInt(1,7); | ||
81 | l = l*2 + 1; | ||
82 | maxhops = randInt(1024, 4096); | ||
83 | minStop = f - 1; | ||
84 | maxStop = minStop; | ||
85 | |||
86 | for (l=0; l<f; l++){ | ||
87 | field[l] = randInt(0, f-w); | ||
88 | } | ||
89 | |||
90 | hops = 0; | ||
91 | idx = initial; | ||
92 | |||
93 | while ((hops < maxhops) && | ||
94 | (!((idx >= minStop) && | ||
95 | (idx < maxStop)))){ | ||
96 | int sum; | ||
97 | |||
98 | unsigned int ll, lll; | ||
99 | unsigned int max, min; | ||
100 | unsigned int partition; | ||
101 | unsigned int high; | ||
102 | max = MAX_FIELD_SIZE; | ||
103 | min = 0; | ||
104 | high = 0; | ||
105 | sum = 0; | ||
106 | |||
107 | for (ll=0; ll<w; ll++){ | ||
108 | unsigned int balance; | ||
109 | unsigned int x; | ||
110 | x = field[idx+ll]; | ||
111 | sum += x; | ||
112 | |||
113 | if (x > max) high++; | ||
114 | else if (x >min){ /* start else* */ | ||
115 | partition = x; | ||
116 | balance = 0; | ||
117 | for (lll=ll+1; lll<w; lll++){ | ||
118 | if (field[idx+lll] > partition) balance++; | ||
119 | } | ||
120 | if (balance+high == w/2) break; | ||
121 | else if (balance+high>w/2){ | ||
122 | min = partition; | ||
123 | }/* end if */ | ||
124 | else{ | ||
125 | max = partition; | ||
126 | high++; | ||
127 | } /* end else */ | ||
128 | } | ||
129 | if (min == max) break; | ||
130 | }/* end else* */ | ||
131 | field[idx] = sum % (f-w); | ||
132 | idx = (partition+hops)%(f-w); | ||
133 | hops++; | ||
134 | }/* end for loop */ | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | int post_job() { | ||
139 | free(field); | ||
140 | return(1); | ||
141 | } | ||
142 | |||
143 | static void usage(char *error) { | ||
144 | fprintf(stderr, "Error: %s\n", error); | ||
145 | fprintf(stderr, | ||
146 | "Usage:\n" | ||
147 | " rt_spin [COMMON-OPTS] WCET PERIOD DURATION\n" | ||
148 | " rt_spin [COMMON-OPTS] -f FILE [-o COLUMN] WCET PERIOD\n" | ||
149 | " rt_spin -l\n" | ||
150 | "\n" | ||
151 | "COMMON-OPTS = [-w] [-s SCALE]\n" | ||
152 | " [-p PARTITION/CLUSTER [-z CLUSTER SIZE]] [-c CLASS] [-m CRITICALITY LEVEL]\n" | ||
153 | "\n" | ||
154 | "WCET and PERIOD are microseconds, DURATION is seconds.\n"); | ||
155 | exit(EXIT_FAILURE); | ||
156 | } | ||
157 | |||
158 | inline unsigned long get_cyclecount (void) | ||
159 | { | ||
160 | unsigned long value; | ||
161 | // Read CCNT Register | ||
162 | asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value)); | ||
163 | return value; | ||
164 | } | ||
165 | |||
166 | static int loop_main(double exec_time, double emergency_exit) | ||
167 | { | ||
168 | double last_loop = 0, loop_start; | ||
169 | int tmp = 0; | ||
170 | |||
171 | double start = cputime(); | ||
172 | double now = cputime(); | ||
173 | |||
174 | while (now + last_loop < start + exec_time) { | ||
175 | loop_start = now; | ||
176 | tmp += main_job(); | ||
177 | now = cputime(); | ||
178 | last_loop = now - loop_start; | ||
179 | if (emergency_exit && wctime() > emergency_exit) { | ||
180 | /* Oops --- this should only be possible if the execution time tracking | ||
181 | * is broken in the LITMUS^RT kernel. */ | ||
182 | fprintf(stderr, "!!! rtspin/%d emergency exit!\n", getpid()); | ||
183 | fprintf(stderr, "Something is seriously wrong! Do not ignore this.\n"); | ||
184 | break; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | return tmp; | ||
189 | } | ||
190 | |||
191 | static int job(double exec_time, double program_end) | ||
192 | { | ||
193 | if (wctime() > program_end) | ||
194 | return 0; | ||
195 | else { | ||
196 | register int iter = 0; | ||
197 | //register unsigned long t; | ||
198 | //t = get_cyclecount(); | ||
199 | //gettimeofday(&t1, NULL); | ||
200 | //while (iter++ < loops) { | ||
201 | loop_main(exec_time, program_end + 1); | ||
202 | //} | ||
203 | //t = get_cyclecount() - t; | ||
204 | //printf("%ld cycles\n", t); | ||
205 | //gettimeofday(&t2, NULL); | ||
206 | //printf("%ld us\n", ((t2.tv_sec * 1000000 + t2.tv_usec) - (t1.tv_sec * 1000000 + t1.tv_usec))); | ||
207 | sleep_next_period(); | ||
208 | return 1; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | #define OPTSTR "p:wves:l:m:i:b:" | ||
213 | int main(int argc, char** argv) | ||
214 | { | ||
215 | int ret; | ||
216 | lt_t wcet; | ||
217 | lt_t period; | ||
218 | lt_t budget; | ||
219 | double wcet_ms, period_ms, budget_ms; | ||
220 | unsigned int priority = LITMUS_NO_PRIORITY; | ||
221 | int migrate = 0; | ||
222 | int cluster = 0; | ||
223 | int opt; | ||
224 | int wait = 0; | ||
225 | int want_enforcement = 0; | ||
226 | double duration = 0, start = 0; | ||
227 | double scale = 1.0; | ||
228 | task_class_t class = RT_CLASS_HARD; | ||
229 | struct rt_task param; | ||
230 | struct mc2_task mc2_param; | ||
231 | struct reservation_config config; | ||
232 | int res_type = PERIODIC_POLLING; | ||
233 | |||
234 | unsigned int job_no; | ||
235 | |||
236 | |||
237 | progname = argv[0]; | ||
238 | |||
239 | /* default for reservation */ | ||
240 | config.id = 0; | ||
241 | config.priority = LITMUS_NO_PRIORITY; /* use EDF by default */ | ||
242 | config.cpu = -1; | ||
243 | |||
244 | mc2_param.crit = CRIT_LEVEL_C; | ||
245 | |||
246 | budget_ms = 0; | ||
247 | |||
248 | while ((opt = getopt(argc, argv, OPTSTR)) != -1) { | ||
249 | switch (opt) { | ||
250 | case 'w': | ||
251 | wait = 1; | ||
252 | break; | ||
253 | case 'p': | ||
254 | cluster = atoi(optarg); | ||
255 | migrate = 1; | ||
256 | config.cpu = cluster; | ||
257 | break; | ||
258 | case 'e': | ||
259 | want_enforcement = 1; | ||
260 | break; | ||
261 | case 's': | ||
262 | scale = atof(optarg); | ||
263 | break; | ||
264 | case 'l': | ||
265 | loops = atoi(optarg); | ||
266 | break; | ||
267 | case 'm': | ||
268 | mc2_param.crit = atoi(optarg); | ||
269 | if (mc2_param.crit < CRIT_LEVEL_A || mc2_param.crit == NUM_CRIT_LEVELS) { | ||
270 | usage("Invalid criticality level."); | ||
271 | } | ||
272 | res_type = PERIODIC_POLLING; | ||
273 | break; | ||
274 | case 'b': | ||
275 | budget_ms = atof(optarg); | ||
276 | break; | ||
277 | case 'i': | ||
278 | config.priority = atoi(optarg); | ||
279 | break; | ||
280 | case ':': | ||
281 | usage("Argument missing."); | ||
282 | break; | ||
283 | case '?': | ||
284 | default: | ||
285 | usage("Bad argument."); | ||
286 | break; | ||
287 | } | ||
288 | } | ||
289 | |||
290 | if (mc2_param.crit > CRIT_LEVEL_A && config.priority != LITMUS_NO_PRIORITY) | ||
291 | usage("Bad criticailty level or priority"); | ||
292 | |||
293 | if (argc - optind < 3) | ||
294 | usage("Arguments missing."); | ||
295 | |||
296 | wcet_ms = atof(argv[optind + 0]); | ||
297 | period_ms = atof(argv[optind + 1]); | ||
298 | |||
299 | wcet = ms2ns(wcet_ms); | ||
300 | period = ms2ns(period_ms); | ||
301 | if (budget_ms == 0) | ||
302 | budget_ms = wcet_ms; | ||
303 | budget = ms2ns(budget_ms); | ||
304 | |||
305 | if (wcet <= 0) | ||
306 | usage("The worst-case execution time must be a " | ||
307 | "positive number."); | ||
308 | if (period <= 0) | ||
309 | usage("The period must be a positive number."); | ||
310 | if (wcet > period) { | ||
311 | usage("The worst-case execution time must not " | ||
312 | "exceed the period."); | ||
313 | } | ||
314 | |||
315 | duration = atof(argv[optind + 2]); | ||
316 | |||
317 | if (migrate) { | ||
318 | ret = be_migrate_to_domain(cluster); | ||
319 | if (ret < 0) | ||
320 | bail_out("could not migrate to target partition or cluster."); | ||
321 | } | ||
322 | |||
323 | /* reservation config */ | ||
324 | config.id = gettid(); | ||
325 | |||
326 | config.polling_params.budget = budget; | ||
327 | config.polling_params.period = period; | ||
328 | config.polling_params.offset = 0; | ||
329 | config.polling_params.relative_deadline = 0; | ||
330 | if (config.polling_params.budget > config.polling_params.period) { | ||
331 | usage("The budget must not exceed the period."); | ||
332 | } | ||
333 | |||
334 | /* create a reservation */ | ||
335 | ret = reservation_create(res_type, &config); | ||
336 | if (ret < 0) { | ||
337 | bail_out("failed to create reservation."); | ||
338 | } | ||
339 | init_job(); | ||
340 | |||
341 | init_rt_task_param(¶m); | ||
342 | param.exec_cost = wcet; | ||
343 | param.period = period; | ||
344 | param.priority = priority; | ||
345 | param.cls = class; | ||
346 | param.release_policy = TASK_PERIODIC; | ||
347 | param.budget_policy = (want_enforcement) ? | ||
348 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | ||
349 | if (migrate) { | ||
350 | param.cpu = gettid(); | ||
351 | } | ||
352 | ret = set_rt_task_param(gettid(), ¶m); | ||
353 | |||
354 | if (ret < 0) | ||
355 | bail_out("could not setup rt task params"); | ||
356 | |||
357 | mc2_param.res_id = gettid(); | ||
358 | ret = set_mc2_task_param(gettid(), &mc2_param); | ||
359 | //printf("SET_MC2_TASK\n"); | ||
360 | if (ret < 0) | ||
361 | bail_out("could not setup mc2 task params"); | ||
362 | |||
363 | init_litmus(); | ||
364 | //printf("CALL\n"); | ||
365 | if (mc2_param.crit == CRIT_LEVEL_C) | ||
366 | set_page_color(-1); | ||
367 | else if (mc2_param.crit < CRIT_LEVEL_C) | ||
368 | set_page_color(config.cpu); | ||
369 | //printf("CALL\n"); | ||
370 | |||
371 | //printf("INIT_LITMUS\n"); | ||
372 | start = wctime(); | ||
373 | ret = task_mode(LITMUS_RT_TASK); | ||
374 | //printf("TASK_MODE\n"); | ||
375 | if (ret != 0) | ||
376 | bail_out("could not become RT task"); | ||
377 | |||
378 | |||
379 | if (wait) { | ||
380 | //printf("BEFORE WAIT\n"); | ||
381 | ret = wait_for_ts_release(); | ||
382 | if (ret != 0) | ||
383 | bail_out("wait_for_ts_release()"); | ||
384 | start = wctime(); | ||
385 | } | ||
386 | |||
387 | while (job(wcet_ms * 0.001 * scale, start + duration)) {}; | ||
388 | |||
389 | ret = task_mode(BACKGROUND_TASK); | ||
390 | if (ret != 0) | ||
391 | bail_out("could not become regular task (huh?)"); | ||
392 | |||
393 | reservation_destroy(gettid(), config.cpu); | ||
394 | post_job(); | ||
395 | //printf("%s/%d finished.\n",progname, gettid()); | ||
396 | return 0; | ||
397 | } | ||
398 | |||