diff options
author | Jeremy Erickson <jerickso@cs.unc.edu> | 2013-11-25 16:00:17 -0500 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2013-11-26 18:14:57 -0500 |
commit | eff718df52ffeb21bff6b59a5584e5b641887832 (patch) | |
tree | 2bcafa03fb5688e112c019095c9d23eca02a7bc5 | |
parent | 972ff75fcdddf59db00b50e8a28414cf0894cc24 (diff) |
Add example code and related end-to-end tests.
-rw-r--r-- | example/__init__.py | 0 | ||||
-rw-r--r-- | example/__main__.py | 12 | ||||
-rw-r--r-- | example/driver.py | 66 | ||||
-rw-r--r-- | example/generator.py | 48 | ||||
-rw-r--r-- | example/lock_example_1 | 1 | ||||
-rw-r--r-- | example/lock_example_2 | 1 | ||||
-rw-r--r-- | example/locking.py | 68 | ||||
-rw-r--r-- | example/mapping.py | 28 | ||||
-rw-r--r-- | example/nolock_example_1 | 1 | ||||
-rw-r--r-- | example/nolock_example_2 | 1 | ||||
-rw-r--r-- | example/oh_host=ludwig_scheduler=C-FL-L2-RM_locks=MX-Q_stat=avg.csv | 21 | ||||
-rw-r--r-- | example/oh_host=ludwig_scheduler=C-FL-L2-RM_stat=avg.csv | 21 | ||||
-rw-r--r-- | example/overheads.py | 39 | ||||
-rw-r--r-- | example/pmo_host=ludwig_background=load_stat=avg.csv | 15 | ||||
-rw-r--r-- | example/schedcat.odp | bin | 0 -> 22532 bytes | |||
-rw-r--r-- | tests/__main__.py | 4 | ||||
-rw-r--r-- | tests/example_end_to_end.py | 67 |
17 files changed, 392 insertions, 1 deletions
diff --git a/example/__init__.py b/example/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/example/__init__.py | |||
diff --git a/example/__main__.py b/example/__main__.py new file mode 100644 index 0000000..f74ba55 --- /dev/null +++ b/example/__main__.py | |||
@@ -0,0 +1,12 @@ | |||
1 | #Necessary includes and stuff | ||
2 | |||
3 | from example.driver import nolock_example, lock_example, \ | ||
4 | generate_random_nolock_sets, \ | ||
5 | generate_random_lock_sets, print_bounds | ||
6 | |||
7 | if __name__ == '__main__': | ||
8 | #Actually run examples when this script is executed | ||
9 | print "Running non-lock example" | ||
10 | print_bounds(nolock_example(generate_random_nolock_sets())) | ||
11 | print "Running lock example" | ||
12 | print_bounds(lock_example(generate_random_lock_sets())) | ||
diff --git a/example/driver.py b/example/driver.py new file mode 100644 index 0000000..6c4c296 --- /dev/null +++ b/example/driver.py | |||
@@ -0,0 +1,66 @@ | |||
1 | #Necessary includes and stuff | ||
2 | |||
3 | from example.generator import generate_taskset_files, \ | ||
4 | generate_lock_taskset_files | ||
5 | from example.mapping import partition_tasks | ||
6 | from example.overheads import get_oh_object, bound_cfl_with_oh | ||
7 | from example.locking import bound_cfl_with_locks | ||
8 | |||
9 | from schedcat.model.serialize import load | ||
10 | |||
11 | import os | ||
12 | |||
13 | def get_script_dir(): | ||
14 | return os.path.dirname(os.path.realpath(__file__)) | ||
15 | |||
16 | def example_overheads(): | ||
17 | script_dir = get_script_dir() | ||
18 | return get_oh_object( | ||
19 | script_dir + "/oh_host=ludwig_scheduler=C-FL-L2-RM_stat=avg.csv", | ||
20 | script_dir + | ||
21 | "/oh_host=ludwig_scheduler=C-FL-L2-RM_locks=MX-Q_stat=avg.csv", | ||
22 | script_dir + "/pmo_host=ludwig_background=load_stat=avg.csv", | ||
23 | "L2") | ||
24 | |||
25 | def nolock_example(task_files): | ||
26 | oheads = example_overheads() | ||
27 | for task_file in task_files: | ||
28 | ts = load(task_file) | ||
29 | for task in ts: | ||
30 | task.wss = 256 | ||
31 | clusts = partition_tasks(2, 12, True, ts) | ||
32 | if clusts and bound_cfl_with_oh(oheads, True, clusts): | ||
33 | yield (task_file, clusts) | ||
34 | else: | ||
35 | yield (task_file, None) | ||
36 | |||
37 | def lock_example(task_files): | ||
38 | oheads = example_overheads() | ||
39 | for task_file in task_files: | ||
40 | ts = load(task_file) | ||
41 | for task in ts: | ||
42 | task.wss = 256 | ||
43 | clusts = partition_tasks(2, 12, True, ts) | ||
44 | if clusts: | ||
45 | clusts2 = bound_cfl_with_locks(ts, clusts, oheads, 2) | ||
46 | if clusts2: | ||
47 | yield (task_file, clusts2) | ||
48 | else: | ||
49 | yield (task_file, None) | ||
50 | else: | ||
51 | yield (task_file, None) | ||
52 | |||
53 | def generate_random_nolock_sets(): | ||
54 | return generate_taskset_files("uni-medium", "uni-moderate", 12, 2) | ||
55 | |||
56 | def generate_random_lock_sets(): | ||
57 | return generate_lock_taskset_files("uni-medium", "uni-moderate", 6, | ||
58 | "medium", 6, 0.1, 2) | ||
59 | |||
60 | def print_bounds(results_list): | ||
61 | for task_file, clusts in results_list: | ||
62 | print "Processed {}".format(task_file) | ||
63 | if clusts is not None: | ||
64 | for clust in clusts: | ||
65 | for task in clust: | ||
66 | print task.response_time - task.deadline | ||
diff --git a/example/generator.py b/example/generator.py new file mode 100644 index 0000000..41a4ed2 --- /dev/null +++ b/example/generator.py | |||
@@ -0,0 +1,48 @@ | |||
1 | #Necessary includes and stuff | ||
2 | |||
3 | from schedcat.model.serialize import write | ||
4 | from schedcat.generator.tasksets import mkgen, \ | ||
5 | NAMED_UTILIZATIONS, \ | ||
6 | NAMED_PERIODS | ||
7 | from schedcat.util.time import ms2us | ||
8 | import schedcat.model.resources as resources | ||
9 | import os | ||
10 | import random | ||
11 | |||
12 | CSLENGTH = { 'short' : lambda: random.randint(1, 15), | ||
13 | 'medium' : lambda: random.randint(1, 100), | ||
14 | 'long' : lambda: random.randint(5, 1280), } | ||
15 | |||
16 | def generate_taskset_files(util_name, period_name, cap, number): | ||
17 | generator = mkgen(NAMED_UTILIZATIONS[util_name], | ||
18 | NAMED_PERIODS[period_name]) | ||
19 | generated_sets = [] | ||
20 | for i in range(number): | ||
21 | taskset = generator(max_util=cap, time_conversion=ms2us) | ||
22 | filename = "{0}_{1}_{2}_{3}".format(util_name, | ||
23 | period_name, cap, i) | ||
24 | write(taskset, filename) | ||
25 | generated_sets.append(filename) | ||
26 | return generated_sets | ||
27 | |||
28 | def generate_lock_taskset_files(util_name, period_name, cap, | ||
29 | cslength, nres, pacc, number): | ||
30 | generator = mkgen(NAMED_UTILIZATIONS[util_name], | ||
31 | NAMED_PERIODS[period_name]) | ||
32 | generated_sets = [] | ||
33 | for i in range(number): | ||
34 | taskset = generator(max_util=cap, time_conversion=ms2us) | ||
35 | resources.initialize_resource_model(taskset) | ||
36 | for task in taskset: | ||
37 | for res_id in range(nres): | ||
38 | if random.random() < pacc: | ||
39 | nreqs = random.randint(1, 5) | ||
40 | length = CSLENGTH[cslength] | ||
41 | for j in range(nreqs): | ||
42 | task.resmodel[res_id].add_request(length()) | ||
43 | filename = "{0}_{1}_{2}_{3}_{4}_{5}_{6}".format( | ||
44 | util_name, period_name, cap, cslength, nres, pacc, | ||
45 | i) | ||
46 | write(taskset, filename) | ||
47 | generated_sets.append(filename) | ||
48 | return generated_sets | ||
diff --git a/example/lock_example_1 b/example/lock_example_1 new file mode 100644 index 0000000..2839265 --- /dev/null +++ b/example/lock_example_1 | |||
@@ -0,0 +1 @@ | |||
<taskset><properties count="11" density="7.85158993665" density_q="92233435393882371160571/11747102961070953840000" hyperperiod="11747102961070953840000" utilization="7.85158993665" utilization_q="92233435393882371160571/11747102961070953840000" /><task period="221000" wcet="175446"><resources /></task><task period="249000" wcet="143983"><resources><requirement max_read_length="0" max_reads="0" max_write_length="14" max_writes="4" res_id="5" /></resources></task><task period="67000" wcet="56926"><resources><requirement max_read_length="0" max_reads="0" max_write_length="7" max_writes="4" res_id="2" /></resources></task><task period="105000" wcet="60381"><resources><requirement max_read_length="0" max_reads="0" max_write_length="15" max_writes="5" res_id="0" /></resources></task><task period="123000" wcet="69329"><resources /></task><task period="177000" wcet="144666"><resources /></task><task period="211000" wcet="142041"><resources /></task><task period="236000" wcet="167824"><resources><requirement max_read_length="0" max_reads="0" max_write_length="7" max_writes="3" res_id="4" /></resources></task><task period="240000" wcet="184243"><resources><requirement max_read_length="0" max_reads="0" max_write_length="15" max_writes="4" res_id="1" /></resources></task><task period="157000" wcet="109222"><resources><requirement max_read_length="0" max_reads="0" max_write_length="11" max_writes="5" res_id="4" /></resources></task><task period="71000" wcet="58656"><resources><requirement max_read_length="0" max_reads="0" max_write_length="15" max_writes="1" res_id="5" /></resources></task></taskset> \ No newline at end of file | |||
diff --git a/example/lock_example_2 b/example/lock_example_2 new file mode 100644 index 0000000..b49377a --- /dev/null +++ b/example/lock_example_2 | |||
@@ -0,0 +1 @@ | |||
<taskset><properties count="22" density="5.7599727736" density_q="1604904754577192741/278630614702440000" hyperperiod="1114522458809760000" utilization="5.7599727736" utilization_q="1604904754577192741/278630614702440000" /><task period="10000" wcet="2382"><resources><requirement max_read_length="0" max_reads="0" max_write_length="99" max_writes="3" res_id="1" /></resources></task><task period="45000" wcet="17247"><resources><requirement max_read_length="0" max_reads="0" max_write_length="74" max_writes="3" res_id="5" /></resources></task><task period="78000" wcet="17960"><resources><requirement max_read_length="0" max_reads="0" max_write_length="96" max_writes="4" res_id="1" /></resources></task><task period="60000" wcet="10573"><resources /></task><task period="32000" wcet="8164"><resources /></task><task period="39000" wcet="9989"><resources /></task><task period="33000" wcet="11992"><resources /></task><task period="42000" wcet="12914"><resources /></task><task period="46000" wcet="12877"><resources /></task><task period="46000" wcet="13775"><resources /></task><task period="74000" wcet="20500"><resources><requirement max_read_length="0" max_reads="0" max_write_length="97" max_writes="5" res_id="2" /></resources></task><task period="72000" wcet="7975"><resources /></task><task period="65000" wcet="20947"><resources /></task><task period="88000" wcet="18770"><resources /></task><task period="53000" wcet="12232"><resources /></task><task period="28000" wcet="9137"><resources><requirement max_read_length="0" max_reads="0" max_write_length="28" max_writes="1" res_id="1" /></resources></task><task period="98000" wcet="32868"><resources><requirement max_read_length="0" max_reads="0" max_write_length="63" max_writes="3" res_id="4" /></resources></task><task period="31000" wcet="11490"><resources><requirement max_read_length="0" max_reads="0" max_write_length="93" max_writes="1" res_id="3" /></resources></task><task period="16000" wcet="4587"><resources /></task><task period="63000" wcet="7244"><resources /></task><task period="80000" wcet="10495"><resources><requirement max_read_length="0" max_reads="0" max_write_length="75" max_writes="4" res_id="2" /></resources></task><task period="79000" wcet="19842"><resources /></task></taskset> \ No newline at end of file | |||
diff --git a/example/locking.py b/example/locking.py new file mode 100644 index 0000000..8414dc3 --- /dev/null +++ b/example/locking.py | |||
@@ -0,0 +1,68 @@ | |||
1 | #Necessary includes and stuff | ||
2 | |||
3 | from schedcat.locking.bounds import apply_task_fair_mutex_bounds, \ | ||
4 | assign_prio_pt_locking_prios | ||
5 | |||
6 | from schedcat.overheads.jlfp import charge_scheduling_overheads, \ | ||
7 | quantize_params | ||
8 | |||
9 | from schedcat.sched.edf.gel_pl import \ | ||
10 | bound_gfl_response_times, has_bounded_tardiness | ||
11 | |||
12 | from schedcat.overheads.locking import charge_spinlock_overheads | ||
13 | |||
14 | def copy_ts(ts, clusts): | ||
15 | new_ts = [] | ||
16 | new_clusts = [] | ||
17 | for clust in clusts: | ||
18 | new_clust = clust.copy() | ||
19 | new_clust.cpus = clust.cpus | ||
20 | new_clusts.append(new_clust) | ||
21 | new_ts += new_clust | ||
22 | return (new_ts, new_clusts) | ||
23 | |||
24 | def preprocess_ts(taskset, clusts, oheads): | ||
25 | for clust in clusts: | ||
26 | charge_spinlock_overheads(oheads, clust) | ||
27 | for task in clust: | ||
28 | #Initially assume completion by deadline and use G-FL | ||
29 | task.response_time = task.deadline | ||
30 | task.prio_pt = task.deadline - \ | ||
31 | (clust.cpus - 1) / (clust.cpus) * task.cost | ||
32 | assign_prio_pt_locking_prios(taskset) | ||
33 | |||
34 | def post_blocking_term_oh_inflation(oheads, clusts): | ||
35 | for clust in clusts: | ||
36 | inflation = oheads.syscall_in(len(clust)) | ||
37 | for t in clust: | ||
38 | if t.arrival_blocked: | ||
39 | t.cost += inflation | ||
40 | t.arrival_blocked += inflation | ||
41 | if not charge_scheduling_overheads(oheads, clust.cpus, | ||
42 | True, clust): | ||
43 | return False | ||
44 | quantize_params(clust) | ||
45 | return True | ||
46 | |||
47 | def bound_cfl_with_locks(tasks, clusts, oheads, cluster_size): | ||
48 | preprocess_ts(tasks, clusts, oheads) | ||
49 | completion_ok = False | ||
50 | count = 0 | ||
51 | while not completion_ok: | ||
52 | completion_ok = True | ||
53 | new_ts, new_clusts = copy_ts(tasks, clusts) | ||
54 | count += 1 | ||
55 | if count > 100: | ||
56 | return False | ||
57 | apply_task_fair_mutex_bounds(new_ts, cluster_size, 0) | ||
58 | if not post_blocking_term_oh_inflation(oheads, | ||
59 | new_clusts): | ||
60 | return False | ||
61 | for i, clust in enumerate(new_clusts): | ||
62 | if not has_bounded_tardiness(clust.cpus, clust): | ||
63 | return False | ||
64 | bound_gfl_response_times(clust.cpus, clust, 15) | ||
65 | for j, t in enumerate(clust): | ||
66 | if t.response_time > clusts[i][j].response_time: | ||
67 | completion_ok = False | ||
68 | return new_clusts | ||
diff --git a/example/mapping.py b/example/mapping.py new file mode 100644 index 0000000..513100b --- /dev/null +++ b/example/mapping.py | |||
@@ -0,0 +1,28 @@ | |||
1 | #Necessary includes and stuff | ||
2 | |||
3 | from schedcat.mapping.rollback import Bin, WorstFit | ||
4 | from schedcat.model.tasks import SporadicTask, TaskSystem | ||
5 | |||
6 | def partition_tasks(cluster_size, clusters, dedicated_irq, | ||
7 | taskset): | ||
8 | first_cap = cluster_size - 1 if dedicated_irq \ | ||
9 | else cluster_size | ||
10 | first_bin = Bin(size=SporadicTask.utilization, | ||
11 | capacity=first_cap) | ||
12 | other_bins = [Bin(size=SporadicTask.utilization, | ||
13 | capacity=cluster_size) | ||
14 | for _ in xrange(1, clusters)] | ||
15 | heuristic = WorstFit(initial_bins=[first_bin] + other_bins) | ||
16 | heuristic.binpack(taskset) | ||
17 | if not (heuristic.misfits): | ||
18 | clusts = [TaskSystem(b.items) for b in heuristic.bins] | ||
19 | for i, c in enumerate(clusts): | ||
20 | if i == 0 and dedicated_irq: | ||
21 | c.cpus = cluster_size - 1 | ||
22 | else: | ||
23 | c.cpus = cluster_size | ||
24 | for task in c: | ||
25 | task.partition = i | ||
26 | return [c for c in clusts if len(c) > 0] | ||
27 | else: | ||
28 | return False | ||
diff --git a/example/nolock_example_1 b/example/nolock_example_1 new file mode 100644 index 0000000..1dbeb8a --- /dev/null +++ b/example/nolock_example_1 | |||
@@ -0,0 +1 @@ | |||
<taskset><properties count="23" density="15.4729907718" density_q="20410015300950549083507309309/1319073707335068058096800000" hyperperiod="699109064887586070791304000000" utilization="15.4729907718" utilization_q="20410015300950549083507309309/1319073707335068058096800000" /><task period="92000" wcet="77458" /><task period="231000" wcet="136533" /><task period="162000" wcet="81968" /><task period="246000" wcet="185116" /><task period="162000" wcet="91878" /><task period="223000" wcet="175137" /><task period="53000" wcet="36093" /><task period="193000" wcet="122459" /><task period="227000" wcet="134213" /><task period="236000" wcet="194596" /><task period="196000" wcet="115232" /><task period="201000" wcet="134545" /><task period="177000" wcet="117609" /><task period="64000" wcet="34458" /><task period="80000" wcet="64850" /><task period="187000" wcet="98045" /><task period="125000" wcet="105110" /><task period="244000" wcet="166497" /><task period="123000" wcet="74986" /><task period="204000" wcet="125921" /><task period="119000" wcet="83377" /><task period="112000" wcet="88028" /><task period="81000" wcet="53934" /></taskset> \ No newline at end of file | |||
diff --git a/example/nolock_example_2 b/example/nolock_example_2 new file mode 100644 index 0000000..edf8278 --- /dev/null +++ b/example/nolock_example_2 | |||
@@ -0,0 +1 @@ | |||
<taskset><properties count="93" density="23.8690492596" density_q="6627145063351516115645722292083155893/277645958633589084681600693034800000" hyperperiod="1110583834534356338726402772139200000" utilization="23.8690492596" utilization_q="6627145063351516115645722292083155893/277645958633589084681600693034800000" /><task period="40000" wcet="7823" /><task period="85000" wcet="21973" /><task period="69000" wcet="10891" /><task period="70000" wcet="19803" /><task period="28000" wcet="3332" /><task period="24000" wcet="4638" /><task period="80000" wcet="22214" /><task period="82000" wcet="22113" /><task period="40000" wcet="13518" /><task period="11000" wcet="4284" /><task period="52000" wcet="12860" /><task period="70000" wcet="21566" /><task period="50000" wcet="12938" /><task period="34000" wcet="5182" /><task period="95000" wcet="27380" /><task period="55000" wcet="6655" /><task period="35000" wcet="13565" /><task period="58000" wcet="14055" /><task period="22000" wcet="4461" /><task period="21000" wcet="7742" /><task period="12000" wcet="2904" /><task period="34000" wcet="5240" /><task period="47000" wcet="13541" /><task period="22000" wcet="3179" /><task period="89000" wcet="30755" /><task period="80000" wcet="22142" /><task period="89000" wcet="25017" /><task period="63000" wcet="23054" /><task period="100000" wcet="33087" /><task period="84000" wcet="18144" /><task period="66000" wcet="20519" /><task period="82000" wcet="24846" /><task period="44000" wcet="9175" /><task period="82000" wcet="23896" /><task period="95000" wcet="19420" /><task period="37000" wcet="11292" /><task period="54000" wcet="12790" /><task period="15000" wcet="4783" /><task period="49000" wcet="12355" /><task period="37000" wcet="6050" /><task period="15000" wcet="3334" /><task period="64000" wcet="12312" /><task period="73000" wcet="9294" /><task period="100000" wcet="20964" /><task period="54000" wcet="13164" /><task period="58000" wcet="18485" /><task period="59000" wcet="19738" /><task period="61000" wcet="22190" /><task period="17000" wcet="3954" /><task period="91000" wcet="33822" /><task period="19000" wcet="3152" /><task period="49000" wcet="9729" /><task period="61000" wcet="17349" /><task period="62000" wcet="7829" /><task period="90000" wcet="27242" /><task period="79000" wcet="25814" /><task period="17000" wcet="5000" /><task period="29000" wcet="10661" /><task period="38000" wcet="14647" /><task period="72000" wcet="26103" /><task period="59000" wcet="20259" /><task period="52000" wcet="16709" /><task period="55000" wcet="21465" /><task period="10000" wcet="2338" /><task period="50000" wcet="19175" /><task period="39000" wcet="7340" /><task period="82000" wcet="28919" /><task period="38000" wcet="11151" /><task period="19000" wcet="6879" /><task period="44000" wcet="8397" /><task period="32000" wcet="9285" /><task period="86000" wcet="11230" /><task period="52000" wcet="8549" /><task period="97000" wcet="38408" /><task period="60000" wcet="23572" /><task period="38000" wcet="6871" /><task period="39000" wcet="6948" /><task period="25000" wcet="8211" /><task period="60000" wcet="16720" /><task period="89000" wcet="13898" /><task period="57000" wcet="9284" /><task period="96000" wcet="34337" /><task period="12000" wcet="1349" /><task period="39000" wcet="7760" /><task period="90000" wcet="10683" /><task period="61000" wcet="7304" /><task period="45000" wcet="10028" /><task period="76000" wcet="14510" /><task period="49000" wcet="7098" /><task period="40000" wcet="6461" /><task period="32000" wcet="6894" /><task period="94000" wcet="26106" /><task period="33000" wcet="9900" /></taskset> \ No newline at end of file | |||
diff --git a/example/oh_host=ludwig_scheduler=C-FL-L2-RM_locks=MX-Q_stat=avg.csv b/example/oh_host=ludwig_scheduler=C-FL-L2-RM_locks=MX-Q_stat=avg.csv new file mode 100644 index 0000000..b99cdc1 --- /dev/null +++ b/example/oh_host=ludwig_scheduler=C-FL-L2-RM_locks=MX-Q_stat=avg.csv | |||
@@ -0,0 +1,21 @@ | |||
1 | TASK-COUNT, LOCK, READ-LOCK, READ-UNLOCK, SYSCALL-IN, SYSCALL-OUT, UNLOCK | ||
2 | 2, 0.1384, 0.53848, 0.06211, 3.70392, 8.80697, 0.06214 | ||
3 | 4, 0.14506, 0.47369, 0.0621, 3.18246, 6.82131, 0.06213 | ||
4 | 6, 0.08174, 0.45971, 0.0621, 2.8336, 6.31049, 0.06212 | ||
5 | 8, 0.08496, 0.47502, 0.06209, 2.73304, 20.91474, 0.06211 | ||
6 | 10, 0.09113, 0.48268, 0.06269, 2.58052, 77.61109, 0.06209 | ||
7 | 12, 0.17603, 0.48421, 0.08559, 2.4247, 140.99054, 0.0623 | ||
8 | 14, 0.17747, 0.47695, 0.08064, 2.28196, 178.77589, 0.0623 | ||
9 | 16, 0.20195, 0.48381, 0.11853, 2.15314, 244.6085, 0.06631 | ||
10 | 18, 0.23352, 0.48954, 0.12895, 2.05774, 298.66, 0.10147 | ||
11 | 20, 0.24854, 0.49222, 0.13417, 1.91271, 351.92975, 0.12259 | ||
12 | 22, 0.25789, 0.49197, 0.13897, 1.83359, 405.82531, 0.12745 | ||
13 | 24, 0.26659, 0.49396, 0.14277, 1.79118, 448.10951, 0.13065 | ||
14 | 26, 0.26749, 0.49041, 0.14375, 1.71109, 508.09325, 0.13336 | ||
15 | 28, 0.27218, 0.49092, 0.14439, 1.69352, 536.4658, 0.13495 | ||
16 | 30, 0.28046, 0.4939, 0.14844, 1.66184, 576.92379, 0.13821 | ||
17 | 32, 0.30073, 0.50478, 0.16025, 1.61638, 571.77327, 0.14682 | ||
18 | 34, 0.30251, 0.50457, 0.16137, 1.62052, 598.64906, 0.1477 | ||
19 | 36, 0.30383, 0.50494, 0.16103, 1.60655, 636.22497, 0.1476 | ||
20 | 38, 0.30507, 0.50418, 0.16117, 1.58808, 661.08658, 0.14781 | ||
21 | 40, 0.31318, 0.50753, 0.16675, 1.56768, 658.96721, 0.14992 | ||
diff --git a/example/oh_host=ludwig_scheduler=C-FL-L2-RM_stat=avg.csv b/example/oh_host=ludwig_scheduler=C-FL-L2-RM_stat=avg.csv new file mode 100644 index 0000000..bb1cad7 --- /dev/null +++ b/example/oh_host=ludwig_scheduler=C-FL-L2-RM_stat=avg.csv | |||
@@ -0,0 +1,21 @@ | |||
1 | TASK-COUNT, CXS, RELEASE-LATENCY, RELEASE, SCHEDULE, IPI-LATENCY, TICK | ||
2 | 2, 6.72978, 29.72057, 9.97856, 14.59542, 4.26253, 1.49529 | ||
3 | 4, 5.50067, 37.68176, 9.54492, 11.59883, 3.45727, 1.61648 | ||
4 | 6, 4.66079, 40.31913, 11.52656, 11.37082, 3.43112, 1.79663 | ||
5 | 8, 4.93466, 46.52168, 12.02322, 12.24551, 3.74841, 2.34484 | ||
6 | 10, 4.81129, 58.24624, 14.5638, 12.2199, 4.00761, 2.46287 | ||
7 | 12, 4.36334, 60.08797, 11.03959, 12.10727, 3.86881, 2.51114 | ||
8 | 14, 4.02139, 64.88597, 12.56629, 11.80076, 3.91408, 2.50994 | ||
9 | 16, 3.95173, 104.25153, 15.86581, 10.87721, 3.92055, 2.52389 | ||
10 | 18, 3.99141, 107.68098, 16.30253, 9.09979, 3.91341, 2.52411 | ||
11 | 20, 3.96936, 119.31053, 18.05341, 8.95408, 3.786, 2.46374 | ||
12 | 22, 4.35578, 123.65897, 19.04576, 8.5018, 3.82484, 2.50819 | ||
13 | 24, 3.94454, 123.59384, 19.86306, 8.36399, 3.81661, 2.49741 | ||
14 | 26, 4.20989, 120.2916, 19.31057, 8.15249, 3.85725, 2.52141 | ||
15 | 28, 3.95358, 132.32261, 20.64414, 7.9894, 3.81458, 2.531 | ||
16 | 30, 4.55631, 127.72966, 19.42275, 7.8974, 3.88953, 2.41506 | ||
17 | 32, 4.81653, 124.99143, 19.50481, 7.93598, 3.88261, 2.49613 | ||
18 | 34, 4.11259, 125.48338, 19.85067, 7.85752, 3.87543, 2.59852 | ||
19 | 36, 4.22586, 122.76203, 19.85806, 7.85018, 3.86897, 2.55698 | ||
20 | 38, 4.8531, 114.62965, 19.0961, 7.84962, 3.91242, 2.55948 | ||
21 | 40, 4.19305, 131.81302, 20.62952, 7.81311, 3.89458, 2.60879 | ||
diff --git a/example/overheads.py b/example/overheads.py new file mode 100644 index 0000000..a022bae --- /dev/null +++ b/example/overheads.py | |||
@@ -0,0 +1,39 @@ | |||
1 | #Necessary includes and stuff | ||
2 | |||
3 | from schedcat.overheads.model import Overheads, CacheDelay | ||
4 | from schedcat.overheads.jlfp import charge_scheduling_overheads, \ | ||
5 | quantize_params | ||
6 | from schedcat.sched.edf.gel_pl import bound_gfl_response_times, \ | ||
7 | has_bounded_tardiness | ||
8 | |||
9 | def copy_lock_overheads(oh, lock_oh): | ||
10 | oh.lock = lock_oh.lock | ||
11 | oh.unlock = lock_oh.unlock | ||
12 | oh.read_lock = lock_oh.read_lock | ||
13 | oh.read_unlock = lock_oh.read_unlock | ||
14 | oh.syscall_in = lock_oh.syscall_in | ||
15 | oh.syscall_out = lock_oh.syscall_out | ||
16 | |||
17 | def get_oh_object(basic_oh, lock_oh, cache_oh, cache_level): | ||
18 | oh = Overheads.from_file(basic_oh) | ||
19 | oh.initial_cache_loss = \ | ||
20 | CacheDelay.from_file(cache_oh).__dict__[cache_level] | ||
21 | oh.cache_affinity_loss = \ | ||
22 | CacheDelay.from_file(cache_oh).__dict__[cache_level] | ||
23 | if lock_oh is not None: | ||
24 | lock_oh = Overheads.from_file(lock_oh) | ||
25 | copy_lock_overheads(oh, lock_oh) | ||
26 | return oh | ||
27 | |||
28 | #Assumes absence of locking | ||
29 | def bound_cfl_with_oh(oheads, dedicated_irq, clusts): | ||
30 | for clust in clusts: | ||
31 | success = charge_scheduling_overheads(oheads, clust.cpus, | ||
32 | dedicated_irq, | ||
33 | clust) | ||
34 | quantize_params(clust) | ||
35 | if (success and has_bounded_tardiness(clust.cpus, clust)): | ||
36 | bound_gfl_response_times(clust.cpus, clust, 15) | ||
37 | else: | ||
38 | return False | ||
39 | return True | ||
diff --git a/example/pmo_host=ludwig_background=load_stat=avg.csv b/example/pmo_host=ludwig_background=load_stat=avg.csv new file mode 100644 index 0000000..c0e3ba2 --- /dev/null +++ b/example/pmo_host=ludwig_background=load_stat=avg.csv | |||
@@ -0,0 +1,15 @@ | |||
1 | WSS,L1,L2,L3,MEM | ||
2 | 4,5.24,5.37,5.66,5.77 | ||
3 | 8,9.14,9.24,9.93,10.09 | ||
4 | 16,17.02,17.05,18.58,18.78 | ||
5 | 32,32.88,32.93,35.82,35.99 | ||
6 | 64,65.05,65.33,70.72,70.50 | ||
7 | 128,128.64,127.09,137.35,141.05 | ||
8 | 256,248.81,246.34,267.73,272.56 | ||
9 | 512,478.45,476.95,507.27,509.18 | ||
10 | 1024,739.20,733.27,772.68,810.37 | ||
11 | 2048,740.10,773.22,837.53,853.27 | ||
12 | 3072,355.76,400.88,377.96,483.20 | ||
13 | 4096,247.88,291.93,274.51,350.07 | ||
14 | 8192,212.90,374.45,436.19,282.28 | ||
15 | 12288,201.20,333.80,467.50,274.23 \ No newline at end of file | ||
diff --git a/example/schedcat.odp b/example/schedcat.odp new file mode 100644 index 0000000..52d64aa --- /dev/null +++ b/example/schedcat.odp | |||
Binary files differ | |||
diff --git a/tests/__main__.py b/tests/__main__.py index 1ecfcdc..8248da0 100644 --- a/tests/__main__.py +++ b/tests/__main__.py | |||
@@ -13,6 +13,7 @@ import tests.binpack | |||
13 | import tests.locking | 13 | import tests.locking |
14 | import tests.sim | 14 | import tests.sim |
15 | import tests.overheads | 15 | import tests.overheads |
16 | import tests.example_end_to_end | ||
16 | 17 | ||
17 | suite = unittest.TestSuite( | 18 | suite = unittest.TestSuite( |
18 | [unittest.defaultTestLoader.loadTestsFromModule(x) for x in | 19 | [unittest.defaultTestLoader.loadTestsFromModule(x) for x in |
@@ -26,7 +27,8 @@ suite = unittest.TestSuite( | |||
26 | tests.binpack, | 27 | tests.binpack, |
27 | tests.locking, | 28 | tests.locking, |
28 | tests.sim, | 29 | tests.sim, |
29 | tests.overheads] | 30 | tests.overheads, |
31 | tests.example_end_to_end] | ||
30 | ]) | 32 | ]) |
31 | 33 | ||
32 | def run_all_tests(): | 34 | def run_all_tests(): |
diff --git a/tests/example_end_to_end.py b/tests/example_end_to_end.py new file mode 100644 index 0000000..1181490 --- /dev/null +++ b/tests/example_end_to_end.py | |||
@@ -0,0 +1,67 @@ | |||
1 | # Uses the example code in the example/ directory, since it's a good end-to-end | ||
2 | # test. | ||
3 | from __future__ import division | ||
4 | |||
5 | import unittest | ||
6 | |||
7 | from example.driver import get_script_dir, nolock_example, lock_example | ||
8 | |||
9 | nolock_example_1_list = [0, 55575, 55575, 67570, 67569, 8805, 8805, 68149, | ||
10 | 68149, 12514, 12513, 55400, 55400, 76501, 76501, | ||
11 | 66761, 66762, -324, -324, 91995, 91995, 35996, 35997] | ||
12 | |||
13 | nolock_example_2_list = None | ||
14 | lock_example_1_list = [-44967, -104360, -9607, -44134, -53237, -31791, -68420, | ||
15 | -67526, -55107, -47183, -11898] | ||
16 | |||
17 | lock_example_2_list = None | ||
18 | |||
19 | class NoLockExample(unittest.TestCase): | ||
20 | def setUp(self): | ||
21 | example_dir = get_script_dir() | ||
22 | self.nolock_example_1 = example_dir + "/nolock_example_1" | ||
23 | self.nolock_example_2 = example_dir + "/nolock_example_2" | ||
24 | results = nolock_example([self.nolock_example_1, self.nolock_example_2]) | ||
25 | self.distilled = [] | ||
26 | for (name, clusts) in results: | ||
27 | if clusts is None: | ||
28 | self.distilled.append((name, None)) | ||
29 | else: | ||
30 | new_distilled = [] | ||
31 | for clust in clusts: | ||
32 | new_distilled += [task.response_time - task.deadline | ||
33 | for task in clust] | ||
34 | self.distilled.append((name, new_distilled)) | ||
35 | |||
36 | def test_nolock_example_1_works(self): | ||
37 | self.assertEqual(self.distilled[0], (self.nolock_example_1, | ||
38 | nolock_example_1_list)) | ||
39 | |||
40 | def test_nolock_example_2_works(self): | ||
41 | self.assertEqual(self.distilled[1], (self.nolock_example_2, | ||
42 | nolock_example_2_list)) | ||
43 | |||
44 | class LockExample(unittest.TestCase): | ||
45 | def setUp(self): | ||
46 | example_dir = get_script_dir() | ||
47 | self.lock_example_1 = example_dir + "/lock_example_1" | ||
48 | self.lock_example_2 = example_dir + "/lock_example_2" | ||
49 | results = lock_example([self.lock_example_1, self.lock_example_2]) | ||
50 | self.distilled = [] | ||
51 | for (name, clusts) in results: | ||
52 | if clusts is None: | ||
53 | self.distilled.append((name, None)) | ||
54 | else: | ||
55 | new_distilled = [] | ||
56 | for clust in clusts: | ||
57 | new_distilled += [task.response_time - task.deadline | ||
58 | for task in clust] | ||
59 | self.distilled.append((name, new_distilled)) | ||
60 | |||
61 | def test_nolock_example_1_works(self): | ||
62 | self.assertEqual(self.distilled[0], (self.lock_example_1, | ||
63 | lock_example_1_list)) | ||
64 | |||
65 | def test_nolock_example_2_works(self): | ||
66 | self.assertEqual(self.distilled[1], (self.lock_example_2, | ||
67 | lock_example_2_list)) | ||