Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/tools/thermal/tmon/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 8 kB image not shown  

Quelle  tmon.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * tmon.c Thermal Monitor (TMON) main function and entry point
 *
 * Copyright (C) 2012 Intel Corporation. All rights reserved.
 *
 * Author: Jacob Pan <jacob.jun.pan@linux.intel.com>
 */


#include <getopt.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ncurses.h>
#include <ctype.h>
#include <time.h>
#include <signal.h>
#include <limits.h>
#include <sys/time.h>
#include <pthread.h>
#include <math.h>
#include <stdarg.h>
#include <syslog.h>

#include "tmon.h"

unsigned long ticktime = 1; /* seconds */
unsigned long no_control = 1; /* monitoring only or use cooling device for
       * temperature control.
       */

double time_elapsed = 0.0;
unsigned long target_temp_user = 65; /* can be select by tui later */
int dialogue_on;
int tmon_exit;
static short daemon_mode;
static int logging; /* for recording thermal data to a file */
static int debug_on;
FILE *tmon_log;
/*cooling device used for the PID controller */
char ctrl_cdev[CDEV_NAME_SIZE] = "None";
int target_thermal_zone; /* user selected target zone instance */
static void start_daemon_mode(void);

pthread_t event_tid;
pthread_mutex_t input_lock;
void usage(void)
{
 printf("Usage: tmon [OPTION...]\n");
 printf(" -c, --control cooling device in control\n");
 printf(" -d, --daemon run as daemon, no TUI\n");
 printf(" -g, --debug debug message in syslog\n");
 printf(" -h, --help show this help message\n");
 printf(" -l, --log log data to /var/tmp/tmon.log\n");
 printf(" -t, --time-interval sampling time interval, > 1 sec.\n");
 printf(" -T, --target-temp initial target temperature\n");
 printf(" -v, --version show version\n");
 printf(" -z, --zone target thermal zone id\n");

 exit(0);
}

void version(void)
{
 printf("TMON version %s\n", VERSION);
 exit(EXIT_SUCCESS);
}

static void tmon_cleanup(void)
{
 syslog(LOG_INFO, "TMON exit cleanup\n");
 fflush(stdout);
 refresh();
 if (tmon_log)
  fclose(tmon_log);
 if (event_tid) {
  pthread_mutex_lock(&input_lock);
  pthread_cancel(event_tid);
  pthread_mutex_unlock(&input_lock);
  pthread_mutex_destroy(&input_lock);
 }
 closelog();
 /* relax control knobs, undo throttling */
 set_ctrl_state(0);

 keypad(stdscr, FALSE);
 echo();
 nocbreak();
 close_windows();
 endwin();
 free_thermal_data();

 exit(1);
}

static void tmon_sig_handler(int sig)
{
 syslog(LOG_INFO, "TMON caught signal %d\n", sig);
 refresh();
 switch (sig) {
 case SIGTERM:
  printf("sigterm, exit and clean up\n");
  fflush(stdout);
  break;
 case SIGKILL:
  printf("sigkill, exit and clean up\n");
  fflush(stdout);
  break;
 case SIGINT:
  printf("ctrl-c, exit and clean up\n");
  fflush(stdout);
  break;
 default:
  break;
 }
 tmon_exit = true;
}

static void start_syslog(void)
{
 if (debug_on)
  setlogmask(LOG_UPTO(LOG_DEBUG));
 else
  setlogmask(LOG_UPTO(LOG_ERR));
 openlog("tmon.log", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);
 syslog(LOG_NOTICE, "TMON started by User %d", getuid());
}

static void prepare_logging(void)
{
 int i;
 struct stat logstat;

 if (!logging)
  return;
 /* open local data log file */
 tmon_log = fopen(TMON_LOG_FILE, "w+");
 if (!tmon_log) {
  syslog(LOG_ERR, "failed to open log file %s\n", TMON_LOG_FILE);
  return;
 }

 if (lstat(TMON_LOG_FILE, &logstat) < 0) {
  syslog(LOG_ERR, "Unable to stat log file %s\n", TMON_LOG_FILE);
  fclose(tmon_log);
  tmon_log = NULL;
  return;
 }

 /* The log file must be a regular file owned by us */
 if (S_ISLNK(logstat.st_mode)) {
  syslog(LOG_ERR, "Log file is a symlink. Will not log\n");
  fclose(tmon_log);
  tmon_log = NULL;
  return;
 }

 if (logstat.st_uid != getuid()) {
  syslog(LOG_ERR, "We don't own the log file. Not logging\n");
  fclose(tmon_log);
  tmon_log = NULL;
  return;
 }

 fprintf(tmon_log, "#----------- THERMAL SYSTEM CONFIG -------------\n");
 for (i = 0; i < ptdata.nr_tz_sensor; i++) {
  char binding_str[33]; /* size of long + 1 */
  int j;

  memset(binding_str, 0, sizeof(binding_str));
  for (j = 0; j < 32; j++)
   binding_str[j] = (ptdata.tzi[i].cdev_binding & (1 << j)) ?
    '1' : '0';

  fprintf(tmon_log, "#thermal zone %s%02d cdevs binding: %32s\n",
   ptdata.tzi[i].type,
   ptdata.tzi[i].instance,
   binding_str);
  for (j = 0; j < ptdata.tzi[i].nr_trip_pts; j++) {
   fprintf(tmon_log, "#\tTP%02d type:%s, temp:%lu\n", j,
    trip_type_name[ptdata.tzi[i].tp[j].type],
    ptdata.tzi[i].tp[j].temp);
  }
 }

 for (i = 0; i < ptdata.nr_cooling_dev; i++)
  fprintf(tmon_log, "#cooling devices%02d: %s\n",
   i, ptdata.cdi[i].type);

 fprintf(tmon_log, "#---------- THERMAL DATA LOG STARTED -----------\n");
 fprintf(tmon_log, "Samples TargetTemp ");
 for (i = 0; i < ptdata.nr_tz_sensor; i++) {
  fprintf(tmon_log, "%s%d ", ptdata.tzi[i].type,
   ptdata.tzi[i].instance);
 }
 for (i = 0; i < ptdata.nr_cooling_dev; i++)
  fprintf(tmon_log, "%s%d ", ptdata.cdi[i].type,
   ptdata.cdi[i].instance);

 fprintf(tmon_log, "\n");
}

