diff options
| author | Jeremy Erickson <jerickso@cs.unc.edu> | 2013-01-02 21:58:07 -0500 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2013-02-04 10:41:25 -0500 |
| commit | 3472c8ececbee3198d680ec711b733472d6606f8 (patch) | |
| tree | 77c4cbbba2b48e22af12fa13a67a02d4c649be2c /native | |
| parent | 4cdaafacd7da23c7c86b524ac26a55f54ad861e7 (diff) | |
Improvements to the GEL Piecewise Linear module: support for arbitrary GEL schedulers in native code and easy max lateness computation.
Diffstat (limited to 'native')
| -rw-r--r-- | native/include/edf/gel_pl.h | 7 | ||||
| -rw-r--r-- | native/include/tasks.h | 12 | ||||
| -rw-r--r-- | native/src/edf/gel_pl.cpp | 25 | ||||
| -rw-r--r-- | native/src/tasks.cpp | 9 |
4 files changed, 27 insertions, 26 deletions
diff --git a/native/include/edf/gel_pl.h b/native/include/edf/gel_pl.h index d70138a..9902e37 100644 --- a/native/include/edf/gel_pl.h +++ b/native/include/edf/gel_pl.h | |||
| @@ -59,13 +59,8 @@ class GELPl | |||
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | public: | 61 | public: |
| 62 | enum Scheduler { | ||
| 63 | GEDF, | ||
| 64 | GFL | ||
| 65 | }; | ||
| 66 | 62 | ||
| 67 | GELPl(Scheduler sched, | 63 | GELPl(unsigned int num_processors, |
| 68 | unsigned int num_processors, | ||
| 69 | const TaskSet& tasks, | 64 | const TaskSet& tasks, |
| 70 | unsigned int rounds); | 65 | unsigned int rounds); |
| 71 | 66 | ||
diff --git a/native/include/tasks.h b/native/include/tasks.h index 0aafa98..092e21a 100644 --- a/native/include/tasks.h +++ b/native/include/tasks.h | |||
| @@ -18,20 +18,23 @@ class Task | |||
| 18 | unsigned long period; | 18 | unsigned long period; |
| 19 | unsigned long wcet; | 19 | unsigned long wcet; |
| 20 | unsigned long deadline; | 20 | unsigned long deadline; |
| 21 | unsigned long prio_pt; | ||
| 21 | 22 | ||
| 22 | public: | 23 | public: |
| 23 | 24 | ||
| 24 | /* construction and initialization */ | 25 | /* construction and initialization */ |
| 25 | void init(unsigned long wcet, unsigned long period, unsigned long deadline = 0); | 26 | void init(unsigned long wcet, unsigned long period, unsigned long deadline = 0, unsigned long prio_pt = 0); |
| 26 | Task(unsigned long wcet = 0, | 27 | Task(unsigned long wcet = 0, |
| 27 | unsigned long period = 0, | 28 | unsigned long period = 0, |
| 28 | unsigned long deadline = 0) { init(wcet, period, deadline); } | 29 | unsigned long deadline = 0, |
| 30 | unsigned long prio_pt = 0) { init(wcet, period, deadline, prio_pt); } | ||
| 29 | 31 | ||
| 30 | /* getter / setter */ | 32 | /* getter / setter */ |
| 31 | unsigned long get_period() const { return period; } | 33 | unsigned long get_period() const { return period; } |
| 32 | unsigned long get_wcet() const { return wcet; } | 34 | unsigned long get_wcet() const { return wcet; } |
| 33 | /* defaults to implicit deadline */ | 35 | /* defaults to implicit deadline */ |
| 34 | unsigned long get_deadline() const {return deadline; } | 36 | unsigned long get_deadline() const {return deadline; } |
| 37 | unsigned long get_prio_pt() const { return prio_pt; } | ||
| 35 | 38 | ||
| 36 | void set_period(unsigned long period) { this->period = period; } | 39 | void set_period(unsigned long period) { this->period = period; } |
| 37 | void set_wcet(unsigned long wcet) { this->wcet = wcet; } | 40 | void set_wcet(unsigned long wcet) { this->wcet = wcet; } |
| @@ -156,9 +159,10 @@ class TaskSet | |||
| 156 | TaskSet(const TaskSet &original); | 159 | TaskSet(const TaskSet &original); |
| 157 | virtual ~TaskSet(); | 160 | virtual ~TaskSet(); |
| 158 | 161 | ||
| 159 | void add_task(unsigned long wcet, unsigned long period, unsigned long deadline = 0) | 162 | void add_task(unsigned long wcet, unsigned long period, |
| 163 | unsigned long deadline = 0, unsigned long prio_pt = 0) | ||
| 160 | { | 164 | { |
| 161 | tasks.push_back(Task(wcet, period, deadline)); | 165 | tasks.push_back(Task(wcet, period, deadline, prio_pt)); |
| 162 | } | 166 | } |
| 163 | 167 | ||
| 164 | unsigned int get_task_count() const { return tasks.size(); } | 168 | unsigned int get_task_count() const { return tasks.size(); } |
diff --git a/native/src/edf/gel_pl.cpp b/native/src/edf/gel_pl.cpp index 89d0177..b058ab1 100644 --- a/native/src/edf/gel_pl.cpp +++ b/native/src/edf/gel_pl.cpp | |||
| @@ -13,7 +13,7 @@ static bool reversed_order(const fractional_t& first, | |||
| 13 | return second < first; | 13 | return second < first; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | GELPl::GELPl(Scheduler sched, unsigned int num_processors, const TaskSet& ts, | 16 | GELPl::GELPl(unsigned int num_processors, const TaskSet& ts, |
| 17 | unsigned int num_rounds) | 17 | unsigned int num_rounds) |
| 18 | :no_cpus(num_processors), tasks(ts), rounds(num_rounds) | 18 | :no_cpus(num_processors), tasks(ts), rounds(num_rounds) |
| 19 | { | 19 | { |
| @@ -25,13 +25,13 @@ GELPl::GELPl(Scheduler sched, unsigned int num_processors, const TaskSet& ts, | |||
| 25 | sys_utilization.get_num().get_mpz_t(), | 25 | sys_utilization.get_num().get_mpz_t(), |
| 26 | sys_utilization.get_den().get_mpz_t()); | 26 | sys_utilization.get_den().get_mpz_t()); |
| 27 | util_ceil = util_ceil_pre.get_ui(); | 27 | util_ceil = util_ceil_pre.get_ui(); |
| 28 | std::vector<unsigned long> pps; | 28 | std::vector<unsigned long> prio_pts; |
| 29 | fractional_t S = 0; | 29 | fractional_t S = 0; |
| 30 | std::vector<fractional_t> Y_ints; | 30 | std::vector<fractional_t> Y_ints; |
| 31 | 31 | ||
| 32 | int task_count = tasks.get_task_count(); | 32 | int task_count = tasks.get_task_count(); |
| 33 | // Reserve capacity in all vectors to minimize allocation costs. | 33 | // Reserve capacity in all vectors to minimize allocation costs. |
| 34 | pps.reserve(task_count); | 34 | prio_pts.reserve(task_count); |
| 35 | Y_ints.reserve(task_count); | 35 | Y_ints.reserve(task_count); |
| 36 | S_i.reserve(task_count); | 36 | S_i.reserve(task_count); |
| 37 | G_i.reserve(task_count); | 37 | G_i.reserve(task_count); |
| @@ -43,29 +43,26 @@ GELPl::GELPl(Scheduler sched, unsigned int num_processors, const TaskSet& ts, | |||
| 43 | utilizations[i] /= tasks[i].get_period(); | 43 | utilizations[i] /= tasks[i].get_period(); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | unsigned long min_pp = std::numeric_limits<unsigned long>::max(); | 46 | unsigned long min_prio_pt = std::numeric_limits<unsigned long>::max(); |
| 47 | 47 | ||
| 48 | // Compute initial priority points, including minimum. | 48 | // Compute initial priority points, including minimum. |
| 49 | for (int i = 0; i < task_count; i++) { | 49 | for (int i = 0; i < task_count; i++) { |
| 50 | const Task& task = tasks[i]; | 50 | const Task& task = tasks[i]; |
| 51 | unsigned long new_pp = task.get_deadline(); | 51 | unsigned long new_prio_pt = task.get_prio_pt(); |
| 52 | if (sched == GFL) { | 52 | prio_pts.push_back(new_prio_pt); |
| 53 | new_pp -= ((num_processors - 1) * task.get_wcet()) / num_processors; | 53 | if (new_prio_pt < min_prio_pt) { |
| 54 | } | 54 | min_prio_pt = new_prio_pt; |
| 55 | pps.push_back(new_pp); | ||
| 56 | if (new_pp < min_pp) { | ||
| 57 | min_pp = new_pp; | ||
| 58 | } | 55 | } |
| 59 | } | 56 | } |
| 60 | 57 | ||
| 61 | // Reduce to compute minimum. Also compute Y intercepts, S_i values, and | 58 | // Reduce to compute minimum. Also compute Y intercepts, S_i values, and |
| 62 | // S. | 59 | // S. |
| 63 | for (int i = 0; i < task_count; i++) { | 60 | for (int i = 0; i < task_count; i++) { |
| 64 | pps[i] -= min_pp; | 61 | prio_pts[i] -= min_prio_pt; |
| 65 | const Task& task = tasks[i]; | 62 | const Task& task = tasks[i]; |
| 66 | unsigned long wcet = task.get_wcet(); | 63 | unsigned long wcet = task.get_wcet(); |
| 67 | unsigned long period = task.get_period(); | 64 | unsigned long period = task.get_period(); |
| 68 | S_i.push_back(pps[i]); | 65 | S_i.push_back(prio_pts[i]); |
| 69 | fractional_t& S_i_i = S_i[i]; | 66 | fractional_t& S_i_i = S_i[i]; |
| 70 | S_i_i *= -1; | 67 | S_i_i *= -1; |
| 71 | S_i_i /= period; | 68 | S_i_i /= period; |
| @@ -102,7 +99,7 @@ GELPl::GELPl(Scheduler sched, unsigned int num_processors, const TaskSet& ts, | |||
| 102 | mpz_cdiv_q(xi_ceil.get_mpz_t(), | 99 | mpz_cdiv_q(xi_ceil.get_mpz_t(), |
| 103 | x_i.get_num().get_mpz_t(), | 100 | x_i.get_num().get_mpz_t(), |
| 104 | x_i.get_den().get_mpz_t()); | 101 | x_i.get_den().get_mpz_t()); |
| 105 | bounds.push_back(pps[i] | 102 | bounds.push_back(prio_pts[i] |
| 106 | + tasks[i].get_wcet() | 103 | + tasks[i].get_wcet() |
| 107 | + xi_ceil.get_ui()); | 104 | + xi_ceil.get_ui()); |
| 108 | G_i.push_back(s); | 105 | G_i.push_back(s); |
diff --git a/native/src/tasks.cpp b/native/src/tasks.cpp index 0d0624c..409c6d6 100644 --- a/native/src/tasks.cpp +++ b/native/src/tasks.cpp | |||
| @@ -9,8 +9,9 @@ | |||
| 9 | #include "task_io.h" | 9 | #include "task_io.h" |
| 10 | 10 | ||
| 11 | void Task::init(unsigned long wcet, | 11 | void Task::init(unsigned long wcet, |
| 12 | unsigned long period, | 12 | unsigned long period, |
| 13 | unsigned long deadline) | 13 | unsigned long deadline, |
| 14 | unsigned long prio_pt) | ||
| 14 | { | 15 | { |
| 15 | this->wcet = wcet; | 16 | this->wcet = wcet; |
| 16 | this->period = period; | 17 | this->period = period; |
| @@ -18,6 +19,10 @@ void Task::init(unsigned long wcet, | |||
| 18 | this->deadline = period; // implicit | 19 | this->deadline = period; // implicit |
| 19 | else | 20 | else |
| 20 | this->deadline = deadline; | 21 | this->deadline = deadline; |
| 22 | if (!prio_pt) | ||
| 23 | this->prio_pt = deadline; | ||
| 24 | else | ||
| 25 | this->prio_pt = prio_pt; | ||
| 21 | } | 26 | } |
| 22 | 27 | ||
| 23 | bool Task::has_implicit_deadline() const | 28 | bool Task::has_implicit_deadline() const |
