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

« back to all changes in this revision

Viewing changes to .pc/0003-Remove-compile-warning.patch/src/thd_rapl_power_meter.cpp

  • Committer: Package Import Robot
  • Author(s): Colin King
  • Date: 2014-05-19 12:41:22 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20140519124122-zan11arvjxtbqcq5
Tags: 1.2-1
* Adjust for coretemp path change
* Deny non root users to send system bus dbus messages
* Remove compile warning
* Remove rpmlint warning for manual page
* Remove old patches that are now included into version 1.2
* Sync up with version 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * thd_rapl_power_meter.cpp: thermal cooling class implementation
 
3
 *      using RAPL
 
4
 * Copyright (C) 2014 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_rapl_power_meter.h"
 
26
#include <dirent.h>
 
27
#include <fnmatch.h>
 
28
#include <time.h>
 
29
 
 
30
static void *rapl_periodic_callback(void *data) {
 
31
        cthd_rapl_power_meter *rapl_cl = (cthd_rapl_power_meter*) data;
 
32
 
 
33
        for (;;) {
 
34
                if (!rapl_cl->rapl_energy_loop())
 
35
                        break;
 
36
                sleep(rapl_cl->rapl_callback_timeout);
 
37
        }
 
38
 
 
39
        return NULL;
 
40
}
 
41
 
 
42
cthd_rapl_power_meter::cthd_rapl_power_meter(unsigned int mask) :
 
43
                rapl_present(true), rapl_sysfs("/sys/class/powercap/intel-rapl/"), domain_list(
 
44
                                0), last_time(0), poll_thread(0), measure_mask(mask), enable_measurement(
 
45
                                false) {
 
46
 
 
47
        if (rapl_sysfs.exists()) {
 
48
                thd_log_debug("RAPL sysfs present \n");
 
49
                rapl_present = true;
 
50
                last_time = time(NULL);
 
51
                rapl_read_domains(rapl_sysfs.get_base_path());
 
52
        } else {
 
53
                thd_log_warn("NO RAPL sysfs present \n");
 
54
                rapl_present = false;
 
55
        }
 
56
}
 
57
 
 
58
void cthd_rapl_power_meter::rapl_read_domains(const char *dir_name) {
 
59
        int count = 0;
 
60
        csys_fs sys_fs;
 
61
 
 
62
        if (rapl_present) {
 
63
                DIR *dir;
 
64
                struct dirent *dir_entry;
 
65
                int run_cnt = 0;
 
66
                thd_log_debug("RAPL base path %s\n", dir_name);
 
67
                if ((dir = opendir(dir_name)) != NULL) {
 
68
                        while ((dir_entry = readdir(dir)) != NULL) {
 
69
                                std::string buffer;
 
70
                                std::stringstream path;
 
71
                                int status;
 
72
                                rapl_domain_t domain;
 
73
 
 
74
                                domain.half_way = 0;
 
75
                                domain.energy_counter = 0;
 
76
                                domain.energy_cumulative_counter = 0;
 
77
                                domain.max_energy_range = 0;
 
78
                                domain.max_energy_range_threshold = 0;
 
79
                                domain.power = 0;
 
80
                                domain.type = PACKAGE;
 
81
 
 
82
                                if (!strcmp(dir_entry->d_name, ".")
 
83
                                                || !strcmp(dir_entry->d_name, ".."))
 
84
                                        continue;
 
85
                                thd_log_debug("RAPL domain dir %s\n", dir_entry->d_name);
 
86
                                path << dir_name << dir_entry->d_name << "/" << "name";
 
87
                                status = sys_fs.read(path.str(), buffer);
 
88
                                if (status < 0)
 
89
                                        continue;
 
90
                                thd_log_debug("name %s\n", buffer.c_str());
 
91
                                if (fnmatch("package-*", buffer.c_str(), 0) == 0) {
 
92
                                        domain.type = PACKAGE;
 
93
                                        std::stringstream path;
 
94
                                        path << dir_name << dir_entry->d_name << "/";
 
95
                                        rapl_read_domains(path.str().c_str());
 
96
                                } else if (buffer == "core") {
 
97
                                        domain.type = CORE;
 
98
                                } else if (buffer == "uncore") {
 
99
                                        domain.type = UNCORE;
 
100
                                } else if (buffer == "dram") {
 
101
                                        domain.type = DRAM;
 
102
                                }
 
103
                                if (measure_mask & domain.type) {
 
104
                                        domain.name = buffer;
 
105
                                        domain.path = std::string(dir_name)
 
106
                                                        + std::string(dir_entry->d_name);
 
107
                                        domain_list.push_back(domain);
 
108
                                        ++count;
 
109
                                }
 
110
                        }
 
111
                        closedir(dir);
 
112
                } else {
 
113
                        thd_log_debug("opendir failed %s :%s\n", strerror(errno),
 
114
                                        rapl_sysfs.get_base_path());
 
115
                }
 
116
        }
 
117
 
 
118
        thd_log_info("RAPL domain count %d\n", count);
 
119
}
 
