(root)/
glibc-2.38/
nptl/
pthread_key_create.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 "pthreadP.h"
      20  #include <atomic.h>
      21  #include <shlib-compat.h>
      22  
      23  int
      24  ___pthread_key_create (pthread_key_t *key, void (*destr) (void *))
      25  {
      26    /* Find a slot in __pthread_keys which is unused.  */
      27    for (size_t cnt = 0; cnt < PTHREAD_KEYS_MAX; ++cnt)
      28      {
      29        uintptr_t seq = __pthread_keys[cnt].seq;
      30  
      31        if (KEY_UNUSED (seq) && KEY_USABLE (seq)
      32  	  /* We found an unused slot.  Try to allocate it.  */
      33  	  && ! atomic_compare_and_exchange_bool_acq (&__pthread_keys[cnt].seq,
      34  						     seq + 1, seq))
      35  	{
      36  	  /* Remember the destructor.  */
      37  	  __pthread_keys[cnt].destr = destr;
      38  
      39  	  /* Return the key to the caller.  */
      40  	  *key = cnt;
      41  
      42  	  /* The call succeeded.  */
      43  	  return 0;
      44  	}
      45      }
      46  
      47    return EAGAIN;
      48  }
      49  versioned_symbol (libc, ___pthread_key_create, __pthread_key_create,
      50  		  GLIBC_2_34);
      51  libc_hidden_ver (___pthread_key_create, __pthread_key_create)
      52  
      53  versioned_symbol (libc, ___pthread_key_create, pthread_key_create,
      54  		  GLIBC_2_34);
      55  #if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34)
      56  compat_symbol (libpthread, ___pthread_key_create, __pthread_key_create,
      57  	       GLIBC_2_0);
      58  compat_symbol (libpthread, ___pthread_key_create, pthread_key_create,
      59  	       GLIBC_2_0);
      60  #endif