aboutsummaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 12:01:56 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 12:01:56 -0400
commit546b17c0f6360f4e83e6f0dda8db99656aa94077 (patch)
treec5e52133b35b2fe5fd0e76b6ddafc71232e04e7a /native
parentf906d6f40b3f447fd1ba65df3f5e4406972a2331 (diff)
Move MPPC++: Break out the MPCP code into own file
Part of refactoring sharedres.cpp.
Diffstat (limited to 'native')
-rw-r--r--native/Makefile2
-rw-r--r--native/include/blocking.h16
-rw-r--r--native/src/blocking/mpcp.cpp320
-rw-r--r--native/src/sharedres.cpp322
4 files changed, 335 insertions, 325 deletions
diff --git a/native/Makefile b/native/Makefile
index 2204788..ec6da1c 100644
--- a/native/Makefile
+++ b/native/Makefile
@@ -54,7 +54,7 @@ vpath %.cpp src src/edf src/blocking
54EDF_OBJ = baker.o baruah.o gfb.o bcl.o bcl_iterative.o rta.o ffdbf.o gedf.o load.o cpu_time.o 54EDF_OBJ = baker.o baruah.o gfb.o bcl.o bcl_iterative.o rta.o ffdbf.o gedf.o load.o cpu_time.o
55SCHED_OBJ = sim.o schedule_sim.o 55SCHED_OBJ = sim.o schedule_sim.o
56CORE_OBJ = tasks.o 56CORE_OBJ = tasks.o
57SYNC_OBJ = sharedres.o dpcp.o 57SYNC_OBJ = sharedres.o dpcp.o mpcp.o
58 58
59# #### Targets #### 59# #### Targets ####
60 60
diff --git a/native/include/blocking.h b/native/include/blocking.h
index 80b4973..9930aa2 100644
--- a/native/include/blocking.h
+++ b/native/include/blocking.h
@@ -2,15 +2,10 @@
2#define BLOCKING_H 2#define BLOCKING_H
3 3
4typedef std::vector<const RequestBound*> ContentionSet; 4typedef std::vector<const RequestBound*> ContentionSet;
5
6typedef std::vector<ContentionSet> Resources; 5typedef std::vector<ContentionSet> Resources;
7
8typedef std::vector<Resources> ClusterResources; 6typedef std::vector<Resources> ClusterResources;
9
10typedef std::vector<ContentionSet> AllPerCluster; 7typedef std::vector<ContentionSet> AllPerCluster;
11
12typedef std::vector<ContentionSet> TaskContention; 8typedef std::vector<ContentionSet> TaskContention;
13
14typedef std::vector<TaskContention> ClusterContention; 9typedef std::vector<TaskContention> ClusterContention;
15 10
16struct LimitedRequestBound { 11struct LimitedRequestBound {
@@ -29,4 +24,15 @@ void sort_by_request_length(Resources& resources);
29void sort_by_request_length(ClusterResources& resources); 24void sort_by_request_length(ClusterResources& resources);
30void sort_by_request_length(ContentionSet& cs); 25void sort_by_request_length(ContentionSet& cs);
31 26
27
28typedef std::vector<const TaskInfo*> Cluster;
29typedef std::vector<Cluster> Clusters;
30
31void split_by_cluster(const ResourceSharingInfo& info, Clusters& clusters);
32void split_by_resource(const ResourceSharingInfo& info, Resources& resources);
33
34
35
36extern const unsigned int UNLIMITED;
37
32#endif 38#endif
diff --git a/native/src/blocking/mpcp.cpp b/native/src/blocking/mpcp.cpp
new file mode 100644
index 0000000..8b87556
--- /dev/null
+++ b/native/src/blocking/mpcp.cpp
@@ -0,0 +1,320 @@
1#include "sharedres.h"
2#include "blocking.h"
3
4#include "stl-helper.h"
5#include "math-helper.h"
6
7// *************************** MPCP ******************************************
8
9
10typedef std::vector<unsigned int> PriorityCeilings;
11
12static void determine_priority_ceilings(const Resources& resources,
13 PriorityCeilings& ceilings)
14{
15 ceilings.reserve(resources.size());
16
17 foreach(resources, it)
18 {
19 unsigned int ceiling = UINT_MAX;
20 const ContentionSet& cs = *it;
21
22 foreach(cs, jt)
23 {
24 const RequestBound* req = *jt;
25 ceiling = std::min(ceiling, req->get_task()->get_priority());
26 }
27
28 ceilings.push_back(ceiling);
29 }
30}
31
32typedef std::vector<unsigned long> ResponseTimes;
33typedef std::vector<ResponseTimes> TaskResponseTimes;
34typedef std::vector<TaskResponseTimes> ClusterResponseTimes;
35
36static unsigned long get_max_gcs_length(const TaskInfo* tsk,
37 const PriorityCeilings& ceilings,
38 unsigned int preempted_ceiling)
39{
40 unsigned long gcs_length = 0;
41
42 foreach(tsk->get_requests(), it)
43 {
44 unsigned int prio = ceilings[it->get_resource_id()];
45 if (prio < preempted_ceiling)
46 gcs_length = std::max(gcs_length,
47 (unsigned long) it->get_request_length());
48 }
49
50 return gcs_length;
51}
52
53static void determine_gcs_response_times(const TaskInfo* tsk,
54 const Cluster& cluster,
55 const PriorityCeilings& ceilings,
56 ResponseTimes& times)
57{
58 times.reserve(tsk->get_requests().size());
59
60 foreach(tsk->get_requests(), it)
61 {
62 unsigned long resp = it->get_request_length();
63 unsigned int prio = ceilings[it->get_resource_id()];
64
65 // Equation (2) in LNR:09.
66 // One request of each local gcs that can preempt our ceiling,
67 // but at most one per task (since tasks are sequential).
68
69 foreach(cluster, jt)
70 {
71 const TaskInfo* t = *jt;
72
73 if (t != tsk)
74 resp += get_max_gcs_length(t, ceilings, prio);
75 }
76
77 times.push_back(resp);
78 }
79}
80
81static void determine_gcs_response_times(const Cluster& cluster,
82 const PriorityCeilings& ceilings,
83 TaskResponseTimes& times)
84{
85 times.reserve(cluster.size());
86 foreach(cluster, it)
87 {
88 times.push_back(ResponseTimes());
89 determine_gcs_response_times(*it, cluster, ceilings,
90 times.back());
91 }
92}
93
94static void determine_gcs_response_times(const Clusters& clusters,
95 const PriorityCeilings& ceilings,
96 ClusterResponseTimes& times)
97{
98 times.reserve(clusters.size());
99 foreach(clusters, it)
100 {
101 times.push_back(TaskResponseTimes());
102 determine_gcs_response_times(*it, ceilings, times.back());
103 }
104}
105
106static unsigned long response_time_for(unsigned int res_id,
107 unsigned long interval,
108 const TaskInfo* tsk,
109 const ResponseTimes& resp,
110 bool multiple)
111{
112 const Requests& requests = tsk->get_requests();
113 unsigned int i = 0;
114
115 for (i = 0; i < requests.size(); i++)
116 if (requests[i].get_resource_id() == res_id)
117 {
118 if (multiple)
119 {
120 // Equation (3) in LNR:09.
121 // How many jobs?
122 unsigned long num_jobs;
123 num_jobs = divide_with_ceil(interval, tsk->get_period());
124 num_jobs += 1;
125
126 // Note: this may represent multiple gcs, so multiply.
127 return num_jobs * resp[i] * requests[i].get_num_requests();
128 }
129 else
130 // Just one request.
131 return resp[i];
132 }
133 // if we get here, then the task does not access res_id
134 return 0;
135}
136
137static unsigned long mpcp_remote_blocking(unsigned int res_id,
138 unsigned long interval,
139 const TaskInfo* tsk,
140 const Cluster& cluster,
141 const TaskResponseTimes times,
142 unsigned long& max_lower)
143{
144 unsigned int i;
145 unsigned long blocking = 0;
146
147 // consider each task in cluster
148 for (i = 0; i < cluster.size(); i++)
149 {
150 const TaskInfo* t = cluster[i];
151 if (t != tsk)
152 {
153 if (t->get_priority() < tsk->get_priority())
154 // This is a higher-priority task;
155 // it can block multiple times.
156 blocking += response_time_for(res_id, interval,
157 t, times[i], true);
158 else
159 // This is a lower-priority task;