tizen 2.3 release
[framework/system/deviced.git] / src / pass / pass-gov-radiation.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdbool.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "pass.h"
24
25 /*
26  * pass_radiation_governor - Check cpu state and determine the amount of resource
27  *
28  * @stats: structure for getting cpu frequency state from kerncel
29  *
30  * This function check periodically current following state of system
31  * and then determine whether pass level up or down according to pass
32  * policy with gathered data.
33  * - current cpu frequency
34  * - the number of nr_running
35  * - the number of busy_cpu
36  */
37 int pass_radiation_governor(struct pass_policy *policy)
38 {
39         struct pass_table *table = policy->pass_table;
40         struct pass_cpu_stats *cpu_stats = policy->pass_cpu_stats;
41         int up_threshold = policy->up_threshold;
42         int down_threshold = policy->down_threshold;
43         int num_pass_gov = 0;
44         int level = policy->curr_level;
45         int up_count = 0;
46         int down_count = 0;
47         int left_count = 0;
48         int right_count = 0;
49         bool up_condition;
50         bool down_condition;
51         bool left_condition;
52         bool right_condition;
53         int freq;
54         int nr_running;
55         int busy_cpu;
56         int i;
57         int j;
58         int64_t time;
59         static int64_t last_time = 0;
60
61         for (i = 0; i < policy->num_pass_cpu_stats; i++) {
62                 time = cpu_stats[i].time;
63                 freq = cpu_stats[i].freq;
64                 nr_running = cpu_stats[i].nr_runnings;
65                 busy_cpu = cpu_stats[i].num_busy_cpu;
66                 up_condition = true;
67                 down_condition = true;
68                 left_condition = true;
69                 right_condition = true;
70
71                 if (last_time >= time)
72                         continue;
73                 last_time = time;
74                 num_pass_gov++;
75
76                 /*
77                 _I("[Level%d][%d][%lld] %d | %d | %d", level, i, time, freq,
78                                                 nr_running, busy_cpu);
79                 */
80
81                 /* Check level up condition */
82                 for (j = 0; j < table[level].num_up_cond && up_condition; j++) {
83                         if (table[level].up_cond[j].freq &&
84                                 !(freq >= table[level].up_cond[j].freq))
85                                 up_condition = false;
86                 }
87
88                 if (table[level].num_up_cond && up_condition) {
89                         up_count++;
90
91                         /*
92                         _I("[Level%d] [up_count : %2d] \
93                                 freq(%d), nr_running(%d), busy_cpu(%d)",
94                                 level, up_count,
95                                 table[level].up_cond[j].freq ? freq : -1,
96                         */
97                 }
98
99                 /* Check level down condition */
100                 for (j = 0; j < table[level].num_down_cond && down_condition; j++) {
101                         if (table[level].down_cond[j].freq
102                                 && !(freq <= table[level].down_cond[j].freq))
103                                 down_condition = false;
104                 }
105
106                 if (table[level].num_down_cond && down_condition) {
107                         down_count++;
108
109                         /*
110                         _I("[Level%d] [dw_count : %2d] \
111                                 freq(%d), nr_running(%d), busy_cpu(%d)",
112                                 level, down_count,
113                                 table[level].down_cond[j].freq ? freq : -1,
114                         */
115                 }
116
117                 /* Check level right condition */
118                 for (j = 0; j < table[level].num_right_cond && right_condition; j++) {
119                         /*
120                          * If one more conditions are false among following
121                          * conditions, don't increment right_count.
122                          */
123                         if (table[level].right_cond[j].nr_running
124                                 && !(nr_running > table[level].right_cond[j].nr_running))
125                                 right_condition = false;
126
127                         if (table[level].right_cond[j].busy_cpu
128                                 && !(busy_cpu >= table[level].right_cond[j].busy_cpu))
129                                 right_condition = false;
130                 }
131
132                 if (table[level].num_right_cond && right_condition) {
133                         right_count++;
134
135                         /*
136                         _I("[Level%d] [right_count : %2d] \
137                                 nr_running(%d), busy_cpu(%d)",
138                                 level, right_count,
139                                 table[level].right_cond[j].nr_running ? nr_running : -1,
140                                 table[level].right_cond[j].busy_cpu ? busy_cpu : -1);
141                         */
142                 }
143
144                 /* Check level left condition */
145                 for (j = 0; j < table[level].num_left_cond && left_condition; j++) {
146                         /*
147                          * If one more conditions are false among following
148                          * conditions, don't increment left_count.
149                          */
150                         if (table[level].left_cond[j].nr_running
151                                 && !(nr_running <= table[level].left_cond[j].nr_running))
152                                 left_condition = false;
153
154                         if (table[level].left_cond[j].busy_cpu
155                                 && !(busy_cpu < table[level].left_cond[j].busy_cpu))
156                                 left_condition = false;
157                 }
158
159                 if (table[level].num_left_cond && left_condition) {
160                         left_count++;
161
162                         /*
163                         _I("[Level%d] [ left_count : %2d] \
164                                 nr_running(%d), busy_cpu(%d)",
165                                 level, left_count,
166                                 table[level].left_cond[j].nr_running ? nr_running : -1,
167                                 table[level].left_cond[j].busy_cpu ? busy_cpu : -1);
168                         */
169                 }
170         }
171
172         if (up_count * 100 >= num_pass_gov * up_threshold)
173                 level += policy->cpufreq.num_nr_cpus;
174         else if (down_count * 100 >= num_pass_gov * down_threshold)
175                 level -= policy->cpufreq.num_nr_cpus;
176
177         if (right_count * 100 >= num_pass_gov * up_threshold)
178                 level += 1;
179         else if (left_count * 100 >= num_pass_gov * down_threshold)
180                 level -= 1;
181
182         /*
183         if (level == policy->prev_level) {
184                 for (i = num_pass_gov; i < policy->num_pass_cpu_stats; i++) {
185                         time = cpu_stats[i].time;
186                         freq = cpu_stats[i].freq;
187                         nr_running = cpu_stats[i].nr_runnings;
188                         busy_cpu = cpu_stats[i].num_busy_cpu;
189
190                         _I("[Level%d][%d][%lld] %d | %d | %d",
191                                         level, i, time, freq,
192                                         nr_running, busy_cpu);
193                 }
194         }
195
196         if (level != policy->curr_level) {
197                 _I("\n[Level%d] num_pass_gov: [%2d]", level, num_pass_gov);
198                 _I("[Level%d] down_count  : %2d (%3d >= %3d)", level, down_count,
199                                 down_count * 100, num_pass_gov * down_threshold);
200                 _I("[Level%d] up_count    : %2d (%3d >= %3d)", level, up_count,
201                                 up_count * 100, num_pass_gov * up_threshold);
202                 _I("[Level%d] left_count  : %2d (%3d >= %3d)", level, left_count,
203                                 left_count * 100, num_pass_gov * down_threshold);
204                 _I("[Level%d] right_count : %2d (%3d >= %3d)", level, right_count,
205                                 right_count * 100, num_pass_gov * up_threshold);
206         }
207         */
208
209         return level;
210 }