blob: abd7127067721c381c162bf61bfc2174a287526c [file]
// Copyright 2019 The Emscripten Authors. All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License. Both these licenses can be
// found in the LICENSE file.
#include <assert.h>
#include <pthread.h>
#include <stdbool.h>
// tests, in the following sequence
// pthread_key_create with key k
// pthread_key_delete of key k
// pthread_key_create returning the same key k
// , that the thread local slot is correctly initialized to 0 in all threads
// overall structure based on test_pthread_reltime.cpp
static pthread_key_t key;
static pthread_barrier_t sync_barrier;
void *thread_main(void *arg) {
assert(pthread_getspecific(key) == 0);
pthread_setspecific(key, (void*)123);
assert(pthread_getspecific(key) == (void*)123);
// 1. Wait for slot to be recreated. First signal that we are done setting our value.
pthread_barrier_wait(&sync_barrier);
// 2. Wait for main thread to finish recreating the key.
pthread_barrier_wait(&sync_barrier);
assert(pthread_getspecific(key) == 0);
return NULL;
}
int main() {
// create tls slot and set the value
pthread_key_create(&key, NULL);
assert(pthread_getspecific(key) == 0);
pthread_setspecific(key, (void*)456);
assert(pthread_getspecific(key) == (void*)456);
pthread_barrier_init(&sync_barrier, NULL, 2);
// launch worker thread that also sets and queries the same slot
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_t thread;
int error = pthread_create(&thread, &attr, thread_main, NULL);
assert(!error);
// 1. Wait for worker thread to finish initial setting of the slot
pthread_barrier_wait(&sync_barrier);
// recreate
pthread_key_delete(key);
pthread_key_t oldkey = key;
pthread_key_create(&key, NULL);
assert(pthread_getspecific(key) == 0);
// this assertion holds in the current musl implementation,
// so we can skip having to loop over pthread_key_create's
// until we recover the same key
assert(oldkey == key);
// 2. Notify worker thread to check the slot again
pthread_barrier_wait(&sync_barrier);
pthread_join(thread, NULL);
return 0;
}