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 );
 }