123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /* Copyright (C) 2015-2022 Free Software Foundation, Inc.
- Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
- This file is part of the GNU Offloading and Multi Processing Library
- (libgomp).
- Libgomp 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 3, or (at your option)
- any later version.
- Libgomp 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.
- Under Section 7 of GPL version 3, you are granted additional
- permissions described in the GCC Runtime Library Exception, version
- 3.1, as published by the Free Software Foundation.
- You should have received a copy of the GNU General Public License and
- a copy of the GCC Runtime Library Exception along with this program;
- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- <http://www.gnu.org/licenses/>. */
- /* This file contains RTEMS specific routines related to counting
- online processors and dynamic load balancing. */
- #include "libgomp.h"
- #include "pool.h"
- #include <errno.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- struct gomp_thread_pool_reservoir **gomp_thread_pool_reservoirs;
- __thread struct gomp_tls_rtems_data gomp_tls_rtems_data;
- static void
- allocate_thread_pool_reservoirs (void)
- {
- struct gomp_thread_pool_reservoir **reservoirs;
- size_t size = _Sched_Count () * sizeof (*reservoirs);
- reservoirs = gomp_malloc (size);
- gomp_thread_pool_reservoirs = reservoirs;
- memset (reservoirs, 0, size);
- }
- static void
- allocate_thread_pool_reservoir (unsigned long count, unsigned long priority,
- unsigned long scheduler)
- {
- struct gomp_thread_pool_reservoir *res;
- struct gomp_thread_pool *pools;
- unsigned long i;
- size_t size;
- res = gomp_thread_pool_reservoirs[scheduler];
- if (res != NULL)
- gomp_fatal ("Multiple thread pool reservoir initialization");
- size = sizeof (*res) + count * (sizeof(pools) + sizeof(*pools));
- pools = gomp_malloc (size);
- memset (pools, 0, size);
- res = (struct gomp_thread_pool_reservoir *) (pools + count);
- res->index = count;
- res->priority = priority;
- gomp_sem_init (&res->available, count);
- pthread_spin_init (&res->lock, PTHREAD_PROCESS_PRIVATE);
- for (i = 0; i < count; ++i)
- res->pools[i] = &pools[i];
- gomp_thread_pool_reservoirs[scheduler] = res;
- }
- static char *
- parse_thread_pools (char *env, unsigned long *count, unsigned long *priority,
- unsigned long *scheduler)
- {
- size_t len;
- int i;
- char *end;
- if (*env == ':')
- ++env;
- errno = 0;
- *count = strtoul (env, &end, 10);
- if (errno != 0 || end == env)
- gomp_fatal ("Invalid thread pool count");
- env = end;
- if (*env == '$')
- {
- ++env;
- errno = 0;
- *priority = strtoul (env, &end, 10);
- if (errno != 0 || end == env)
- gomp_fatal ("Invalid thread pool priority");
- env = end;
- }
- else
- *priority = -1;
- if (*env != '@')
- gomp_fatal ("Invalid thread pool scheduler prefix");
- ++env;
- len = 0;
- while (env[len] != '\0' && env[len] != ':')
- ++len;
- i = _Sched_Name_to_index (env, len);
- if (i < 0)
- gomp_fatal ("Invalid thread pool scheduler");
- *scheduler = i;
- env += len;
- return env;
- }
- static void
- init_thread_pool_reservoirs (void)
- {
- char *env = getenv ("GOMP_RTEMS_THREAD_POOLS");
- if (env != NULL)
- {
- allocate_thread_pool_reservoirs ();
- while (*env != '\0')
- {
- unsigned long count;
- unsigned long priority;
- unsigned long scheduler;
- env = parse_thread_pools (env, &count, &priority, &scheduler);
- allocate_thread_pool_reservoir (count, priority, scheduler);
- }
- }
- }
- void
- gomp_init_num_threads (void)
- {
- gomp_global_icv.nthreads_var = omp_get_num_procs();
- init_thread_pool_reservoirs ();
- }
- unsigned
- gomp_dynamic_max_threads (void)
- {
- unsigned n_onln = (unsigned) omp_get_num_procs();
- unsigned nthreads_var = gomp_icv (false)->nthreads_var;
- if (n_onln > nthreads_var)
- return nthreads_var;
- else
- return n_onln;
- }
- int
- omp_get_num_procs (void)
- {
- return sysconf (_SC_NPROCESSORS_ONLN);
- }
- ialias (omp_get_num_procs)
|