xref: /netbsd-src/external/gpl3/gcc.old/dist/libgomp/config/bsd/proc.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1*8feb0f0bSmrg /* Copyright (C) 2005-2020 Free Software Foundation, Inc.
236ac495dSmrg    Contributed by Richard Henderson <rth@redhat.com>.
336ac495dSmrg 
436ac495dSmrg    This file is part of the GNU Offloading and Multi Processing Library
536ac495dSmrg    (libgomp).
636ac495dSmrg 
736ac495dSmrg    Libgomp is free software; you can redistribute it and/or modify it
836ac495dSmrg    under the terms of the GNU General Public License as published by
936ac495dSmrg    the Free Software Foundation; either version 3, or (at your option)
1036ac495dSmrg    any later version.
1136ac495dSmrg 
1236ac495dSmrg    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
1336ac495dSmrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1436ac495dSmrg    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1536ac495dSmrg    more details.
1636ac495dSmrg 
1736ac495dSmrg    Under Section 7 of GPL version 3, you are granted additional
1836ac495dSmrg    permissions described in the GCC Runtime Library Exception, version
1936ac495dSmrg    3.1, as published by the Free Software Foundation.
2036ac495dSmrg 
2136ac495dSmrg    You should have received a copy of the GNU General Public License and
2236ac495dSmrg    a copy of the GCC Runtime Library Exception along with this program;
2336ac495dSmrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2436ac495dSmrg    <http://www.gnu.org/licenses/>.  */
2536ac495dSmrg 
2636ac495dSmrg /* This file contains system specific routines related to counting
2736ac495dSmrg    online processors and dynamic load balancing.  It is expected that
2836ac495dSmrg    a system may well want to write special versions of each of these.
2936ac495dSmrg 
3036ac495dSmrg    The following implementation uses a mix of POSIX and BSD routines.  */
3136ac495dSmrg 
3236ac495dSmrg #include "libgomp.h"
3336ac495dSmrg #include <unistd.h>
3436ac495dSmrg #include <stdlib.h>
3536ac495dSmrg #ifdef HAVE_GETLOADAVG
3636ac495dSmrg # ifdef HAVE_SYS_LOADAVG_H
3736ac495dSmrg #  include <sys/loadavg.h>
3836ac495dSmrg # endif
3936ac495dSmrg #endif
4036ac495dSmrg #ifdef HAVE_SYS_SYSCTL_H
4136ac495dSmrg # include <sys/sysctl.h>
4236ac495dSmrg #endif
4336ac495dSmrg 
4436ac495dSmrg static int
get_num_procs(void)4536ac495dSmrg get_num_procs (void)
4636ac495dSmrg {
4736ac495dSmrg #ifdef _SC_NPROCESSORS_ONLN
4836ac495dSmrg   return sysconf (_SC_NPROCESSORS_ONLN);
4936ac495dSmrg #elif defined HW_NCPU
5036ac495dSmrg   int ncpus = 1;
5136ac495dSmrg   size_t len = sizeof(ncpus);
5236ac495dSmrg   sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
5336ac495dSmrg   return ncpus;
5436ac495dSmrg #else
5536ac495dSmrg   return 0;
5636ac495dSmrg #endif
5736ac495dSmrg }
5836ac495dSmrg 
5936ac495dSmrg /* At startup, determine the default number of threads.  It would seem
6036ac495dSmrg    this should be related to the number of cpus online.  */
6136ac495dSmrg 
6236ac495dSmrg void
gomp_init_num_threads(void)6336ac495dSmrg gomp_init_num_threads (void)
6436ac495dSmrg {
6536ac495dSmrg   int ncpus = get_num_procs ();
6636ac495dSmrg 
6736ac495dSmrg   if (ncpus > 0)
6836ac495dSmrg     gomp_global_icv.nthreads_var = ncpus;
6936ac495dSmrg }
7036ac495dSmrg 
7136ac495dSmrg /* When OMP_DYNAMIC is set, at thread launch determine the number of
7236ac495dSmrg    threads we should spawn for this team.  */
7336ac495dSmrg /* ??? I have no idea what best practice for this is.  Surely some
7436ac495dSmrg    function of the number of processors that are *still* online and
7536ac495dSmrg    the load average.  Here I use the number of processors online
7636ac495dSmrg    minus the 15 minute load average.  */
7736ac495dSmrg 
7836ac495dSmrg unsigned
gomp_dynamic_max_threads(void)7936ac495dSmrg gomp_dynamic_max_threads (void)
8036ac495dSmrg {
8136ac495dSmrg   unsigned n_onln, loadavg;
8236ac495dSmrg   unsigned nthreads_var = gomp_icv (false)->nthreads_var;
8336ac495dSmrg 
8436ac495dSmrg   n_onln = get_num_procs ();
8536ac495dSmrg   if (!n_onln || n_onln > nthreads_var)
8636ac495dSmrg     n_onln = nthreads_var;
8736ac495dSmrg 
8836ac495dSmrg   loadavg = 0;
8936ac495dSmrg #ifdef HAVE_GETLOADAVG
9036ac495dSmrg   {
9136ac495dSmrg     double dloadavg[3];
9236ac495dSmrg     if (getloadavg (dloadavg, 3) == 3)
9336ac495dSmrg       {
9436ac495dSmrg 	/* Add 0.1 to get a kind of biased rounding.  */
9536ac495dSmrg 	loadavg = dloadavg[2] + 0.1;
9636ac495dSmrg       }
9736ac495dSmrg   }
9836ac495dSmrg #endif
9936ac495dSmrg 
10036ac495dSmrg   if (loadavg >= n_onln)
10136ac495dSmrg     return 1;
10236ac495dSmrg   else
10336ac495dSmrg     return n_onln - loadavg;
10436ac495dSmrg }
10536ac495dSmrg 
10636ac495dSmrg int
omp_get_num_procs(void)10736ac495dSmrg omp_get_num_procs (void)
10836ac495dSmrg {
10936ac495dSmrg   int ncpus = get_num_procs ();
11036ac495dSmrg   if (ncpus <= 0)
11136ac495dSmrg     ncpus = gomp_icv (false)->nthreads_var;
11236ac495dSmrg   return ncpus;
11336ac495dSmrg }
11436ac495dSmrg 
11536ac495dSmrg ialias (omp_get_num_procs)
116