pool.h revision 1.1.1.9 1 1.1.1.9 mrg /* Copyright (C) 2015-2024 Free Software Foundation, Inc.
2 1.1 mrg Contributed by Sebastian Huber <sebastian.huber (at) embedded-brains.de>.
3 1.1 mrg
4 1.1 mrg This file is part of the GNU Offloading and Multi Processing Library
5 1.1 mrg (libgomp).
6 1.1 mrg
7 1.1 mrg Libgomp is free software; you can redistribute it and/or modify it
8 1.1 mrg under the terms of the GNU General Public License as published by
9 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
10 1.1 mrg any later version.
11 1.1 mrg
12 1.1 mrg Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 1.1 mrg FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 1.1 mrg more details.
16 1.1 mrg
17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
18 1.1 mrg permissions described in the GCC Runtime Library Exception, version
19 1.1 mrg 3.1, as published by the Free Software Foundation.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU General Public License and
22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1 mrg <http://www.gnu.org/licenses/>. */
25 1.1 mrg
26 1.1 mrg /* This is the RTEMS implementation of the thread pool management
27 1.1 mrg for libgomp. This type is private to the library. */
28 1.1 mrg
29 1.1 mrg #ifndef GOMP_POOL_H
30 1.1 mrg #define GOMP_POOL_H 1
31 1.1 mrg
32 1.1 mrg #include "libgomp.h"
33 1.1 mrg #include <sys/lock.h>
34 1.1 mrg #include <string.h>
35 1.1 mrg
36 1.1 mrg /* For each scheduler instance there may be a thread pool reservoir
37 1.1 mrg to limit the number of thread pools used by the OpenMP master threads of this
38 1.1 mrg scheduler instance. The reservoirs are configured via the
39 1.1 mrg GOMP_RTEMS_THREAD_POOLS environment variable. */
40 1.1 mrg struct gomp_thread_pool_reservoir {
41 1.1 mrg gomp_sem_t available;
42 1.1 mrg pthread_spinlock_t lock;
43 1.1 mrg size_t index;
44 1.1 mrg int priority;
45 1.1 mrg struct gomp_thread_pool *pools[];
46 1.1 mrg };
47 1.1 mrg
48 1.1 mrg struct gomp_tls_rtems_data {
49 1.1 mrg struct gomp_thread_pool_reservoir *thread_pool_reservoir;
50 1.1 mrg };
51 1.1 mrg
52 1.1 mrg extern struct gomp_thread_pool_reservoir **gomp_thread_pool_reservoirs;
53 1.1 mrg
54 1.1 mrg extern __thread struct gomp_tls_rtems_data gomp_tls_rtems_data;
55 1.1 mrg
56 1.1 mrg static inline struct gomp_thread_pool_reservoir *
57 1.1 mrg gomp_get_thread_pool_reservoir (void)
58 1.1 mrg {
59 1.1 mrg struct gomp_thread_pool_reservoir *res =
60 1.1 mrg gomp_tls_rtems_data.thread_pool_reservoir;
61 1.1 mrg
62 1.1 mrg if (res == NULL && gomp_thread_pool_reservoirs != NULL)
63 1.1 mrg {
64 1.1 mrg struct gomp_thread *thr = gomp_thread ();
65 1.1 mrg thr->thread_pool = gomp_malloc_cleared (sizeof (*thr->thread_pool));
66 1.1 mrg res = gomp_thread_pool_reservoirs[_Sched_Index ()];
67 1.1 mrg gomp_tls_rtems_data.thread_pool_reservoir = res;
68 1.1 mrg }
69 1.1 mrg
70 1.1 mrg return res;
71 1.1 mrg }
72 1.1 mrg
73 1.1 mrg static inline struct gomp_thread_pool *
74 1.1 mrg gomp_get_own_thread_pool (struct gomp_thread *thr, unsigned nthreads)
75 1.1 mrg {
76 1.1 mrg struct gomp_thread_pool *pool = thr->thread_pool;
77 1.1 mrg if (__builtin_expect (pool == NULL, 0))
78 1.1 mrg {
79 1.1 mrg pool = gomp_malloc_cleared (sizeof (*pool));
80 1.1 mrg pool->threads_busy = nthreads;
81 1.1 mrg thr->thread_pool = pool;
82 1.1 mrg }
83 1.1 mrg return pool;
84 1.1 mrg }
85 1.1 mrg
86 1.1 mrg static inline struct gomp_thread_pool *
87 1.1 mrg gomp_get_thread_pool (struct gomp_thread *thr, unsigned nthreads)
88 1.1 mrg {
89 1.1 mrg struct gomp_thread_pool *pool;
90 1.1 mrg struct gomp_thread_pool_reservoir *res;
91 1.1 mrg
92 1.1 mrg if (__builtin_expect (thr->thread_pool == NULL, 0))
93 1.1 mrg pthread_setspecific (gomp_thread_destructor, thr);
94 1.1 mrg
95 1.1 mrg res = gomp_get_thread_pool_reservoir ();
96 1.1 mrg if (res != NULL)
97 1.1 mrg {
98 1.1 mrg gomp_sem_wait (&res->available);
99 1.1 mrg pthread_spin_lock (&res->lock);
100 1.1 mrg pool = res->pools[--res->index];
101 1.1 mrg pthread_spin_unlock (&res->lock);
102 1.1 mrg pool->threads_busy = nthreads;
103 1.1 mrg thr->thread_pool = pool;
104 1.1 mrg }
105 1.1 mrg else
106 1.1 mrg pool = gomp_get_own_thread_pool (thr, nthreads);
107 1.1 mrg
108 1.1 mrg return pool;
109 1.1 mrg }
110 1.1 mrg
111 1.1 mrg static inline void
112 1.1 mrg gomp_release_thread_pool (struct gomp_thread_pool *pool)
113 1.1 mrg {
114 1.1 mrg struct gomp_thread_pool_reservoir *res =
115 1.1 mrg gomp_tls_rtems_data.thread_pool_reservoir;
116 1.1 mrg if (res != NULL)
117 1.1 mrg {
118 1.1 mrg pthread_spin_lock (&res->lock);
119 1.1 mrg res->pools[res->index++] = pool;
120 1.1 mrg pthread_spin_unlock (&res->lock);
121 1.1 mrg gomp_sem_post (&res->available);
122 1.1 mrg }
123 1.1 mrg }
124 1.1 mrg
125 1.1 mrg static inline pthread_attr_t *
126 1.1 mrg gomp_adjust_thread_attr (pthread_attr_t *attr, pthread_attr_t *mutable_attr)
127 1.1 mrg {
128 1.1 mrg struct gomp_thread_pool_reservoir *res = gomp_get_thread_pool_reservoir ();
129 1.1 mrg if (res != NULL && res->priority > 0)
130 1.1 mrg {
131 1.1 mrg struct sched_param param;
132 1.1 mrg int err;
133 1.1 mrg if (attr != mutable_attr)
134 1.1 mrg {
135 1.1 mrg attr = mutable_attr;
136 1.1 mrg pthread_attr_init (attr);
137 1.1 mrg }
138 1.1 mrg memset (¶m, 0, sizeof (param));
139 1.1 mrg param.sched_priority = res->priority;
140 1.1 mrg err = pthread_attr_setschedparam (attr, ¶m);
141 1.1 mrg if (err != 0)
142 1.1 mrg gomp_fatal ("Thread attribute set scheduler parameters failed: %s", strerror (err));
143 1.1 mrg err = pthread_attr_setschedpolicy (attr, SCHED_FIFO);
144 1.1 mrg if (err != 0)
145 1.1 mrg gomp_fatal ("Thread attribute set scheduler policy failed: %s", strerror (err));
146 1.1 mrg err = pthread_attr_setinheritsched (attr, PTHREAD_EXPLICIT_SCHED);
147 1.1 mrg if (err != 0)
148 1.1 mrg gomp_fatal ("Thread attribute set explicit scheduler failed: %s", strerror (err));
149 1.1 mrg }
150 1.1 mrg return attr;
151 1.1 mrg }
152 1.1 mrg
153 1.1 mrg #endif /* GOMP_POOL_H */
154