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 | |
| parent | b7373fbe338936145b9d55471dc353951cb3a81a (diff) | |
C++: Break out the phase-fair RW locks code
Part of refactoring sharedres.cpp.
| -rw-r--r-- | native/Makefile | 1 | ||||
| -rw-r--r-- | native/include/blocking.h | 45 | ||||
| -rw-r--r-- | native/src/blocking/rw-phase-fair.cpp | 223 | ||||
| -rw-r--r-- | native/src/sharedres.cpp | 252 |
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 | |||
| 57 | SYNC_OBJ = sharedres.o dpcp.o mpcp.o | 57 | SYNC_OBJ = sharedres.o dpcp.o mpcp.o |
| 58 | SYNC_OBJ += fmlp_plus.o global-fmlp.o | 58 | SYNC_OBJ += fmlp_plus.o global-fmlp.o |
| 59 | SYNC_OBJ += global-omlp.o part-omlp.o clust-omlp.o | 59 | SYNC_OBJ += global-omlp.o part-omlp.o clust-omlp.o |
| 60 | SYNC_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 | ||
| 44 | Interference 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 | |||
| 44 | Interference np_fifo_per_resource( | 51 | Interference 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 | ||
| 78 | Interference 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 | |||
| 85 | void split_by_type(const ContentionSet& requests, | ||
| 86 | ContentionSet& reads, | ||
| 87 | ContentionSet& writes); | ||
| 88 | void split_by_type(const Resources& resources, | ||
| 89 | Resources &reads, | ||
| 90 | Resources &writes); | ||
| 91 | void split_by_type(const ClusterResources& per_cluster, | ||
| 92 | ClusterResources &reads); | ||
| 93 | void split_by_type(const ClusterResources& per_cluster, | ||
| 94 | ClusterResources &reads, | ||
| 95 | ClusterResources &writes); | ||
| 96 | |||
| 97 | struct 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 | |||
| 112 | typedef std::vector<RWCount> RWCounts; | ||
| 113 | |||
| 114 | void merge_rw_requests(const TaskInfo &tsk, RWCounts &counts); | ||
| 115 | |||
| 71 | extern const unsigned int UNLIMITED; | 116 | extern 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 | |||
| 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; | ||
