]>
Commit | Line | Data |
---|---|---|
66c59f92 SH |
1 | /* Copyright (C) 2015 Free Software Foundation, Inc. |
2 | Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>. | |
3 | ||
4 | This file is part of the GNU Offloading and Multi Processing Library | |
5 | (libgomp). | |
6 | ||
7 | Libgomp is free software; you can redistribute it and/or modify it | |
8 | under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3, or (at your option) | |
10 | any later version. | |
11 | ||
12 | Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
14 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 | more details. | |
16 | ||
17 | Under Section 7 of GPL version 3, you are granted additional | |
18 | permissions described in the GCC Runtime Library Exception, version | |
19 | 3.1, as published by the Free Software Foundation. | |
20 | ||
21 | You should have received a copy of the GNU General Public License and | |
22 | a copy of the GCC Runtime Library Exception along with this program; | |
23 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
24 | <http://www.gnu.org/licenses/>. */ | |
25 | ||
26 | /* This file contains RTEMS specific routines related to counting | |
27 | online processors and dynamic load balancing. */ | |
28 | ||
29 | #include "libgomp.h" | |
30 | #include "pool.h" | |
31 | #include <errno.h> | |
32 | #include <stdlib.h> | |
33 | #include <string.h> | |
34 | #include <unistd.h> | |
35 | ||
36 | struct gomp_thread_pool_reservoir **gomp_thread_pool_reservoirs; | |
37 | ||
38 | __thread struct gomp_tls_rtems_data gomp_tls_rtems_data; | |
39 | ||
40 | static void | |
41 | allocate_thread_pool_reservoirs (void) | |
42 | { | |
43 | struct gomp_thread_pool_reservoir **reservoirs; | |
44 | size_t size = _Sched_Count () * sizeof (*reservoirs); | |
45 | reservoirs = gomp_malloc (size); | |
46 | gomp_thread_pool_reservoirs = reservoirs; | |
47 | memset (reservoirs, 0, size); | |
48 | } | |
49 | ||
50 | static void | |
06441dd5 SH |
51 | allocate_thread_pool_reservoir (unsigned long count, unsigned long priority, |
52 | unsigned long scheduler) | |
66c59f92 SH |
53 | { |
54 | struct gomp_thread_pool_reservoir *res; | |
55 | struct gomp_thread_pool *pools; | |
56 | unsigned long i; | |
57 | size_t size; | |
58 | ||
59 | res = gomp_thread_pool_reservoirs[scheduler]; | |
60 | if (res != NULL) | |
61 | gomp_fatal ("Multiple thread pool reservoir initialization"); | |
62 | size = sizeof (*res) + count * (sizeof(pools) + sizeof(*pools)); | |
63 | pools = gomp_malloc (size); | |
64 | memset (pools, 0, size); | |
65 | res = (struct gomp_thread_pool_reservoir *) (pools + count); | |
66 | res->index = count; | |
06441dd5 | 67 | res->priority = priority; |
66c59f92 SH |
68 | gomp_sem_init (&res->available, count); |
69 | gomp_mutex_init (&res->lock); | |
70 | for (i = 0; i < count; ++i) | |
71 | res->pools[i] = &pools[i]; | |
72 | gomp_thread_pool_reservoirs[scheduler] = res; | |
73 | } | |
74 | ||
75 | static char * | |
06441dd5 SH |
76 | parse_thread_pools (char *env, unsigned long *count, unsigned long *priority, |
77 | unsigned long *scheduler) | |
66c59f92 SH |
78 | { |
79 | size_t len; | |
80 | int i; | |
81 | ||
82 | if (*env == ':') | |
83 | ++env; | |
84 | ||
85 | errno = 0; | |
86 | *count = strtoul (env, &env, 10); | |
87 | if (errno != 0) | |
88 | gomp_fatal ("Invalid thread pool count"); | |
89 | ||
06441dd5 SH |
90 | if (*env == '$') |
91 | { | |
92 | ++env; | |
93 | errno = 0; | |
94 | *priority = strtoul (env, &env, 10); | |
95 | if (errno != 0) | |
96 | gomp_fatal ("Invalid thread pool priority"); | |
97 | } | |
98 | else | |
99 | *priority = -1; | |
100 | ||
66c59f92 SH |
101 | if (*env != '@') |
102 | gomp_fatal ("Invalid thread pool scheduler prefix"); | |
103 | ++env; | |
104 | ||
105 | len = 0; | |
106 | while (env[len] != '\0' && env[len] != ':') | |
107 | ++len; | |
108 | i = _Sched_Name_to_index (env, len); | |
109 | if (i < 0) | |
110 | gomp_fatal ("Invalid thread pool scheduler"); | |
111 | *scheduler = i; | |
112 | env += len; | |
113 | ||
114 | return env; | |
115 | } | |
116 | ||
117 | static void | |
118 | init_thread_pool_reservoirs (void) | |
119 | { | |
120 | char *env = getenv ("GOMP_RTEMS_THREAD_POOLS"); | |
121 | if (env != NULL) | |
122 | { | |
123 | allocate_thread_pool_reservoirs (); | |
124 | while (*env != '\0') | |
125 | { | |
126 | unsigned long count; | |
06441dd5 | 127 | unsigned long priority; |
66c59f92 | 128 | unsigned long scheduler; |
06441dd5 SH |
129 | env = parse_thread_pools (env, &count, &priority, &scheduler); |
130 | allocate_thread_pool_reservoir (count, priority, scheduler); | |
66c59f92 SH |
131 | } |
132 | } | |
133 | } | |
134 | ||
135 | void | |
136 | gomp_init_num_threads (void) | |
137 | { | |
138 | gomp_global_icv.nthreads_var = omp_get_num_procs(); | |
139 | init_thread_pool_reservoirs (); | |
140 | } | |
141 | ||
142 | unsigned | |
143 | gomp_dynamic_max_threads (void) | |
144 | { | |
145 | unsigned n_onln = (unsigned) omp_get_num_procs(); | |
146 | unsigned nthreads_var = gomp_icv (false)->nthreads_var; | |
147 | ||
148 | if (n_onln > nthreads_var) | |
149 | return nthreads_var; | |
150 | else | |
151 | return n_onln; | |
152 | } | |
153 | ||
154 | int | |
155 | omp_get_num_procs (void) | |
156 | { | |
157 | return sysconf (_SC_NPROCESSORS_ONLN); | |
158 | } | |
159 | ||
160 | ialias (omp_get_num_procs) |