~ubuntu-branches/ubuntu/utopic/thermald/utopic-proposed

« back to all changes in this revision

Viewing changes to .pc/0029-coverity-scans-Uninitialized-scalar-field-errors.patch/src/thd_model.cpp

  • Committer: Package Import Robot
  • Author(s): Colin King, Colin Ian King, Srinivas Pandruvada
  • Date: 2014-03-12 10:03:33 UTC
  • Revision ID: package-import@ubuntu.com-20140312100333-3s2g2c6tvl2r550x
Tags: 1.1~rc2-10
[Colin Ian King]
* coverity scan: fix memory leak on trip_ptr
* coverity scan: fix leaking dir on error exit path
[Srinivas Pandruvada]
* coverity scan: fix Unrecoverable parse warning
* coverity scan: Untrusted loop bound
* coverity scan: Uninitialized scalar field errors

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * thd_model.h: thermal model class implementation
 
3
 *
 
4
 * Copyright (C) 2012 Intel Corporation. All rights reserved.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License version
 
8
 * 2 or later as published by the Free Software Foundation.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
18
 * 02110-1301, USA.
 
19
 *
 
20
 *
 
21
 * Author Name <Srinivas.Pandruvada@linux.intel.com>
 
22
 *
 
23
 */
 
24
 
 
25
#include "thd_model.h"
 
26
#include "thd_engine.h"
 
27
#include "thd_zone.h"
 
28
 
 
29
#include <time.h>
 
30
#include <math.h>
 
31
 
 
32
#include <string>
 
33
#include <cstring>
 
34
#include <sstream>
 
35
#include <iostream>
 
36
#include <fstream>
 
37
 
 
38
/*
 
39
 * Dynamically adjust set point based on the amount of time spent on hot zone.
 
40
 */
 
41
cthd_model::cthd_model(std::string _zone_type, bool use_pid) :
 
42
                zone_type(_zone_type), trend_increase_start(0), max_temp(
 
43
                                def_max_temperature), set_point(def_max_temperature), hot_zone(
 
44
                                0), last_temp(0), trend_decrease_start(0), max_temp_reached(0), current_angle(
 
45
                                0), set_point_reached(false), delay_cnt(0), max_temp_seen(
 
46
                                false), updated_set_point(false), use_pid_param(use_pid), set_point_delay_start(
 
47
                                0), user_forced_set_point_change(false) {
 
48
        if (use_pid) {
 
49
                // set default pid parameters
 
50
                kp = 0.5;
 
51
                ki = kd = 0.0001;
 
52
                last_time = 0;
 
53
                err_sum = 0.0;
 
54
                last_err = 0.0;
 
55
        }
 
56
}
 
