mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 10:13:56 +00:00
Implemented the Fiber* functions (with the help of Huw Davies).
This commit is contained in:
parent
ea118ecb50
commit
9e8e5ff71d
6 changed files with 213 additions and 8 deletions
|
@ -182,7 +182,9 @@
|
||||||
@ stdcall ConnectNamedPipe(long ptr) ConnectNamedPipe
|
@ stdcall ConnectNamedPipe(long ptr) ConnectNamedPipe
|
||||||
@ stdcall ContinueDebugEvent(long long long) ContinueDebugEvent
|
@ stdcall ContinueDebugEvent(long long long) ContinueDebugEvent
|
||||||
@ stdcall ConvertDefaultLocale (long) ConvertDefaultLocale
|
@ stdcall ConvertDefaultLocale (long) ConvertDefaultLocale
|
||||||
@ stub ConvertThreadToFiber
|
@ stdcall ConvertFiberToThread() ConvertFiberToThread
|
||||||
|
@ stdcall ConvertThreadToFiber(ptr) ConvertThreadToFiber
|
||||||
|
@ stdcall ConvertThreadToFiberEx(ptr long) ConvertThreadToFiberEx
|
||||||
@ stdcall ConvertToGlobalHandle(long) ConvertToGlobalHandle
|
@ stdcall ConvertToGlobalHandle(long) ConvertToGlobalHandle
|
||||||
@ stdcall CopyFileA(str str long) CopyFileA
|
@ stdcall CopyFileA(str str long) CopyFileA
|
||||||
@ stdcall CopyFileW(wstr wstr long) CopyFileW
|
@ stdcall CopyFileW(wstr wstr long) CopyFileW
|
||||||
|
@ -983,10 +985,11 @@
|
||||||
@ stdcall CancelWaitableTimer(long) CancelWaitableTimer
|
@ stdcall CancelWaitableTimer(long) CancelWaitableTimer
|
||||||
@ stdcall CopyFileExA (str str ptr ptr ptr long) CopyFileExA
|
@ stdcall CopyFileExA (str str ptr ptr ptr long) CopyFileExA
|
||||||
@ stdcall CopyFileExW (wstr wstr ptr ptr ptr long) CopyFileExW
|
@ 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 CreateWaitableTimerA(ptr long str) CreateWaitableTimerA
|
||||||
@ stdcall CreateWaitableTimerW(ptr long wstr) CreateWaitableTimerW
|
@ stdcall CreateWaitableTimerW(ptr long wstr) CreateWaitableTimerW
|
||||||
@ stub DeleteFiber
|
@ stdcall DeleteFiber(ptr) DeleteFiber
|
||||||
@ stub DuplicateConsoleHandle
|
@ stub DuplicateConsoleHandle
|
||||||
@ stdcall FindFirstFileExA(str long ptr long ptr long)FindFirstFileExA
|
@ stdcall FindFirstFileExA(str long ptr long ptr long)FindFirstFileExA
|
||||||
@ stdcall FindFirstFileExW(wstr long ptr long ptr long)FindFirstFileExW
|
@ stdcall FindFirstFileExW(wstr long ptr long ptr long)FindFirstFileExW
|
||||||
|
@ -1018,7 +1021,7 @@
|
||||||
@ stdcall SetThreadPriorityBoost(long long) SetThreadPriorityBoost
|
@ stdcall SetThreadPriorityBoost(long long) SetThreadPriorityBoost
|
||||||
@ stdcall SetWaitableTimer(long ptr long ptr ptr long) SetWaitableTimer
|
@ stdcall SetWaitableTimer(long ptr long ptr ptr long) SetWaitableTimer
|
||||||
@ stub SignalObjectAndWait
|
@ stub SignalObjectAndWait
|
||||||
@ stub SwitchToFiber
|
@ stdcall SwitchToFiber(ptr) SwitchToFiber
|
||||||
@ stdcall SwitchToThread() SwitchToThread
|
@ stdcall SwitchToThread() SwitchToThread
|
||||||
@ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection
|
@ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection
|
||||||
@ stdcall VirtualAllocEx(long ptr long long long) VirtualAllocEx
|
@ stdcall VirtualAllocEx(long ptr long long long) VirtualAllocEx
|
||||||
|
|
|
@ -59,6 +59,7 @@ C_SRCS = \
|
||||||
$(TOPOBJDIR)/relay32/snoop.c \
|
$(TOPOBJDIR)/relay32/snoop.c \
|
||||||
$(TOPOBJDIR)/scheduler/client.c \
|
$(TOPOBJDIR)/scheduler/client.c \
|
||||||
$(TOPOBJDIR)/scheduler/critsection.c \
|
$(TOPOBJDIR)/scheduler/critsection.c \
|
||||||
|
$(TOPOBJDIR)/scheduler/fiber.c \
|
||||||
$(TOPOBJDIR)/scheduler/handle.c \
|
$(TOPOBJDIR)/scheduler/handle.c \
|
||||||
$(TOPOBJDIR)/scheduler/pipe.c \
|
$(TOPOBJDIR)/scheduler/pipe.c \
|
||||||
$(TOPOBJDIR)/scheduler/process.c \
|
$(TOPOBJDIR)/scheduler/process.c \
|
||||||
|
|
|
@ -29,6 +29,7 @@ struct __EXCEPTION_FRAME;
|
||||||
struct _SECURITY_ATTRIBUTES;
|
struct _SECURITY_ATTRIBUTES;
|
||||||
struct tagSYSLEVEL;
|
struct tagSYSLEVEL;
|
||||||
struct server_buffer_info;
|
struct server_buffer_info;
|
||||||
|
struct fiber_data;
|
||||||
|
|
||||||
/* Thread exception block
|
/* Thread exception block
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ typedef struct _TEB
|
||||||
void *stack_low; /* 12- 08 Stack low-water mark */
|
void *stack_low; /* 12- 08 Stack low-water mark */
|
||||||
HTASK16 htask16; /* 1-- 0c Win16 task handle */
|
HTASK16 htask16; /* 1-- 0c Win16 task handle */
|
||||||
WORD stack_sel; /* 1-- 0e 16-bit stack selector */
|
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 */
|
DWORD user_ptr; /* 12n 14 User pointer */
|
||||||
/* end of NT_TIB */
|
/* end of NT_TIB */
|
||||||
struct _TEB *self; /* 12- 18 Pointer to this structure */
|
struct _TEB *self; /* 12- 18 Pointer to this structure */
|
||||||
|
@ -73,8 +74,8 @@ typedef struct _TEB
|
||||||
void (*startup)(void); /* --3 48 Thread startup routine */
|
void (*startup)(void); /* --3 48 Thread startup routine */
|
||||||
int thread_errno; /* --3 4c Per-thread errno (was: ring0_thread) */
|
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) */
|
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 54 Signal stack (was: stack_base) */
|
||||||
void *signal_stack; /* --3 58 Signal stack (was: exit_stack) */
|
void *exit_stack; /* 1-n 58 Exit stack */
|
||||||
void *emu_data; /* --n 5c Related to 80387 emulation */
|
void *emu_data; /* --n 5c Related to 80387 emulation */
|
||||||
DWORD last_error; /* 1-- 60 Last error code */
|
DWORD last_error; /* 1-- 60 Last error code */
|
||||||
HANDLE debug_cb; /* 1-n 64 Debugger context block */
|
HANDLE debug_cb; /* 1-n 64 Debugger context block */
|
||||||
|
@ -121,7 +122,7 @@ typedef struct _TEB
|
||||||
DWORD pad6[624]; /* --n 238 */
|
DWORD pad6[624]; /* --n 238 */
|
||||||
UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */
|
UNICODE_STRING StaticUnicodeString; /* -2- bf8 used by advapi32 */
|
||||||
USHORT StaticUnicodeBuffer[261]; /* -2- c00 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 */
|
LPVOID tls_array[64]; /* -2- e10 Thread local storage */
|
||||||
DWORD pad8[3]; /* --n f10 */
|
DWORD pad8[3]; /* --n f10 */
|
||||||
PVOID ReservedForNtRpc; /* -2- f1c used by rpcrt4 */
|
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)
|
#define CopyFileEx WINELIB_NAME_AW(CopyFileEx)
|
||||||
BOOL WINAPI CopySid(DWORD,PSID,PSID);
|
BOOL WINAPI CopySid(DWORD,PSID,PSID);
|
||||||
INT WINAPI CompareFileTime(const FILETIME*,const FILETIME*);
|
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 CreateEventA(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR);
|
||||||
HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCWSTR);
|
HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCWSTR);
|
||||||
#define CreateEvent WINELIB_NAME_AW(CreateEvent)
|
#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 CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
|
||||||
HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
|
HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
|
||||||
#define CreateFile WINELIB_NAME_AW(CreateFile)
|
#define CreateFile WINELIB_NAME_AW(CreateFile)
|
||||||
|
@ -1217,6 +1222,7 @@ BOOL WINAPI DebugActiveProcessStop(DWORD);
|
||||||
void WINAPI DebugBreak(void);
|
void WINAPI DebugBreak(void);
|
||||||
BOOL WINAPI DebugBreakProcess(HANDLE);
|
BOOL WINAPI DebugBreakProcess(HANDLE);
|
||||||
BOOL WINAPI DebugSetProcessKillOnExit(BOOL);
|
BOOL WINAPI DebugSetProcessKillOnExit(BOOL);
|
||||||
|
void WINAPI DeleteFiber(LPVOID);
|
||||||
BOOL WINAPI DeleteTimerQueueEx(HANDLE,HANDLE);
|
BOOL WINAPI DeleteTimerQueueEx(HANDLE,HANDLE);
|
||||||
BOOL WINAPI DeleteTimerQueueTimer(HANDLE,HANDLE,HANDLE);
|
BOOL WINAPI DeleteTimerQueueTimer(HANDLE,HANDLE,HANDLE);
|
||||||
BOOL WINAPI DeregisterEventSource(HANDLE);
|
BOOL WINAPI DeregisterEventSource(HANDLE);
|
||||||
|
@ -1501,6 +1507,7 @@ DWORD WINAPI SignalObjectAndWait(HANDLE,HANDLE,DWORD,BOOL);
|
||||||
VOID WINAPI Sleep(DWORD);
|
VOID WINAPI Sleep(DWORD);
|
||||||
DWORD WINAPI SleepEx(DWORD,BOOL);
|
DWORD WINAPI SleepEx(DWORD,BOOL);
|
||||||
DWORD WINAPI SuspendThread(HANDLE);
|
DWORD WINAPI SuspendThread(HANDLE);
|
||||||
|
void WINAPI SwitchToFiber(LPVOID);
|
||||||
BOOL WINAPI SwitchToThread(void);
|
BOOL WINAPI SwitchToThread(void);
|
||||||
BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
|
BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
|
||||||
DWORD WINAPI TlsAlloc(void);
|
DWORD WINAPI TlsAlloc(void);
|
||||||
|
|
|
@ -1676,6 +1676,12 @@ extern inline struct _TEB * WINAPI NtCurrentTeb(void)
|
||||||
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
extern struct _TEB * WINAPI NtCurrentTeb(void);
|
||||||
#endif
|
#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
|
* 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