about summary refs log tree commit diff
path: root/src/thread/pthread_key_create.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-03-31 19:04:56 -0400
committerRich Felker <dalias@aerifal.cx>2011-03-31 19:04:56 -0400
commitc9806fc2f9b68be8942740da508eaaf0695d020e (patch)
treede27fc86fa1ba74c0526f0b72c64f96533eba0f7 /src/thread/pthread_key_create.c
parenta5323c57686340d3a8a6b0d6b3e6faab2a22ce8d (diff)
downloadmusl-c9806fc2f9b68be8942740da508eaaf0695d020e.tar.gz
musl-c9806fc2f9b68be8942740da508eaaf0695d020e.tar.xz
musl-c9806fc2f9b68be8942740da508eaaf0695d020e.zip
greatly simplify pthread_key_create (~20% size reduction)
Diffstat (limited to 'src/thread/pthread_key_create.c')
-rw-r--r--src/thread/pthread_key_create.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/src/thread/pthread_key_create.c b/src/thread/pthread_key_create.c
index 52c09734..c703bfe3 100644
--- a/src/thread/pthread_key_create.c
+++ b/src/thread/pthread_key_create.c
@@ -9,18 +9,17 @@ 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;
+	unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX;
+	unsigned j = i;
 
 	pthread_self();
 	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;
+	do {
+		if (!a_cas_p(keys+j, 0, dtor)) {
+			*k = j;
+			return 0;
+		}
+	} while ((j=(j+1)%PTHREAD_KEYS_MAX) != i);
+	return EAGAIN;
 }