aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/blocking
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/blocking')
-rw-r--r--native/src/blocking/linprog/lp_common.cpp108
-rw-r--r--native/src/blocking/linprog/lp_mpcp.cpp589
2 files changed, 697 insertions, 0 deletions
diff --git a/native/src/blocking/linprog/lp_common.cpp b/native/src/blocking/linprog/lp_common.cpp
index a7bb1b5..1715d3b 100644
--- a/native/src/blocking/linprog/lp_common.cpp
+++ b/native/src/blocking/linprog/lp_common.cpp
@@ -234,6 +234,7 @@ void add_local_lower_priority_constraints(
234} 234}
235 235
236 236
237// Constraint 10 in [Brandenburg 2013]
237// For shared-memory protocols. 238// For shared-memory protocols.
238// Remote tasks cannot preempt Ti since they are not scheduled 239// Remote tasks cannot preempt Ti since they are not scheduled
239// on Ti's assigned task; therefore force BLOCKING_PREEMPT to zero. 240// on Ti's assigned task; therefore force BLOCKING_PREEMPT to zero.
@@ -261,3 +262,110 @@ void add_topology_constraints_shm(
261 } 262 }
262 lp.add_equality(exp, 0); 263 lp.add_equality(exp, 0);
263} 264}
265
266// Constraint 9 in [Brandenburg 2013]
267// local higher-priority tasks never cause blocking under SHM protocols
268void add_local_higher_priority_constraints_shm(
269 VarMapper& vars,
270 const ResourceSharingInfo& info,
271 const TaskInfo& ti,
272 LinearProgram& lp)
273{
274 LinearExpression *exp = new LinearExpression();
275
276 foreach_local_task(info.get_tasks(), ti, tx)
277 {
278 if (tx->get_priority() < ti.get_priority())
279 {
280 unsigned int t = tx->get_id();
281 foreach(tx->get_requests(), request)
282 {
283 unsigned int q = request->get_resource_id();
284 foreach_request_instance(*request, ti, v)
285 {
286 unsigned int var_id;
287 var_id = vars.lookup(t, q, v,
288 BLOCKING_PREEMPT);
289 exp->add_var(var_id);
290
291 var_id = vars.lookup(t, q, v,
292 BLOCKING_INDIRECT);
293 exp->add_var(var_id);
294
295 var_id = vars.lookup(t, q, v,
296 BLOCKING_DIRECT);
297 exp->add_var(var_id);
298 }
299 }
300 }
301 }
302 lp.add_equality(exp, 0);
303}
304
305static unsigned int max_num_arrivals_shm(
306 const ResourceSharingInfo& info,
307 const TaskInfo& ti)
308{
309 hashmap<unsigned int, unsigned int> request_counts;
310
311 foreach(ti.get_requests(), req)
312 request_counts[req->get_resource_id()] = 0;
313
314 // count how often each resource is accessed on remote cores
315 foreach_remote_task(info.get_tasks(), ti, tx)
316 {
317 foreach(tx->get_requests(), req)
318 {
319 unsigned int q = req->get_resource_id();
320 if (request_counts.find(q) != request_counts.end())
321 request_counts[q] += req->get_max_num_requests(ti.get_response());
322 }
323 }
324
325 // initialize to 1 to account for job release
326 unsigned int total = 1;
327
328 foreach(ti.get_requests(), req)
329 total += std::min(request_counts[req->get_resource_id()],
330 req->get_num_requests());
331
332 return total;
333}
334
335// Constraint 11 in [Brandenburg 2013]
336// Local lower-priority tasks block at most once each time
337// that Ti suspends (and once after release).
338void add_local_lower_priority_constraints_shm(
339 VarMapper& vars,
340 const ResourceSharingInfo& info,
341 const TaskInfo& ti,
342 LinearProgram& lp)
343{
344 unsigned int num_arrivals = max_num_arrivals_shm(info, ti);
345
346 foreach_local_lowereq_priority_task_except(info.get_tasks(), ti, tx)
347 {
348 LinearExpression *exp = new LinearExpression();
349 unsigned int t = tx->get_id();
350 foreach(tx->get_requests(), request)
351 {
352 unsigned int q = request->get_resource_id();
353 foreach_request_instance(*request, ti, v)
354 {
355 unsigned int var_id;
356 var_id = vars.lookup(t, q, v,
357 BLOCKING_PREEMPT);
358 exp->add_var(var_id);
359
360 var_id = vars.lookup(t, q, v,
361 BLOCKING_INDIRECT);
362 exp->add_var(var_id);
363
364 var_id = vars.lookup(t, q, v,
365 BLOCKING_DIRECT);
366 exp->add_var(var_id);
367 }
368 }
369 lp.add_equality(exp, num_arrivals);
370 }
371}
diff --git a/native/src/blocking/linprog/lp_mpcp.cpp b/native/src/blocking/linprog/lp_mpcp.cpp
new file mode 100644
index 0000000..bccea5d
--- /dev/null
+++ b/native/src/blocking/linprog/lp_mpcp.cpp
@@ -0,0 +1,589 @@
1#include <iostream>
2#include <set>
3#include <algorithm>
4
5#include "lp_common.h"
6#include "blocking.h"
7#include "stl-hashmap.h"
8
9#include "cpu_time.h"
10
11#include "mpcp.h"
12
13#define NO_BOUND (-1)
14
15typedef hashmap<unsigned int, unsigned int> PerResourceCounts;
16typedef hashmap<unsigned int, hashmap<unsigned int, unsigned int> > PerTaskPerRequestDirectBlockingBound;
17typedef hashmap<unsigned int, unsigned int> PerTaskIndirectBlockingBound;
18
19class GcsResponseTimes
20{
21private:
22 // per each task, and per each global critical section (gcs),
23 // the maximum wait time bound
24 hashmap< unsigned long, hashmap< unsigned int, long> > remote_delay;
25
26 hashmap< unsigned long, hashmap< unsigned int, unsigned long> > gcs_response;
27
28 const ResourceSharingInfo &info;
29 const MPCPCeilings &prio_ceilings;
30
31 long bound_remote_delay(const TaskInfo &tsk,
32 unsigned int res_id);
33
34 void bound_gcs_response_times(void);
35
36
37public:
38 GcsResponseTimes(const ResourceSharingInfo &i,
39 const MPCPCeilings &pc)
40 : info(i), prio_ceilings(pc)
41 {
42 bound_gcs_response_times();
43 }
44
45
46 long get_max_remote_delay(const TaskInfo &ti, unsigned int res_id)
47 {
48 if (remote_delay.find(ti.get_id()) == remote_delay.end())
49 remote_delay[ti.get_id()] = hashmap<unsigned int, long>();
50
51 hashmap<unsigned int, long> &tmap = remote_delay[ti.get_id()];
52
53 if (tmap.find(res_id) == tmap.end())
54 tmap[res_id] = bound_remote_delay(ti, res_id);
55
56 return tmap[res_id];
57 }
58
59 long get_gcs_response(const TaskInfo &ti, unsigned int res_id)
60 {
61 // look up the task
62 if (gcs_response.find(ti.get_id()) == gcs_response.end())
63 return NO_BOUND;
64
65 hashmap<unsigned int, unsigned long> &tmap = gcs_response[ti.get_id()];
66
67 // look up the resource
68 if (tmap.find(res_id) == tmap.end())
69 return NO_BOUND;
70
71 return tmap[res_id];
72 }
73};
74
75
76void GcsResponseTimes::bound_gcs_response_times()
77{
78 Clusters clusters;
79 split_by_cluster(info, clusters);
80
81 ClusterResponseTimes responses;
82 determine_gcs_response_times(clusters, prio_ceilings, responses);
83
84 for (unsigned int c = 0; c < clusters.size(); c++)