Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
50fba7ff
Commit
50fba7ff
authored
Nov 09, 2003
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved the remaining SYSDEPS_* functions to the wine_pthread interface.
Let the pthread library allocate the stack itself.
parent
8d0ac557
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
173 additions
and
169 deletions
+173
-169
pthread.c
dlls/kernel/pthread.c
+1
-0
Makefile.in
dlls/ntdll/Makefile.in
+0
-1
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-1
server.c
dlls/ntdll/server.c
+3
-3
sysdeps.c
dlls/ntdll/sysdeps.c
+0
-134
thread.c
dlls/ntdll/thread.c
+25
-4
thread.h
include/thread.h
+0
-4
pthread.h
include/wine/pthread.h
+12
-8
port.c
libs/wine/port.c
+9
-1
kthread.c
loader/kthread.c
+55
-2
pthread.c
loader/pthread.c
+67
-11
No files found.
dlls/kernel/pthread.c
View file @
50fba7ff
...
...
@@ -551,6 +551,7 @@ static void wine_set_thread_data( void *data )
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 */
...
...
dlls/ntdll/Makefile.in
View file @
50fba7ff
...
...
@@ -36,7 +36,6 @@ C_SRCS = \
signal_sparc.c
\
string.c
\
sync.c
\
sysdeps.c
\
version.c
\
thread.c
\
time.c
\
...
...
dlls/ntdll/ntdll_misc.h
View file @
50fba7ff
...
...
@@ -52,7 +52,7 @@ extern void thread_init(void);
/* 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
);
...
...
dlls/ntdll/server.c
View file @
50fba7ff
...
...
@@ -666,7 +666,7 @@ void server_init_process(void)
*
* 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 @@ void server_init_thread(void)
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
];
...
...
dlls/ntdll/sysdeps.c
deleted
100644 → 0
View file @
8d0ac557
/*
* 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\t
movl 0x18,%eax
\n\t
ret"
);
#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\t
mr r3,r13
\n\t
blr"
);
# else
__ASM_GLOBAL_FUNC
(
NtCurrentTeb
,
"
\n\t
mr 3,2
\n\t
blr"
);
# endif
#else
# error NtCurrentTeb not defined for this architecture
#endif
/* __i386__ */
dlls/ntdll/thread.c
View file @
50fba7ff
...
...
@@ -95,6 +95,7 @@ void thread_init(void)
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 @@ void thread_init(void)
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 @@ static void start_thread( struct wine_pthread_thread_info *info )
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 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
return
STATUS_NOT_IMPLEMENTED
;
}
}
/**********************************************************************
* NtCurrentTeb (NTDLL.@)
*/
#if defined(__i386__) && defined(__GNUC__)
__ASM_GLOBAL_FUNC
(
NtCurrentTeb
,
".byte 0x64
\n\t
movl 0x18,%eax
\n\t
ret"
);
#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__ */
include/thread.h
View file @
50fba7ff
...
...
@@ -143,8 +143,4 @@ typedef struct _TEB
/* 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 */
include/wine/pthread.h
View file @
50fba7ff
...
...
@@ -37,6 +37,7 @@ typedef void *pthread_rwlockattr_t;
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 @@ struct wine_pthread_functions
/* 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
);
...
...
libs/wine/port.c
View file @
50fba7ff
...
...
@@ -54,7 +54,7 @@ void wine_pthread_init_process( const struct wine_pthread_functions *functions )
/***********************************************************************
* 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 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
}
/***********************************************************************
* 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
)
...
...
loader/kthread.c
View file @
50fba7ff
...
...
@@ -206,7 +206,7 @@ static void cleanup_thread( void *ptr )
*/
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 @@ void wine_pthread_init_process( const struct wine_pthread_functions *functions )
*
* 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 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
/***********************************************************************
* wine_pthread_get_current_teb
*/
void
*
wine_pthread_get_current_teb
(
void
)
{
void
*
ret
;
#ifdef __i386__
__asm__
(
".byte 0x64
\n\t
movl 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
)
...
...
loader/pthread.c
View file @
50fba7ff
...
...
@@ -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 @@ void wine_pthread_init_process( const struct wine_pthread_functions *functions )
*
* 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 @@ int wine_pthread_create_thread( struct wine_pthread_thread_info *info )
{
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\t
movl 0x18,%0"
:
"=r"
(
ret
)
);
return
ret
;
#else
return
pthread_getspecific
(
teb_key
);
#endif
}
...
...
@@ -103,7 +159,6 @@ void wine_pthread_exit_thread( struct wine_pthread_thread_info *info )
{
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_exit_thread( struct wine_pthread_thread_info *info )
*/
void
wine_pthread_abort_thread
(
int
status
)
{
pthread_detach
(
pthread_self
()
);
/* no one will be joining with us */
pthread_exit
(
(
void
*
)
status
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment