mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- Kernel32: implemented fibers. Almost complete - only lacks some Windows 2003 Server features (switching the floating point context and Fiber Local Storage functions)
- Kernel32: GetCurrentFiber and GetFiberData are macros, not functions - Kernel32: ExitThread now is declared as __declspec(noreturn) - RosRtl: two new functions to allocate and free stacks - RosRtl: corrected a couple of prototypes svn path=/trunk/; revision=4794
This commit is contained in:
parent
2382d9e48e
commit
66080da575
15 changed files with 697 additions and 272 deletions
|
@ -1136,6 +1136,9 @@ extern "C" {
|
||||||
|
|
||||||
/* FindNextPrinterNotification */
|
/* FindNextPrinterNotification */
|
||||||
|
|
||||||
|
/* FlsAlloc */
|
||||||
|
#define FLS_OUT_OF_INDEXES (0xFFFFFFFF)
|
||||||
|
|
||||||
/* FMExtensionProc */
|
/* FMExtensionProc */
|
||||||
|
|
||||||
/* FoldString */
|
/* FoldString */
|
||||||
|
|
|
@ -1515,6 +1515,7 @@ GetThreadTimes(
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
__declspec(noreturn)
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
STDCALL
|
||||||
ExitThread(
|
ExitThread(
|
||||||
|
@ -2796,6 +2797,16 @@ TlsFree(
|
||||||
DWORD dwTlsIndex
|
DWORD dwTlsIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef VOID WINAPI (*PFLS_CALLBACK_FUNCTION)(PVOID lpFlsData);
|
||||||
|
|
||||||
|
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback);
|
||||||
|
|
||||||
|
BOOL WINAPI FlsFree(DWORD dwFlsIndex);
|
||||||
|
|
||||||
|
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex);
|
||||||
|
|
||||||
|
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData);
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
SleepEx(
|
SleepEx(
|
||||||
|
@ -7569,45 +7580,38 @@ SHLoadInProc (REFCLSID);
|
||||||
|
|
||||||
/* Win32 Fibers */
|
/* Win32 Fibers */
|
||||||
|
|
||||||
typedef
|
typedef VOID (WINAPI * PFIBER_START_ROUTINE) (IN LPVOID lpFiberArgument);
|
||||||
VOID (WINAPI *PFIBER_START_ROUTINE) (
|
|
||||||
IN LPVOID lpFiberArgument
|
|
||||||
);
|
|
||||||
typedef PFIBER_START_ROUTINE LPFIBER_START_ROUTINE;
|
typedef PFIBER_START_ROUTINE LPFIBER_START_ROUTINE;
|
||||||
|
|
||||||
LPVOID
|
#define FIBER_FLAG_FLOAT_SWITCH (1)
|
||||||
STDCALL
|
|
||||||
ConvertThreadToFiber (
|
|
||||||
LPVOID lpArgument
|
|
||||||
);
|
|
||||||
LPVOID
|
|
||||||
STDCALL
|
|
||||||
CreateFiber (
|
|
||||||
DWORD dwStackSize,
|
|
||||||
LPFIBER_START_ROUTINE lpStartAddress,
|
|
||||||
LPVOID lpArgument
|
|
||||||
);
|
|
||||||
VOID
|
|
||||||
STDCALL
|
|
||||||
DeleteFiber(
|
|
||||||
LPVOID lpFiber
|
|
||||||
);
|
|
||||||
PVOID
|
|
||||||
STDCALL
|
|
||||||
GetCurrentFiber (
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
PVOID
|
|
||||||
STDCALL
|
|
||||||
GetFiberData (
|
|
||||||
VOID
|
|
||||||
);
|
|
||||||
VOID
|
|
||||||
STDCALL
|
|
||||||
SwitchToFiber (
|
|
||||||
LPVOID lpFiber
|
|
||||||
);
|
|
||||||
|
|
||||||
|
BOOL WINAPI ConvertFiberToThread(void);
|
||||||
|
|
||||||
|
LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter);
|
||||||
|
|
||||||
|
LPVOID WINAPI ConvertThreadToFiberEx(LPVOID lpParameter, DWORD dwFlags);
|
||||||
|
|
||||||
|
LPVOID WINAPI CreateFiber
|
||||||
|
(
|
||||||
|
SIZE_T dwStackSize,
|
||||||
|
LPFIBER_START_ROUTINE lpStartAddress,
|
||||||
|
LPVOID lpParameter
|
||||||
|
);
|
||||||
|
|
||||||
|
LPVOID WINAPI CreateFiberEx
|
||||||
|
(
|
||||||
|
SIZE_T dwStackCommitSize,
|
||||||
|
SIZE_T dwStackReserveSize,
|
||||||
|
DWORD dwFlags,
|
||||||
|
LPFIBER_START_ROUTINE lpStartAddress,
|
||||||
|
LPVOID lpParameter
|
||||||
|
);
|
||||||
|
|
||||||
|
void WINAPI DeleteFiber(LPVOID lpFiber);
|
||||||
|
|
||||||
|
void WINAPI SwitchToFiber(LPVOID lpFiber);
|
||||||
|
|
||||||
|
#define GetFiberData() *(LPVOID *)(((PNT_TIB)NtCurrentTeb())->Fib.FiberData)
|
||||||
|
|
||||||
WINBOOL STDCALL
|
WINBOOL STDCALL
|
||||||
RegisterServicesProcess(DWORD ServicesProcessId);
|
RegisterServicesProcess(DWORD ServicesProcessId);
|
||||||
|
|
|
@ -179,7 +179,7 @@ typedef struct _TEB
|
||||||
ULONG LastErrorValue; // 34h
|
ULONG LastErrorValue; // 34h
|
||||||
ULONG CountOfOwnedCriticalSections; // 38h
|
ULONG CountOfOwnedCriticalSections; // 38h
|
||||||
PVOID CsrClientThread; // 3Ch
|
PVOID CsrClientThread; // 3Ch
|
||||||
struct _W32THREAD* Win32ThreadInfo; // 40h
|
struct _W32THREAD* Win32ThreadInfo; // 40h
|
||||||
ULONG Win32ClientInfo[0x1F]; // 44h
|
ULONG Win32ClientInfo[0x1F]; // 44h
|
||||||
PVOID WOW32Reserved; // C0h
|
PVOID WOW32Reserved; // C0h
|
||||||
ULONG CurrentLocale; // C4h
|
ULONG CurrentLocale; // C4h
|
||||||
|
@ -220,9 +220,11 @@ typedef struct _TEB
|
||||||
PVOID Instrumentation[0x10]; // F2Ch
|
PVOID Instrumentation[0x10]; // F2Ch
|
||||||
PVOID WinSockData; // F6Ch
|
PVOID WinSockData; // F6Ch
|
||||||
ULONG GdiBatchCount; // F70h
|
ULONG GdiBatchCount; // F70h
|
||||||
ULONG Spare2; // F74h // NOTE: RtlExitUserThread writes something here
|
USHORT Spare2; // F74h
|
||||||
ULONG Spare3; // F78h
|
BOOLEAN IsFiber; // F76h
|
||||||
ULONG Spare4; // F7Ch
|
UCHAR Spare3; // F77h
|
||||||
|
ULONG Spare4; // F78h
|
||||||
|
ULONG Spare5; // F7Ch
|
||||||
PVOID ReservedForOle; // F80h
|
PVOID ReservedForOle; // F80h
|
||||||
ULONG WaitingOnLoaderLock; // F84h
|
ULONG WaitingOnLoaderLock; // F84h
|
||||||
PVOID WineDebugInfo; // Needed for WINE DLL's
|
PVOID WineDebugInfo; // Needed for WINE DLL's
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: thread.h,v 1.1 2003/04/29 02:17:00 hyperion Exp $
|
/* $Id: thread.h,v 1.2 2003/05/29 00:36:41 hyperion Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -14,7 +14,7 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
|
||||||
IN LONG StackZeroBits,
|
IN LONG StackZeroBits,
|
||||||
IN OUT PULONG StackReserve OPTIONAL,
|
IN OUT PULONG StackReserve OPTIONAL,
|
||||||
IN OUT PULONG StackCommit OPTIONAL,
|
IN OUT PULONG StackCommit OPTIONAL,
|
||||||
IN PTHREAD_START_ROUTINE StartAddress,
|
IN PVOID StartAddress,
|
||||||
OUT PHANDLE ThreadHandle OPTIONAL,
|
OUT PHANDLE ThreadHandle OPTIONAL,
|
||||||
OUT PCLIENT_ID ClientId OPTIONAL,
|
OUT PCLIENT_ID ClientId OPTIONAL,
|
||||||
IN ULONG ParameterCount,
|
IN ULONG ParameterCount,
|
||||||
|
@ -29,7 +29,7 @@ NTSTATUS CDECL RtlRosCreateUserThreadVa
|
||||||
IN LONG StackZeroBits,
|
IN LONG StackZeroBits,
|
||||||
IN OUT PULONG StackReserve OPTIONAL,
|
IN OUT PULONG StackReserve OPTIONAL,
|
||||||
IN OUT PULONG StackCommit OPTIONAL,
|
IN OUT PULONG StackCommit OPTIONAL,
|
||||||
IN PTHREAD_START_ROUTINE StartAddress,
|
IN PVOID StartAddress,
|
||||||
OUT PHANDLE ThreadHandle OPTIONAL,
|
OUT PHANDLE ThreadHandle OPTIONAL,
|
||||||
OUT PCLIENT_ID ClientId OPTIONAL,
|
OUT PCLIENT_ID ClientId OPTIONAL,
|
||||||
IN ULONG ParameterCount,
|
IN ULONG ParameterCount,
|
||||||
|
@ -39,13 +39,28 @@ NTSTATUS CDECL RtlRosCreateUserThreadVa
|
||||||
NTSTATUS NTAPI RtlRosInitializeContextEx
|
NTSTATUS NTAPI RtlRosInitializeContextEx
|
||||||
(
|
(
|
||||||
IN HANDLE ProcessHandle,
|
IN HANDLE ProcessHandle,
|
||||||
IN PCONTEXT Context,
|
OUT PCONTEXT Context,
|
||||||
IN PTHREAD_START_ROUTINE StartAddress,
|
IN PVOID StartAddress,
|
||||||
IN PUSER_STACK UserStack,
|
IN PUSER_STACK UserStack,
|
||||||
IN ULONG ParameterCount,
|
IN ULONG ParameterCount,
|
||||||
IN ULONG_PTR * Parameters
|
IN ULONG_PTR * Parameters
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS NTAPI RtlRosCreateStack
|
||||||
|
(
|
||||||
|
IN HANDLE ProcessHandle,
|
||||||
|
OUT PUSER_STACK UserStack,
|
||||||
|
IN LONG StackZeroBits,
|
||||||
|
IN OUT PULONG StackReserve OPTIONAL,
|
||||||
|
IN OUT PULONG StackCommit OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
|
NTSTATUS NTAPI RtlRosDeleteStack
|
||||||
|
(
|
||||||
|
IN HANDLE ProcessHandle,
|
||||||
|
IN PUSER_STACK UserStack
|
||||||
|
);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -171,6 +171,10 @@ FindResourceA@12
|
||||||
FindResourceExA@16
|
FindResourceExA@16
|
||||||
FindResourceExW@16
|
FindResourceExW@16
|
||||||
FindResourceW@12
|
FindResourceW@12
|
||||||
|
FlsAlloc@4
|
||||||
|
FlsFree@4
|
||||||
|
FlsGetValue@4
|
||||||
|
FlsSetValue@8
|
||||||
FlushConsoleInputBuffer@4
|
FlushConsoleInputBuffer@4
|
||||||
FlushFileBuffers@4
|
FlushFileBuffers@4
|
||||||
FlushInstructionCache@12
|
FlushInstructionCache@12
|
||||||
|
@ -239,7 +243,6 @@ GetCurrencyFormatW@24
|
||||||
GetCurrentConsoleFont@12
|
GetCurrentConsoleFont@12
|
||||||
GetCurrentDirectoryA@8
|
GetCurrentDirectoryA@8
|
||||||
GetCurrentDirectoryW@8
|
GetCurrentDirectoryW@8
|
||||||
GetCurrentFiber@0
|
|
||||||
GetCurrentProcess@0
|
GetCurrentProcess@0
|
||||||
GetCurrentProcessId@0
|
GetCurrentProcessId@0
|
||||||
GetCurrentThread@0
|
GetCurrentThread@0
|
||||||
|
@ -260,7 +263,6 @@ GetEnvironmentVariableA@12
|
||||||
GetEnvironmentVariableW@12
|
GetEnvironmentVariableW@12
|
||||||
GetExitCodeProcess@8
|
GetExitCodeProcess@8
|
||||||
GetExitCodeThread@8
|
GetExitCodeThread@8
|
||||||
GetFiberData@0
|
|
||||||
GetFileAttributesA@4
|
GetFileAttributesA@4
|
||||||
GetFileAttributesW@4
|
GetFileAttributesW@4
|
||||||
GetFileAttributesExA
|
GetFileAttributesExA
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; $Id: kernel32.edf,v 1.23 2003/04/26 00:25:01 hyperion Exp $
|
; $Id: kernel32.edf,v 1.24 2003/05/29 00:36:41 hyperion Exp $
|
||||||
;
|
;
|
||||||
; kernel32.edf
|
; kernel32.edf
|
||||||
;
|
;
|
||||||
|
@ -175,6 +175,10 @@ FindResourceA=FindResourceA@12
|
||||||
FindResourceExA=FindResourceExA@16
|
FindResourceExA=FindResourceExA@16
|
||||||
FindResourceExW=FindResourceExW@16
|
FindResourceExW=FindResourceExW@16
|
||||||
FindResourceW=FindResourceW@12
|
FindResourceW=FindResourceW@12
|
||||||
|
FlsAlloc=FlsAlloc@4
|
||||||
|
FlsFree=FlsFree@4
|
||||||
|
FlsGetValue=FlsGetValue@4
|
||||||
|
FlsSetValue=FlsSetValue@8
|
||||||
FlushConsoleInputBuffer=FlushConsoleInputBuffer@4
|
FlushConsoleInputBuffer=FlushConsoleInputBuffer@4
|
||||||
FlushFileBuffers=FlushFileBuffers@4
|
FlushFileBuffers=FlushFileBuffers@4
|
||||||
FlushInstructionCache=FlushInstructionCache@12
|
FlushInstructionCache=FlushInstructionCache@12
|
||||||
|
@ -243,7 +247,6 @@ GetCurrencyFormatW=GetCurrencyFormatW@24
|
||||||
GetCurrentConsoleFont=GetCurrentConsoleFont@12
|
GetCurrentConsoleFont=GetCurrentConsoleFont@12
|
||||||
GetCurrentDirectoryA=GetCurrentDirectoryA@8
|
GetCurrentDirectoryA=GetCurrentDirectoryA@8
|
||||||
GetCurrentDirectoryW=GetCurrentDirectoryW@8
|
GetCurrentDirectoryW=GetCurrentDirectoryW@8
|
||||||
GetCurrentFiber=GetCurrentFiber@0
|
|
||||||
GetCurrentProcess=GetCurrentProcess@0
|
GetCurrentProcess=GetCurrentProcess@0
|
||||||
GetCurrentProcessId=GetCurrentProcessId@0
|
GetCurrentProcessId=GetCurrentProcessId@0
|
||||||
GetCurrentThread=GetCurrentThread@0
|
GetCurrentThread=GetCurrentThread@0
|
||||||
|
@ -265,7 +268,6 @@ GetEnvironmentVariableA=GetEnvironmentVariableA@12
|
||||||
GetEnvironmentVariableW=GetEnvironmentVariableW@12
|
GetEnvironmentVariableW=GetEnvironmentVariableW@12
|
||||||
GetExitCodeProcess=GetExitCodeProcess@8
|
GetExitCodeProcess=GetExitCodeProcess@8
|
||||||
GetExitCodeThread=GetExitCodeThread@8
|
GetExitCodeThread=GetExitCodeThread@8
|
||||||
GetFiberData=GetFiberData@0
|
|
||||||
GetFileAttributesA=GetFileAttributesA@4
|
GetFileAttributesA=GetFileAttributesA@4
|
||||||
GetFileAttributesW=GetFileAttributesW@4
|
GetFileAttributesW=GetFileAttributesW@4
|
||||||
GetFileAttributesExA=GetFileAttributesExA@12
|
GetFileAttributesExA=GetFileAttributesExA@12
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.65 2003/05/25 17:17:03 ekohl Exp $
|
# $Id: makefile,v 1.66 2003/05/29 00:36:41 hyperion Exp $
|
||||||
|
|
||||||
PATH_TO_TOP = ../..
|
PATH_TO_TOP = ../..
|
||||||
|
|
||||||
|
@ -44,7 +44,11 @@ NLS_OBJECTS =
|
||||||
THREAD_OBJECTS = \
|
THREAD_OBJECTS = \
|
||||||
thread/fiber.o \
|
thread/fiber.o \
|
||||||
thread/thread.o \
|
thread/thread.o \
|
||||||
thread/tls.o
|
thread/tls.o \
|
||||||
|
thread/fls.o
|
||||||
|
|
||||||
|
THREAD_I386_OBJECTS = \
|
||||||
|
thread/i386/fiber.o
|
||||||
|
|
||||||
PROCESS_OBJECTS = \
|
PROCESS_OBJECTS = \
|
||||||
process/proc.o \
|
process/proc.o \
|
||||||
|
@ -58,9 +62,12 @@ EXCEPT_OBJECTS = except/except.o
|
||||||
|
|
||||||
DEBUG_OBJECTS = debug/debugger.o debug/output.o debug/break.o
|
DEBUG_OBJECTS = debug/debugger.o debug/output.o debug/break.o
|
||||||
|
|
||||||
|
ARCH_OBJECTS = $(THREAD_I386_OBJECTS)
|
||||||
|
|
||||||
TARGET_OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \
|
TARGET_OBJECTS = $(MISC_OBJECTS) $(FILE_OBJECTS) $(THREAD_OBJECTS) \
|
||||||
$(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) \
|
$(PROCESS_OBJECTS) $(STRING_OBJECTS) $(MEM_OBJECTS) \
|
||||||
$(SYNCH_OBJECTS) $(EXCEPT_OBJECTS) $(DEBUG_OBJECTS)
|
$(SYNCH_OBJECTS) $(EXCEPT_OBJECTS) $(DEBUG_OBJECTS) \
|
||||||
|
$(ARCH_OBJECTS)
|
||||||
|
|
||||||
|
|
||||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: fiber.c,v 1.4 2003/01/15 21:24:36 chorns Exp $
|
/* $Id: fiber.c,v 1.5 2003/05/29 00:36:41 hyperion Exp $
|
||||||
*
|
*
|
||||||
* FILE: lib/kernel32/thread/fiber.c
|
* FILE: lib/kernel32/thread/fiber.c
|
||||||
*
|
*
|
||||||
|
@ -7,88 +7,264 @@
|
||||||
*/
|
*/
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <kernel32/kernel32.h>
|
||||||
|
|
||||||
|
struct _FIBER /* Field offsets: */
|
||||||
|
{ /* 32 bit 64 bit */
|
||||||
|
/* this must be the first field */
|
||||||
|
LPVOID Parameter; /* 0x00 0x00 */
|
||||||
|
|
||||||
/**********************************************************************
|
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList; /* 0x04 0x08 */
|
||||||
* ConvertThreadToFiber
|
LPVOID StackBase; /* 0x08 0x10 */
|
||||||
*/
|
LPVOID StackLimit; /* 0x0C 0x18 */
|
||||||
LPVOID
|
LPVOID DeallocationStack; /* 0x10 0x20 */
|
||||||
STDCALL
|
ULONG_PTR Flags; /* 0x14 0x28 */
|
||||||
ConvertThreadToFiber(
|
#if defined(_M_IX86)
|
||||||
LPVOID lpArgument
|
/* control flow registers */
|
||||||
)
|
DWORD Eip; /* 0x18 ---- */
|
||||||
|
DWORD Esp; /* 0x1C ---- */
|
||||||
|
DWORD Ebp; /* 0x20 ---- */
|
||||||
|
|
||||||
|
/* general-purpose registers that must be preserved across calls */
|
||||||
|
DWORD Ebx; /* 0x24 ---- */
|
||||||
|
DWORD Esi; /* 0x28 ---- */
|
||||||
|
DWORD Edi; /* 0x2C ---- */
|
||||||
|
|
||||||
|
/* floating point save area (optional) */
|
||||||
|
FLOATING_SAVE_AREA FloatSave; /* 0x30 ---- */
|
||||||
|
#else
|
||||||
|
#error Unspecified or unsupported architecture.
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _FIBER FIBER, * PFIBER;
|
||||||
|
|
||||||
|
__declspec(noreturn) void WINAPI FiberStartup(PVOID lpStartAddress);
|
||||||
|
|
||||||
|
BOOL WINAPI ConvertFiberToThread(void)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
PTEB pTeb = NtCurrentTeb();
|
||||||
return NULL;
|
|
||||||
|
/* the current thread isn't running a fiber: failure */
|
||||||
|
if(!pTeb->IsFiber)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this thread won't run a fiber anymore */
|
||||||
|
pTeb->IsFiber = FALSE;
|
||||||
|
|
||||||
|
/* free the fiber */
|
||||||
|
if(pTeb->Tib.Fib.FiberData != NULL)
|
||||||
|
RtlFreeHeap(pTeb->Peb->ProcessHeap, 0, pTeb->Tib.Fib.FiberData);
|
||||||
|
|
||||||
|
/* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter)
|
||||||
/**********************************************************************
|
|
||||||
* CreateFiber
|
|
||||||
*/
|
|
||||||
LPVOID
|
|
||||||
STDCALL
|
|
||||||
CreateFiber(
|
|
||||||
DWORD dwStackSize,
|
|
||||||
LPFIBER_START_ROUTINE lpStartAddress,
|
|
||||||
LPVOID lpArgument
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
return ConvertThreadToFiberEx(lpParameter, 0);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPVOID WINAPI ConvertThreadToFiberEx(LPVOID lpParameter, DWORD dwFlags)
|
||||||
/**********************************************************************
|
|
||||||
* DeleteFiber
|
|
||||||
*/
|
|
||||||
VOID
|
|
||||||
STDCALL
|
|
||||||
DeleteFiber(
|
|
||||||
LPVOID lpFiber
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
PTEB pTeb = NtCurrentTeb();
|
||||||
return;
|
PFIBER pfCurFiber;
|
||||||
|
|
||||||
|
/* the current thread is already a fiber */
|
||||||
|
if(pTeb->IsFiber && pTeb->Tib.Fib.FiberData) return pTeb->Tib.Fib.FiberData;
|
||||||
|
|
||||||
|
/* allocate the fiber */
|
||||||
|
pfCurFiber = (PFIBER)RtlAllocateHeap(pTeb->Peb->ProcessHeap, 0, sizeof(FIBER));
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(pfCurFiber == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfCurFiber->Parameter = lpParameter;
|
||||||
|
pfCurFiber->Flags = dwFlags;
|
||||||
|
|
||||||
|
/* copy some contextual data from the thread to the fiber */
|
||||||
|
pfCurFiber->ExceptionList = pTeb->Tib.ExceptionList;
|
||||||
|
pfCurFiber->StackBase = pTeb->Tib.StackBase;
|
||||||
|
pfCurFiber->StackLimit = pTeb->Tib.StackLimit;
|
||||||
|
pfCurFiber->DeallocationStack = pTeb->DeallocationStack;
|
||||||
|
|
||||||
|
/* associate the fiber to the current thread */
|
||||||
|
pTeb->Tib.Fib.FiberData = pfCurFiber;
|
||||||
|
pTeb->IsFiber = TRUE;
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return (LPVOID)pfCurFiber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPVOID WINAPI CreateFiber
|
||||||
/**********************************************************************
|
(
|
||||||
* GetCurrentFiber
|
SIZE_T dwStackSize,
|
||||||
*/
|
LPFIBER_START_ROUTINE lpStartAddress,
|
||||||
PVOID
|
LPVOID lpParameter
|
||||||
STDCALL
|
)
|
||||||
GetCurrentFiber(VOID)
|
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
return CreateFiberEx(dwStackSize, 0, 0, lpStartAddress, lpParameter);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LPVOID WINAPI CreateFiberEx
|
||||||
/**********************************************************************
|
(
|
||||||
* GetFiberData
|
SIZE_T dwStackCommitSize,
|
||||||
*/
|
SIZE_T dwStackReserveSize,
|
||||||
PVOID
|
DWORD dwFlags,
|
||||||
STDCALL
|
LPFIBER_START_ROUTINE lpStartAddress,
|
||||||
GetFiberData(VOID)
|
LPVOID lpParameter
|
||||||
|
)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
PFIBER pfCurFiber;
|
||||||
return NULL;
|
NTSTATUS nErrCode;
|
||||||
|
PSIZE_T pnStackReserve = NULL;
|
||||||
|
PSIZE_T pnStackCommit = NULL;
|
||||||
|
USER_STACK usFiberStack;
|
||||||
|
CONTEXT ctxFiberContext;
|
||||||
|
PCHAR pStackBase;
|
||||||
|
PCHAR pStackLimit;
|
||||||
|
PTEB pTeb = NtCurrentTeb();
|
||||||
|
|
||||||
|
/* allocate the fiber */
|
||||||
|
pfCurFiber = (PFIBER)RtlAllocateHeap(pTeb->Peb->ProcessHeap, 0, sizeof(FIBER));
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(pfCurFiber == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the stack reserve or commit size weren't specified, use defaults */
|
||||||
|
if(dwStackReserveSize > 0) pnStackReserve = &dwStackReserveSize;
|
||||||
|
if(dwStackCommitSize > 0) pnStackCommit = &dwStackCommitSize;
|
||||||
|
|
||||||
|
/* create the stack for the fiber */
|
||||||
|
nErrCode = RtlRosCreateStack
|
||||||
|
(
|
||||||
|
NtCurrentProcess(),
|
||||||
|
&usFiberStack,
|
||||||
|
0,
|
||||||
|
pnStackReserve,
|
||||||
|
pnStackCommit
|
||||||
|
);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(!NT_SUCCESS(nErrCode)) goto l_CleanupFiber;
|
||||||
|
|
||||||
|
/* initialize the context for the fiber */
|
||||||
|
nErrCode = RtlRosInitializeContextEx
|
||||||
|
(
|
||||||
|
NtCurrentProcess(),
|
||||||
|
&ctxFiberContext,
|
||||||
|
FiberStartup,
|
||||||
|
&usFiberStack,
|
||||||
|
1,
|
||||||
|
(ULONG_PTR *)&lpStartAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(!NT_SUCCESS(nErrCode)) goto l_CleanupStack;
|
||||||
|
|
||||||
|
/* copy the data into the fiber */
|
||||||
|
|
||||||
|
/* fixed-size stack */
|
||||||
|
if(usFiberStack.FixedStackBase && usFiberStack.FixedStackLimit)
|
||||||
|
{
|
||||||
|
pfCurFiber->StackBase = usFiberStack.FixedStackBase;
|
||||||
|
pfCurFiber->StackLimit = usFiberStack.FixedStackLimit;
|
||||||
|
pfCurFiber->DeallocationStack = usFiberStack.FixedStackLimit;
|
||||||
|
}
|
||||||
|
/* expandable stack */
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
usFiberStack.ExpandableStackBase &&
|
||||||
|
usFiberStack.ExpandableStackLimit &&
|
||||||
|
usFiberStack.ExpandableStackBottom
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pfCurFiber->StackBase = usFiberStack.ExpandableStackBase;
|
||||||
|
pfCurFiber->StackLimit = usFiberStack.ExpandableStackLimit;
|
||||||
|
pfCurFiber->DeallocationStack = usFiberStack.ExpandableStackBottom;
|
||||||
|
}
|
||||||
|
/* bad initial stack */
|
||||||
|
else goto l_CleanupStack;
|
||||||
|
|
||||||
|
pfCurFiber->Parameter = lpParameter;
|
||||||
|
pfCurFiber->Flags = dwFlags;
|
||||||
|
pfCurFiber->ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)-1;
|
||||||
|
|
||||||
|
#if defined(_M_IX86)
|
||||||
|
|
||||||
|
pfCurFiber->Eip = ctxFiberContext.Eip;
|
||||||
|
pfCurFiber->Esp = ctxFiberContext.Esp;
|
||||||
|
pfCurFiber->Ebp = ctxFiberContext.Ebp;
|
||||||
|
pfCurFiber->Ebx = ctxFiberContext.Ebx;
|
||||||
|
pfCurFiber->Esi = ctxFiberContext.Esi;
|
||||||
|
pfCurFiber->Edi = ctxFiberContext.Edi;
|
||||||
|
|
||||||
|
if(dwFlags & FIBER_FLAG_FLOAT_SWITCH)
|
||||||
|
pfCurFiber->FloatSave = ctxFiberContext.FloatSave;
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Unspecified or unsupported architecture.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pfCurFiber;
|
||||||
|
|
||||||
|
l_CleanupStack:
|
||||||
|
/* free the stack */
|
||||||
|
RtlRosDeleteStack(NtCurrentProcess(), &usFiberStack);
|
||||||
|
|
||||||
|
l_CleanupFiber:
|
||||||
|
/* free the fiber */
|
||||||
|
RtlFreeHeap(pTeb->Peb->ProcessHeap, 0, pfCurFiber);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
assert(!NT_SUCCESS(nErrCode));
|
||||||
|
SetLastErrorByStatus(nErrCode);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WINAPI DeleteFiber(LPVOID lpFiber)
|
||||||
/**********************************************************************
|
|
||||||
* SwitchToFiber
|
|
||||||
*/
|
|
||||||
VOID
|
|
||||||
STDCALL
|
|
||||||
SwitchToFiber(
|
|
||||||
LPVOID lpFiber
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SIZE_T nSize = 0;
|
||||||
return;
|
PVOID pStackAllocBase = ((PFIBER)lpFiber)->DeallocationStack;
|
||||||
|
PTEB pTeb = NtCurrentTeb();
|
||||||
|
|
||||||
|
/* free the fiber */
|
||||||
|
RtlFreeHeap(pTeb->Peb->ProcessHeap, 0, lpFiber);
|
||||||
|
|
||||||
|
/* the fiber is deleting itself: let the system deallocate the stack */
|
||||||
|
if(pTeb->Tib.Fib.FiberData == lpFiber) ExitThread(1);
|
||||||
|
|
||||||
|
/* deallocate the stack */
|
||||||
|
NtFreeVirtualMemory
|
||||||
|
(
|
||||||
|
NtCurrentProcess(),
|
||||||
|
&pStackAllocBase,
|
||||||
|
&nSize,
|
||||||
|
MEM_RELEASE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__declspec(noreturn) extern void WINAPI ThreadStartup
|
||||||
|
(
|
||||||
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
|
LPVOID lpParameter
|
||||||
|
);
|
||||||
|
|
||||||
|
__declspec(noreturn) void WINAPI FiberStartup(PVOID lpStartAddress)
|
||||||
|
{
|
||||||
|
/* FIXME? this should be pretty accurate */
|
||||||
|
ThreadStartup(lpStartAddress, NtCurrentTeb()->Tib.Fib.FiberData);
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
55
reactos/lib/kernel32/thread/fls.c
Normal file
55
reactos/lib/kernel32/thread/fls.c
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/* $Id: fls.c,v 1.1 2003/05/29 00:36:41 hyperion Exp $
|
||||||
|
*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* FILE: lib/kernel32/thread/fls.c
|
||||||
|
* PURPOSE: Fiber local storage functions
|
||||||
|
* PROGRAMMER: KJK::Hyperion <noog@libero.it>
|
||||||
|
*
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* 28/05/2003 - created. Stubs only
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <k32.h>
|
||||||
|
|
||||||
|
#include <kernel32/kernel32.h>
|
||||||
|
|
||||||
|
DWORD WINAPI FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback)
|
||||||
|
{
|
||||||
|
(void)lpCallback;
|
||||||
|
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return FLS_OUT_OF_INDEXES;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI FlsFree(DWORD dwFlsIndex)
|
||||||
|
{
|
||||||
|
(void)dwFlsIndex;
|
||||||
|
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID WINAPI FlsGetValue(DWORD dwFlsIndex)
|
||||||
|
{
|
||||||
|
(void)dwFlsIndex;
|
||||||
|
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
|
||||||
|
{
|
||||||
|
(void)dwFlsIndex;
|
||||||
|
(void)lpFlsData;
|
||||||
|
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
94
reactos/lib/kernel32/thread/i386/fiber.S
Normal file
94
reactos/lib/kernel32/thread/i386/fiber.S
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/* $Id: fiber.S,v 1.1 2003/05/29 00:36:41 hyperion Exp $
|
||||||
|
*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* FILE: lib/kernel32/thread/i386/fiber.S
|
||||||
|
* PURPOSE: Fiber context switch code for the x86 architecture
|
||||||
|
* PROGRAMMER: KJK::Hyperion <noog@libero.it>
|
||||||
|
*
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* 28/05/2003 - created
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
.extern _DbgPrint
|
||||||
|
|
||||||
|
.globl _SwitchToFiber@4
|
||||||
|
|
||||||
|
_SwitchToFiber@4:
|
||||||
|
|
||||||
|
ErrStr:
|
||||||
|
.ascii \
|
||||||
|
"(KERNEL32:" __FILE__ ") Saving and restoring the floating point context \
|
||||||
|
currently unimplemented\n\0"
|
||||||
|
|
||||||
|
movl %fs:0x18, %ecx /* Teb = NtCurrentTeb() */
|
||||||
|
|
||||||
|
/* get the current fiber */
|
||||||
|
movl 0x10(%ecx), %eax /* Fiber = Teb->Tib.Fib.FiberData */
|
||||||
|
|
||||||
|
/* store the volatile context of the current fiber */
|
||||||
|
movl 0x0(%ecx), %edx
|
||||||
|
movl %edx, 0x4(%eax) /* Fiber->ExceptionList = Teb->ExceptionList */
|
||||||
|
movl 0x4(%ecx), %edx
|
||||||
|
movl %edx, 0x8(%eax) /* Fiber->StackBase = Teb->StackBase */
|
||||||
|
movl 0x8(%ecx), %edx
|
||||||
|
movl %edx, 0xC(%eax) /* Fiber->StackLimit = Teb->StackLimit */
|
||||||
|
movl 0xE0C(%ecx), %edx
|
||||||
|
movl %edx, 0x10(%eax) /* Fiber->StackBottom = Teb->StackBottom */
|
||||||
|
movl 0x0(%esp), %edx
|
||||||
|
movl %edx, 0x18(%eax) /* Fiber->Eip = [esp] */
|
||||||
|
movl %esp, %edx
|
||||||
|
addl $0x8, %edx
|
||||||
|
movl %edx, 0x1C(%eax) /* Fiber->Esp = esp + 8 */
|
||||||
|
movl %ebp, 0x20(%eax) /* Fiber->Ebp = ebp */
|
||||||
|
movl %ebx, 0x24(%eax) /* Fiber->Ebx = ebx */
|
||||||
|
movl %esi, 0x28(%eax) /* Fiber->Esi = edi */
|
||||||
|
movl %edi, 0x2C(%eax) /* Fiber->Edi = esi */
|
||||||
|
|
||||||
|
testl $1, 0x14(%eax)
|
||||||
|
jz l_NoFloatSave
|
||||||
|
|
||||||
|
/* save the floating point context */
|
||||||
|
/* TODO */
|
||||||
|
pushl ErrStr
|
||||||
|
call _DbgPrint
|
||||||
|
popl %ecx
|
||||||
|
|
||||||
|
l_NoFloatSave:
|
||||||
|
|
||||||
|
/* switch to the specified fiber */
|
||||||
|
movl 0x4(%esp), %eax /* Fiber = lpFiber */
|
||||||
|
movl %eax, 0x10(%ecx) /* Teb->Tib.FiberData = Fiber */
|
||||||
|
|
||||||
|
/* restore the volatile context of the specified fiber */
|
||||||
|
movl 0x4(%eax), %edx
|
||||||
|
movl %edx, 0x0(%ecx) /* Teb->ExceptionList = Fiber->ExceptionList */
|
||||||
|
movl 0x8(%eax), %edx
|
||||||
|
movl %edx, 0x4(%ecx) /* Teb->StackBase = Fiber->StackBase */
|
||||||
|
movl 0xC(%eax), %edx
|
||||||
|
movl %edx, 0x8(%ecx) /* Teb->StackLimit = Fiber->StackLimit */
|
||||||
|
movl 0x10(%eax), %edx
|
||||||
|
movl %edx, 0xE0C(%ecx) /* Teb->StackBottom = Fiber->StackBottom */
|
||||||
|
movl 0x18(%eax), %edx /* edx = Fiber->Eip */
|
||||||
|
movl 0x1C(%eax), %esp /* esp = Fiber->Esp */
|
||||||
|
movl 0x20(%eax), %ebp /* ebp = Fiber->Ebp */
|
||||||
|
movl 0x24(%eax), %ebx /* ebx = Fiber->Ebx */
|
||||||
|
movl 0x28(%eax), %esi /* esi = Fiber->Esi */
|
||||||
|
movl 0x2C(%eax), %edi /* edi = Fiber->Edi */
|
||||||
|
|
||||||
|
testb $1, 0x14(%eax)
|
||||||
|
jz l_NoFloatSave
|
||||||
|
|
||||||
|
/* restore the floating point context */
|
||||||
|
/* TODO */
|
||||||
|
pushl ErrStr
|
||||||
|
call _DbgPrint
|
||||||
|
popl %ecx
|
||||||
|
|
||||||
|
l_NoFloatRestore:
|
||||||
|
|
||||||
|
/* jump to the saved program counter */
|
||||||
|
jmp *%edx
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: thread.c,v 1.39 2003/04/30 22:00:41 gvg Exp $
|
/* $Id: thread.c,v 1.40 2003/05/29 00:36:41 hyperion Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -35,9 +35,11 @@ _except_handler(EXCEPTION_RECORD *ExceptionRecord,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID STDCALL
|
__declspec(noreturn) void STDCALL ThreadStartup
|
||||||
ThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress,
|
(
|
||||||
LPVOID lpParameter)
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
|
LPVOID lpParameter
|
||||||
|
)
|
||||||
{
|
{
|
||||||
UINT uExitCode;
|
UINT uExitCode;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.1 2003/04/29 02:17:01 hyperion Exp $
|
# $Id: makefile,v 1.2 2003/05/29 00:36:41 hyperion Exp $
|
||||||
|
|
||||||
PATH_TO_TOP = ../..
|
PATH_TO_TOP = ../..
|
||||||
|
|
||||||
|
@ -8,7 +8,8 @@ TARGET_NAME = rosrtl
|
||||||
|
|
||||||
THREAD_OBJECTS = \
|
THREAD_OBJECTS = \
|
||||||
thread/context.o \
|
thread/context.o \
|
||||||
thread/create.o
|
thread/create.o \
|
||||||
|
thread/stack.o
|
||||||
|
|
||||||
TARGET_OBJECTS = $(THREAD_OBJECTS)
|
TARGET_OBJECTS = $(THREAD_OBJECTS)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: context.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $
|
/* $Id: context.c,v 1.2 2003/05/29 00:36:41 hyperion Exp $
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
@ -16,8 +16,8 @@
|
||||||
NTSTATUS NTAPI RtlRosInitializeContextEx
|
NTSTATUS NTAPI RtlRosInitializeContextEx
|
||||||
(
|
(
|
||||||
IN HANDLE ProcessHandle,
|
IN HANDLE ProcessHandle,
|
||||||
IN PCONTEXT Context,
|
OUT PCONTEXT Context,
|
||||||
IN PTHREAD_START_ROUTINE StartAddress,
|
IN PVOID StartAddress,
|
||||||
IN PUSER_STACK UserStack,
|
IN PUSER_STACK UserStack,
|
||||||
IN ULONG ParameterCount,
|
IN ULONG ParameterCount,
|
||||||
IN ULONG_PTR * Parameters
|
IN ULONG_PTR * Parameters
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: create.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $
|
/* $Id: create.c,v 1.2 2003/05/29 00:36:41 hyperion Exp $
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
@ -18,7 +18,7 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
|
||||||
IN LONG StackZeroBits,
|
IN LONG StackZeroBits,
|
||||||
IN OUT PULONG StackReserve OPTIONAL,
|
IN OUT PULONG StackReserve OPTIONAL,
|
||||||
IN OUT PULONG StackCommit OPTIONAL,
|
IN OUT PULONG StackCommit OPTIONAL,
|
||||||
IN PTHREAD_START_ROUTINE StartAddress,
|
IN PVOID StartAddress,
|
||||||
OUT PHANDLE ThreadHandle OPTIONAL,
|
OUT PHANDLE ThreadHandle OPTIONAL,
|
||||||
OUT PCLIENT_ID ClientId OPTIONAL,
|
OUT PCLIENT_ID ClientId OPTIONAL,
|
||||||
IN ULONG ParameterCount,
|
IN ULONG ParameterCount,
|
||||||
|
@ -27,13 +27,6 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
|
||||||
{
|
{
|
||||||
USER_STACK usUserStack;
|
USER_STACK usUserStack;
|
||||||
OBJECT_ATTRIBUTES oaThreadAttribs;
|
OBJECT_ATTRIBUTES oaThreadAttribs;
|
||||||
/* FIXME: read the defaults from the executable image */
|
|
||||||
ULONG_PTR nStackReserve = 0x100000;
|
|
||||||
/* FIXME: when we finally have exception handling, make this PAGE_SIZE */
|
|
||||||
ULONG_PTR nStackCommit = 0x100000;
|
|
||||||
ULONG_PTR nSize = 0;
|
|
||||||
PVOID pStackLowest = NULL;
|
|
||||||
ULONG nDummy;
|
|
||||||
CONTEXT ctxInitialContext;
|
CONTEXT ctxInitialContext;
|
||||||
NTSTATUS nErrCode;
|
NTSTATUS nErrCode;
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
|
@ -41,130 +34,19 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
|
||||||
|
|
||||||
if(ThreadHandle == NULL) ThreadHandle = &hThread;
|
if(ThreadHandle == NULL) ThreadHandle = &hThread;
|
||||||
if(ClientId == NULL) ClientId = &cidClientId;
|
if(ClientId == NULL) ClientId = &cidClientId;
|
||||||
|
|
||||||
|
/* allocate the stack for the thread */
|
||||||
|
nErrCode = RtlRosCreateStack
|
||||||
|
(
|
||||||
|
ProcessHandle,
|
||||||
|
&usUserStack,
|
||||||
|
StackZeroBits,
|
||||||
|
StackReserve,
|
||||||
|
StackCommit
|
||||||
|
);
|
||||||
|
|
||||||
if(StackReserve == NULL) StackReserve = &nStackReserve;
|
/* failure */
|
||||||
else ROUNDUP(*StackReserve, PAGE_SIZE);
|
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
||||||
|
|
||||||
if(StackCommit == NULL) StackCommit = &nStackCommit;
|
|
||||||
else ROUNDUP(*StackCommit, PAGE_SIZE);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* the stack commit size must be equal to or less than the reserve size */
|
|
||||||
if(*StackCommit > *StackReserve) *StackCommit = *StackReserve;
|
|
||||||
#else
|
|
||||||
/* FIXME: no SEH, no guard pages */
|
|
||||||
*StackCommit = *StackReserve;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
usUserStack.FixedStackBase = NULL;
|
|
||||||
usUserStack.FixedStackLimit = NULL;
|
|
||||||
usUserStack.ExpandableStackBase = NULL;
|
|
||||||
usUserStack.ExpandableStackLimit = NULL;
|
|
||||||
usUserStack.ExpandableStackBottom = NULL;
|
|
||||||
|
|
||||||
/* FIXME: this code assumes a stack growing downwards */
|
|
||||||
/* fixed stack */
|
|
||||||
if(*StackCommit == *StackReserve)
|
|
||||||
{
|
|
||||||
usUserStack.FixedStackLimit = NULL;
|
|
||||||
|
|
||||||
/* allocate the stack */
|
|
||||||
nErrCode = NtAllocateVirtualMemory
|
|
||||||
(
|
|
||||||
ProcessHandle,
|
|
||||||
&(usUserStack.FixedStackLimit),
|
|
||||||
StackZeroBits,
|
|
||||||
StackReserve,
|
|
||||||
MEM_RESERVE | MEM_COMMIT,
|
|
||||||
PAGE_READWRITE
|
|
||||||
);
|
|
||||||
|
|
||||||
/* failure */
|
|
||||||
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
|
||||||
|
|
||||||
/* store the highest (first) address of the stack */
|
|
||||||
usUserStack.FixedStackBase =
|
|
||||||
(PUCHAR)(usUserStack.FixedStackLimit) + *StackReserve;
|
|
||||||
|
|
||||||
*StackCommit = *StackReserve;
|
|
||||||
}
|
|
||||||
/* expandable stack */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ULONG_PTR nGuardSize = PAGE_SIZE;
|
|
||||||
PVOID pGuardBase;
|
|
||||||
|
|
||||||
DPRINT("Expandable stack\n");
|
|
||||||
|
|
||||||
usUserStack.FixedStackLimit = NULL;
|
|
||||||
usUserStack.FixedStackBase = NULL;
|
|
||||||
usUserStack.ExpandableStackBottom = NULL;
|
|
||||||
|
|
||||||
/* reserve the stack */
|
|
||||||
nErrCode = NtAllocateVirtualMemory
|
|
||||||
(
|
|
||||||
ProcessHandle,
|
|
||||||
&(usUserStack.ExpandableStackBottom),
|
|
||||||
StackZeroBits,
|
|
||||||
StackReserve,
|
|
||||||
MEM_RESERVE,
|
|
||||||
PAGE_READWRITE
|
|
||||||
);
|
|
||||||
|
|
||||||
/* failure */
|
|
||||||
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
|
||||||
|
|
||||||
DPRINT("Reserved %08X bytes\n", *StackReserve);
|
|
||||||
|
|
||||||
/* expandable stack base - the highest address of the stack */
|
|
||||||
usUserStack.ExpandableStackBase =
|
|
||||||
(PUCHAR)(usUserStack.ExpandableStackBottom) + *StackReserve;
|
|
||||||
|
|
||||||
/* expandable stack limit - the lowest committed address of the stack */
|
|
||||||
usUserStack.ExpandableStackLimit =
|
|
||||||
(PUCHAR)(usUserStack.ExpandableStackBase) - *StackCommit;
|
|
||||||
|
|
||||||
DPRINT("Stack base %p\n", usUserStack.ExpandableStackBase);
|
|
||||||
DPRINT("Stack limit %p\n", usUserStack.ExpandableStackLimit);
|
|
||||||
DPRINT("Stack bottom %p\n", usUserStack.ExpandableStackBottom);
|
|
||||||
|
|
||||||
/* commit as much stack as requested */
|
|
||||||
nErrCode = NtAllocateVirtualMemory
|
|
||||||
(
|
|
||||||
ProcessHandle,
|
|
||||||
&(usUserStack.ExpandableStackLimit),
|
|
||||||
0,
|
|
||||||
StackCommit,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE
|
|
||||||
);
|
|
||||||
|
|
||||||
/* failure */
|
|
||||||
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
|
||||||
|
|
||||||
assert((*StackReserve - *StackCommit) >= PAGE_SIZE);
|
|
||||||
assert((*StackReserve - *StackCommit) % PAGE_SIZE == 0);
|
|
||||||
|
|
||||||
pGuardBase = (PUCHAR)(usUserStack.ExpandableStackLimit) - PAGE_SIZE;
|
|
||||||
|
|
||||||
DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase);
|
|
||||||
|
|
||||||
/* set up the guard page */
|
|
||||||
nErrCode = NtAllocateVirtualMemory
|
|
||||||
(
|
|
||||||
ProcessHandle,
|
|
||||||
&pGuardBase,
|
|
||||||
0,
|
|
||||||
&nGuardSize,
|
|
||||||
MEM_COMMIT,
|
|
||||||
PAGE_READWRITE | PAGE_GUARD
|
|
||||||
);
|
|
||||||
|
|
||||||
/* failure */
|
|
||||||
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
|
||||||
|
|
||||||
DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the registers and stack for the thread */
|
/* initialize the registers and stack for the thread */
|
||||||
nErrCode = RtlRosInitializeContextEx
|
nErrCode = RtlRosInitializeContextEx
|
||||||
|
@ -178,7 +60,7 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
|
||||||
);
|
);
|
||||||
|
|
||||||
/* failure */
|
/* failure */
|
||||||
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
|
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
||||||
|
|
||||||
/* create the thread object */
|
/* create the thread object */
|
||||||
nErrCode = NtCreateThread
|
nErrCode = NtCreateThread
|
||||||
|
@ -194,25 +76,18 @@ NTSTATUS STDCALL RtlRosCreateUserThreadEx
|
||||||
);
|
);
|
||||||
|
|
||||||
/* failure */
|
/* failure */
|
||||||
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
|
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
/* deallocate the stack */
|
|
||||||
l_Cleanup:
|
|
||||||
if(usUserStack.FixedStackLimit)
|
|
||||||
pStackLowest = usUserStack.FixedStackLimit;
|
|
||||||
else if(usUserStack.ExpandableStackBottom)
|
|
||||||
pStackLowest = usUserStack.ExpandableStackBottom;
|
|
||||||
|
|
||||||
/* free the stack, if it was allocated */
|
|
||||||
if(pStackLowest != NULL)
|
|
||||||
NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
|
|
||||||
|
|
||||||
/* failure */
|
/* failure */
|
||||||
l_Fail:
|
l_Fail:
|
||||||
assert(!NT_SUCCESS(nErrCode));
|
assert(!NT_SUCCESS(nErrCode));
|
||||||
|
|
||||||
|
/* deallocate the stack */
|
||||||
|
RtlRosDeleteStack(ProcessHandle, &usUserStack);
|
||||||
|
|
||||||
return nErrCode;
|
return nErrCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +99,7 @@ NTSTATUS CDECL RtlRosCreateUserThreadVa
|
||||||
IN LONG StackZeroBits,
|
IN LONG StackZeroBits,
|
||||||
IN OUT PULONG StackReserve OPTIONAL,
|
IN OUT PULONG StackReserve OPTIONAL,
|
||||||
IN OUT PULONG StackCommit OPTIONAL,
|
IN OUT PULONG StackCommit OPTIONAL,
|
||||||
IN PTHREAD_START_ROUTINE StartAddress,
|
IN PVOID StartAddress,
|
||||||
OUT PHANDLE ThreadHandle OPTIONAL,
|
OUT PHANDLE ThreadHandle OPTIONAL,
|
||||||
OUT PCLIENT_ID ClientId OPTIONAL,
|
OUT PCLIENT_ID ClientId OPTIONAL,
|
||||||
IN ULONG ParameterCount,
|
IN ULONG ParameterCount,
|
||||||
|
|
187
reactos/lib/rosrtl/thread/stack.c
Normal file
187
reactos/lib/rosrtl/thread/stack.c
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
/* $Id: stack.c,v 1.1 2003/05/29 00:36:41 hyperion Exp $
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <rosrtl/thread.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <ntdll/ntdll.h>
|
||||||
|
|
||||||
|
NTSTATUS NTAPI RtlRosCreateStack
|
||||||
|
(
|
||||||
|
IN HANDLE ProcessHandle,
|
||||||
|
OUT PUSER_STACK UserStack,
|
||||||
|
IN LONG StackZeroBits,
|
||||||
|
IN OUT PULONG StackReserve OPTIONAL,
|
||||||
|
IN OUT PULONG StackCommit OPTIONAL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/* FIXME: read the defaults from the executable image */
|
||||||
|
ULONG_PTR nStackReserve = 0x100000;
|
||||||
|
/* FIXME: when we finally have exception handling, make this PAGE_SIZE */
|
||||||
|
ULONG_PTR nStackCommit = 0x100000;
|
||||||
|
PVOID pStackLowest;
|
||||||
|
ULONG_PTR nSize = 0;
|
||||||
|
NTSTATUS nErrCode;
|
||||||
|
|
||||||
|
if(StackReserve == NULL) StackReserve = &nStackReserve;
|
||||||
|
else ROUNDUP(*StackReserve, PAGE_SIZE);
|
||||||
|
|
||||||
|
if(StackCommit == NULL) StackCommit = &nStackCommit;
|
||||||
|
else ROUNDUP(*StackCommit, PAGE_SIZE);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* the stack commit size must be equal to or less than the reserve size */
|
||||||
|
if(*StackCommit > *StackReserve) *StackCommit = *StackReserve;
|
||||||
|
#else
|
||||||
|
/* FIXME: no SEH, no guard pages */
|
||||||
|
*StackCommit = *StackReserve;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: this code assumes a stack growing downwards */
|
||||||
|
/* fixed stack */
|
||||||
|
if(*StackCommit == *StackReserve)
|
||||||
|
{
|
||||||
|
UserStack->ExpandableStackBase = NULL;
|
||||||
|
UserStack->ExpandableStackLimit = NULL;
|
||||||
|
UserStack->ExpandableStackBottom = NULL;
|
||||||
|
|
||||||
|
UserStack->FixedStackLimit = NULL;
|
||||||
|
|
||||||
|
/* allocate the stack */
|
||||||
|
nErrCode = NtAllocateVirtualMemory
|
||||||
|
(
|
||||||
|
ProcessHandle,
|
||||||
|
&(UserStack->FixedStackLimit),
|
||||||
|
StackZeroBits,
|
||||||
|
StackReserve,
|
||||||
|
MEM_RESERVE | MEM_COMMIT,
|
||||||
|
PAGE_READWRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
||||||
|
|
||||||
|
/* store the highest (first) address of the stack */
|
||||||
|
UserStack->FixedStackBase =
|
||||||
|
(PUCHAR)(UserStack->FixedStackLimit) + *StackReserve;
|
||||||
|
|
||||||
|
*StackCommit = *StackReserve;
|
||||||
|
}
|
||||||
|
/* expandable stack */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ULONG_PTR nGuardSize = PAGE_SIZE;
|
||||||
|
PVOID pGuardBase;
|
||||||
|
|
||||||
|
DPRINT("Expandable stack\n");
|
||||||
|
|
||||||
|
UserStack->FixedStackBase = NULL;
|
||||||
|
UserStack->FixedStackLimit = NULL;
|
||||||
|
|
||||||
|
UserStack->ExpandableStackBottom = NULL;
|
||||||
|
|
||||||
|
/* reserve the stack */
|
||||||
|
nErrCode = NtAllocateVirtualMemory
|
||||||
|
(
|
||||||
|
ProcessHandle,
|
||||||
|
&(UserStack->ExpandableStackBottom),
|
||||||
|
StackZeroBits,
|
||||||
|
StackReserve,
|
||||||
|
MEM_RESERVE,
|
||||||
|
PAGE_READWRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(!NT_SUCCESS(nErrCode)) goto l_Fail;
|
||||||
|
|
||||||
|
DPRINT("Reserved %08X bytes\n", *StackReserve);
|
||||||
|
|
||||||
|
/* expandable stack base - the highest address of the stack */
|
||||||
|
UserStack->ExpandableStackBase =
|
||||||
|
(PUCHAR)(UserStack->ExpandableStackBottom) + *StackReserve;
|
||||||
|
|
||||||
|
/* expandable stack limit - the lowest committed address of the stack */
|
||||||
|
UserStack->ExpandableStackLimit =
|
||||||
|
(PUCHAR)(UserStack->ExpandableStackBase) - *StackCommit;
|
||||||
|
|
||||||
|
DPRINT("Stack base %p\n", UserStack->ExpandableStackBase);
|
||||||
|
DPRINT("Stack limit %p\n", UserStack->ExpandableStackLimit);
|
||||||
|
DPRINT("Stack bottom %p\n", UserStack->ExpandableStackBottom);
|
||||||
|
|
||||||
|
/* commit as much stack as requested */
|
||||||
|
nErrCode = NtAllocateVirtualMemory
|
||||||
|
(
|
||||||
|
ProcessHandle,
|
||||||
|
&(UserStack->ExpandableStackLimit),
|
||||||
|
0,
|
||||||
|
StackCommit,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
|
||||||
|
|
||||||
|
assert((*StackReserve - *StackCommit) >= PAGE_SIZE);
|
||||||
|
assert((*StackReserve - *StackCommit) % PAGE_SIZE == 0);
|
||||||
|
|
||||||
|
pGuardBase = (PUCHAR)(UserStack->ExpandableStackLimit) - PAGE_SIZE;
|
||||||
|
|
||||||
|
DPRINT("Guard base %p\n", UserStack->ExpandableStackBase);
|
||||||
|
|
||||||
|
/* set up the guard page */
|
||||||
|
nErrCode = NtAllocateVirtualMemory
|
||||||
|
(
|
||||||
|
ProcessHandle,
|
||||||
|
&pGuardBase,
|
||||||
|
0,
|
||||||
|
&nGuardSize,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE | PAGE_GUARD
|
||||||
|
);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
|
||||||
|
|
||||||
|
DPRINT("Guard base %p\n", UserStack->ExpandableStackBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* success */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* deallocate the stack */
|
||||||
|
l_Cleanup:
|
||||||
|
RtlRosDeleteStack(ProcessHandle, UserStack);
|
||||||
|
|
||||||
|
/* failure */
|
||||||
|
l_Fail:
|
||||||
|
assert(!NT_SUCCESS(nErrCode));
|
||||||
|
return nErrCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS NTAPI RtlRosDeleteStack
|
||||||
|
(
|
||||||
|
IN HANDLE ProcessHandle,
|
||||||
|
IN PUSER_STACK UserStack
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PVOID pStackLowest = NULL;
|
||||||
|
ULONG_PTR nSize;
|
||||||
|
|
||||||
|
if(UserStack->FixedStackLimit)
|
||||||
|
pStackLowest = UserStack->FixedStackLimit;
|
||||||
|
else if(UserStack->ExpandableStackBottom)
|
||||||
|
pStackLowest = UserStack->ExpandableStackBottom;
|
||||||
|
|
||||||
|
/* free the stack, if it was allocated */
|
||||||
|
if(pStackLowest != NULL)
|
||||||
|
return NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
Loading…
Reference in a new issue