mirror of
git://source.winehq.org/git/wine.git
synced 2024-08-31 10:54:06 +00:00
Implemented the Fiber* functions (with the help of Huw Davies).
This commit is contained in:
parent
ea118ecb50
commit
9e8e5ff71d
|
@ -182,7 +182,9 @@
|
|||
@ stdcall ConnectNamedPipe(long ptr) ConnectNamedPipe
|
||||
@ stdcall ContinueDebugEvent(long long long) ContinueDebugEvent
|
||||
@ stdcall ConvertDefaultLocale (long) ConvertDefaultLocale
|
||||
@ stub ConvertThreadToFiber
|
||||
@ stdcall ConvertFiberToThread() ConvertFiberToThread
|
||||
@ stdcall ConvertThreadToFiber(ptr) ConvertThreadToFiber
|
||||
@ stdcall ConvertThreadToFiberEx(ptr long) ConvertThreadToFiberEx
|
||||
@ stdcall ConvertToGlobalHandle(long) ConvertToGlobalHandle
|
||||
@ stdcall CopyFileA(str str long) CopyFileA
|
||||
@ stdcall CopyFileW(wstr wstr long) CopyFileW
|
||||
|
@ -983,10 +985,11 @@
|
|||
@ stdcall CancelWaitableTimer(long) CancelWaitableTimer
|
||||
@ stdcall CopyFileExA (str str ptr ptr ptr long) CopyFileExA
|
||||
@ stdcall CopyFileExW (wstr wstr ptr ptr ptr long) CopyFileExW
|
||||
@ stub CreateFiber
|
||||
@ stdcall CreateFiber(long ptr ptr) CreateFiber
|
||||
@ stdcall CreateFiberEx(long long long ptr ptr) CreateFiberEx
|
||||
@ stdcall CreateWaitableTimerA(ptr long str) CreateWaitableTimerA
|
||||
@ stdcall CreateWaitableTimerW(ptr long wstr) CreateWaitableTimerW
|
||||
@ stub DeleteFiber
|
||||
@ stdcall DeleteFiber(ptr) DeleteFiber
|
||||
@ stub DuplicateConsoleHandle
|
||||
@ stdcall FindFirstFileExA(str long ptr long ptr long)FindFirstFileExA
|
||||
@ stdcall FindFirstFileExW(wstr long ptr long ptr long)FindFirstFileExW
|
||||
|
@ -1018,7 +1021,7 @@
|
|||
@ stdcall SetThreadPriorityBoost(long long) SetThreadPriorityBoost
|
||||
@ stdcall SetWaitableTimer(long ptr long ptr ptr long) SetWaitableTimer
|
||||
@ stub SignalObjectAndWait
|
||||
@ stub SwitchToFiber
|
||||
@ stdcall SwitchToFiber(ptr) SwitchToFiber
|
||||
@ stdcall SwitchToThread() SwitchToThread
|
||||
@ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection
|
||||
@ stdcall VirtualAllocEx(long ptr long long long) VirtualAllocEx
|
||||
|
|
|
@ -59,6 +59,7 @@ C_SRCS = \
|
|||
$(TOPOBJDIR)/relay32/snoop.c \
|
||||
$(TOPOBJDIR)/scheduler/client.c \
|
||||
$(TOPOBJDIR)/scheduler/critsection.c \
|
||||
$(TOPOBJDIR)/scheduler/fiber.c \
|
||||
$(TOPOBJDIR)/scheduler/handle.c \
|
||||
$(TOPOBJDIR)/scheduler/pipe.c \
|
||||
$(TOPOBJDIR)/scheduler/process.c \
|
||||
|
|
|
@ -29,6 +29,7 @@ struct __EXCEPTION_FRAME;
|
|||
struct _SECURITY_ATTRIBUTES;
|
||||
struct tagSYSLEVEL;
|
||||
struct server_buffer_info;
|
||||
struct fiber_data;
|
||||
|
||||
/* Thread exception block
|
||||
|
||||
|
@ -52,7 +53,7 @@ typedef struct _TEB
|
|||
void *stack_low; /* 12- 08 Stack low-water mark */
|
||||
HTASK16 htask16; /* 1-- 0c Win16 task handle */
|
||||
WORD stack_sel; /* 1-- 0e 16-bit stack selector */
|
||||
DWORD selman_list; /* 1-n 10 Selector manager list */
|
||||
struct fiber_data *fiber; /* -2- 10 Current fiber data (Win95: selector manager list) */
|
||||
DWORD user_ptr; /* 12n 14 User pointer */
|
||||
/* end of NT_TIB */
|
||||
struct _TEB *self; /* 12- 18 Pointer to this structure */
|
||||
|
@ -73,8 +74,8 @@ typedef struct _TEB
|
|||
void (*startup)(void); /* --3 48 Thread startup routine */
|
||||
int thread_errno; /* --3 4c Per-thread errno (was: ring0_thread) */
|
||||
int thread_h_errno; /* --3 50 Per-thread h_errno (was: ptr to tdbx structure) */
|
||||
void *stack_base; /* 1-- 54 Base of the stack */
|
||||
void *signal_stack; /* --3 58 Signal stack (was: exit_stack) */
|
||||
void *signal_stack; /* --3 54 Signal stack (was: stack_base) */
|
||||
void *exit_stack; /* 1-n 58 Exit stack */
|
||||
void *emu_data; /* --n 5c Related to 80387 emulation */
|
||||
DWORD last_error; /* 1-- 60 Last error code */
|
||||
HANDLE debug_cb; /* 1-n 64 Debugger context block */
|
||||
|
@ -121,7 +122,7 @@ typedef struct _TEB
|
|||
DWORD pad6[624]; /* --n 238 */
|
||||
UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */
|
||||
USHORT StaticUnicodeBuffer[261]; /* -2- c00 used by advapi32 */
|
||||
DWORD pad7; /* --n e0c */
|
||||
void *stack_base; /* -2- e0c Base of the stack */
|
||||
LPVOID tls_array[64]; /* -2- e10 Thread local storage */
|
||||
DWORD pad8[3]; /* --n f10 */
|
||||
PVOID ReservedForNtRpc; /* -2- f1c used by rpcrt4 */
|
||||
|
|
|
@ -1178,9 +1178,14 @@ BOOL WINAPI CopyFileExW(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPB
|
|||
#define CopyFileEx WINELIB_NAME_AW(CopyFileEx)
|
||||
BOOL WINAPI CopySid(DWORD,PSID,PSID);
|
||||
INT WINAPI CompareFileTime(const FILETIME*,const FILETIME*);
|
||||
BOOL WINAPI ConvertFiberToThread(void);
|
||||
LPVOID WINAPI ConvertThreadToFiber(LPVOID);
|
||||
LPVOID WINAPI ConvertThreadToFiberEx(LPVOID,DWORD);
|
||||
HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR);
|
||||
HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCWSTR);
|
||||
#define CreateEvent WINELIB_NAME_AW(CreateEvent)
|
||||
LPVOID WINAPI CreateFiber(SIZE_T,LPFIBER_START_ROUTINE,LPVOID);
|
||||
LPVOID WINAPI CreateFiberEx(SIZE_T,SIZE_T,DWORD,LPFIBER_START_ROUTINE,LPVOID);
|
||||
HANDLE WINAPI CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
|
||||
HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
|
||||
#define CreateFile WINELIB_NAME_AW(CreateFile)
|
||||
|
@ -1217,6 +1222,7 @@ BOOL WINAPI DebugActiveProcessStop(DWORD);
|
|||
void WINAPI DebugBreak(void);
|
||||
BOOL WINAPI DebugBreakProcess(HANDLE);
|
||||
BOOL WINAPI DebugSetProcessKillOnExit(BOOL);
|
||||
void WINAPI DeleteFiber(LPVOID);
|
||||
BOOL WINAPI DeleteTimerQueueEx(HANDLE,HANDLE);
|
||||
BOOL WINAPI DeleteTimerQueueTimer(HANDLE,HANDLE,HANDLE);
|
||||
BOOL WINAPI DeregisterEventSource(HANDLE);
|
||||
|
@ -1501,6 +1507,7 @@ DWORD WINAPI SignalObjectAndWait(HANDLE,HANDLE,DWORD,BOOL);
|
|||
VOID WINAPI Sleep(DWORD);
|
||||
DWORD WINAPI SleepEx(DWORD,BOOL);
|
||||
DWORD WINAPI SuspendThread(HANDLE);
|
||||
void WINAPI SwitchToFiber(LPVOID);
|
||||
BOOL WINAPI SwitchToThread(void);
|
||||
BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
|
||||
DWORD WINAPI TlsAlloc(void);
|
||||
|
|
|
@ -1676,6 +1676,12 @@ extern inline struct _TEB * WINAPI NtCurrentTeb(void)
|
|||
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||
#endif
|
||||
|
||||
#ifdef NONAMELESSUNION
|
||||
#define GetCurrentFiber() (((NT_TIB *)NtCurrentTeb())->u.FiberData)
|
||||
#else
|
||||
#define GetCurrentFiber() (((NT_TIB *)NtCurrentTeb())->FiberData)
|
||||
#endif
|
||||
#define GetFiberData() (*(void **)GetCurrentFiber())
|
||||
|
||||
/*
|
||||
* File formats definitions
|
||||
|
|
187
scheduler/fiber.c
Normal file
187
scheduler/fiber.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Fiber support
|
||||
*
|
||||
* Copyright 2002 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
|
||||
*
|
||||
* FIXME:
|
||||
* - proper handling of 16-bit stack and signal stack
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "thread.h"
|
||||
|
||||
struct fiber_data
|
||||
{
|
||||
LPVOID param; /* 00 fiber param */
|
||||
void *except; /* 04 saved exception handlers list */
|
||||
void *stack_top; /* 08 top of fiber stack */
|
||||
void *stack_low; /* 0c fiber stack low-water mark */
|
||||
void *stack_base; /* 10 base of the fiber stack */
|
||||
jmp_buf jmpbuf; /* 14 setjmp buffer (on Windows: CONTEXT) */
|
||||
DWORD flags; /* fiber flags */
|
||||
LPFIBER_START_ROUTINE start; /* start routine */
|
||||
};
|
||||
|
||||
|
||||
/* call the fiber initial function once we have switched stack */
|
||||
static void start_fiber(void)
|
||||
{
|
||||
struct fiber_data *fiber = NtCurrentTeb()->fiber;
|
||||
LPFIBER_START_ROUTINE start = fiber->start;
|
||||
|
||||
fiber->start = NULL;
|
||||
start( fiber->param );
|
||||
ExitThread( 1 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateFiber (KERNEL32.@)
|
||||
*/
|
||||
LPVOID WINAPI CreateFiber( SIZE_T stack, LPFIBER_START_ROUTINE start, LPVOID param )
|
||||
{
|
||||
return CreateFiberEx( stack, 0, 0, start, param );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateFiberEx (KERNEL32.@)
|
||||
*/
|
||||
LPVOID WINAPI CreateFiberEx( SIZE_T stack_commit, SIZE_T stack_reserve, DWORD flags,
|
||||
LPFIBER_START_ROUTINE start, LPVOID param )
|
||||
{
|
||||
struct fiber_data *fiber;
|
||||
|
||||
if (!(fiber = HeapAlloc( GetProcessHeap(), 0, sizeof(*fiber) )))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: should use the thread stack allocation routines here */
|
||||
if (!stack_reserve) stack_reserve = 1024*1024;
|
||||
if(!(fiber->stack_base = VirtualAlloc( 0, stack_reserve, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, fiber );
|
||||
return NULL;
|
||||
}
|
||||
fiber->stack_top = (char *)fiber->stack_base + stack_reserve;
|
||||
fiber->stack_low = fiber->stack_base;
|
||||
fiber->param = param;
|
||||
fiber->except = (void *)-1;
|
||||
fiber->start = start;
|
||||
fiber->flags = flags;
|
||||
return fiber;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DeleteFiber (KERNEL32.@)
|
||||
*/
|
||||
void WINAPI DeleteFiber( LPVOID fiber_ptr )
|
||||
{
|
||||
struct fiber_data *fiber = fiber_ptr;
|
||||
|
||||
if (!fiber) return;
|
||||
if (fiber == NtCurrentTeb()->fiber)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, fiber );
|
||||
ExitThread(1);
|
||||
}
|
||||
VirtualFree( fiber->stack_base, 0, MEM_RELEASE );
|
||||
HeapFree( GetProcessHeap(), 0, fiber );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ConvertThreadToFiber (KERNEL32.@)
|
||||
*/
|
||||
LPVOID WINAPI ConvertThreadToFiber( LPVOID param )
|
||||
{
|
||||
return ConvertThreadToFiberEx( param, 0 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ConvertThreadToFiberEx (KERNEL32.@)
|
||||
*/
|
||||
LPVOID WINAPI ConvertThreadToFiberEx( LPVOID param, DWORD flags )
|
||||
{
|
||||
struct fiber_data *fiber;
|
||||
|
||||
if (!(fiber = HeapAlloc( GetProcessHeap(), 0, sizeof(*fiber) )))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return NULL;
|
||||
}
|
||||
fiber->param = param;
|
||||
fiber->except = NtCurrentTeb()->except;
|
||||
fiber->stack_top = NtCurrentTeb()->stack_top;
|
||||
fiber->stack_low = NtCurrentTeb()->stack_low;
|
||||
fiber->stack_base = NtCurrentTeb()->stack_base;
|
||||
fiber->start = NULL;
|
||||
fiber->flags = flags;
|
||||
NtCurrentTeb()->fiber = fiber;
|
||||
return fiber;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ConvertFiberToThread (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI ConvertFiberToThread(void)
|
||||
{
|
||||
struct fiber_data *fiber = NtCurrentTeb()->fiber;
|
||||
|
||||
if (fiber)
|
||||
{
|
||||
NtCurrentTeb()->fiber = NULL;
|
||||
HeapFree( GetProcessHeap(), 0, fiber );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SwitchToFiber (KERNEL32.@)
|
||||
*/
|
||||
void WINAPI SwitchToFiber( LPVOID fiber )
|
||||
{
|
||||
struct fiber_data *new_fiber = fiber;
|
||||
struct fiber_data *current_fiber = NtCurrentTeb()->fiber;
|
||||
|
||||
current_fiber->except = NtCurrentTeb()->except;
|
||||
current_fiber->stack_low = NtCurrentTeb()->stack_low;
|
||||
/* stack_base and stack_top never change */
|
||||
|
||||
/* FIXME: should save floating point context if requested in fiber->flags */
|
||||
if (!setjmp( current_fiber->jmpbuf ))
|
||||
{
|
||||
NtCurrentTeb()->fiber = new_fiber;
|
||||
NtCurrentTeb()->except = new_fiber->except;
|
||||
NtCurrentTeb()->stack_top = new_fiber->stack_top;
|
||||
NtCurrentTeb()->stack_low = new_fiber->stack_low;
|
||||
NtCurrentTeb()->stack_base = new_fiber->stack_base;
|
||||
if (new_fiber->start) /* first time */
|
||||
SYSDEPS_SwitchToThreadStack( start_fiber );
|
||||
else
|
||||
longjmp( new_fiber->jmpbuf, 1 );
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue