-/* $Id: fiber.c,v 1.5 2003/05/29 00:36:41 hyperion Exp $
+/* $Id: fiber.c,v 1.13 2004/11/05 12:26:36 ekohl Exp $
*
* FILE: lib/kernel32/thread/fiber.c
*
#include <k32.h>
#define NDEBUG
-#include <kernel32/kernel32.h>
+#include "../include/debug.h"
struct _FIBER /* Field offsets: */
{ /* 32 bit 64 bit */
__declspec(noreturn) void WINAPI FiberStartup(PVOID lpStartAddress);
+/*
+ * @implemented
+ */
BOOL WINAPI ConvertFiberToThread(void)
{
PTEB pTeb = NtCurrentTeb();
pTeb->IsFiber = FALSE;
/* free the fiber */
- if(pTeb->Tib.Fib.FiberData != NULL)
- RtlFreeHeap(pTeb->Peb->ProcessHeap, 0, pTeb->Tib.Fib.FiberData);
+ if(pTeb->Tib.FiberData != NULL)
+ RtlFreeHeap(pTeb->Peb->ProcessHeap, 0, pTeb->Tib.FiberData);
/* success */
+ return TRUE;
}
-LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter)
-{
- return ConvertThreadToFiberEx(lpParameter, 0);
-}
+/*
+ * @implemented
+ */
LPVOID WINAPI ConvertThreadToFiberEx(LPVOID lpParameter, DWORD dwFlags)
{
PTEB pTeb = NtCurrentTeb();
PFIBER pfCurFiber;
/* the current thread is already a fiber */
- if(pTeb->IsFiber && pTeb->Tib.Fib.FiberData) return pTeb->Tib.Fib.FiberData;
+ if(pTeb->IsFiber && pTeb->Tib.FiberData) return pTeb->Tib.FiberData;
/* allocate the fiber */
pfCurFiber = (PFIBER)RtlAllocateHeap(pTeb->Peb->ProcessHeap, 0, sizeof(FIBER));
pfCurFiber->DeallocationStack = pTeb->DeallocationStack;
/* associate the fiber to the current thread */
- pTeb->Tib.Fib.FiberData = pfCurFiber;
+ pTeb->Tib.FiberData = pfCurFiber;
pTeb->IsFiber = TRUE;
/* success */
return (LPVOID)pfCurFiber;
}
+
+/*
+ * @implemented
+ */
+LPVOID WINAPI ConvertThreadToFiber(LPVOID lpParameter)
+{
+ return ConvertThreadToFiberEx(lpParameter, 0);
+}
+
+
+/*
+ * @implemented
+ */
LPVOID WINAPI CreateFiber
(
SIZE_T dwStackSize,
return CreateFiberEx(dwStackSize, 0, 0, lpStartAddress, lpParameter);
}
+
+/*
+ * @implemented
+ */
LPVOID WINAPI CreateFiberEx
(
SIZE_T dwStackCommitSize,
NTSTATUS nErrCode;
PSIZE_T pnStackReserve = NULL;
PSIZE_T pnStackCommit = NULL;
- USER_STACK usFiberStack;
+ INITIAL_TEB usFiberInitialTeb;
CONTEXT ctxFiberContext;
- PCHAR pStackBase;
- PCHAR pStackLimit;
PTEB pTeb = NtCurrentTeb();
/* allocate the fiber */
nErrCode = RtlRosCreateStack
(
NtCurrentProcess(),
- &usFiberStack,
+ &usFiberInitialTeb,
0,
pnStackReserve,
pnStackCommit
if(!NT_SUCCESS(nErrCode)) goto l_CleanupFiber;
/* initialize the context for the fiber */
- nErrCode = RtlRosInitializeContextEx
+ nErrCode = RtlRosInitializeContext
(
NtCurrentProcess(),
&ctxFiberContext,
FiberStartup,
- &usFiberStack,
+ &usFiberInitialTeb,
1,
(ULONG_PTR *)&lpStartAddress
);
/* copy the data into the fiber */
/* fixed-size stack */
- if(usFiberStack.FixedStackBase && usFiberStack.FixedStackLimit)
+ if(usFiberInitialTeb.StackBase && usFiberInitialTeb.StackLimit)
{
- pfCurFiber->StackBase = usFiberStack.FixedStackBase;
- pfCurFiber->StackLimit = usFiberStack.FixedStackLimit;
- pfCurFiber->DeallocationStack = usFiberStack.FixedStackLimit;
+ pfCurFiber->StackBase = usFiberInitialTeb.StackBase;
+ pfCurFiber->StackLimit = usFiberInitialTeb.StackLimit;
+ pfCurFiber->DeallocationStack = usFiberInitialTeb.StackLimit;
}
/* expandable stack */
else if
(
- usFiberStack.ExpandableStackBase &&
- usFiberStack.ExpandableStackLimit &&
- usFiberStack.ExpandableStackBottom
+ usFiberInitialTeb.StackCommit &&
+ usFiberInitialTeb.StackCommitMax &&
+ usFiberInitialTeb.StackReserved
)
{
- pfCurFiber->StackBase = usFiberStack.ExpandableStackBase;
- pfCurFiber->StackLimit = usFiberStack.ExpandableStackLimit;
- pfCurFiber->DeallocationStack = usFiberStack.ExpandableStackBottom;
+ pfCurFiber->StackBase = usFiberInitialTeb.StackCommit;
+ pfCurFiber->StackLimit = usFiberInitialTeb.StackCommitMax;
+ pfCurFiber->DeallocationStack = usFiberInitialTeb.StackReserved;
}
/* bad initial stack */
else goto l_CleanupStack;
l_CleanupStack:
/* free the stack */
- RtlRosDeleteStack(NtCurrentProcess(), &usFiberStack);
+ RtlRosDeleteStack(NtCurrentProcess(), &usFiberInitialTeb);
l_CleanupFiber:
/* free the fiber */
RtlFreeHeap(pTeb->Peb->ProcessHeap, 0, pfCurFiber);
/* failure */
- assert(!NT_SUCCESS(nErrCode));
+ ASSERT(!NT_SUCCESS(nErrCode));
SetLastErrorByStatus(nErrCode);
return NULL;
}
+
+/*
+ * @implemented
+ */
void WINAPI DeleteFiber(LPVOID lpFiber)
{
SIZE_T nSize = 0;
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);
+ if(pTeb->Tib.FiberData == lpFiber) ExitThread(1);
/* deallocate the stack */
NtFreeVirtualMemory
);
}
+
__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);
+ ThreadStartup(lpStartAddress, GetFiberData());
}
/* EOF */