aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2013-08-15 02:47:03 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2013-12-13 02:39:06 -0500
commitb98848e9570d00ded81d5b82672003a50c3e4c99 (patch)
tree29de1ab9085e8ba6f80e83295348b819bad7b9b0
parentdb61527e79699990bbad8a3dff5ae20af8227591 (diff)
Add holistic MSRP analysis (with PCP/SRP for local resources)
This patch adds holistic analysis of the MSRP, which combines the PCP/SRP for local resources and task-fair mutex spin locks for global resources. This is added as its own analysis (rather than patching the task-fair mutex code directly) because - the MSRP only applies to partitioned scheduling, and - to not break existing code that does not expect special treatment of local resources. Simple tests included. Adds some convenience code to Interference and BlockingBounds.
-rw-r--r--native/Makefile1
-rw-r--r--native/include/blocking.h3
-rw-r--r--native/include/sharedres.h4
-rw-r--r--native/include/sharedres_types.h7
-rw-r--r--native/interface/locking.i1
-rw-r--r--native/src/blocking/msrp-holistic.cpp90
-rw-r--r--tests/locking.py46
7 files changed, 152 insertions, 0 deletions
diff --git a/native/Makefile b/native/Makefile
index 54c75d8..965f049 100644
--- a/native/Makefile
+++ b/native/Makefile
@@ -111,6 +111,7 @@ SYNC_OBJ = sharedres.o dpcp.o mpcp.o
111SYNC_OBJ += fmlp_plus.o global-fmlp.o 111SYNC_OBJ += fmlp_plus.o global-fmlp.o
112SYNC_OBJ += global-omlp.o part-omlp.o clust-omlp.o 112SYNC_OBJ += global-omlp.o part-omlp.o clust-omlp.o
113SYNC_OBJ += rw-phase-fair.o rw-task-fair.o 113SYNC_OBJ += rw-phase-fair.o rw-task-fair.o
114SYNC_OBJ += msrp-holistic.o
114 115
115# #### Targets #### 116# #### Targets ####
116 117
diff --git a/native/include/blocking.h b/native/include/blocking.h
index a4e48f5..cbb4d15 100644
--- a/native/include/blocking.h
+++ b/native/include/blocking.h
@@ -102,6 +102,9 @@ ResourceSharingInfo extract_local_resources(
102ResourceSharingInfo extract_global_resources( 102ResourceSharingInfo extract_global_resources(
103 const ResourceSharingInfo& info, 103 const ResourceSharingInfo& info,
104 const ResourceSet& locals); 104 const ResourceSet& locals);
105
106BlockingBounds pcp_blocking(const ResourceSharingInfo& info);
107
105extern const unsigned int UNLIMITED; 108extern const unsigned int UNLIMITED;
106 109
107#endif 110#endif
diff --git a/native/include/sharedres.h b/native/include/sharedres.h
index 7765fd8..437176b 100644
--- a/native/include/sharedres.h
+++ b/native/include/sharedres.h
@@ -18,6 +18,10 @@ BlockingBounds* phase_fair_rw_bounds(const ResourceSharingInfo& info,
18 unsigned int procs_per_cluster, 18 unsigned int procs_per_cluster,
19 int dedicated_irq = NO_CPU); 19 int dedicated_irq = NO_CPU);
20 20
21BlockingBounds* msrp_bounds_holistic(
22 const ResourceSharingInfo& info,
23 int dedicated_irq = NO_CPU);
24
21// s-oblivious protocols 25// s-oblivious protocols
22 26
23BlockingBounds* global_omlp_bounds(const ResourceSharingInfo& info, 27BlockingBounds* global_omlp_bounds(const ResourceSharingInfo& info,
diff --git a/native/include/sharedres_types.h b/native/include/sharedres_types.h
index fbe8f72..800659a 100644
--- a/native/include/sharedres_types.h
+++ b/native/include/sharedres_types.h
@@ -240,6 +240,7 @@ struct Interference
240 unsigned long total_length; 240 unsigned long total_length;
241 241
242 Interference() : count(0), total_length(0) {} 242 Interference() : count(0), total_length(0) {}
243 Interference(unsigned int length) : count(1), total_length(length) {}
243 244
244 Interference& operator+=(const Interference& other) 245 Interference& operator+=(const Interference& other)
245 { 246 {
@@ -311,6 +312,12 @@ public:
311 return request_span[idx]; 312 return request_span[idx];
312 } 313 }
313 314
315 void raise_blocking_length(unsigned idx, const Interference& val)
316 {
317 assert( idx < size() );
318 blocking[idx] = std::max(blocking[idx], val);
319 }
320
314 size_t size() const 321 size_t size() const
315 { 322 {
316 return blocking.size(); 323 return blocking.size();
diff --git a/native/interface/locking.i b/native/interface/locking.i
index 208fb74..5f4e75d 100644
--- a/native/interface/locking.i
+++ b/native/interface/locking.i
@@ -7,6 +7,7 @@
7%newobject task_fair_mutex_bounds; 7%newobject task_fair_mutex_bounds;
8%newobject task_fair_rw_bounds; 8%newobject task_fair_rw_bounds;
9%newobject phase_fair_rw_bounds; 9%newobject phase_fair_rw_bounds;
10%newobject msrp_bounds_holistic;
10 11
11%newobject global_omlp_bounds; 12%newobject global_omlp_bounds;
12%newobject global_fmlp_bounds; 13%newobject global_fmlp_bounds;
diff --git a/native/src/blocking/msrp-holistic.cpp b/native/src/blocking/msrp-holistic.cpp
new file mode 100644
index 0000000..f9b4185
--- /dev/null
+++ b/native/src/blocking/msrp-holistic.cpp
@@ -0,0 +1,90 @@
1#include "stl-hashmap.h"
2
3#include "sharedres.h"
4#include "blocking.h"
5
6
7// Analysis of the MSRP: PCP/SRP for local resources, task-fair mutex
8// spin locks for global resources
9// Applies only to partitioned scheduling.
10BlockingBounds* msrp_bounds_holistic(
11 const ResourceSharingInfo& info,
12 int dedicated_irq)
13{
14 ResourceSet locals = get_local_resources(info);
15 ResourceSharingInfo linfo = extract_local_resources(info, locals);
16 ResourceSharingInfo ginfo = extract_global_resources(info, locals);
17
18 BlockingBounds pcp = pcp_blocking(linfo);
19
20 BlockingBounds* results = task_fair_mutex_bounds(ginfo, 1, dedicated_irq);
21
22 // merge the two analysis results
23 for (unsigned int i = 0; i < results->size(); i++)
24 {
25 unsigned int b_pcp = pcp.get_blocking_term(i);
26 unsigned int b_spin = results->get_arrival_blocking(i);
27
28 if (b_pcp > b_spin) {
29 // need to account for larger local blocking
30 Interference new_arrival(b_pcp);
31 Interference total = (*results)[i];
32 // increase total by difference to spin-only blocking
33 total.total_length += (b_pcp - b_spin);
34
35 // update
36 results->set_arrival_blocking(i, new_arrival);
37 (*results)[i] = total;
38 }
39 }
40
41 return results;
42}
43
44
45BlockingBounds pcp_blocking(const ResourceSharingInfo& info)
46{
47 PriorityCeilings prio_ceilings = get_priority_ceilings(info);
48
49 // split everything by partition
50 Clusters clusters;
51 split_by_cluster(info, clusters);
52
53 // blocking results
54 BlockingBounds results(info);
55
56 foreach(clusters, ct)
57 {
58 Cluster& cluster = *ct;
59 foreach(cluster, it)
60 {
61 const TaskInfo* tsk = *it;
62 unsigned int id = tsk->get_id();
63 unsigned int prio = tsk->get_priority();
64
65 // check each other task
66 foreach(cluster, jt)
67 {
68 const TaskInfo* other = *jt;
69 if (id != other->get_id() &&
70 prio <= other->get_priority())
71 {
72 // blocking possible
73
74 foreach(other->get_requests(), req)
75 {
76 unsigned int res = req->get_resource_id();
77 if (prio_ceilings[res] <= prio) {
78 // this CS could cause ceiling blocking / PI blocking
79 // make sure blocking term is at least this large
80 Interference inf(req->get_request_length());
81 results.raise_blocking_length(id, inf);
82 }
83 }
84 }
85 }
86 }
87 }
88
89 return results;
90}
diff --git a/tests/locking.py b/tests/locking.py
index 2a9766f..1a13a4c 100644
--- a/tests/locking.py
+++ b/tests/locking.py
@@ -204,6 +204,52 @@ class Test_bounds(unittest.TestCase):
204 self.assertEqual(7 + 7 + 77, res.get_arrival_blocking(4)) 204 self.assertEqual(7 + 7 + 77, res.get_arrival_blocking(4))
205 self.assertEqual(0, res.get_arrival_blocking(5)) 205 self.assertEqual(0, res.get_arrival_blocking(5))
206 206
207
208 def test_arrival_blocking_msrp(self):
209 res = cpp.msrp_bounds_holistic(self.rsi1)
210 self.assertEqual(6 + 7 + 7, res.get_arrival_blocking(0))
211 self.assertEqual(5 + 7 + 7, res.get_arrival_blocking(1))
212 self.assertEqual(0, res.get_arrival_blocking(2))
213 self.assertEqual(0, res.get_arrival_blocking(3))
214 self.assertEqual(7 + 7 + 77, res.get_arrival_blocking(4))
215 self.assertEqual(0, res.get_arrival_blocking(5))
216
217 def test_local_resources_msrp(self):
218 self.rsi1.add_request(99, 100, 123456)
219 res = cpp.msrp_bounds_holistic(self.rsi1)
220 self.assertEqual(7 + 7 + 77, res.get_arrival_blocking(4))
221
222 def test_local_resources_msrp2(self):
223 self.rsi1 = cpp.ResourceSharingInfo(7)
224
225 self.rsi1.add_task(100, 100, 0, 0)
226 self.rsi1.add_request(0, 1, 77)
227
228 self.rsi1.add_task(50, 50, 0, 1)
229 self.rsi1.add_request(0, 1, 6)
230
231 self.rsi1.add_task(10, 10, 0, 2)
232 self.rsi1.add_request(0, 1, 5)
233
234 self.rsi1.add_task(10, 10, 1, 3)
235 self.rsi1.add_request(0, 1, 7)
236
237 self.rsi1.add_task(20, 20, 2, 4)
238 self.rsi1.add_request(0, 4, 1)
239
240 self.rsi1.add_task(30, 30, 2, 5)
241 self.rsi1.add_request(0, 1, 7)
242 self.rsi1.add_request(99, 1, 1)
243
244 self.rsi1.add_task(100, 100, 2, 6)
245 self.rsi1.add_request(99, 100, 123456)
246 res = cpp.msrp_bounds_holistic(self.rsi1)
247 self.assertEqual(7 + 7 + 77, res.get_arrival_blocking(4))
248 self.assertEqual(123456, res.get_arrival_blocking(5))
249 self.assertEqual(123456 + 7 + 77, res.get_blocking_term(5))
250 self.assertEqual(0, res.get_blocking_term(6))
251 self.assertEqual(0, res.get_arrival_blocking(6))
252
207 def test_arrival_blocking_pf(self): 253 def test_arrival_blocking_pf(self):
208 c = 1 254 c = 1
209 255