120
 
 
121
void cthd_rapl_power_meter::rapl_enable_periodic_timer() {
 
122
        pthread_attr_init(&thd_attr);
 
123
        pthread_attr_setdetachstate(&thd_attr, PTHREAD_CREATE_DETACHED);
 
124
        pthread_create(&poll_thread, &thd_attr, rapl_periodic_callback,
 
125
                        (void*) this);
 
126
}
 
127
 
 
128
bool cthd_rapl_power_meter::rapl_energy_loop() {
 
129
        csys_fs sys_fs;
 
130
        int status;
 
131
        unsigned long long counter;
 
132
        unsigned long long diff;
 
133
        time_t curr_time;
 
134
 
 
135
        if (!enable_measurement)
 
136
                return false;
 
137
 
 
138
        curr_time = time(NULL);
 
139
        if ((curr_time - last_time) <= 0)
 
140
                return true;
 
141
        for (unsigned int i = 0; i < domain_list.size(); ++i) {
 
142
                std::string buffer;
 
143
                std::string path;
 
144
 
 
145
                if (!domain_list[i].max_energy_range) {
 
146
                        std::string _path;
 
147
                        std::string _buffer;
 
148
                        _path = domain_list[i].path + "/" + "max_energy_range_uj";
 
149
                        status = sys_fs.read(_path, _buffer);
 
150
                        if (status >= 0)
 
151
                                domain_list[i].max_energy_range = atoll(_buffer.c_str()) / 1000;
 
152
                        domain_list[i].max_energy_range_threshold =
 
153
                                        domain_list[i].max_energy_range / 2;
 
154
                }
 
155
 
 
156
                path = domain_list[i].path + "/" + "energy_uj";
 
157
                status = sys_fs.read(path, buffer);
 
158
                if (status >= 0) {
 
159
                        counter = domain_list[i].energy_counter;
 
160
                        domain_list[i].energy_counter = atoll(buffer.c_str()) / 1000; // To milli Js
 
161
 
 
162
                        diff = 0;
 
163
                        if (domain_list[i].half_way
 
164
                                        && domain_list[i].energy_counter
 
165
                                                        < domain_list[i].max_energy_range_threshold) {
 
166
                                // wrap around
 
167
                                domain_list[i].energy_cumulative_counter +=
 
168
                                                domain_list[i].max_energy_range;
 
169
                                diff = domain_list[i].max_energy_range - counter;
 
170
                                counter = 0;
 
171
                                domain_list[i].half_way = 0;
 
172
 
 
173
                        } else if (domain_list[i].energy_counter
 
174
                                        > domain_list[i].max_energy_range_threshold)
 
175
                                domain_list[i].half_way = 1;
 
176
 
 
177
                        if (counter)
 
178
                                domain_list[i].power = (domain_list[i].energy_counter - counter
 
179
                                                + diff) / (curr_time - last_time);
 
180
                        thd_log_debug(" energy %d:%lld:%lld mj: %u mw \n",
 
181
                                        domain_list[i].type,
 
182
                                        domain_list[i].energy_cumulative_counter,
 
183
                                        domain_list[i].energy_counter
 
184
                                                        + domain_list[i].energy_cumulative_counter,
 
185
                                        domain_list[i].power);
 
186
 
 
187
                }
 
188
        }
 
189
        last_time = curr_time;
 
190
 
 
191
        return true;
 
192
}
 
193
 
 
194
unsigned long long cthd_rapl_power_meter::rapl_action_get_energy(
 
195
                domain_type type) {
 
196
        unsigned long long value = 0;
 
197
 
 
198
        for (unsigned int i = 0; i < domain_list.size(); ++i) {
 
199
                if (type == domain_list[i].type) {
 
200
                        value = (domain_list[i].energy_counter
 
201
                                        + domain_list[i].energy_cumulative_counter) * 1000;
 
202
                        if (!value) {
 
203
                                rapl_energy_loop();
 
204
                                value = (domain_list[i].energy_counter
 
205
                                                + domain_list[i].energy_cumulative_counter) * 1000;
 
206
                        }
 
207
 
 
208
                        break;
 
209
                }
 
210
        }
 
211
 
 
212
        return value;
 
213
}
 
214
 
 
215
unsigned int cthd_rapl_power_meter::rapl_action_get_power(domain_type type) {
 
216
        unsigned int value = 0;
 
217
 
 
218
        if (!rapl_present)
 
219
                return 0;
 
220
 
 
221
        for (unsigned int i = 0; i < domain_list.size(); ++i) {
 
222
                if (type == domain_list[i].type) {
 
223
                        value = domain_list[i].power * 1000;
 
224
                        if (!value) {
 
225
                                rapl_energy_loop();
 
226
                                sleep(1);
 
227
                                rapl_energy_loop();
 
228
                                value = domain_list[i].power * 1000;
 
229
                        }
 
230
                        break;
 
231
                }
 
232
        }
 
233
 
 
234
        return value;
 
235
}
 
236
 
 
237
void cthd_rapl_power_meter::rapl_measure_power() {
 
238
        if (rapl_present && enable_measurement)
 
239
                rapl_energy_loop();
 
240
}