"Fossies" - the Fresh Open Source Software Archive

Member "stress-ng-0.09.56/core-thermal-zone.c" (15 Mar 2019, 4592 Bytes) of package /linux/privat/stress-ng-0.09.56.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "core-thermal-zone.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.09.52_vs_0.09.54.

    1 /*
    2  * Copyright (C) 2013-2019 Canonical, Ltd.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
   17  *
   18  * This code is a complete clean re-write of the stress tool by
   19  * Colin Ian King <colin.king@canonical.com> and attempts to be
   20  * backwardly compatible with the stress tool by Amos Waterland
   21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
   22  * functionality.
   23  *
   24  */
   25 #include "stress-ng.h"
   26 
   27 #if defined(STRESS_THERMAL_ZONES)
   28 /*
   29  *  tz_init()
   30  *  gather all thermal zones
   31  */
   32 int tz_init(tz_info_t **tz_info_list)
   33 {
   34     DIR *dir;
   35         struct dirent *entry;
   36     size_t i = 0;
   37 
   38     dir = opendir("/sys/class/thermal");
   39     if (!dir)
   40         return 0;
   41 
   42     while ((entry = readdir(dir)) != NULL) {
   43         char path[PATH_MAX];
   44         FILE *fp;
   45         tz_info_t *tz_info;
   46 
   47         /* Ignore non TZ interfaces */
   48         if (strncmp(entry->d_name, "thermal_zone", 12))
   49             continue;
   50 
   51         /* Ensure we don't overstep the max limit of TZs */
   52         if (i >= STRESS_THERMAL_ZONES_MAX)
   53             break;
   54 
   55         if ((tz_info = calloc(1, sizeof(*tz_info))) == NULL) {
   56             pr_err("Cannot allocate thermal information\n");
   57             (void)closedir(dir);
   58             return -1;
   59         }
   60         (void)snprintf(path, sizeof(path),
   61             "/sys/class/thermal/%s/type",
   62             entry->d_name);
   63 
   64         tz_info->path = strdup(entry->d_name);
   65         if (!tz_info->path) {
   66             free(tz_info);
   67             (void)closedir(dir);
   68             return -1;
   69         }
   70         tz_info->type = NULL;
   71         if ((fp = fopen(path, "r")) != NULL) {
   72             char type[128];
   73 
   74             if (fgets(type, sizeof(type), fp) != NULL) {
   75                 type[strcspn(type, "\n")] = '\0';
   76                 tz_info->type  = strdup(type);
   77             }
   78             (void)fclose(fp);
   79         }
   80         if (!tz_info->type) {
   81             free(tz_info->path);
   82             free(tz_info);
   83             (void)closedir(dir);
   84             return -1;
   85         }
   86         tz_info->index = i++;
   87         tz_info->next = *tz_info_list;
   88         *tz_info_list = tz_info;
   89     }
   90 
   91     (void)closedir(dir);
   92     return 0;
   93 }
   94 
   95 /*
   96  *  tz_free()
   97  *  free thermal zones
   98  */
   99 void tz_free(tz_info_t **tz_info_list)
  100 {
  101     tz_info_t *tz_info = *tz_info_list;
  102 
  103     while (tz_info) {
  104         tz_info_t *next = tz_info->next;
  105 
  106         free(tz_info->path);
  107         free(tz_info->type);
  108         free(tz_info);
  109         tz_info = next;
  110     }
  111 }
  112 
  113 /*
  114  *  tz_get_temperatures()
  115  *  collect valid thermal_zones details
  116  */
  117 int tz_get_temperatures(tz_info_t **tz_info_list, stress_tz_t *tz)
  118 {
  119         tz_info_t *tz_info;
  120 
  121     for (tz_info = *tz_info_list; tz_info; tz_info = tz_info->next) {
  122         char path[PATH_MAX];
  123         FILE *fp;
  124         size_t i = tz_info->index;
  125 
  126         (void)snprintf(path, sizeof(path),
  127             "/sys/class/thermal/%s/temp",
  128             tz_info->path);
  129 
  130         tz->tz_stat[i].temperature = 0;
  131         if ((fp = fopen(path, "r")) != NULL) {
  132             if (fscanf(fp, "%" SCNu64,
  133                  &tz->tz_stat[i].temperature) != 1) {
  134                 tz->tz_stat[i].temperature = 0;
  135             }
  136             (void)fclose(fp);
  137         }
  138     }
  139     return 0;
  140 }
  141 
  142 /*
  143  *  tz_dump()
  144  *  dump thermal zone temperatures
  145  */
  146 void tz_dump(FILE *yaml, proc_info_t *procs_head)
  147 {
  148     bool no_tz_stats = true;
  149     proc_info_t *pi;
  150 
  151     pr_yaml(yaml, "thermal-zones:\n");
  152 
  153     for (pi = procs_head; pi; pi = pi->next) {
  154         tz_info_t *tz_info;
  155         int32_t  j;
  156         uint64_t total = 0;
  157         uint32_t count = 0;
  158         bool dumped_heading = false;
  159 
  160         for (tz_info = g_shared->tz_info; tz_info; tz_info = tz_info->next) {
  161             for (j = 0; j < pi->started_procs; j++) {
  162                 uint64_t temp;
  163 
  164                 temp = pi->stats[j]->tz.tz_stat[tz_info->index].temperature;
  165                 /* Avoid crazy temperatures. e.g. > 250 C */
  166                 if (temp <= 250000) {
  167                     total += temp;
  168                     count++;
  169                 }
  170             }
  171 
  172             if (total) {
  173                 double temp = ((double)total / count) / 1000.0;
  174                 char *munged = stress_munge_underscore(pi->stressor->name);
  175 
  176                 if (!dumped_heading) {
  177                     dumped_heading = true;
  178                     pr_inf("%s:\n", munged);
  179                     pr_yaml(yaml, "    - stressor: %s\n",
  180                         munged);
  181                 }
  182                 pr_inf("%20s %7.2f C (%.2f K)\n",
  183                     tz_info->type, temp, temp + 273.15);
  184                 pr_yaml(yaml, "      %s: %7.2f\n",
  185                     tz_info->type, temp);
  186                 no_tz_stats = false;
  187             }
  188         }
  189         if (total)
  190             pr_yaml(yaml, "\n");
  191     }
  192 
  193     if (no_tz_stats)
  194         pr_inf("thermal zone temperatures not available\n");
  195 }
  196 
  197 #endif