| 1 | /* Set the default attributes to be used by pthread_create in the process. | 
| 2 |    Copyright (C) 2013-2023 Free Software Foundation, Inc. | 
| 3 |    This file is part of the GNU C Library. | 
| 4 |  | 
| 5 |    The GNU C Library is free software; you can redistribute it and/or | 
| 6 |    modify it under the terms of the GNU Lesser General Public | 
| 7 |    License as published by the Free Software Foundation; either | 
| 8 |    version 2.1 of the License, or (at your option) any later version. | 
| 9 |  | 
| 10 |    The GNU C Library is distributed in the hope that it will be useful, | 
| 11 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| 12 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
| 13 |    Lesser General Public License for more details. | 
| 14 |  | 
| 15 |    You should have received a copy of the GNU Lesser General Public | 
| 16 |    License along with the GNU C Library; if not, see | 
| 17 |    <https://www.gnu.org/licenses/>.  */ | 
| 18 |  | 
| 19 | #include <errno.h> | 
| 20 | #include <stdlib.h> | 
| 21 | #include <pthreadP.h> | 
| 22 | #include <string.h> | 
| 23 | #include <shlib-compat.h> | 
| 24 |  | 
| 25 | int | 
| 26 | __pthread_setattr_default_np (const pthread_attr_t *in) | 
| 27 | { | 
| 28 |   const struct pthread_attr *real_in; | 
| 29 |   int ret; | 
| 30 |  | 
| 31 |   real_in = (struct pthread_attr *) in; | 
| 32 |  | 
| 33 |   /* Catch invalid values.  */ | 
| 34 |   int policy = real_in->schedpolicy; | 
| 35 |   ret = check_sched_policy_attr (policy); | 
| 36 |   if (ret) | 
| 37 |     return ret; | 
| 38 |  | 
| 39 |   const struct sched_param *param = &real_in->schedparam; | 
| 40 |   if (param->sched_priority > 0) | 
| 41 |     { | 
| 42 |       ret = check_sched_priority_attr (param->sched_priority, policy); | 
| 43 |       if (ret) | 
| 44 | 	return ret; | 
| 45 |     } | 
| 46 |  | 
| 47 |   /* stacksize == 0 is fine.  It means that we don't change the current | 
| 48 |      value.  */ | 
| 49 |   if (real_in->stacksize != 0) | 
| 50 |     { | 
| 51 |       ret = check_stacksize_attr (real_in->stacksize); | 
| 52 |       if (ret) | 
| 53 | 	return ret; | 
| 54 |     } | 
| 55 |  | 
| 56 |   /* Having a default stack address is wrong.  */ | 
| 57 |   if (real_in->flags & ATTR_FLAG_STACKADDR) | 
| 58 |     return EINVAL; | 
| 59 |  | 
| 60 |   union pthread_attr_transparent temp; | 
| 61 |   ret = __pthread_attr_copy (&temp.external, in); | 
| 62 |   if (ret != 0) | 
| 63 |     return ret; | 
| 64 |  | 
| 65 |   /* Now take the lock because we start accessing | 
| 66 |      __default_pthread_attr.  */ | 
| 67 |   lll_lock (__default_pthread_attr_lock, LLL_PRIVATE); | 
| 68 |  | 
| 69 |   /* Preserve the previous stack size (see above).  */ | 
| 70 |   if (temp.internal.stacksize == 0) | 
| 71 |     temp.internal.stacksize = __default_pthread_attr.internal.stacksize; | 
| 72 |  | 
| 73 |   /* Destroy the old attribute structure because it will be | 
| 74 |      overwritten.  */ | 
| 75 |   __pthread_attr_destroy (&__default_pthread_attr.external); | 
| 76 |  | 
| 77 |   /* __default_pthread_attr takes ownership, so do not free | 
| 78 |      attrs.internal after this point.  */ | 
| 79 |   __default_pthread_attr = temp; | 
| 80 |  | 
| 81 |   lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE); | 
| 82 |   return ret; | 
| 83 | } | 
| 84 | versioned_symbol (libc, __pthread_setattr_default_np, | 
| 85 | 		  pthread_setattr_default_np, GLIBC_2_34); | 
| 86 | #if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_18, GLIBC_2_34) | 
| 87 | compat_symbol (libc, __pthread_setattr_default_np, | 
| 88 | 	       pthread_setattr_default_np, GLIBC_2_18); | 
| 89 | #endif | 
| 90 |  | 
| 91 | /* This is placed in the same file as pthread_setattr_default_np | 
| 92 |    because only this function can trigger allocation of attribute | 
| 93 |    data.  This way, the function is automatically defined for all the | 
| 94 |    cases when it is needed in static builds.  */ | 
| 95 | void | 
| 96 | __default_pthread_attr_freeres (void) | 
| 97 | { | 
| 98 |   __pthread_attr_destroy (&__default_pthread_attr.external); | 
| 99 | } | 
| 100 |  |