aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2007-10-07 01:41:46 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2007-10-07 01:41:46 -0400
commit3909278d5cb6c06907df1c542a60e09e2ded4e37 (patch)
treeb3eb071164548f81c021b2b0f076b2f19371933a /include/linux
parenta75df6573126387eca0e10bd30ce99c11f6a61b1 (diff)
adaptive: introduce fixed point math
Introduces fixed point math header stuff and start of predictor support in sched_adaptive.c
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/fpmath.h79
-rw-r--r--include/linux/rt_param.h41
-rw-r--r--include/linux/sched_adaptive.h34
3 files changed, 143 insertions, 11 deletions
diff --git a/include/linux/fpmath.h b/include/linux/fpmath.h
new file mode 100644
index 0000000000..73d89ba210
--- /dev/null
+++ b/include/linux/fpmath.h
@@ -0,0 +1,79 @@
1#ifndef __FP_MATH_H__
2#define __FP_MATH_H__
3
4#define FP_SHIFT 16
5#define ROUND_BIT (FP_SHIFT - 1)
6#define ONE FP(1)
7
8#define _fp(x) ((fp_t) {x})
9
10static inline fp_t FP(long x)
11{
12 return _fp(((long long) x) << FP_SHIFT);
13}
14
15static inline long _floor(fp_t x)
16{
17 return x.val >> FP_SHIFT;
18}
19
20/* FIXME: negative rounding */
21static inline long _round(fp_t x)
22{
23 return _floor(x) + ((x.val >> ROUND_BIT) & 1);
24}
25
26/* divide two integers to obtain a fixed point value */
27static inline fp_t _frac(long a, long b)
28{
29 return _fp(FP(a).val / (b));
30}
31
32/* multiply two fixed point values */
33static inline fp_t _mul(fp_t a, fp_t b)
34{
35 return _fp((a.val * b.val) >> FP_SHIFT);
36}
37
38static inline fp_t _div(fp_t a, fp_t b)
39{
40 return _fp(FP(a.val).val / b.val);
41}
42
43static inline fp_t _add(fp_t a, fp_t b)
44{
45 return _fp(a.val + b.val);
46}
47
48static inline fp_t _sub(fp_t a, fp_t b)
49{
50 return _fp(a.val - b.val);
51}
52
53static inline fp_t _neg(fp_t x)
54{
55 return _fp(-x.val);
56}
57
58static inline int _leq(fp_t a, fp_t b)
59{
60 return a.val <= b.val;
61}
62
63static inline int _geq(fp_t a, fp_t b)
64{
65 return a.val >= b.val;
66}
67
68static inline int _lt(fp_t a, fp_t b)
69{
70 return a.val < b.val;
71}
72
73static inline int _gt(fp_t a, fp_t b)
74{
75 return a.val > b.val;
76}
77
78
79#endif
diff --git a/include/linux/rt_param.h b/include/linux/rt_param.h
index 69aa781a40..c275565835 100644
--- a/include/linux/rt_param.h
+++ b/include/linux/rt_param.h
@@ -23,14 +23,27 @@ typedef struct rt_param {
23 task_class_t class; 23 task_class_t class;
24} rt_param_t; 24} rt_param_t;
25 25
26/* fixed point wrapper to force compiler
27 * errors in case of misuse of a fixed point value
28 */
29typedef struct
30{
31 long long val;
32} fp_t;
33
26typedef struct { 34typedef struct {
27 unsigned long exec_cost; 35 fp_t weight;
28 unsigned long period; 36 unsigned long period;
29 /* fixed point */ 37 fp_t value;
30 unsigned long utility;
31} service_level_t; 38} service_level_t;
32 39
33typedef struct { 40typedef struct {
41 fp_t error;
42 fp_t estimate;
43 fp_t accumulated;
44} predictor_state_t;
45
46typedef struct {
34 /* when will this task be release the next time? */ 47 /* when will this task be release the next time? */
35 jiffie_t release; 48 jiffie_t release;
36 /* time instant the last job was released */ 49 /* time instant the last job was released */
@@ -111,14 +124,14 @@ typedef struct task_rt_param {
111 * section support. 124 * section support.
112 * TODO: What happens on fork? 125 * TODO: What happens on fork?
113 */ 126 */
114 __user short* np_flag; 127 __user short* np_flag;
115 128
116 /* For the FMLP under PSN-EDF, it is required to make the task 129 /* For the FMLP under PSN-EDF, it is required to make the task
117 * non-preemptive from kernel space. In order not to interfere with 130 * non-preemptive from kernel space. In order not to interfere with
118 * user space, this counter indicates the kernel space np setting. 131 * user space, this counter indicates the kernel space np setting.
119 * kernel_np > 0 => task is non-preemptive 132 * kernel_np > 0 => task is non-preemptive
120 */ 133 */
121 unsigned int kernel_np; 134 unsigned int kernel_np;
122 135
123 /* put information for feedback control stuff and 136 /* put information for feedback control stuff and
124 * information about the performance of the task here 137 * information about the performance of the task here
@@ -126,15 +139,15 @@ typedef struct task_rt_param {
126 struct { 139 struct {
127 /* How many non-tardy jobs since the last tardy job? */ 140 /* How many non-tardy jobs since the last tardy job? */
128 unsigned int nontardy_jobs_ctr; 141 unsigned int nontardy_jobs_ctr;
129 long accumulated_error; 142 long accumulated_error;
130 } stats; 143 } stats;
131 144
132 rt_times_t times; 145 rt_times_t times;
133 146
134 /* This is currently only used by the PFAIR code 147 /* This is currently only used by the PFAIR code
135 * and a prime candidate for cleanup. 148 * and a prime candidate for cleanup.
136 */ 149 */
137 rt_times_t backup; 150 rt_times_t backup;
138 151
139 /* This field can be used by plugins to store where the task 152 /* This field can be used by plugins to store where the task
140 * is currently scheduled. It is the responsibility of the 153 * is currently scheduled. It is the responsibility of the
@@ -155,9 +168,13 @@ typedef struct task_rt_param {
155 /* Adaptive support. Adaptive tasks will store service levels 168 /* Adaptive support. Adaptive tasks will store service levels
156 * in this (dynamically allocated) structure. 169 * in this (dynamically allocated) structure.
157 */ 170 */
158 service_level_t* service_level; 171 service_level_t* service_level;
159 unsigned int no_service_levels; 172 unsigned int no_service_levels;
160 unsigned int cur_service_level; 173 unsigned int cur_service_level;
174
175 /* Adaptive support. Store state for weight estimation.
176 */
177 predictor_state_t predictor_state;
161} task_rt_param_t; 178} task_rt_param_t;
162 179
163/* Possible RT flags */ 180/* Possible RT flags */
@@ -180,6 +197,8 @@ typedef struct task_rt_param {
180#define get_deadline(t) ((t)->rt_param.times.deadline) 197#define get_deadline(t) ((t)->rt_param.times.deadline)
181#define get_class(t) ((t)->rt_param.basic_params.class) 198#define get_class(t) ((t)->rt_param.basic_params.class)
182 199
200#define get_est_weight(t) ((t)->rt_param.predictor_state.estimate)
201
183#define is_realtime(t) ((t)->rt_param.is_realtime) 202#define is_realtime(t) ((t)->rt_param.is_realtime)
184#define is_subject_to_srp(t) ((t)->rt_param.subject_to_srp) 203#define is_subject_to_srp(t) ((t)->rt_param.subject_to_srp)
185#define is_hrt(t) \ 204#define is_hrt(t) \
diff --git a/include/linux/sched_adaptive.h b/include/linux/sched_adaptive.h
new file mode 100644
index 0000000000..eac2f90652
--- /dev/null
+++ b/include/linux/sched_adaptive.h
@@ -0,0 +1,34 @@
1#ifndef __ADAPTIVE_H__
2#define __ADAPTIVE_H__
3
4static inline unsigned long ideal_allocation(fp_t weight, unsigned long delta_t)
5{
6 return _floor(_mul(weight, FP(delta_t)));
7}
8
9/* this makes a whole bunch of linearity assumptions */
10static inline fp_t weight_transfer(fp_t from_val, fp_t to_val,
11 fp_t slope, fp_t intercept, fp_t act_weight)
12{
13 fp_t rel_from, rel_to;
14 rel_from = _add(intercept, _mul(from_val, slope));
15 rel_to = _add(intercept, _mul(to_val, slope));
16 return _div(_mul(act_weight, rel_to), rel_from);
17}
18
19static inline void update_estimate(predictor_state_t *state, fp_t actual_weight,
20 fp_t a, fp_t b, fp_t c)
21{
22 fp_t err, new, delta_err;
23
24 err = _sub(actual_weight, state->estimate);
25 state->accumulated = _add(state->accumulated, err);
26 delta_err = _sub(err, state->error);
27 new = _add(_add(_mul(a, err),
28 _mul(b, state->accumulated)),
29 _mul(c, delta_err));
30 state->estimate = new;
31 state->error = err;
32}
33
34#endif