diff options
| author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-16 12:01:56 -0400 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-05-16 12:01:56 -0400 |
| commit | 546b17c0f6360f4e83e6f0dda8db99656aa94077 (patch) | |
| tree | c5e52133b35b2fe5fd0e76b6ddafc71232e04e7a /native | |
| parent | f906d6f40b3f447fd1ba65df3f5e4406972a2331 (diff) | |
Move MPPC++: Break out the MPCP code into own file
Part of refactoring sharedres.cpp.
Diffstat (limited to 'native')
| -rw-r--r-- | native/Makefile | 2 | ||||
| -rw-r--r-- | native/include/blocking.h | 16 | ||||
| -rw-r--r-- | native/src/blocking/mpcp.cpp | 320 | ||||
| -rw-r--r-- | native/src/sharedres.cpp | 322 |
4 files changed, 335 insertions, 325 deletions
diff --git a/native/Makefile b/native/Makefile index 2204788..ec6da1c 100644 --- a/native/Makefile +++ b/native/Makefile | |||
| @@ -54,7 +54,7 @@ vpath %.cpp src src/edf src/blocking | |||
| 54 | EDF_OBJ = baker.o baruah.o gfb.o bcl.o bcl_iterative.o rta.o ffdbf.o gedf.o load.o cpu_time.o | 54 | EDF_OBJ = baker.o baruah.o gfb.o bcl.o bcl_iterative.o rta.o ffdbf.o gedf.o load.o cpu_time.o |
| 55 | SCHED_OBJ = sim.o schedule_sim.o | 55 | SCHED_OBJ = sim.o schedule_sim.o |
| 56 | CORE_OBJ = tasks.o | 56 | CORE_OBJ = tasks.o |
| 57 | SYNC_OBJ = sharedres.o dpcp.o | 57 | SYNC_OBJ = sharedres.o dpcp.o mpcp.o |
| 58 | 58 | ||
| 59 | # #### Targets #### | 59 | # #### Targets #### |
| 60 | 60 | ||
diff --git a/native/include/blocking.h b/native/include/blocking.h index 80b4973..9930aa2 100644 --- a/native/include/blocking.h +++ b/native/include/blocking.h | |||
| @@ -2,15 +2,10 @@ | |||
| 2 | #define BLOCKING_H | 2 | #define BLOCKING_H |
| 3 | 3 | ||
| 4 | typedef std::vector<const RequestBound*> ContentionSet; | 4 | typedef std::vector<const RequestBound*> ContentionSet; |
| 5 | |||
| 6 | typedef std::vector<ContentionSet> Resources; | 5 | typedef std::vector<ContentionSet> Resources; |
| 7 | |||
| 8 | typedef std::vector<Resources> ClusterResources; | 6 | typedef std::vector<Resources> ClusterResources; |
| 9 | |||
| 10 | typedef std::vector<ContentionSet> AllPerCluster; | 7 | typedef std::vector<ContentionSet> AllPerCluster; |
| 11 | |||
| 12 | typedef std::vector<ContentionSet> TaskContention; | 8 | typedef std::vector<ContentionSet> TaskContention; |
| 13 | |||
| 14 | typedef std::vector<TaskContention> ClusterContention; | 9 | typedef std::vector<TaskContention> ClusterContention; |
| 15 | 10 | ||
| 16 | struct LimitedRequestBound { | 11 | struct LimitedRequestBound { |
| @@ -29,4 +24,15 @@ void sort_by_request_length(Resources& resources); | |||
| 29 | void sort_by_request_length(ClusterResources& resources); | 24 | void sort_by_request_length(ClusterResources& resources); |
| 30 | void sort_by_request_length(ContentionSet& cs); | 25 | void sort_by_request_length(ContentionSet& cs); |
| 31 | 26 | ||
| 27 | |||
| 28 | typedef std::vector<const TaskInfo*> Cluster; | ||
| 29 | typedef std::vector<Cluster> Clusters; | ||
| 30 | |||
| 31 | void split_by_cluster(const ResourceSharingInfo& info, Clusters& clusters); | ||
| 32 | void split_by_resource(const ResourceSharingInfo& info, Resources& resources); | ||
| 33 | |||
| 34 | |||
| 35 | |||
| 36 | extern const unsigned int UNLIMITED; | ||
| 37 | |||
| 32 | #endif | 38 | #endif |
diff --git a/native/src/blocking/mpcp.cpp b/native/src/blocking/mpcp.cpp new file mode 100644 index 0000000..8b87556 --- /dev/null +++ b/native/src/blocking/mpcp.cpp | |||
| @@ -0,0 +1,320 @@ | |||
| 1 | #include "sharedres.h" | ||
| 2 | #include "blocking.h" | ||
| 3 | |||
| 4 | #include "stl-helper.h" | ||
| 5 | #include "math-helper.h" | ||
| 6 | |||
| 7 | // *************************** MPCP ****************************************** | ||
| 8 | |||
| 9 | |||
| 10 | typedef std::vector<unsigned int> PriorityCeilings; | ||
| 11 | |||
| 12 | static void determine_priority_ceilings(const Resources& resources, | ||
| 13 | PriorityCeilings& ceilings) | ||
| 14 | { | ||
| 15 | ceilings.reserve(resources.size()); | ||
| 16 | |||
| 17 | foreach(resources, it) | ||
| 18 | { | ||
| 19 | unsigned int ceiling = UINT_MAX; | ||
| 20 | const ContentionSet& cs = *it; | ||
| 21 | |||
| 22 | foreach(cs, jt) | ||
| 23 | { | ||
| 24 | const RequestBound* req = *jt; | ||
| 25 | ceiling = std::min(ceiling, req->get_task()->get_priority()); | ||
| 26 | } | ||
| 27 | |||
| 28 | ceilings.push_back(ceiling); | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | typedef std::vector<unsigned long> ResponseTimes; | ||
| 33 | typedef std::vector<ResponseTimes> TaskResponseTimes; | ||
| 34 | typedef std::vector<TaskResponseTimes> ClusterResponseTimes; | ||
| 35 | |||
| 36 | static unsigned long get_max_gcs_length(const TaskInfo* tsk, | ||
| 37 | const PriorityCeilings& ceilings, | ||
| 38 | unsigned int preempted_ceiling) | ||
| 39 | { | ||
| 40 | unsigned long gcs_length = 0; | ||
| 41 | |||
| 42 | foreach(tsk->get_requests(), it) | ||
| 43 | { | ||
| 44 | unsigned int prio = ceilings[it->get_resource_id()]; | ||
| 45 | if (prio < preempted_ceiling) | ||
| 46 | gcs_length = std::max(gcs_length, | ||
| 47 | (unsigned long) it->get_request_length()); | ||
| 48 | } | ||
| 49 | |||
| 50 | return gcs_length; | ||
| 51 | } | ||
| 52 | |||
| 53 | static void determine_gcs_response_times(const TaskInfo* tsk, | ||
| 54 | const Cluster& cluster, | ||
| 55 | const PriorityCeilings& ceilings, | ||
| 56 | ResponseTimes& times) | ||
| 57 | { | ||
| 58 | times.reserve(tsk->get_requests().size()); | ||
| 59 | |||
| 60 | foreach(tsk->get_requests(), it) | ||
| 61 | { | ||
| 62 | unsigned long resp = it->get_request_length(); | ||
| 63 | unsigned int prio = ceilings[it->get_resource_id()]; | ||
| 64 | |||
| 65 | // Equation (2) in LNR:09. | ||
| 66 | // One request of each local gcs that can preempt our ceiling, | ||
| 67 | // but at most one per task (since tasks are sequential). | ||
| 68 | |||
| 69 | foreach(cluster, jt) | ||
| 70 | { | ||
| 71 | const TaskInfo* t = *jt; | ||
| 72 | |||
| 73 | if (t != tsk) | ||
| 74 | resp += get_max_gcs_length(t, ceilings, prio); | ||
| 75 | } | ||
| 76 | |||
| 77 | times.push_back(resp); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | static void determine_gcs_response_times(const Cluster& cluster, | ||
| 82 | const PriorityCeilings& ceilings, | ||
| 83 | TaskResponseTimes& times) | ||
| 84 | { | ||
| 85 | times.reserve(cluster.size()); | ||
| 86 | foreach(cluster, it) | ||
| 87 | { | ||
| 88 | times.push_back(ResponseTimes()); | ||
| 89 | determine_gcs_response_times(*it, cluster, ceilings, | ||
| 90 | times.back()); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | static void determine_gcs_response_times(const Clusters& clusters, | ||
| 95 | const PriorityCeilings& ceilings, | ||
| 96 | ClusterResponseTimes& times) | ||
| 97 | { | ||
| 98 | times.reserve(clusters.size()); | ||
| 99 | foreach(clusters, it) | ||
| 100 | { | ||
| 101 | times.push_back(TaskResponseTimes()); | ||
| 102 | determine_gcs_response_times(*it, ceilings, times.back()); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | static unsigned long response_time_for(unsigned int res_id, | ||
| 107 | unsigned long interval, | ||
| 108 | const TaskInfo* tsk, | ||
| 109 | const ResponseTimes& resp, | ||
| 110 | bool multiple) | ||
| 111 | { | ||
| 112 | const Requests& requests = tsk->get_requests(); | ||
| 113 | unsigned int i = 0; | ||
| 114 | |||
| 115 | for (i = 0; i < requests.size(); i++) | ||
| 116 | if (requests[i].get_resource_id() == res_id) | ||
| 117 | { | ||
| 118 | if (multiple) | ||
| 119 | { | ||
| 120 | // Equation (3) in LNR:09. | ||
| 121 | // How many jobs? | ||
| 122 | unsigned long num_jobs; | ||
| 123 | num_jobs = divide_with_ceil(interval, tsk->get_period()); | ||
| 124 | num_jobs += 1; | ||
| 125 | |||
| 126 | // Note: this may represent multiple gcs, so multiply. | ||
| 127 | return num_jobs * resp[i] * requests[i].get_num_requests(); | ||
| 128 | } | ||
| 129 | else | ||
| 130 | // Just one request. | ||
| 131 | return resp[i]; | ||
| 132 | } | ||
| 133 | // if we get here, then the task does not access res_id | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | static unsigned long mpcp_remote_blocking(unsigned int res_id, | ||
| 138 | unsigned long interval, | ||
| 139 | const TaskInfo* tsk, | ||
| 140 | const Cluster& cluster, | ||
| 141 | const TaskResponseTimes times, | ||
| 142 | unsigned long& max_lower) | ||
| 143 | { | ||
| 144 | unsigned int i; | ||
| 145 | unsigned long blocking = 0; | ||
| 146 | |||
| 147 | // consider each task in cluster | ||
| 148 | for (i = 0; i < cluster.size(); i++) | ||
| 149 | { | ||
| 150 | const TaskInfo* t = cluster[i]; | ||
| 151 | if (t != tsk) | ||
| 152 | { | ||
| 153 | if (t->get_priority() < tsk->get_priority()) | ||
| 154 | // This is a higher-priority task; | ||
| 155 | // it can block multiple times. | ||
| 156 | blocking += response_time_for(res_id, interval, | ||
| 157 | t, times[i], true); | ||
| 158 | else | ||
| 159 | // This is a lower-priority task; | ||
