"Fossies" - the Fresh Open Source Software Archive

Member "procmeter3-3.6+svn387/modules/longrun.c" (24 Dec 2010, 6116 Bytes) of package /linux/misc/procmeter3-3.6+svn387.tgz:


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 "longrun.c" see the Fossies "Dox" file reference documentation.

    1 /***************************************
    2   $Header: /home/amb/CVS/procmeter3/modules/longrun.c,v 1.10 2010-02-28 10:22:16 amb Exp $
    3 
    4   ProcMeter - A system monitoring program for Linux - Version 3.5d.
    5 
    6   Transmeta longrun support.
    7   ******************/ /******************
    8   Written by Joey Hess (with heavy borrowing from longrun)
    9 
   10   This file Copyright 2002 Joey Hess
   11             Copyright 2001 Transmeta Corporation
   12   It may be distributed under the GNU Public License, version 2, or
   13   any higher version.  See section COPYING of the GNU Public license
   14   for conditions under which this file may be redistributed.
   15   ***************************************/
   16 
   17 #define _XOPEN_SOURCE 500
   18 
   19 #include <stdio.h>
   20 #include <stdlib.h>
   21 #include <string.h>
   22 #include <stdint.h>
   23 #include <sys/types.h>
   24 #include <sys/stat.h>
   25 #include <fcntl.h>
   26 #define __USE_FILE_OFFSET64 /* we should use 64 bit offset for pread */
   27 #include <unistd.h>
   28 
   29 #include "procmeter.h"
   30 
   31 /* The canonical source for these defines is longrun.c in the longrun
   32  * utility. */
   33 #define CPUID_DEVICE "/dev/cpu/0/cpuid"
   34 #define CPUID_TMx86_LONGRUN_STATUS 0x80860007
   35 #define CPUID_TMx86_VENDOR_ID 0x80860000
   36 #define CPUID_TMx86_PROCESSOR_INFO 0x80860001
   37 #define CPUID_TMx86_FEATURE_LONGRUN(x) ((x) & 0x02)
   38 
   39 static int cpuid_fd = 0;
   40 
   41 static void read_cpuid(loff_t address, int *eax, int *ebx, int *ecx, int *edx) {
   42         uint32_t data[4];
   43 
   44         if (pread(cpuid_fd, &data, 16, address) != 16) {
   45                 perror("error reading");
   46         }
   47 
   48         if (eax) *eax = data[0];
   49         if (ebx) *ebx = data[1];
   50         if (ecx) *ecx = data[2];
   51         if (edx) *edx = data[3];
   52 }
   53 
   54 /* The interface information.  */
   55 
   56 /*+ The template for the longrun devices +*/
   57 ProcMeterOutput _outputs[1]=
   58 {
   59  {
   60   /* char  name[];          */ "Longrun",
   61   /* char *description;     */ "current longrun performance level",
   62   /* char  type;            */ PROCMETER_GRAPH|PROCMETER_TEXT|PROCMETER_BAR,
   63   /* short interval;        */ 1,
   64   /* char  text_value[];    */ "0 %",
   65   /* long  graph_value;     */ 0,
   66   /* short graph_scale;     */ 20,
   67   /* char  graph_units[];   */ "(%d%%)"
   68  },
   69 };
   70 
   71 static int ndevices=0;
   72 static unsigned long *current=NULL,*previous=NULL;
   73 static char **device=NULL;
   74 
   75 static void add_device(void);
   76 
   77 /*+ The outputs. +*/
   78 ProcMeterOutput **outputs=NULL;
   79 
   80 /*+ The module. +*/
   81 ProcMeterModule module=
   82 {
   83  /* char name[];            */ "Longrun",
   84  /* char *description;      */ "Transmeta Crusoe longrun information.  "
   85                                "Only available if using a Transmeta Crusoe CPU that supports it and the kernel was compiled with CONFIG_X86_CPUID=y."
   86 };
   87 
   88 /*++++++++++++++++++++++++++++++++++++++
   89   Load the module.
   90 
   91   ProcMeterModule *Load Returns the module information.
   92   ++++++++++++++++++++++++++++++++++++++*/
   93 
   94 ProcMeterModule *Load(void)
   95 {
   96  return(&module);
   97 }
   98 
   99 
  100 /*++++++++++++++++++++++++++++++++++++++
  101   Initialise the module, creating the outputs as required.
  102 
  103   ProcMeterOutput **Initialise Returns a NULL terminated list of outputs.
  104 
  105   char *options The options string for the module from the .procmeterrc file.
  106   ++++++++++++++++++++++++++++++++++++++*/
  107 
  108 ProcMeterOutput **Initialise(char *options)
  109 {
  110  int eax, ebx, ecx, edx;
  111 
  112  outputs=(ProcMeterOutput**)malloc(sizeof(ProcMeterOutput*));
  113  outputs[0]=NULL;
  114 
  115  if ((cpuid_fd = open(CPUID_DEVICE, O_RDONLY)) < 0) {
  116   /* Don't bother giving an error message for 99% of systems. */
  117   //     fprintf(stderr, "ProcMeter(%s): Cannot open " CPUID_DEVICE ". make sure your kernel was compiled with CONFIG_X86_CPUID=y, and make sure the device is readable\n", __FILE__);
  118      return outputs;
  119  }
  120  
  121  /* See if longrun is supported by this system. */
  122  read_cpuid(CPUID_TMx86_VENDOR_ID, &eax, &ebx, &ecx, &edx);
  123  if (ebx != 0x6e617254 || ecx != 0x55504361 || edx != 0x74656d73) {
  124      fprintf(stderr, "ProcMeter(%s): Not a Transmeta x86 CPU.\n", __FILE__);
  125      return outputs;
  126  }
  127  read_cpuid(CPUID_TMx86_PROCESSOR_INFO, &eax, &ebx, &ecx, &edx);
  128  if (!CPUID_TMx86_FEATURE_LONGRUN(edx)) {
  129      fprintf(stderr, "ProcMeter(%s): Longrun unsupported.\n", __FILE__);
  130      return outputs;
  131  }
  132  
  133  add_device();
  134 
  135  current =(unsigned long*)malloc(sizeof(long)*ndevices);
  136  previous=(unsigned long*)malloc(sizeof(long)*ndevices);
  137 
  138  return(outputs);
  139 }
  140 
  141 /*++++++++++++++++++++++++++++++++++++++
  142   Add a new device to the list.
  143 
  144   Currently we just support one CPU, so no parameters.
  145   ++++++++++++++++++++++++++++++++++++++*/
  146 
  147 static void add_device(void)
  148 {
  149  int nstats=1;
  150  int i;
  151 
  152  outputs=(ProcMeterOutput**)realloc((void*)outputs,(ndevices+nstats+1)*sizeof(ProcMeterOutput*));
  153  device=(char**)realloc((void*)device,(ndevices+nstats+1)*sizeof(char*));
  154 
  155  for(i=0;nstats;nstats--)
  156    {
  157     outputs[ndevices]=(ProcMeterOutput*)malloc(sizeof(ProcMeterOutput));
  158     device[ndevices]=(char*)malloc(1);
  159 
  160     *outputs[ndevices]=_outputs[i];
  161     outputs[ndevices]->description=(char*)malloc(strlen(_outputs[i].description)+4);
  162     strcpy(outputs[ndevices]->description,_outputs[i].description);
  163 
  164     strcpy(device[ndevices],"0");
  165 
  166     ndevices++;
  167 
  168     i++;
  169    }
  170 
  171  outputs[ndevices]=NULL;
  172 }
  173 
  174 /*++++++++++++++++++++++++++++++++++++++
  175   Perform an update on one of the statistics.
  176 
  177   int Update Returns 0 if OK, else -1.
  178 
  179   time_t now The current time.
  180 
  181   ProcMeterOutput *output The output that the value is wanted for.
  182   ++++++++++++++++++++++++++++++++++++++*/
  183 
  184 int Update(time_t now,ProcMeterOutput *output)
  185 {
  186  int percent;
  187  read_cpuid(CPUID_TMx86_LONGRUN_STATUS, 0, 0, &percent, 0);
  188  output[0].graph_value=PROCMETER_GRAPH_FLOATING(percent/output[0].graph_scale);
  189  sprintf(output->text_value,"%i %%",percent);
  190  return(0);
  191 }
  192 
  193 
  194 /*++++++++++++++++++++++++++++++++++++++
  195   Tidy up and prepare to have the module unloaded.
  196   ++++++++++++++++++++++++++++++++++++++*/
  197 
  198 void Unload(void)
  199 {
  200  int i;
  201 
  202  if(outputs)
  203    {
  204     for(i=0;outputs[i];i++)
  205       {
  206        free(outputs[i]->description);
  207        free(outputs[i]);
  208       }
  209     free(outputs);
  210    }
  211  if(current)
  212     free(current);
  213  if(previous)
  214     free(previous);
  215  if(device)
  216    {
  217     for(i=0;i<ndevices;i++)
  218        free(device[i]);
  219     free(device);
  220    }
  221  if (cpuid_fd)
  222    close(cpuid_fd);
  223 }