home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / emacs-15.0.3 / etc / loadst.c < prev    next >
C/C++ Source or Header  |  1990-08-09  |  8KB  |  345 lines

  1. /*
  2.  * loadst -- print current time and load statistics.
  3.  *                -- James Gosling @ CMU, May 1981
  4.  *  loadst [ -n ] [ interval ]
  5.  */
  6.  
  7. #define NO_SHORTNAMES  /* Do not want config to try to include remap.h */
  8. #include "../src/config.h"
  9. #include <stdio.h>
  10. #include <pwd.h>
  11.  
  12. /* Define two macros KERNEL_FILE (file to find kernel symtab in)
  13.    and LDAV_SYMBOL (symbol name to look for), based on system type.
  14.    Also define NLIST_STRUCT if the type `nlist' is a structure we
  15.    can get from nlist.h; otherwise must use a.out.h and initialize
  16.    with strcpy.  Note that config.h may define NLIST_STRUCT
  17.    for more modern USG systems.  */
  18.  
  19.  
  20. #ifdef LOAD_AVE_TYPE
  21. #ifndef NLIST_STRUCT
  22. #include <a.out.h>
  23. #else /* NLIST_STRUCT */
  24. #include <nlist.h>
  25. #endif /* NLIST_STRUCT */
  26. #endif /* LOAD_AVE_TYPE */
  27.  
  28. /* All this serves to #include <param.h> and clean up the consequences.  */
  29. #ifdef BSD
  30. /* It appears param.h defines BSD and BSD4_3 in 4.3
  31.    and is not considerate enough to avoid bombing out
  32.    if they are already defined.  */
  33. #undef BSD
  34. #ifdef BSD4_3
  35. #undef BSD4_3
  36. #define XBSD4_3 /* XBSD4_3 says BSD4_3 is supposed to be defined.  */
  37. #endif
  38. #include <sys/param.h>
  39. /* Now if BSD or BSD4_3 was defined and is no longer,
  40.    define it again.  */
  41. #ifndef BSD
  42. #define BSD
  43. #endif
  44. #ifdef XBSD4_3
  45. #ifndef BSD4_3
  46. #define BSD4_3
  47. #endif
  48. #endif /* XBSD4_3 */
  49. #endif /* BSD */
  50.  
  51. #ifdef USG
  52. #include <time.h>
  53. #include <sys/types.h>
  54. #else /* not USG */
  55. #include <sys/time.h>
  56. #ifdef LOAD_AVE_TYPE
  57. #ifndef RTU
  58. #ifndef UMAX
  59. #ifdef DKSTAT_HEADER_FILE
  60. #include <sys/dkstat.h>
  61. #else
  62. #include <sys/dk.h>
  63. #endif /* not DKSTAT_HEADER_FILE */
  64. #endif /* UMAX */
  65. #endif /* not RTU */
  66. #endif /* LOAD_AVE_TYPE */
  67. #endif /* USG */
  68.  
  69. #include <sys/stat.h>
  70.  
  71. #ifdef BSD
  72. #include <sys/ioctl.h>
  73. #endif /* BSD */
  74.  
  75. #ifdef UMAX
  76. /*
  77.  *  UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
  78.  *  have a /dev/kmem.  Information about the workings of the running kernel
  79.  *  can be gathered with inq_stats system calls.
  80.  */
  81. #include <sys/sysdefs.h>
  82. #include <sys/syscall.h>
  83. #include <sys/statistics.h>
  84. #include <sys/procstats.h>
  85. #include <sys/sysstats.h>
  86. #endif /* UMAX */
  87.  
  88. /* We don't want Emacs's macro definitions for these USG primitives. */
  89.  
  90. #undef open
  91. #undef read
  92. #undef close
  93.  
  94. struct tm *localtime ();
  95.  
  96. #ifndef DKXFER_SYMBOL
  97. #define DKXFER_SYMBOL "_dk_xfer"
  98. #endif
  99. #ifndef CPTIME_SYMBOL
  100. #define CPTIME_SYMBOL "_cp_time"
  101. #endif
  102.  
  103. #ifdef LOAD_AVE_TYPE
  104. #ifndef NLIST_STRUCT
  105. struct nlist nl[2];
  106. #else /* NLIST_STRUCT */
  107. struct nlist nl[] =
  108.   {
  109.     {{ LDAV_SYMBOL }},
  110. #if defined (CPUSTATES) && defined (DK_NDRIVE)
  111. #define    X_CPTIME    1
  112.     {{ CPTIME_SYMBOL }},
  113. #define    X_DKXFER    2
  114.     {{ DKXFER_SYMBOL }},
  115. #endif /* have CPUSTATES and DK_NDRIVE */
  116.     {{ 0 }},
  117.   };
  118. #endif /* NLIST_STRUCT */
  119. #endif /* LOAD_AVE_TYPE */
  120.  
  121. #if defined (CPUSTATES) && defined (DK_NDRIVE)
  122.  
  123. struct
  124. {
  125.   long    time[CPUSTATES];
  126.   long    xfer[DK_NDRIVE];
  127. } s, s1;
  128.  
  129. double    etime;
  130.  
  131. #endif /* have CPUSTATES and DK_NDRIVE */
  132.  
  133. int nflag;            /* -n flag -- no newline */
  134. int uflag;            /* -u flag -- user current user ID rather
  135.                    than login user ID */
  136. int repetition;            /* repetition interval */
  137.  
  138. #ifdef LOAD_AVE_TYPE
  139. LOAD_AVE_TYPE load_average ();
  140. #endif /* LOAD_AVE_TYPE */
  141.  
  142. main (argc, argv)
  143.      char  **argv;
  144. {
  145.   register int kmem, i;
  146.   char *mail;
  147.   char *user_name;
  148.   struct stat st;
  149. #ifdef LOAD_AVE_TYPE
  150.   LOAD_AVE_TYPE load;
  151. #endif /* LOAD_AVE_TYPE */
  152.  
  153.   kmem = open ("/dev/kmem", 0);
  154.  
  155. #ifdef LOAD_AVE_TYPE
  156. #ifndef NLIST_STRUCT
  157.   strcpy (nl[0].n_name, LDAV_SYMBOL);
  158.   strcpy (nl[1].n_name, "");
  159. #endif /* not NLIST_STRUCT */
  160.  
  161. #ifdef    NeXT
  162. #define KERNEL_FILE "/vmunix"
  163.   nlist (KERNEL_FILE, nl);
  164. #undef KERNEL_FILE
  165. #else    NeXT
  166.   nlist (KERNEL_FILE, nl);
  167. #endif    NeXT
  168. #endif /* LOAD_AVE_TYPE */
  169.  
  170.   while (--argc > 0)
  171.     {
  172.       argv++;
  173.       if (strcmp (*argv, "-n") == 0)
  174.     nflag++;
  175.       else if (strcmp (*argv, "-u") == 0)
  176.     uflag++;
  177.       else
  178.     if ((repetition = atoi (*argv)) <= 0)
  179.       {
  180.         fprintf (stderr, "Bogus argument: %s\n", *argv);
  181.         exit (1);
  182.       }
  183.     }
  184.  
  185.   user_name = uflag ? ((struct passwd *) getpwuid (getuid ())) -> pw_name
  186. #ifdef USG
  187.     : (char *) getenv ("LOGNAME");
  188. #else
  189.     : (char *) getenv ("USER");
  190. #endif
  191.  
  192.   mail = (char *) getenv ("MAIL");
  193.  
  194.   if (mail == 0)
  195.     {
  196.       mail = (char *) malloc (strlen (user_name) + 30);
  197.  
  198. #if defined (USG) && ! defined (XENIX)
  199.       sprintf (mail, "/usr/mail/%s", user_name);
  200. #else /* Xenix, or not USG */
  201.       sprintf (mail, "/usr/spool/mail/%s", user_name);
  202. #endif /* Xenix, or not USG */
  203.     }
  204.  
  205.   if (stat (mail, &st) >= 0
  206.       && (st.st_mode & S_IFMT) == S_IFDIR)
  207.     {
  208.       strcat (mail, "/");
  209.       strcat (mail, user_name);
  210.     }
  211.  
  212.   while (1)
  213.     {
  214.       register struct tm *nowt;
  215.       long now;
  216.  
  217.       time (&now);
  218.       nowt = localtime (&now);
  219.  
  220.       printf ("%d:%02d%s ",
  221.           ((nowt->tm_hour + 11) % 12) + 1,
  222.           nowt->tm_min,
  223.           nowt->tm_hour >= 12 ? "pm" : "am");
  224.  
  225. #ifdef LOAD_AVE_TYPE
  226.       load = load_average (kmem);
  227.       if (load != (LOAD_AVE_TYPE) -1)
  228.     printf("%.2f", LOAD_AVE_CVT (load) / 100.0);
  229. #endif /* LOAD_AVE_TYPE */
  230.  
  231.       printf ("%s",
  232.           ((stat (mail, &st) >= 0 && st.st_size > 0)
  233.            ? " Mail"
  234.            : ""));
  235.  
  236. #if defined (CPUSTATES) && defined (DK_NDRIVE)
  237.       if (kmem >= 0)
  238.     {
  239.       lseek (kmem, (long) nl[X_CPTIME].n_value, 0);
  240.       read (kmem, s.time, sizeof s.time);
  241.       lseek (kmem, (long) nl[X_DKXFER].n_value, 0);
  242.       read (kmem, s.xfer, sizeof s.xfer);
  243.       etime = 0;
  244.       for (i = 0; i < DK_NDRIVE; i++)
  245.         {
  246.           register t = s.xfer[i];
  247.           s.xfer[i] -= s1.xfer[i];
  248.           s1.xfer[i] = t;
  249.         }
  250.       for (i = 0; i < CPUSTATES; i++)
  251.         {
  252.           register t = s.time[i];
  253.           s.time[i] -= s1.time[i];
  254.           s1.time[i] = t;
  255.           etime += s.time[i];
  256.         }
  257.       if (etime == 0.)
  258.         etime = 1.;
  259.       etime /= 60.;
  260.      
  261.       {   register max = s.xfer[0];
  262.           for (i = 1; i < DK_NDRIVE; i++)
  263.         if (s.xfer[i] > max)
  264.           max = s.xfer[i];
  265.           printf ("[%d]", (int) (max / etime + 0.5));
  266.         }
  267.     }
  268. #endif /* have CPUSTATES and DK_NDRIVE */
  269.       if (!nflag)
  270.     putchar ('\n');
  271.       fflush (stdout);
  272.       if (repetition <= 0)
  273.     break;
  274.       sleep (repetition);
  275.  
  276. #ifdef BSD
  277.       /* We are about to loop back and write another unit of output.  */
  278.       /* If previous output has not yet been read by Emacs, flush it
  279.      so the pty output buffer never gets full and Emacs
  280.      can always get the latest update right away.  */
  281.       /* ??? Someone should write a USG version of this code!  */
  282.       {
  283.     int zero = 0;
  284.  
  285.     ioctl (fileno (stdout), TIOCFLUSH, &zero);
  286.       }
  287. #endif
  288.     }
  289. }
  290.  
  291. #ifdef LOAD_AVE_TYPE
  292.  
  293. LOAD_AVE_TYPE
  294. load_average (kmem)
  295.      int kmem;
  296. {
  297. #ifdef UMAX
  298.  
  299.   int i, j;
  300.   double sum;
  301.   struct proc_summary proc_sum_data;
  302.   struct stat_descr proc_info;
  303.   
  304.   proc_info.sd_next = NULL;
  305.   proc_info.sd_subsys = SUBSYS_PROC;
  306.   proc_info.sd_type = PROCTYPE_SUMMARY;
  307.   proc_info.sd_addr = (char *) &proc_sum_data;
  308.   proc_info.sd_size = sizeof (struct proc_summary);
  309.   proc_info.sd_sizeused = 0;
  310.   
  311.   if (inq_stats (1, &proc_info) != 0 )
  312.     {
  313.       perror ("sysline proc summary inq_stats");
  314.       exit (1);
  315.     }
  316.   /*
  317.    * Generate current load average.
  318.    */
  319.   sum = 0;
  320.   for (i = proc_sum_data.ps_nrunidx, j = 0; j < 12; j++)
  321.     {
  322.       sum += proc_sum_data.ps_nrun[i];
  323.       if (--i < 0)
  324.     i = 179;
  325.     }
  326.   return sum / 12;
  327.  
  328. #else /* not UMAX */
  329.  
  330.   if (kmem >= 0)
  331.     {
  332.       LOAD_AVE_TYPE avenrun[3];
  333.       avenrun[0] = 0;
  334.       lseek (kmem, (long) nl[0].n_value, 0);
  335.       read (kmem, avenrun, sizeof (avenrun));
  336.       return avenrun[0];
  337.     }
  338.   else
  339.     return (LOAD_AVE_TYPE) -1;
  340.  
  341. #endif /* UMAX */
  342. }
  343.  
  344. #endif /* LOAD_AVE_TYPE */
  345.