1 #include "pthread_impl.h"
3 volatile size_t __pthread_tsd_size
= sizeof(void *) * PTHREAD_KEYS_MAX
;
4 void *__pthread_tsd_main
[PTHREAD_KEYS_MAX
] = { 0 };
6 static void (*keys
[PTHREAD_KEYS_MAX
])(void *);
8 static pthread_rwlock_t key_lock
= PTHREAD_RWLOCK_INITIALIZER
;
10 static pthread_key_t next_key
;
12 static void nodtor(void *dummy
)
16 static void dummy_0(void)
20 weak_alias(dummy_0
, __tl_lock
);
21 weak_alias(dummy_0
, __tl_unlock
);
23 int __pthread_key_create(pthread_key_t
*k
, void (*dtor
)(void *))
25 pthread_t self
= __pthread_self();
27 /* This can only happen in the main thread before
28 * pthread_create has been called. */
29 if (!self
->tsd
) self
->tsd
= __pthread_tsd_main
;
31 /* Purely a sentinel value since null means slot is free. */
32 if (!dtor
) dtor
= nodtor
;
34 __pthread_rwlock_wrlock(&key_lock
);
35 pthread_key_t j
= next_key
;
38 keys
[next_key
= *k
= j
] = dtor
;
39 __pthread_rwlock_unlock(&key_lock
);
42 } while ((j
=(j
+1)%PTHREAD_KEYS_MAX
) != next_key
);
44 __pthread_rwlock_unlock(&key_lock
);
48 int __pthread_key_delete(pthread_key_t k
)
51 pthread_t self
= __pthread_self(), td
=self
;
53 #ifdef __wasilibc_unmodified_upstream
54 __block_app_sigs(&set
);
56 __pthread_rwlock_wrlock(&key_lock
);
60 while ((td
=td
->next
)!=self
);
65 __pthread_rwlock_unlock(&key_lock
);
66 #ifdef __wasilibc_unmodified_upstream
73 void __pthread_tsd_run_dtors()
75 pthread_t self
= __pthread_self();
77 for (j
=0; self
->tsd_used
&& j
<PTHREAD_DESTRUCTOR_ITERATIONS
; j
++) {
78 __pthread_rwlock_rdlock(&key_lock
);
80 for (i
=0; i
<PTHREAD_KEYS_MAX
; i
++) {
81 void *val
= self
->tsd
[i
];
82 void (*dtor
)(void *) = keys
[i
];
84 if (val
&& dtor
&& dtor
!= nodtor
) {
85 __pthread_rwlock_unlock(&key_lock
);
87 __pthread_rwlock_rdlock(&key_lock
);
90 __pthread_rwlock_unlock(&key_lock
);
94 weak_alias(__pthread_key_create
, pthread_key_create
);
95 weak_alias(__pthread_key_delete
, pthread_key_delete
);