57
 
 
58
unsigned int cthd_model::update_set_point(unsigned int curr_temp) {
 
59
        if (!use_pid_param) {
 
60
                double slope;
 
61
                double delta_x = (max_temp_reached - trend_increase_start) * 1000;
 
62
                double delta_y = max_temp - hot_zone;
 
63
                int _setpoint;
 
64
                double radians;
 
65
                double arc_len;
 
66
 
 
67
                if (delta_y > 0 && delta_x > 0) {
 
68
                        slope = delta_y / delta_x;
 
69
                        radians = atan(slope);
 
70
                        thd_log_info("current slope %g angle before %g (%g degree)\n",
 
71
                                        slope, radians, 57.2957795 * radians);
 
72
                        radians += (0.01746 * (current_angle + angle_increment));
 
73
                        thd_log_info("current slope %g angle before %g (%g degree)\n",
 
74
                                        slope, radians, 57.2957795 * radians);
 
75
                        arc_len = delta_x * tan(radians);
 
76
                        _setpoint = max_temp - (unsigned int) (arc_len - delta_y);
 
77
                        _setpoint = _setpoint - _setpoint % 1000;
 
78
                        thd_log_info("** set point  x:%g y:%g arc_len:%g set_point %d\n",
 
79
                                        delta_x, delta_y, arc_len, _setpoint);
 
80
                        if ((_setpoint < 0)
 
81
                                        || (abs(set_point - _setpoint) > max_compensation))
 
82
                                set_point -= max_compensation;
 
83
                        else
 
84
                                set_point = _setpoint;
 
85
 
 
86
                        if (set_point < hot_zone)
 
87
                                set_point = hot_zone;
 
88
 
 
89
                        current_angle += angle_increment;
 
90
                }
 
91
 
 
92
                return set_point;
 
93
        } else {
 
94
                double output;
 
95
                double d_err = 0;
 
96
                int _setpoint;
 
97
 
 
98
                time_t now;
 
99
                time(&now);
 
100
                if (last_time == 0)
 
101
                        last_time = now;
 
102
                time_t timeChange = (now - last_time);
 
103
 
 
104
                int error = curr_temp - max_temp;
 
105
                err_sum += (error * timeChange);
 
106
                if (timeChange)
 
107
                        d_err = (error - last_err) / timeChange;
 
108
                else
 
109
                        d_err = 0.0;
 
110
 
 
111
                /*Compute PID Output*/
 
112
                output = kp * error + ki * err_sum + kd * d_err;
 
113
                _setpoint = max_temp - (unsigned int) output;
 
114
                thd_log_info("update_pid %ld %ld %d %g %d\n", now, last_time, error,
 
115
                                output, _setpoint);
 
116
                if ((_setpoint < 0) || (abs(set_point - _setpoint) > max_compensation))
 
117
                        set_point -= max_compensation;
 
118
                else
 
119
                        set_point = _setpoint;
 
120
 
 
121
                /*Remember some variables for next time*/
 
122
                last_err = error;
 
123
                last_time = now;
 
124
 
 
125
                return set_point;
 
126
        }
 
127
}
 
128
 
 
129
void cthd_model::add_sample(int temperature) {
 
130
        time_t tm;
 
131
 
 
132
        time(&tm);
 
133
        updated_set_point = false;
 
134
        if (trend_increase_start == 0 && temperature > hot_zone) {
 
135
                trend_increase_start = tm;
 
136
                thd_log_debug("Trend increase start %ld\n", trend_increase_start);
 
137
        } else if (trend_increase_start && temperature < hot_zone) {
 
138
                int _set_point;
 
139
                thd_log_debug("Trend increase stopped %ld\n", trend_increase_start);
 
140
                trend_increase_start = 0;
 
141
                _set_point = read_set_point(); // Restore set point to a calculated max
 
142
                if (_set_point > set_point) {
 
143
                        set_point = _set_point;
 
144
                        updated_set_point = true;
 
145
                        current_angle = 0;
 
146
                        // Reset PID params
 
147
                        err_sum = last_err = 0.0;
 
148
                        last_time = 0;
 
149
                }
 
150
        }
 
151
        if (temperature > max_temp) {
 
152
                max_temp_reached = tm;
 
153
                // Very first time when we reached max temp
 
154
                // then we need to start tuning
 
155
                if (!max_temp_seen) {
 
156
                        int _set_point;
 
157
                        update_set_point(temperature);
 
158
                        _set_point = read_set_point();
 
159
                        // Update only if the current set point is more than
 
160
                        // the stored one.
 
161
                        if (_set_point == 0 || set_point > _set_point)
 
162
                                store_set_point();
 
163
                        max_temp_seen = true;
 
164
                }
 
165
                // Give some time to cooling device to cool, after that set next set point
 
166
                if (set_point_delay_start
 
167
                                && (tm - set_point_delay_start) >= set_point_delay_tm
 
168
                                && (last_temp < temperature))
 
169
                        update_set_point(temperature);
 
170
                delay_cnt++;
 
171
                if (!set_point_delay_start)
 
172
                        set_point_delay_start = tm;
 
173
                set_point_reached = true;
 
174
        } else {
 
175
                set_point_reached = false;
 
176
                delay_cnt = 0;
 
177
                set_point_delay_start = 0;
 
178
        }
 
179
        if (user_forced_set_point_change) {
 
180
                user_forced_set_point_change = false;
 
181
                set_point_reached = true;
 
182
        }
 
183
        last_temp = temperature;
 
184
        thd_log_debug("update_set_point %u,%d,%u\n", last_temp, current_angle,
 
185
                        set_point);
 
186
}
 
