about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/env/__init_tls.c13
-rw-r--r--src/thread/i386/__set_thread_area.s22
2 files changed, 22 insertions, 13 deletions
diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
index 89d081ef..e1a2b614 100644
--- a/src/env/__init_tls.c
+++ b/src/env/__init_tls.c
@@ -11,17 +11,12 @@ int __init_tp(void *p)
 {
 	pthread_t td = p;
 	td->self = td;
-	if (__set_thread_area(TP_ADJ(p)) < 0)
-		return -1;
+	int r = __set_thread_area(TP_ADJ(p));
+	if (r < 0) return -1;
+	if (!r) libc.can_do_threads = 1;
+	libc.has_thread_pointer = 1;
 	td->tid = td->pid = __syscall(SYS_set_tid_address, &td->tid);
 	td->errno_ptr = &td->errno_val;
-	/* Currently, both of these predicates depend in the same thing:
-	 * successful initialization of the thread pointer. However, in
-	 * the future, we may support setups where setting the thread
-	 * pointer is possible but threads other than the main thread
-	 * cannot work, so it's best to keep the predicates separate. */
-	libc.has_thread_pointer = 1;
-	libc.can_do_threads = 1;
 	return 0;
 }
 
diff --git a/src/thread/i386/__set_thread_area.s b/src/thread/i386/__set_thread_area.s
index cccf1cd3..ad538151 100644
--- a/src/thread/i386/__set_thread_area.s
+++ b/src/thread/i386/__set_thread_area.s
@@ -12,11 +12,25 @@ __set_thread_area:
 	mov $243,%al
 	int $128
 	testl %eax,%eax
-	jnz 1f
-	movl (%esp),%ecx
-	leal 3(,%ecx,8),%ecx
-	movw %cx,%gs
+	jnz 2f
+	movl (%esp),%edx
+	leal 3(,%edx,8),%edx
+3:	movw %dx,%gs
 1:
 	addl $16,%esp
 	popl %ebx
 	ret
+2:
+	mov %ebx,%ecx
+	xor %ebx,%ebx
+	xor %edx,%edx
+	mov %ebx,(%esp)
+	mov $1,%bl
+	mov $16,%dl
+	mov $123,%al
+	int $128
+	testl %eax,%eax
+	jnz 1b
+	mov $7,%dl
+	inc %al
+	jmp 3b