aboutsummaryrefslogtreecommitdiffstats
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
parentb7373fbe338936145b9d55471dc353951cb3a81a (diff)
C++: Break out the phase-fair RW locks code
Part of refactoring sharedres.cpp.
-rw-r--r--native/Makefile1
-rw-r--r--native/include/blocking.h45
-rw-r--r--native/src/blocking/rw-phase-fair.cpp223
-rw-r--r--native/src/sharedres.cpp252
4 files changed, 278 insertions, 243 deletions
diff --git a/native/Makefile b/native/Makefile
index 7ce7c47..e79c40e 100644
--- a/native/Makefile
+++ b/native/Makefile
@@ -57,6 +57,7 @@ CORE_OBJ = tasks.o
57SYNC_OBJ = sharedres.o dpcp.o mpcp.o 57SYNC_OBJ = sharedres.o dpcp.o mpcp.o
58SYNC_OBJ += fmlp_plus.o global-fmlp.o 58SYNC_OBJ += fmlp_plus.o global-fmlp.o
59SYNC_OBJ += global-omlp.o part-omlp.o clust-omlp.o 59SYNC_OBJ += global-omlp.o part-omlp.o clust-omlp.o
60SYNC_OBJ += rw-phase-fair.o
60 61
61# #### Targets #### 62# #### Targets ####
62 63
diff --git a/native/include/blocking.h b/native/include/blocking.h
index f5a5a13..0734d9d 100644
--- a/native/include/blocking.h
+++ b/native/include/blocking.h
@@ -41,6 +41,13 @@ Interference bound_blocking(const ContentionSet& cont,
41 const TaskInfo* exclude_tsk, 41 const TaskInfo* exclude_tsk,
42 unsigned int min_priority = 0); 42 unsigned int min_priority = 0);
43 43
44Interference bound_blocking(const ContentionSet& cont,
45 unsigned long interval,
46 unsigned int max_total_requests,
47 unsigned int max_requests_per_source,
48 bool exclude_whole_cluster,
49 const TaskInfo* exclude_tsk);
50
44Interference np_fifo_per_resource( 51Interference np_fifo_per_resource(
45 const TaskInfo& tsk, const ClusterResources& clusters, 52 const TaskInfo& tsk, const ClusterResources& clusters,
46 unsigned int procs_per_cluster, 53 unsigned int procs_per_cluster,
@@ -68,6 +75,44 @@ ClusterLimits np_fifo_limits(
68 const unsigned int issued, 75 const unsigned int issued,
69 int dedicated_irq); 76 int dedicated_irq);
70 77
78Interference bound_blocking_all_clusters(
79 const ClusterResources& clusters,
80 const ClusterLimits& limits,
81 unsigned int res_id,
82 unsigned long interval,
83 const TaskInfo* exclude_tsk);
84
85void split_by_type(const ContentionSet& requests,
86 ContentionSet& reads,
87 ContentionSet& writes);
88void split_by_type(const Resources& resources,
89 Resources &reads,
90 Resources &writes);
91void split_by_type(const ClusterResources& per_cluster,
92 ClusterResources &reads);
93void split_by_type(const ClusterResources& per_cluster,
94 ClusterResources &reads,
95 ClusterResources &writes);
96
97struct RWCount {
98 unsigned int res_id;
99 unsigned int num_reads;
100 unsigned int num_writes;
101 unsigned int rlength;
102 unsigned int wlength;
103
104 RWCount(unsigned int id) : res_id(id),
105 num_reads(0),
106 num_writes(0),
107 rlength(0),
108 wlength(0)
109 {}
110};
111
112typedef std::vector<RWCount> RWCounts;
113
114void merge_rw_requests(const TaskInfo &tsk, RWCounts &counts);
115
71extern const unsigned int UNLIMITED; 116extern const unsigned int UNLIMITED;
72 117
73#endif 118#endif
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;