static struct option opts[] = {
 { "control", 1, NULL, 'c' },
 { "daemon", 0, NULL, 'd' },
 { "time-interval", 1, NULL, 't' },
 { "target-temp", 1, NULL, 'T' },
 { "log", 0, NULL, 'l' },
 { "help", 0, NULL, 'h' },
 { "version", 0, NULL, 'v' },
 { "debug", 0, NULL, 'g' },
 { 0, 0, NULL, 0 }
};

int main(int argc, char **argv)
{
 int err = 0;
 int id2 = 0, c;
 double yk = 0.0, temp; /* controller output */
 int target_tz_index;

 if (geteuid() != 0) {
  printf("TMON needs to be run as root\n");
  exit(EXIT_FAILURE);
 }

 while ((c = getopt_long(argc, argv, "c:dlht:T:vgz:", opts, &id2)) != -1) {
  switch (c) {
  case 'c':
   no_control = 0;
   strncpy(ctrl_cdev, optarg, CDEV_NAME_SIZE);
   break;
  case 'd':
   start_daemon_mode();
   printf("Run TMON in daemon mode\n");
   break;
  case 't':
   ticktime = strtod(optarg, NULL);
   if (ticktime < 1)
    ticktime = 1;
   break;
  case 'T':
   temp = strtod(optarg, NULL);
   if (temp < 0) {
    fprintf(stderr, "error: temperature must be positive\n");
    return 1;
   }
   target_temp_user = temp;
   break;
  case 'l':
   printf("Logging data to /var/tmp/tmon.log\n");
   logging = 1;
   break;
  case 'h':
   usage();
   break;
  case 'v':
   version();
   break;
  case 'g':
   debug_on = 1;
   break;
  case 'z':
   target_thermal_zone = strtod(optarg, NULL);
   break;
  default:
   break;
  }
 }
 if (pthread_mutex_init(&input_lock, NULL) != 0) {
  fprintf(stderr, "\n mutex init failed, exit\n");
  return 1;
 }
 start_syslog();
 if (signal(SIGINT, tmon_sig_handler) == SIG_ERR)
  syslog(LOG_DEBUG, "Cannot handle SIGINT\n");
 if (signal(SIGTERM, tmon_sig_handler) == SIG_ERR)
  syslog(LOG_DEBUG, "Cannot handle SIGTERM\n");

 if (probe_thermal_sysfs()) {
  pthread_mutex_destroy(&input_lock);
  closelog();
  return -1;
 }
 initialize_curses();
 setup_windows();
 signal(SIGWINCH, resize_handler);
 show_title_bar();
 show_sensors_w();
 show_cooling_device();
 update_thermal_data();
 show_data_w();
 prepare_logging();
 init_thermal_controller();

 nodelay(stdscr, TRUE);
 err = pthread_create(&event_tid, NULL, &handle_tui_events, NULL);
 if (err != 0) {
  printf("\ncan't create thread :[%s]", strerror(err));
  tmon_cleanup();
  exit(EXIT_FAILURE);
 }

 /* validate range of user selected target zone, default to the first
 * instance if out of range
 */

 target_tz_index = zone_instance_to_index(target_thermal_zone);
 if (target_tz_index < 0) {
  target_thermal_zone = ptdata.tzi[0].instance;
  syslog(LOG_ERR, "target zone is not found, default to %d\n",
   target_thermal_zone);
 }
 while (1) {
  sleep(ticktime);
  show_title_bar();
  show_sensors_w();
  update_thermal_data();
  if (!dialogue_on) {
   show_data_w();
   show_cooling_device();
  }
  time_elapsed += ticktime;
  controller_handler(trec[0].temp[target_tz_index] / 1000, &yk);
  trec[0].pid_out_pct = yk;
  if (!dialogue_on)
   show_control_w();
  if (tmon_exit)
   break;
 }
 tmon_cleanup();
 return 0;
}

static void start_daemon_mode(void)
{
 daemon_mode = 1;
 /* fork */
 pid_t sid, pid = fork();

 if (pid < 0)
  exit(EXIT_FAILURE);
 else if (pid > 0)
  /* kill parent */
  exit(EXIT_SUCCESS);

 /* disable TUI, it may not be necessary, but saves some resource */
 disable_tui();

 /* change the file mode mask */
 umask(S_IWGRP | S_IWOTH);

 /* new SID for the daemon process */
 sid = setsid();
 if (sid < 0)
  exit(EXIT_FAILURE);

 /* change working directory */
 if ((chdir("/")) < 0)
  exit(EXIT_FAILURE);

 sleep(10);

 close(STDIN_FILENO);
 close(STDOUT_FILENO);
 close(STDERR_FILENO);
}

Messung V0.5
C=96 H=92 G=93

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.