187
 
 
188
void cthd_model::store_set_point() {
 
189
        std::stringstream filename;
 
190
 
 
191
        filename << TDRUNDIR << "/" << "thermal_set_point." << zone_type << "."
 
192
                        << "conf";
 
193
        std::ofstream fout(filename.str().c_str());
 
194
        if (fout.good()) {
 
195
                fout << set_point;
 
196
        }
 
197
        thd_log_info("storing set point %d\n", set_point);
 
198
        fout.close();
 
199
}
 
200
 
 
201
int cthd_model::read_set_point() {
 
202
        std::stringstream filename;
 
203
        unsigned int _set_point = 0;
 
204
 
 
205
        filename << TDRUNDIR << "/" << "thermal_set_point." << zone_type << "."
 
206
                        << "conf";
 
207
        std::ifstream ifs(filename.str().c_str(), std::ifstream::in);
 
208
        if (ifs.good()) {
 
209
                ifs >> _set_point;
 
210
        }
 
211
        ifs.close();
 
212
        thd_log_info("Read set point %u\n", _set_point);
 
213
 
 
214
        return _set_point;
 
215
}
 
216
 
 
217
void cthd_model::set_max_temperature(int temp) {
 
218
        int _set_point;
 
219
        int user_defined_max;
 
220
 
 
221
        max_temp = temp - safety_margin;
 
222
        user_defined_max = read_user_set_max_temp();
 
223
        if (user_defined_max > 0)
 
224
                max_temp = user_defined_max;
 
225
        _set_point = read_set_point();
 
226
        if (_set_point > 0 && _set_point < max_temp) {
 
227
                set_point = _set_point;
 
228
        } else {
 
229
                set_point = max_temp;
 
230
        }
 
231
        hot_zone = max_temp - ((max_temp * hot_zone_percent) / 100);
 
232
}
 
233
 
 
234
bool cthd_model::update_user_set_max_temp() {
 
235
        std::stringstream filename;
 
236
        bool present = false;
 
237
        unsigned int temp;
 
238
 
 
239
        filename << TDRUNDIR << "/" << "thd_user_set_max." << zone_type << "."
 
240
                        << "conf";
 
241
        std::ifstream ifs(filename.str().c_str(), std::ifstream::in);
 
242
        if (ifs.good()) {
 
243
                ifs >> temp;
 
244
                if (temp > 1000) {
 
245
                        max_temp = temp;
 
246
                        set_point = max_temp;
 
247
                        hot_zone = max_temp - ((max_temp * hot_zone_percent) / 100);
 
248
                        store_set_point();
 
249
                        present = true;
 
250
                        user_forced_set_point_change = true;
 
251
                        thd_log_info("User forced maximum temperature is %d\n", max_temp);
 
252
                }
 
253
        }
 
254
        ifs.close();
 
255
 
 
256
        return present;
 
257
}
 
258
 
 
259
int cthd_model::read_user_set_max_temp() {
 
260
        std::stringstream filename;
 
261
        unsigned int user_max = 0;
 
262
 
 
263
        filename << TDRUNDIR << "/" << "thd_user_set_max." << zone_type << "."
 
264
                        << "conf";
 
265
        std::ifstream ifs(filename.str().c_str(), std::ifstream::in);
 
266
        if (ifs.good()) {
 
267
                ifs >> user_max;
 
268
                thd_log_info("User defined max temperature %u\n", user_max);
 
269
        }
 
270
        ifs.close();
 
271
 
 
272
        return user_max;
 
273
}