diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/env/__init_tls.c | 13 | ||||
| -rw-r--r-- | src/thread/i386/__set_thread_area.s | 22 | 
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  | 
