aboutsummaryrefslogtreecommitdiffstats
path: root/native/src/blocking
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 13:04:36 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-05-16 13:04:36 -0400
commite7e500366aa7b892070bf41500c64cb3f8a98f88 (patch)
tree1852f6f1c53c740ee2c7c298bdd2e2477d29ae35 /native/src/blocking
parentb7373fbe338936145b9d55471dc353951cb3a81a (diff)
C++: Break out the phase-fair RW locks code
Part of refactoring sharedres.cpp.
Diffstat (limited to 'native/src/blocking')
-rw-r--r--native/src/blocking/rw-phase-fair.cpp223
1 files changed, 223 insertions, 0 deletions
diff --git a/native/src/blocking/rw-phase-fair.cpp b/native/src/blocking/rw-phase-fair.cpp
new file mode 100644
index 0000000..65b85b4
--- /dev/null
+++ b/native/src/blocking/rw-phase-fair.cpp
@@ -0,0 +1,223 @@
1#include "sharedres.h"
2#include "blocking.h"
3
4#include "stl-helper.h"
5
6
7static Interference pf_writer_fifo(
8 const TaskInfo& tsk, const ClusterResources& writes,
9 const unsigned int num_writes,
10 const unsigned int num_reads,
11 const unsigned int res_id,
12 const unsigned int procs_per_cluster,
13 const int dedicated_irq)
14{
15 const unsigned int per_src_wlimit = num_reads + num_writes;
16 const unsigned long interval = tsk.get_response();
17 ClusterLimits limits;
18 int idx;
19
20 limits.reserve(writes.size());
21 enumerate(writes, ct, idx)
22 {
23 unsigned int total, parallelism = procs_per_cluster;
24
25 if (idx == dedicated_irq)
26 parallelism--;
27
28 if (parallelism && (int) tsk.get_cluster() == idx)
29 parallelism--;
30
31 // At most one blocking request per remote CPU in
32 // cluster per request.
33 if (parallelism)
34 total = num_reads + num_writes * parallelism;
35 else
36 // No interference from writers if we are hogging
37 // the only available CPU.
38 total = 0;
39
40 limits.push_back(ClusterLimit(total, per_src_wlimit));
41 }
42
43 Interference blocking;
44 blocking = bound_blocking_all_clusters(writes,
45 limits,
46 res_id,
47 interval,
48 &tsk);
49 return blocking;
50
51}
52
53static Interference pf_reader_all(
54 const TaskInfo& tsk,
55 const Resources& all_reads,
56 const unsigned int num_writes,
57 const unsigned int num_wblock,
58 const unsigned int num_reads,
59 const unsigned int res_id,
60 const unsigned int procs_per_cluster,
61 const unsigned int num_procs)
62{
63 const unsigned long interval = tsk.get_response();
64 Interference blocking;
65 unsigned int rlimit = std::min(num_wblock + num_writes,
66 num_reads + num_writes * (num_procs - 1));
67 blocking = bound_blocking(all_reads[res_id],
68 interval,
69 rlimit,
70 rlimit,
71 // exclude all if c == 1
72 procs_per_cluster == 1,
73 &tsk);
74 return blocking;
75}
76
77BlockingBounds* clustered_rw_omlp_bounds(const ResourceSharingInfo& info,
78 unsigned int procs_per_cluster,
79 int dedicated_irq)
80{
81 // split everything by partition
82 Clusters clusters;
83
84 split_by_cluster(info, clusters);
85
86 // split each partition by resource
87 ClusterResources resources;
88
89 split_by_resource(clusters, resources);
90
91 // split all by resource
92 Resources all_task_reqs, all_reads, __all_writes;
93 split_by_resource(info, all_task_reqs);
94 split_by_type(all_task_reqs, all_reads, __all_writes);
95
96 // sort each contention set by request length
97 sort_by_request_length(resources);
98 sort_by_request_length(all_reads);
99
100 // split by type --- sorted order is maintained
101 ClusterResources __reads, writes;
102 split_by_type(resources, __reads, writes);
103
104
105 // We need for each task the maximum request span. We also need the
106 // maximum direct blocking from remote partitions for each request. We
107 // can determine both in one pass.
108
109 const unsigned int num_procs = procs_per_cluster * clusters.size();
110 unsigned int i;
111
112 // direct blocking results
113 BlockingBounds* _results = new BlockingBounds(info);
114 BlockingBounds& results = *_results;
115
116 for (i = 0; i < info.get_tasks().size(); i++)
117 {
118 const TaskInfo& tsk = info.get_tasks()[i];
119 RWCounts rwcounts;
120 Interference bterm;
121
122 merge_rw_requests(tsk, rwcounts);
123
124 foreach(rwcounts, jt)
125 {
126 const RWCount& rw = *jt;
127
128 // skip placeholders
129 if (!rw.num_reads && !rw.num_writes)
130 continue;
131
132 Interference wblocking, rblocking;
133
134 wblocking = pf_writer_fifo(tsk, writes, rw.num_writes,
135 rw.num_reads, rw.res_id,
136 procs_per_cluster,
137 dedicated_irq);
138
139 rblocking = pf_reader_all(tsk, all_reads, rw.num_writes,
140 wblocking.count, rw.num_reads,
141 rw.res_id, procs_per_cluster,
142 num_procs);
143
144 //**** SINGLE WRITE
145 Interference rblocking_w1, wblocking_w1;
146
147 // Keep track of maximum request span.
148 // Is this already a single-issue request?
149 if (rw.num_writes &&
150 (rw.num_writes != 1 || rw.num_reads != 0))
151 {
152 wblocking_w1 = pf_writer_fifo(tsk, writes, 1, 0,
153 rw.res_id, procs_per_cluster,
154 dedicated_irq);
155
156 rblocking_w1 = pf_reader_all(
157 tsk, all_reads, 1,
158 wblocking_w1.count, 0,
159 rw.res_id, procs_per_cluster,
160 num_procs);
161 }
162 else if (rw.num_writes)
163 {
164 wblocking_w1 = wblocking;
165 rblocking_w1 = rblocking;
166 }
167 // else: zero, nothing to do
168
169 //**** SINGLE READ
170
171 Interference rblocking_r1, wblocking_r1;
172
173
174 if (rw.num_reads &&
175 (rw.num_reads != 1 || rw.num_writes != 0))
176 {
177 wblocking_r1 = pf_writer_fifo(tsk, writes, 0, 1,
178 rw.res_id, procs_per_cluster,
179 dedicated_irq);
180
181 rblocking_r1 = pf_reader_all(
182 tsk, all_reads, 0,
183 wblocking_r1.count, 1,
184 rw.res_id, procs_per_cluster,
185 num_procs);
186 }
187 else if (rw.num_reads)
188 {
189 wblocking_r1 = wblocking;
190 rblocking_r1 = rblocking;
191 }
192
193 // else: zero, nothing to do
194
195 // The span includes our own request.
196 if (rw.num_writes)
197 {
198 wblocking_w1.total_length += rw.wlength;
199 wblocking_w1.count += 1;
200 }
201 if (rw.num_reads)
202 {
203 rblocking_r1.total_length += rw.rlength;
204 wblocking_r1.count += 1;
205 }
206
207 // combine
208 wblocking_w1 += rblocking_w1;
209 wblocking_r1 += rblocking_r1;
210 wblocking += rblocking;
211
212 results.raise_request_span(i, wblocking_w1);
213 results.raise_request_span(i, wblocking_r1);
214 bterm += wblocking;
215 }
216 results[i] = bterm;
217 }
218
219 // This is the initial delay due to priority donation.
220 charge_arrival_blocking(info, results);
221
222 return _results;
223}