X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=libc-top-half%2Fmusl%2Fsrc%2Fthread%2Fpthread_key_create.c;h=d112094122b316d161a6fd17f1c08d12d0b58e05;hb=f41256b60274f4db25da179c05e4ce844c4cfee2;hp=0903d48f3f5c36cdf3f10cdc25593703195390e9;hpb=65107e782f135ebbc651c01d6676462ab27c43b8;p=wasi-libc.git diff --git a/libc-top-half/musl/src/thread/pthread_key_create.c b/libc-top-half/musl/src/thread/pthread_key_create.c index 0903d48..d112094 100644 --- a/libc-top-half/musl/src/thread/pthread_key_create.c +++ b/libc-top-half/musl/src/thread/pthread_key_create.c @@ -13,49 +13,16 @@ static void nodtor(void *dummy) { } -static void dirty(void *dummy) +static void dummy_0(void) { } -struct cleanup_args { - pthread_t caller; - int ret; -}; - -static void clean_dirty_tsd_callback(void *p) -{ - struct cleanup_args *args = p; - pthread_t self = __pthread_self(); - pthread_key_t i; - for (i=0; itsd[i]) - self->tsd[i] = 0; - } - /* Arbitrary choice to avoid data race. */ - if (args->caller == self) args->ret = 0; -} - -static void dummy2(void (*f)(void *), void *p) -{ -} - -weak_alias(dummy2, __pthread_key_delete_synccall); - -static int clean_dirty_tsd(void) -{ - struct cleanup_args args = { - .caller = __pthread_self(), - .ret = EAGAIN - }; - __pthread_key_delete_synccall(clean_dirty_tsd_callback, &args); - return args.ret; -} +weak_alias(dummy_0, __tl_lock); +weak_alias(dummy_0, __tl_unlock); int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *)) { - pthread_key_t j = next_key; pthread_t self = __pthread_self(); - int found_dirty = 0; /* This can only happen in the main thread before * pthread_create has been called. */ @@ -64,46 +31,38 @@ int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *)) /* Purely a sentinel value since null means slot is free. */ if (!dtor) dtor = nodtor; - pthread_rwlock_wrlock(&key_lock); + __pthread_rwlock_wrlock(&key_lock); + pthread_key_t j = next_key; do { if (!keys[j]) { keys[next_key = *k = j] = dtor; - pthread_rwlock_unlock(&key_lock); + __pthread_rwlock_unlock(&key_lock); return 0; - } else if (keys[j] == dirty) { - found_dirty = 1; } } while ((j=(j+1)%PTHREAD_KEYS_MAX) != next_key); - /* It's possible that all slots are in use or __synccall fails. */ - if (!found_dirty || clean_dirty_tsd()) { - pthread_rwlock_unlock(&key_lock); - return EAGAIN; - } - - /* If this point is reached there is necessarily a newly-cleaned - * slot to allocate to satisfy the caller's request. Find it and - * mark any additional previously-dirty slots clean. */ - for (j=0; jtsd[k] = 0; + while ((td=td->next)!=self); + __tl_unlock(); + + keys[k] = 0; + + __pthread_rwlock_unlock(&key_lock); + __restore_sigs(&set); + return 0; } @@ -112,20 +71,21 @@ void __pthread_tsd_run_dtors() pthread_t self = __pthread_self(); int i, j; for (j=0; self->tsd_used && jtsd_used = 0; for (i=0; itsd[i]; void (*dtor)(void *) = keys[i]; self->tsd[i] = 0; - if (val && dtor && dtor != nodtor && dtor != dirty) { - pthread_rwlock_unlock(&key_lock); + if (val && dtor && dtor != nodtor) { + __pthread_rwlock_unlock(&key_lock); dtor(val); - pthread_rwlock_rdlock(&key_lock); + __pthread_rwlock_rdlock(&key_lock); } } - pthread_rwlock_unlock(&key_lock); + __pthread_rwlock_unlock(&key_lock); } } weak_alias(__pthread_key_create, pthread_key_create); +weak_alias(__pthread_key_delete, pthread_key_delete);