diff options
| author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-16 13:04:36 -0400 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-16 13:04:36 -0400 |
| commit | e7e500366aa7b892070bf41500c64cb3f8a98f88 (patch) | |
| tree | 1852f6f1c53c740ee2c7c298bdd2e2477d29ae35 /native/src/blocking | |
| parent | b7373fbe338936145b9d55471dc353951cb3a81a (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.cpp | 223 |
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 | |||
| 7 | static 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 | |||
| 53 | static 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 | |||
| 77 | BlockingBounds* 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 | } | ||
