(root)/
glibc-2.38/
sysdeps/
htl/
pt-key-create.c
       1  /* pthread_key_create.  Hurd version.
       2     Copyright (C) 2002-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 <pthread.h>
      20  #include <stdlib.h>
      21  #include <assert.h>
      22  
      23  #include <pt-internal.h>
      24  #include <pthreadP.h>
      25  
      26  pthread_mutex_t __pthread_key_lock;
      27  pthread_once_t __pthread_key_once = PTHREAD_ONCE_INIT;
      28  
      29  void (**__pthread_key_destructors) (void *arg);
      30  int __pthread_key_size;
      31  int __pthread_key_count;
      32  int __pthread_key_invalid_count;
      33  
      34  int
      35  __pthread_key_create (pthread_key_t *key, void (*destructor) (void *))
      36  {
      37    /* Where to look for the next key slot.  */
      38    static int index;
      39  
      40    __pthread_key_lock_ready ();
      41  
      42    __pthread_mutex_lock (&__pthread_key_lock);
      43  
      44  do_search:
      45    /* Use the search hint and try to find a free slot.  */
      46    for (; index < __pthread_key_count
      47         && __pthread_key_destructors[index] != PTHREAD_KEY_INVALID; index++)
      48      ;
      49  
      50    /* See if we actually found a free element.  */
      51    if (index < __pthread_key_count)
      52      {
      53        assert (__pthread_key_destructors[index] == PTHREAD_KEY_INVALID);
      54        assert (__pthread_key_invalid_count > 0);
      55  
      56        __pthread_key_invalid_count--;
      57        __pthread_key_destructors[index] = destructor;
      58        *key = index++;
      59  
      60        __pthread_mutex_unlock (&__pthread_key_lock);
      61        return 0;
      62      }
      63  
      64    assert (index == __pthread_key_count);
      65  
      66    /* No space at the end.  */
      67    if (__pthread_key_size == __pthread_key_count)
      68      {
      69        /* See if it is worth looking for a free element.  */
      70        if (__pthread_key_invalid_count > 4
      71  	  && __pthread_key_invalid_count > __pthread_key_size / 8)
      72  	{
      73  	  index = 0;
      74  	  goto do_search;
      75  	}
      76  
      77  
      78        /* Resize the array.  */
      79        {
      80  	void *t;
      81  	int newsize;
      82  
      83  	if (__pthread_key_size == 0)
      84  	  newsize = 8;
      85  	else
      86  	  newsize = __pthread_key_size * 2;
      87  
      88  	t = realloc (__pthread_key_destructors,
      89  		     newsize * sizeof (*__pthread_key_destructors));
      90  	if (t == NULL)
      91  	  {
      92  	    __pthread_mutex_unlock (&__pthread_key_lock);
      93  	    return ENOMEM;
      94  	  }
      95  
      96  	__pthread_key_size = newsize;
      97  	__pthread_key_destructors = t;
      98        }
      99      }
     100  
     101    __pthread_key_destructors[index] = destructor;
     102    *key = index;
     103  
     104    index++;
     105    __pthread_key_count++;
     106  
     107    __pthread_mutex_unlock (&__pthread_key_lock);
     108    return 0;
     109  }
     110  weak_alias (__pthread_key_create, pthread_key_create)
     111  hidden_def (__pthread_key_create)