about summary refs log tree commit diff
path: root/src/thread/pthread_key_create.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread/pthread_key_create.c')
-rw-r--r--src/thread/pthread_key_create.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/thread/pthread_key_create.c b/src/thread/pthread_key_create.c
new file mode 100644
index 00000000..efc38046
--- /dev/null
+++ b/src/thread/pthread_key_create.c
@@ -0,0 +1,25 @@
+#include "pthread_impl.h"
+
+const size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
+
+static void nodtor(void *dummy)
+{
+}
+
+int pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
+{
+	static void (*keys[PTHREAD_KEYS_MAX])(void *);
+	int i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
+	int j = i;
+
+	libc.tsd_keys = keys;
+	if (!dtor) dtor = nodtor;
+	/* Cheap trick - &k cannot match any destructor pointer */
+	while (a_cas_p(keys+j, 0, &k)
+		&& (j=(j+1)%PTHREAD_KEYS_MAX) != i);
+	if (keys[j] != (void (*)(void *))&k)
+		return EAGAIN;
+	keys[j] = dtor;
+	*k = j;
+	return 0;
+}