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