home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1988, 1989 Free Software Foundation, Inc.
- This file is part of GNU Make.
-
- GNU Make is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- GNU Make is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Make; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /*
- * MS-DOS port (c) 1990 by Thorsten Ohl <ohl@gnu.ai.mit.edu>
- *
- * To this port, the same copying conditions apply as to the
- * original release.
- *
- * IMPORTANT:
- * This file is not identical to the original GNU release!
- * You should have received this code as patch to the official
- * GNU release.
- *
- * MORE IMPORTANT:
- * This port comes with ABSOLUTELY NO WARRANTY.
- *
- * $Header: e:/gnu/make/RCS/load.c'v 3.58.0.1 90/07/17 00:59:28 tho Exp $
- */
-
- #include "make.h"
- #include "commands.h"
- #include "job.h"
-
- #ifdef UMAX
-
- #define LDAV_BASED
-
- /* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
- have a /dev/kmem. Information about the workings of the running kernel
- can be gathered with inq_stats system calls. */
- #include <stdio.h>
- #include <signal.h>
-
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/sysdefs.h>
- #include <sys/syscall.h>
-
- #ifdef UMAX_43
- #include <machine/cpu.h>
- #include <inq_stats/statistics.h>
- #include <inq_stats/sysstats.h>
- #include <inq_stats/cpustats.h>
- #include <inq_stats/procstats.h>
- #else /* Not UMAX_43. */
- #include <sys/statistics.h>
- #include <sys/sysstats.h>
- #include <sys/cpudefs.h>
- #include <sys/cpustats.h>
- #include <sys/procstats.h>
- #endif
-
- static double
- load_average ()
- {
- static unsigned int cpus = 0, samples;
- struct proc_summary proc_sum_data;
- struct stat_descr proc_info;
- double load;
- register unsigned int i, j;
-
- if (cpus == 0)
- {
- register unsigned int c, i;
- struct cpu_config conf;
- struct stat_descr desc;
-
- desc.sd_next = 0;
- desc.sd_subsys = SUBSYS_CPU;
- desc.sd_type = CPUTYPE_CONFIG;
- desc.sd_addr = (char *) &conf;
- desc.sd_size = sizeof conf;
-
- if (inq_stats (1, &desc))
- return 0.0;
-
- c = 0;
- for (i = 0; i < conf.config_maxclass; ++i)
- {
- struct class_stats stats;
- bzero ((char *) &stats, sizeof stats);
-
- desc.sd_type = CPUTYPE_CLASS;
- desc.sd_objid = i;
- desc.sd_addr = (char *) &stats;
- desc.sd_size = sizeof stats;
-
- if (inq_stats (1, &desc))
- return 0.0;
-
- c += stats.class_numcpus;
- }
- cpus = c;
- samples = cpus < 2 ? 3 : (2 * cpus / 3);
- }
-
- proc_info.sd_next = 0;
- proc_info.sd_subsys = SUBSYS_PROC;
- proc_info.sd_type = PROCTYPE_SUMMARY;
- proc_info.sd_addr = (char *) &proc_sum_data;
- proc_info.sd_size = sizeof (struct proc_summary);
- proc_info.sd_sizeused = 0;
-
- if (inq_stats (1, &proc_info) != 0)
- return 0.0;
-
- load = proc_sum_data.ps_nrunnable;
- j = 0;
- for (i = samples - 1; i > 0; --i)
- {
- load += proc_sum_data.ps_nrun[j];
- if (j++ == PS_NRUNSIZE)
- j = 0;
- }
-
- return (load / samples / cpus);
- }
-
- #else /* Not UMAX. */
-
- #ifndef NO_LDAV
-
- #define LDAV_BASED
-
- #ifndef KERNEL_FILE_NAME
- #define KERNEL_FILE_NAME "/vmunix"
- #endif
- #ifndef LDAV_SYMBOL
- #define LDAV_SYMBOL "_avenrun"
- #endif
- #ifndef LDAV_TYPE
- #define LDAV_TYPE long int
- #endif
- #ifndef LDAV_CVT
- #define LDAV_CVT ((double) load)
- #endif
-
- #ifndef MSDOS
- #include <nlist.h>
- #include <nlist.h>
- #ifdef NLIST_NAME_UNION
- #define nl_name n_un.n_name
- #else
- #define nl_name n_name
- #endif
- #endif /* not MSDOS */
-
- #ifdef USG
- #include <fcntl.h>
- #else
- #include <sys/file.h>
- #endif
-
- /* Return the current load average as a double. */
-
- static double
- load_average ()
- {
- extern int nlist ();
- LDAV_TYPE load;
- static int complained = 0;
- static int kmem = -1;
- static unsigned long int offset = 0;
-
- if (kmem < 0)
- {
- kmem = open ("/dev/kmem", O_RDONLY);
- if (kmem < 0)
- {
- if (!complained)
- perror_with_name ("open: ", "/dev/kmem");
- goto lose;
- }
- }
-
- if (offset == 0)
- {
- struct nlist nl[2];
-
- #ifdef NLIST_NAME_ARRAY
- strcpy (nl[0].nl_name, LDAV_SYMBOL);
- strcpy (nl[1].nl_name, "");
- #else /* Not NLIST_NAME_ARRAY. */
- nl[0].nl_name = LDAV_SYMBOL;
- nl[1].nl_name = 0;
- #endif /* NLIST_NAME_ARRAY. */
-
- if (nlist (KERNEL_FILE_NAME, nl) < 0 || nl[0].n_type == 0)
- {
- if (!complained)
- perror_with_name ("nlist: ", KERNEL_FILE_NAME);
- goto lose;
- }
- offset = nl[0].n_value;
- }
-
- if (lseek (kmem, offset, 0) == -1L)
- {
- if (!complained)
- perror_with_name ("lseek: ", "/dev/kmem");
- goto lose;
- }
- if (read (kmem, &load, sizeof load) < 0)
- {
- if (!complained)
- perror_with_name ("read: ", "/dev/kmem");
- goto lose;
- }
-
- if (complained)
- {
- error ("Load average limits will be enforced again.");
- complained = 0;
- }
- return LDAV_CVT;
-
- lose:;
- if (!complained)
- {
- error ("Load average limits will not be enforced.");
- complained = 1;
- }
- return 0.0;
- }
-
- #endif /* Not NO_LDAV. */
-
- #endif /* UMAX. */
-
-
- #ifdef LDAV_BASED
-
- extern unsigned int job_slots_used;
-
- extern int sleep ();
-
- /* Don't return until a job should be started. */
-
- void
- wait_to_start_job ()
- {
- register unsigned int loops = 0;
-
- if (max_load_average < 0.0)
- return;
-
- while (job_slots_used > 0)
- {
- double load = load_average ();
-
- if (load < max_load_average)
- return;
-
- ++loops;
- if (loops == 5 || load > max_load_average * 2)
- {
- /* If the load is still too high after five loops or it is very
- high, just wait for a child to die before checking again. */
- loops = 0;
- wait_for_children (1, 0);
- }
- else
- /* Don't check the load again immediately, because that will
- just worsen the load. Check it progressively more slowly. */
- sleep (loops);
- }
- }
-
- #else /* Not LDAV_BASED. */
-
- /* How else to do it? */
-
- void
- wait_to_start_job ()
- {
- return;
- }
- #endif /* LDAV_BASED. */
-