(root)/
glibc-2.38/
nptl/
sem_init.c
       1  /* Copyright (C) 2002-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <semaphore.h>
      20  #include <shlib-compat.h>
      21  #include "semaphoreP.h"
      22  #include <kernel-features.h>
      23  #include <futex-internal.h>
      24  
      25  
      26  int
      27  __new_sem_init (sem_t *sem, int pshared, unsigned int value)
      28  {
      29    ASSERT_PTHREAD_INTERNAL_SIZE (sem_t, struct new_sem);
      30  
      31    /* Parameter sanity check.  */
      32    if (__glibc_unlikely (value > SEM_VALUE_MAX))
      33      {
      34        __set_errno (EINVAL);
      35        return -1;
      36      }
      37    pshared = pshared != 0 ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE;
      38    int err = futex_supports_pshared (pshared);
      39    if (err != 0)
      40      {
      41        __set_errno (err);
      42        return -1;
      43      }
      44  
      45    /* Map to the internal type.  */
      46    struct new_sem *isem = (struct new_sem *) sem;
      47  
      48    /* Use the values the caller provided.  */
      49  #if __HAVE_64B_ATOMICS
      50    isem->data = value;
      51  #else
      52    isem->value = value << SEM_VALUE_SHIFT;
      53    /* pad is used as a mutex on pre-v9 sparc and ignored otherwise.  */
      54    isem->pad = 0;
      55    isem->nwaiters = 0;
      56  #endif
      57  
      58    isem->private = (pshared == PTHREAD_PROCESS_PRIVATE
      59  		   ? FUTEX_PRIVATE : FUTEX_SHARED);
      60  
      61    return 0;
      62  }
      63  versioned_symbol (libc, __new_sem_init, sem_init, GLIBC_2_34);
      64  
      65  #if OTHER_SHLIB_COMPAT(libpthread, GLIBC_2_1, GLIBC_2_34)
      66  compat_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1);
      67  #endif
      68  
      69  #if OTHER_SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
      70  int
      71  attribute_compat_text_section
      72  __old_sem_init (sem_t *sem, int pshared, unsigned int value)
      73  {
      74    ASSERT_PTHREAD_INTERNAL_SIZE (sem_t, struct new_sem);
      75  
      76    /* Parameter sanity check.  */
      77    if (__glibc_unlikely (value > SEM_VALUE_MAX))
      78      {
      79        __set_errno (EINVAL);
      80        return -1;
      81      }
      82  
      83    /* Map to the internal type.  */
      84    struct old_sem *isem = (struct old_sem *) sem;
      85  
      86    /* Use the value the user provided.  */
      87    isem->value = value;
      88  
      89    /* We cannot store the PSHARED attribute.  So we always use the
      90       operations needed for shared semaphores.  */
      91  
      92    return 0;
      93  }
      94  compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0);
      95  #endif