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