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