diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-08-07 14:28:29 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2013-02-12 06:49:40 -0500 |
commit | 4d45e06a55ad463247edd949e6d0c98a69fcf332 (patch) | |
tree | e522d252342ca658397323301af1a77c03e515d5 /native/src/blocking/linprog/lp_common.cpp | |
parent | a4ff45bfbaef292ee1106b759c7ae80213b03cd4 (diff) |
Add DPCP and DFLP linear program generation
These files implement the generation and evaluation of linear programs
that bound maximum s-aware pi-blocking under the DPCP and the DFLP.
Diffstat (limited to 'native/src/blocking/linprog/lp_common.cpp')
-rw-r--r-- | native/src/blocking/linprog/lp_common.cpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/native/src/blocking/linprog/lp_common.cpp b/native/src/blocking/linprog/lp_common.cpp new file mode 100644 index 0000000..808ff28 --- /dev/null +++ b/native/src/blocking/linprog/lp_common.cpp | |||
@@ -0,0 +1,177 @@ | |||
1 | #include "lp_common.h" | ||
2 | |||
3 | // LP-based analysis of semaphore protocols. | ||
4 | // Based on the paper: | ||
5 | // B. Brandenburg, "Improved Analysis and Evaluation of Real-Time Semaphore | ||
6 | // Protocols for P-FP Scheduling", Proceedings of the 19th IEEE Real-Time and | ||
7 | // Embedded Technology and Applications Symposium (RTAS 2013), April 2013. | ||
8 | |||
9 | void set_blocking_objective( | ||
10 | VarMapper& vars, | ||
11 | const ResourceSharingInfo& info, const ResourceLocality& locality, | ||
12 | const TaskInfo& ti, | ||
13 | LinearProgram& lp, | ||
14 | LinearExpression *local_obj, | ||
15 | LinearExpression *remote_obj) | ||
16 | { | ||
17 | LinearExpression *obj; | ||
18 | |||
19 | obj = lp.get_objective(); | ||
20 | |||
21 | foreach_task_except(info.get_tasks(), ti, tx) | ||
22 | { | ||
23 | unsigned int t = tx->get_id(); | ||
24 | foreach(tx->get_requests(), request) | ||
25 | { | ||
26 | unsigned int q = request->get_resource_id(); | ||
27 | bool local = locality[q] == (int) ti.get_cluster(); | ||
28 | double length; | ||
29 | |||
30 | // Sanity check topology info in debug mode. | ||
31 | assert(locality[q] != NO_CPU); | ||
32 | |||
33 | length = request->get_request_length(); | ||
34 | |||
35 | foreach_request_instance(*request, ti, v) | ||
36 | { | ||
37 | unsigned int var_id; | ||
38 | |||
39 | var_id = vars.lookup(t, q, v, BLOCKING_DIRECT); | ||
40 | obj->add_term(length, var_id); | ||
41 | if (local && local_obj) | ||
42 | local_obj->add_term(length, var_id); | ||
43 | else if (!local && remote_obj) | ||
44 | remote_obj->add_term(length, var_id); | ||
45 | |||
46 | var_id = vars.lookup(t, q, v, BLOCKING_INDIRECT); | ||
47 | obj->add_term(length, var_id); | ||
48 | if (local && local_obj) | ||
49 | local_obj->add_term(length, var_id); | ||
50 | else if (!local && remote_obj) | ||
51 | remote_obj->add_term(length, var_id); | ||
52 | |||
53 | var_id = vars.lookup(t, q, v, BLOCKING_PREEMPT); | ||
54 | obj->add_term(length, var_id); | ||
55 | if (local && local_obj) | ||
56 | local_obj->add_term(length, var_id); | ||
57 | else if (!local && remote_obj) | ||
58 | remote_obj->add_term(length, var_id); | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // Constraint 1 in [Brandenburg 2013] | ||
65 | void add_mutex_constraints( | ||
66 | VarMapper& vars, | ||
67 | const ResourceSharingInfo& info, | ||
68 | const TaskInfo& ti, | ||
69 | LinearProgram& lp) | ||
70 | { | ||
71 | |||
72 | foreach_task_except(info.get_tasks(), ti, tx) | ||
73 | { | ||
74 | unsigned int t = tx->get_id(); | ||
75 | foreach(tx->get_requests(), request) | ||
76 | { | ||
77 | unsigned int q = request->get_resource_id(); | ||
78 | foreach_request_instance(*request, ti, v) | ||
79 | { | ||
80 | LinearExpression *exp = new LinearExpression(); | ||
81 | unsigned int var_id; | ||
82 | |||
83 | var_id = vars.lookup(t, q, v, BLOCKING_DIRECT); | ||
84 | exp->add_var(var_id); | ||
85 | |||
86 | var_id = vars.lookup(t, q, v, BLOCKING_INDIRECT); | ||
87 | exp->add_var(var_id); | ||
88 | |||
89 | var_id = vars.lookup(t, q, v, BLOCKING_PREEMPT); | ||
90 | exp->add_var(var_id); | ||
91 | |||
92 | lp.add_inequality(exp, 1); | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | // Constraint 2 in [Brandenburg 2013] | ||
99 | void add_topology_constraints( | ||
100 | VarMapper& vars, | ||
101 | const ResourceSharingInfo& info, | ||
102 | const ResourceLocality& locality, | ||
103 | const TaskInfo& ti, | ||
104 | LinearProgram& lp) | ||
105 | { | ||
106 | LinearExpression *exp = new LinearExpression(); | ||
107 | |||
108 | foreach_task_except(info.get_tasks(), ti, tx) | ||
109 | { | ||
110 | unsigned int t = tx->get_id(); | ||
111 | foreach_remote_request(tx->get_requests(), locality, ti, request) | ||
112 | { | ||
113 | unsigned int q = request->get_resource_id(); | ||
114 | foreach_request_instance(*request, ti, v) | ||
115 | { | ||
116 | unsigned int var_id; | ||
117 | var_id = vars.lookup(t, q, v, BLOCKING_PREEMPT); | ||
118 | exp->add_var(var_id); | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | lp.add_equality(exp, 0); | ||
123 | } | ||
124 | |||
125 | static unsigned int max_num_arrivals_remote( | ||
126 | const ResourceLocality& locality, | ||
127 | const TaskInfo& ti) | ||
128 | { | ||
129 | // initialize to 1 to account for job release | ||
130 | unsigned int count = 1; | ||
131 | |||
132 | // count how often resources on remote cores are accessed | ||
133 | foreach(ti.get_requests(), req) | ||
134 | if (locality[req->get_resource_id()] != (int) ti.get_cluster()) | ||
135 | count += req->get_num_requests(); | ||
136 | |||
137 | return count; | ||
138 | } | ||
139 | |||
140 | |||
141 | // Constraint 3 in [Brandenburg 2013] | ||
142 | // One priority-boosting-related preemption per local task | ||
143 | // each time that Ji arrives (is released or resumed) | ||
144 | void add_local_lower_priority_constraints( | ||
145 | VarMapper& vars, | ||
146 | const ResourceSharingInfo& info, | ||
147 | const ResourceLocality& locality, | ||
148 | const TaskInfo& ti, | ||
149 | LinearProgram& lp) | ||
150 | { | ||
151 | unsigned int num_arrivals = max_num_arrivals_remote(locality, ti); | ||
152 | |||
153 | foreach_local_lowereq_priority_task_except(info.get_tasks(), ti, tx) | ||
154 | { | ||
155 | LinearExpression *exp = new LinearExpression(); | ||
156 | |||
157 | unsigned int t = tx->get_id(); | ||
158 | foreach(tx->get_requests(), request) | ||
159 | { | ||
160 | unsigned int q = request->get_resource_id(); | ||
161 | |||
162 | // is it a resource local to Ti? | ||
163 | if (locality[q] == (int) ti.get_cluster()) | ||
164 | { | ||
165 | foreach_request_instance(*request, ti, v) | ||
166 | { | ||
167 | unsigned int var_id; | ||
168 | var_id = vars.lookup(t, q, v, | ||
169 | BLOCKING_PREEMPT); | ||
170 | exp->add_var(var_id); | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | lp.add_equality(exp, num_arrivals); | ||
175 | } | ||
176 | } | ||
177 | |||