Moved the remaining SYSDEPS_* functions to the wine_pthread interface.
Let the pthread library allocate the stack itself.

diff --git a/dlls/kernel/pthread.c b/dlls/kernel/pthread.c
index 4104a4f..076925b 100644
--- a/dlls/kernel/pthread.c
+++ b/dlls/kernel/pthread.c
@@ -551,6 +551,7 @@
 
 static const struct wine_pthread_functions functions =
 {
+    sizeof(functions),              /* size */
     wine_get_thread_data,           /* ptr_get_thread_data */
     wine_set_thread_data,           /* ptr_set_thread_data */
     wine_pthread_self,              /* ptr_pthread_self */
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 3b79747..b907af0 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -36,7 +36,6 @@
 	signal_sparc.c \
 	string.c \
 	sync.c \
-	sysdeps.c \
 	version.c \
 	thread.c \
 	time.c \
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 2878b6e..4622001 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -52,7 +52,7 @@
 
 /* server support */
 extern void server_init_process(void);
-extern void server_init_thread(void);
+extern void server_init_thread( int unix_pid, int unix_tid );
 extern void DECLSPEC_NORETURN server_protocol_error( const char *err, ... );
 extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
 extern void DECLSPEC_NORETURN server_abort_thread( int status );
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c
index f68eea6..c6bcb0a 100644
--- a/dlls/ntdll/server.c
+++ b/dlls/ntdll/server.c
@@ -666,7 +666,7 @@
  *
  * Send an init thread request. Return 0 if OK.
  */
-void server_init_thread(void)
+void server_init_thread( int unix_pid, int unix_tid )
 {
     TEB *teb = NtCurrentTeb();
     int version, ret;
@@ -700,8 +700,8 @@
 
     SERVER_START_REQ( init_thread )
     {
-        req->unix_pid    = getpid();
-        req->unix_tid    = SYSDEPS_GetUnixTid();
+        req->unix_pid    = unix_pid;
+        req->unix_tid    = unix_tid;
         req->teb         = teb;
         req->entry       = teb->entry_point;
         req->reply_fd    = reply_pipe[1];
diff --git a/dlls/ntdll/sysdeps.c b/dlls/ntdll/sysdeps.c
deleted file mode 100644
index 466e450..0000000
--- a/dlls/ntdll/sysdeps.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * System-dependent scheduler support
- *
- * Copyright 1998 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <signal.h>
-#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_SYSCALL_H
-# include <sys/syscall.h>
-#endif
-#ifdef HAVE_SYS_LWP_H
-# include <sys/lwp.h>
-#endif
-#ifdef HAVE_UCONTEXT_H
-# include <ucontext.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#ifdef HAVE_SCHED_H
-#include <sched.h>
-#endif
-
-#include "ntstatus.h"
-#include "thread.h"
-#include "wine/pthread.h"
-#include "wine/server.h"
-#include "winbase.h"
-#include "wine/library.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(thread);
-
-
-/***********************************************************************
- *           SYSDEPS_SetCurThread
- *
- * Make 'thread' the current thread.
- */
-void SYSDEPS_SetCurThread( TEB *teb )
-{
-#if defined(__i386__)
-    /* On the i386, the current thread is in the %fs register */
-    LDT_ENTRY fs_entry;
-
-    wine_ldt_set_base( &fs_entry, teb );
-    wine_ldt_set_limit( &fs_entry, 0xfff );
-    wine_ldt_set_flags( &fs_entry, WINE_LDT_FLAGS_DATA|WINE_LDT_FLAGS_32BIT );
-    wine_ldt_init_fs( teb->teb_sel, &fs_entry );
-#elif defined(__powerpc__)
-    /* On PowerPC, the current TEB is in the gpr13 register */
-# ifdef __APPLE__
-    __asm__ __volatile__("mr r13, %0" : : "r" (teb));
-# else
-    __asm__ __volatile__("mr 2, %0" : : "r" (teb));
-# endif
-#elif defined(HAVE__LWP_CREATE)
-    /* On non-i386 Solaris, we use the LWP private pointer */
-    _lwp_setprivate( teb );
-#endif
-    wine_pthread_init_thread();
-}
-
-
-/***********************************************************************
- *           SYSDEPS_GetUnixTid
- *
- * Get the Unix tid of the current thread.
- */
-int SYSDEPS_GetUnixTid(void)
-{
-#ifdef HAVE__LWP_SELF
-    return _lwp_self();
-#elif 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;
-#endif
-}
-
-/**********************************************************************
- *           NtCurrentTeb   (NTDLL.@)
- *
- * This will crash and burn if called before threading is initialized
- */
-#if defined(__i386__) && defined(__GNUC__)
-__ASM_GLOBAL_FUNC( NtCurrentTeb, ".byte 0x64\n\tmovl 0x18,%eax\n\tret" );
-#elif defined(__i386__) && defined(_MSC_VER)
-/* Nothing needs to be done. MS C "magically" exports the inline version from winnt.h */
-#elif defined(HAVE__LWP_CREATE)
-/***********************************************************************
- *		NtCurrentTeb (NTDLL.@)
- */
-struct _TEB * WINAPI NtCurrentTeb(void)
-{
-    extern void *_lwp_getprivate(void);
-    return (struct _TEB *)_lwp_getprivate();
-}
-#elif defined(__powerpc__)
-# ifdef __APPLE__
-__ASM_GLOBAL_FUNC( NtCurrentTeb, "\n\tmr r3,r13\n\tblr" );
-# else
-__ASM_GLOBAL_FUNC( NtCurrentTeb, "\n\tmr 3,2\n\tblr" );
-# endif
-#else
-# error NtCurrentTeb not defined for this architecture
-#endif  /* __i386__ */
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 2b08024..e438be3 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -95,6 +95,7 @@
     TEB *teb;
     void *addr;
     ULONG size;
+    struct wine_pthread_thread_info thread_info;
     static struct debug_info debug_info;  /* debug info for initial thread */
 
     debug_info.str_pos = debug_info.strings;
@@ -118,11 +119,16 @@
     teb->debug_info    = &debug_info;
     InsertHeadList( &tls_links, &teb->TlsLinks );
 
-    SYSDEPS_SetCurThread( teb );
+    thread_info.stack_base = NULL;
+    thread_info.stack_size = 0;
+    thread_info.teb_base   = teb;
+    thread_info.teb_size   = size;
+    thread_info.teb_sel    = teb->teb_sel;
+    wine_pthread_init_thread( &thread_info );
 
     /* setup the server connection */
     server_init_process();
-    server_init_thread();
+    server_init_thread( thread_info.pid, thread_info.tid );
 
     /* create a memory view for the TEB */
     NtAllocateVirtualMemory( GetCurrentProcess(), &addr, teb, &size,
@@ -153,9 +159,9 @@
     debug_info.out_pos = debug_info.output;
     teb->debug_info = &debug_info;
 
-    SYSDEPS_SetCurThread( teb );
+    wine_pthread_init_thread( info );
     SIGNAL_Init();
-    server_init_thread();
+    server_init_thread( info->pid, info->tid );
 
     /* allocate a memory view for the stack */
     size = info->stack_size;
@@ -540,3 +546,18 @@
         return STATUS_NOT_IMPLEMENTED;
     }
 }
+
+
+/**********************************************************************
+ *           NtCurrentTeb   (NTDLL.@)
+ */
+#if defined(__i386__) && defined(__GNUC__)
+__ASM_GLOBAL_FUNC( NtCurrentTeb, ".byte 0x64\n\tmovl 0x18,%eax\n\tret" );
+#elif defined(__i386__) && defined(_MSC_VER)
+/* Nothing needs to be done. MS C "magically" exports the inline version from winnt.h */
+#else
+TEB * WINAPI NtCurrentTeb(void)
+{
+    return wine_pthread_get_current_teb();
+}
+#endif  /* __i386__ */
diff --git a/include/thread.h b/include/thread.h
index 4cfd79c..0dc27e1 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -143,8 +143,4 @@
 /* scheduler/thread.c */
 extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size );
 
-/* scheduler/sysdeps.c */
-extern void SYSDEPS_SetCurThread( TEB *teb );
-extern int SYSDEPS_GetUnixTid(void);
-
 #endif  /* __WINE_THREAD_H */
diff --git a/include/wine/pthread.h b/include/wine/pthread.h
index 448c547..26aa78a 100644
--- a/include/wine/pthread.h
+++ b/include/wine/pthread.h
@@ -37,6 +37,7 @@
 
 struct wine_pthread_functions
 {
+    size_t      size;
     void *    (*ptr_get_thread_data)(void);
     void      (*ptr_set_thread_data)(void *data);
     pthread_t (*ptr_pthread_self)(void);
@@ -85,18 +86,21 @@
 /* thread information used to creating and exiting threads */
 struct wine_pthread_thread_info
 {
-    void          *stack_base;
-    size_t         stack_size;
-    void          *teb_base;
-    size_t         teb_size;
-    unsigned short teb_sel;
-    void         (*entry)( struct wine_pthread_thread_info *info );
-    int            exit_status;
+    void          *stack_base;  /* base address of the stack */
+    size_t         stack_size;  /* size of the stack */
+    void          *teb_base;    /* base address of the TEB */
+    size_t         teb_size;    /* size of the TEB (possibly including signal stack) */
+    unsigned short teb_sel;     /* selector to use for TEB */
+    int            pid;         /* Unix process id */
+    int            tid;         /* Unix thread id */
+    void         (*entry)( struct wine_pthread_thread_info *info );  /* thread entry point */
+    int            exit_status; /* thread exit status when calling wine_pthread_exit_thread */
 };
 
 extern void wine_pthread_init_process( const struct wine_pthread_functions *functions );
-extern void wine_pthread_init_thread(void);
+extern void wine_pthread_init_thread( struct wine_pthread_thread_info *info );
 extern int wine_pthread_create_thread( struct wine_pthread_thread_info *info );
+extern void *wine_pthread_get_current_teb(void);
 extern void DECLSPEC_NORETURN wine_pthread_exit_thread( struct wine_pthread_thread_info *info );
 extern void DECLSPEC_NORETURN wine_pthread_abort_thread( int status );
 
diff --git a/libs/wine/port.c b/libs/wine/port.c
index 1228e6e..19332fd 100644
--- a/libs/wine/port.c
+++ b/libs/wine/port.c
@@ -54,7 +54,7 @@
 /***********************************************************************
  *           wine_pthread_init_thread
  */
-void wine_pthread_init_thread(void)
+void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
 {
 }
 
@@ -67,6 +67,14 @@
 }
 
 /***********************************************************************
+ *           wine_pthread_get_current_teb
+ */
+void *wine_pthread_get_current_teb(void)
+{
+    return NULL;
+}
+
+/***********************************************************************
  *           wine_pthread_exit_thread
  */
 void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
diff --git a/loader/kthread.c b/loader/kthread.c
index 3d647dc..4cd6806 100644
--- a/loader/kthread.c
+++ b/loader/kthread.c
@@ -206,7 +206,7 @@
  */
 void wine_pthread_init_process( const struct wine_pthread_functions *functions )
 {
-    memcpy( &funcs, functions, sizeof(funcs) );
+    memcpy( &funcs, functions, min(functions->size,sizeof(funcs)) );
     funcs.ptr_set_thread_data( &initial_descr );
 }
 
@@ -216,10 +216,38 @@
  *
  * Initialization for a newly created thread.
  */
-void wine_pthread_init_thread(void)
+void wine_pthread_init_thread( struct wine_pthread_thread_info *info )
 {
     struct pthread_descr_struct *descr;
 
+#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 );
+#elif defined(__powerpc__)
+    /* On PowerPC, the current TEB is in the gpr13 register */
+# ifdef __APPLE__
+    __asm__ __volatile__("mr r13, %0" : : "r" (info->teb_base));
+# else
+    __asm__ __volatile__("mr 2, %0" : : "r" (info->teb_base));
+# endif
+#elif defined(HAVE__LWP_CREATE)
+    /* On non-i386 Solaris, we use the LWP private pointer */
+    _lwp_setprivate( info->teb_base );
+#endif
+
+    /* set pid and tid */
+    info->pid = getpid();
+#ifdef HAVE__LWP_SELF
+    info->tid = _lwp_self();
+#else
+    info->tid = -1;
+#endif
+
     if (funcs.ptr_set_thread_data)
     {
         descr = calloc( 1, sizeof(*descr) );
@@ -291,6 +319,31 @@
 
 
 /***********************************************************************
+ *           wine_pthread_get_current_teb
+ */
+void *wine_pthread_get_current_teb(void)
+{
+    void *ret;
+
+#ifdef __i386__
+    __asm__( ".byte 0x64\n\tmovl 0x18,%0" : "=r" (ret) );
+#elif defined(HAVE__LWP_CREATE)
+    ret = _lwp_getprivate();
+#elif defined(__powerpc__)
+# ifdef __APPLE__
+    __asm__( "mr %0,r13" : "=r" (ret) );
+# else
+    __asm__( "mr %0,2" : "=r" (ret) );
+# endif
+#else
+# error wine_pthread_get_current_teb not defined for this architecture
+#endif  /* __i386__ */
+
+    return ret;
+}
+
+
+/***********************************************************************
  *           wine_pthread_exit_thread
  */
 void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
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 );
 }