Moved the remaining SYSDEPS_* functions to the wine_pthread interface.
Let the pthread library allocate the stack itself.
diff --git a/loader/pthread.c b/loader/pthread.c
index 339176f..4ec91b7 100644
--- a/loader/pthread.c
+++ b/loader/pthread.c
@@ -38,6 +38,25 @@
#include "wine/library.h"
#include "wine/pthread.h"
+static struct wine_pthread_functions funcs;
+
+#ifndef __i386__
+static pthread_key_t teb_key;
+#endif
+
+static inline int gettid(void)
+{
+#if defined(__linux__) && defined(__i386__)
+ int ret;
+ __asm__("int $0x80" : "=a" (ret) : "0" (224) /* SYS_gettid */);
+ if (ret < 0) ret = -1;
+ return ret;
+#else
+ return -1; /* FIXME */
+#endif
+}
+
+
/***********************************************************************
* wine_pthread_init_process
*
@@ -45,6 +64,7 @@
*/
void wine_pthread_init_process( const struct wine_pthread_functions *functions )
{
+ memcpy( &funcs, functions, min(functions->size,sizeof(funcs)) );
}
@@ -53,8 +73,33 @@
*
* Initialization for a newly created thread.
*/
-void wine_pthread_init_thread(void)
+void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
{
+#ifdef __i386__
+ /* On the i386, the current thread is in the %fs register */
+ LDT_ENTRY fs_entry;
+
+ wine_ldt_set_base( &fs_entry, info->teb_base );
+ wine_ldt_set_limit( &fs_entry, info->teb_size - 1 );
+ wine_ldt_set_flags( &fs_entry, WINE_LDT_FLAGS_DATA|WINE_LDT_FLAGS_32BIT );
+ wine_ldt_init_fs( info->teb_sel, &fs_entry );
+#else
+ if (!funcs.ptr_set_thread_data) /* first thread */
+ pthread_key_create( &teb_key, NULL );
+ pthread_setspecific( teb_key, info->teb_base );
+#endif
+
+ /* retrieve the stack info (except for main thread) */
+ if (funcs.ptr_set_thread_data)
+ {
+ pthread_attr_t attr;
+ pthread_getattr_np( pthread_self(), &attr );
+ pthread_attr_getstack( &attr, &info->stack_base, &info->stack_size );
+ }
+
+ /* set pid and tid */
+ info->pid = getpid();
+ info->tid = gettid();
}
@@ -65,17 +110,28 @@
{
pthread_t id;
pthread_attr_t attr;
+ int ret = 0;
- if (!info->stack_base)
- {
- info->stack_base = wine_anon_mmap( NULL, info->stack_size,
- PROT_READ | PROT_WRITE | PROT_EXEC, 0 );
- if (info->stack_base == (void *)-1) return -1;
- }
pthread_attr_init( &attr );
- pthread_attr_setstack( &attr, info->stack_base, info->stack_size );
- if (pthread_create( &id, &attr, (void * (*)(void *))info->entry, info )) return -1;
- return 0;
+ pthread_attr_setstacksize( &attr, info->stack_size );
+ if (pthread_create( &id, &attr, (void * (*)(void *))info->entry, info )) ret = -1;
+ pthread_attr_destroy( &attr );
+ return ret;
+}
+
+
+/***********************************************************************
+ * wine_pthread_get_current_teb
+ */
+void *wine_pthread_get_current_teb(void)
+{
+#ifdef __i386__
+ void *ret;
+ __asm__( ".byte 0x64\n\tmovl 0x18,%0" : "=r" (ret) );
+ return ret;
+#else
+ return pthread_getspecific( teb_key );
+#endif
}
@@ -103,7 +159,6 @@
{
pthread_join( free_info->self, &ptr );
wine_ldt_free_fs( free_info->thread_info.teb_sel );
- munmap( free_info->thread_info.stack_base, free_info->thread_info.stack_size );
munmap( free_info->thread_info.teb_base, free_info->thread_info.teb_size );
}
pthread_exit( (void *)info->exit_status );
@@ -115,6 +170,7 @@
*/
void wine_pthread_abort_thread( int status )
{
+ pthread_detach( pthread_self() ); /* no one will be joining with us */
pthread_exit( (void *)status );
}