ReactOS 0.4.16-dev-197-g92996da
fiber.c File Reference
#include <k32.h>
#include <ndk/rtltypes.h>
#include <debug.h>
Include dependency graph for fiber.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID WINAPI BaseRundownFls (_In_ PVOID FlsData)
 
BOOL WINAPI ConvertFiberToThread (VOID)
 
LPVOID WINAPI ConvertThreadToFiberEx (_In_opt_ LPVOID lpParameter, _In_ DWORD dwFlags)
 
LPVOID WINAPI ConvertThreadToFiber (_In_opt_ LPVOID lpParameter)
 
LPVOID WINAPI CreateFiber (_In_ SIZE_T dwStackSize, _In_ LPFIBER_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter)
 
LPVOID WINAPI CreateFiberEx (_In_ SIZE_T dwStackCommitSize, _In_ SIZE_T dwStackReserveSize, _In_ DWORD dwFlags, _In_ LPFIBER_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter)
 
VOID WINAPI DeleteFiber (_In_ LPVOID lpFiber)
 
BOOL WINAPI IsThreadAFiber (VOID)
 
DWORD WINAPI FlsAlloc (PFLS_CALLBACK_FUNCTION lpCallback)
 
BOOL WINAPI FlsFree (DWORD dwFlsIndex)
 
PVOID WINAPI FlsGetValue (DWORD dwFlsIndex)
 
BOOL WINAPI FlsSetValue (DWORD dwFlsIndex, PVOID lpFlsData)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file fiber.c.

Function Documentation

◆ BaseRundownFls()

VOID WINAPI BaseRundownFls ( _In_ PVOID  FlsData)

Definition at line 32 of file fiber.c.

33{
34 ULONG n, FlsHighIndex;
35 PRTL_FLS_DATA pFlsData;
36 PFLS_CALLBACK_FUNCTION lpCallback;
37
38 pFlsData = FlsData;
39
41 FlsHighIndex = NtCurrentPeb()->FlsHighIndex;
42 RemoveEntryList(&pFlsData->ListEntry);
44
45 for (n = 1; n <= FlsHighIndex; ++n)
46 {
47 lpCallback = NtCurrentPeb()->FlsCallback[n];
48 if (lpCallback && pFlsData->Data[n])
49 {
50 lpCallback(pFlsData->Data[n]);
51 }
52 }
53
54 RtlFreeHeap(RtlGetProcessHeap(), 0, FlsData);
55}
#define NtCurrentPeb()
Definition: FLS.c:22
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
GLdouble n
Definition: glext.h:7729
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:84
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:74
LIST_ENTRY ListEntry
Definition: rtltypes.h:1223
PVOID Data[RTL_FLS_MAXIMUM_AVAILABLE]
Definition: rtltypes.h:1224
uint32_t ULONG
Definition: typedefs.h:59
VOID(WINAPI * PFLS_CALLBACK_FUNCTION)(PVOID)
Definition: winbase.h:1468

Referenced by DeleteFiber().

◆ ConvertFiberToThread()

BOOL WINAPI ConvertFiberToThread ( VOID  )

Definition at line 64 of file fiber.c.

65{
66 PTEB Teb;
68 DPRINT1("Converting Fiber to Thread\n");
69
70 /* Check if the thread is already not a fiber */
71 Teb = NtCurrentTeb();
72 if (!Teb->HasFiberData)
73 {
74 /* Fail */
76 return FALSE;
77 }
78
79 /* This thread won't run a fiber anymore */
80 Teb->HasFiberData = FALSE;
82 Teb->NtTib.FiberData = NULL;
83
84 /* Free the fiber */
86 RtlFreeHeap(RtlGetProcessHeap(),
87 0,
88 FiberData);
89
90 /* Success */
91 return TRUE;
92}
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
#define NtCurrentTeb
#define ASSERT(a)
Definition: mode.c:44
PVOID FiberData
Definition: compat.h:716
Definition: compat.h:836
NT_TIB NtTib
Definition: ntddk_ex.h:332
#define ERROR_ALREADY_THREAD
Definition: winerror.h:778

Referenced by init_funcs().

◆ ConvertThreadToFiber()

LPVOID WINAPI ConvertThreadToFiber ( _In_opt_ LPVOID  lpParameter)

Definition at line 162 of file fiber.c.

163{
164 /* Call the newer function */
165 return ConvertThreadToFiberEx(lpParameter,
166 0);
167}
LPVOID WINAPI ConvertThreadToFiberEx(_In_opt_ LPVOID lpParameter, _In_ DWORD dwFlags)
Definition: fiber.c:99

Referenced by Fbt_CreateFiber(), and init_funcs().

◆ ConvertThreadToFiberEx()

LPVOID WINAPI ConvertThreadToFiberEx ( _In_opt_ LPVOID  lpParameter,
_In_ DWORD  dwFlags 
)

Definition at line 99 of file fiber.c.

101{
102 PTEB Teb;
103 PFIBER Fiber;
104 DPRINT1("Converting Thread to Fiber\n");
105
106 /* Check for invalid flags */
107 if (dwFlags & ~FIBER_FLAG_FLOAT_SWITCH)
108 {
109 /* Fail */
111 return NULL;
112 }
113
114 /* Are we already a fiber? */
115 Teb = NtCurrentTeb();
116 if (Teb->HasFiberData)
117 {
118 /* Fail */
120 return NULL;
121 }
122
123 /* Allocate the fiber */
124 Fiber = RtlAllocateHeap(RtlGetProcessHeap(),
125 0,
126 sizeof(FIBER));
127 if (!Fiber)
128 {
129 /* Fail */
131 return NULL;
132 }
133
134 /* Copy some contextual data from the thread to the fiber */
135 Fiber->FiberData = lpParameter;
136 Fiber->ExceptionList = Teb->NtTib.ExceptionList;
137 Fiber->StackBase = Teb->NtTib.StackBase;
138 Fiber->StackLimit = Teb->NtTib.StackLimit;
140 Fiber->FlsData = Teb->FlsData;
143
144 /* Save FPU State if requested, otherwise just the basic registers */
145 Fiber->FiberContext.ContextFlags = (dwFlags & FIBER_FLAG_FLOAT_SWITCH) ?
148
149 /* Associate the fiber to the current thread */
150 Teb->NtTib.FiberData = Fiber;
151 Teb->HasFiberData = TRUE;
152
153 /* Return opaque fiber data */
154 return (LPVOID)Fiber;
155}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1372
#define CONTEXT_FULL
Definition: nt_native.h:1375
ULONG ContextFlags
Definition: nt_native.h:1426
PVOID StackLimit
Definition: ketypes.h:151
CONTEXT FiberContext
Definition: ketypes.h:153
PVOID DeallocationStack
Definition: ketypes.h:152
ULONG GuaranteedStackBytes
Definition: ketypes.h:158
PVOID StackBase
Definition: ketypes.h:150
struct _ACTIVATION_CONTEXT_STACK * ActivationContextStackPointer
Definition: ketypes.h:156
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: ketypes.h:149
PVOID FiberData
Definition: ketypes.h:148
PVOID FlsData
Definition: ketypes.h:157
PVOID StackLimit
Definition: compat.h:713
PVOID StackBase
Definition: compat.h:712
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711
PVOID ActivationContextStackPointer
Definition: compat.h:854
ULONG GuaranteedStackBytes
Definition: winternl.h:279
PVOID DeallocationStack
Definition: compat.h:878
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define ERROR_ALREADY_FIBER
Definition: winerror.h:777

Referenced by ConvertThreadToFiber(), and init_funcs().

◆ CreateFiber()

LPVOID WINAPI CreateFiber ( _In_ SIZE_T  dwStackSize,
_In_ LPFIBER_START_ROUTINE  lpStartAddress,
_In_opt_ LPVOID  lpParameter 
)

Definition at line 174 of file fiber.c.

177{
178 /* Call the Newer Function */
179 return CreateFiberEx(dwStackSize,
180 0,
181 0,
182 lpStartAddress,
183 lpParameter);
184}
LPVOID WINAPI CreateFiberEx(_In_ SIZE_T dwStackCommitSize, _In_ SIZE_T dwStackReserveSize, _In_ DWORD dwFlags, _In_ LPFIBER_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter)
Definition: fiber.c:191

Referenced by Fbt_CreateFiber(), and init_funcs().

◆ CreateFiberEx()

LPVOID WINAPI CreateFiberEx ( _In_ SIZE_T  dwStackCommitSize,
_In_ SIZE_T  dwStackReserveSize,
_In_ DWORD  dwFlags,
_In_ LPFIBER_START_ROUTINE  lpStartAddress,
_In_opt_ LPVOID  lpParameter 
)

Definition at line 191 of file fiber.c.

196{
197 PFIBER Fiber;
199 INITIAL_TEB InitialTeb;
200 PACTIVATION_CONTEXT_STACK ActivationContextStackPointer;
201 DPRINT("Creating Fiber\n");
202
203 /* Check for invalid flags */
204 if (dwFlags & ~FIBER_FLAG_FLOAT_SWITCH)
205 {
206 /* Fail */
208 return NULL;
209 }
210
211 /* Allocate the Activation Context Stack */
212 ActivationContextStackPointer = NULL;
213 Status = RtlAllocateActivationContextStack(&ActivationContextStackPointer);
214 if (!NT_SUCCESS(Status))
215 {
216 /* Fail */
218 return NULL;
219 }
220
221 /* Allocate the fiber */
222 Fiber = RtlAllocateHeap(RtlGetProcessHeap(),
223 0,
224 sizeof(FIBER));
225 if (!Fiber)
226 {
227 /* Free the activation context stack */
228 RtlFreeActivationContextStack(ActivationContextStackPointer);
229
230 /* Fail */
232 return NULL;
233 }
234
235 /* Create the stack for the fiber */
237 dwStackCommitSize,
238 dwStackReserveSize,
239 &InitialTeb);
240 if (!NT_SUCCESS(Status))
241 {
242 /* Free the fiber */
244 0,
245 Fiber);
246
247 /* Free the activation context stack */
248 RtlFreeActivationContextStack(ActivationContextStackPointer);
249
250 /* Failure */
252 return NULL;
253 }
254
255 /* Clear the context */
257 sizeof(CONTEXT));
258
259 /* Copy the data into the fiber */
260 Fiber->StackBase = InitialTeb.StackBase;
261 Fiber->StackLimit = InitialTeb.StackLimit;
262 Fiber->DeallocationStack = InitialTeb.AllocatedStackBase;
263 Fiber->FiberData = lpParameter;
265 Fiber->GuaranteedStackBytes = 0;
266 Fiber->FlsData = NULL;
267 Fiber->ActivationContextStackPointer = ActivationContextStackPointer;
268
269 /* Save FPU State if requested, otherwise just the basic registers */
270 Fiber->FiberContext.ContextFlags = (dwFlags & FIBER_FLAG_FLOAT_SWITCH) ?
273
274 /* Initialize the context for the fiber */
276 lpParameter,
277 lpStartAddress,
278 InitialTeb.StackBase,
279 2);
280
281 /* Return the Fiber */
282 return Fiber;
283}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define GetProcessHeap()
Definition: compat.h:736
NTSTATUS WINAPI BaseCreateStack(_In_ HANDLE hProcess, _In_opt_ SIZE_T StackCommit, _In_opt_ SIZE_T StackReserve, _Out_ PINITIAL_TEB InitialTeb)
Definition: utils.c:354
VOID WINAPI BaseInitializeContext(IN PCONTEXT Context, IN PVOID Parameter, IN PVOID StartAddress, IN PVOID StackAddress, IN ULONG ContextType)
Definition: utils.c:513
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
#define NtCurrentProcess()
Definition: nt_native.h:1657
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define DPRINT
Definition: sndvol32.h:73
PVOID StackBase
Definition: pstypes.h:695
PVOID AllocatedStackBase
Definition: pstypes.h:697
PVOID StackLimit
Definition: pstypes.h:696
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by CreateFiber(), and init_funcs().

◆ DeleteFiber()

VOID WINAPI DeleteFiber ( _In_ LPVOID  lpFiber)

Definition at line 290 of file fiber.c.

291{
292 SIZE_T Size;
293 PFIBER Fiber;
294 PTEB Teb;
295
296 /* Are we deleting ourselves? */
297 Teb = NtCurrentTeb();
298 Fiber = (PFIBER)lpFiber;
299 if ((Teb->HasFiberData) &&
300 (Teb->NtTib.FiberData == Fiber))
301 {
302 /* Just exit */
303 ExitThread(1);
304 }
305
306 /* Not ourselves, de-allocate the stack */
307 Size = 0 ;
309 &Fiber->DeallocationStack,
310 &Size,
312
313 /* Get rid of FLS */
314 if (Fiber->FlsData) BaseRundownFls(Fiber->FlsData);
315
316 /* Get rid of the activation context stack */
317 RtlFreeActivationContextStack(Fiber->ActivationContextStackPointer);
318
319 /* Free the fiber data */
320 RtlFreeHeap(RtlGetProcessHeap(),
321 0,
322 lpFiber);
323}
VOID WINAPI BaseRundownFls(_In_ PVOID FlsData)
Definition: fiber.c:32
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
struct _FIBER * PFIBER
#define MEM_RELEASE
Definition: nt_native.h:1316
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5230
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by Fbt_AfterSwitch(), Fbt_Dispatch(), and init_funcs().

◆ FlsAlloc()

DWORD WINAPI FlsAlloc ( PFLS_CALLBACK_FUNCTION  lpCallback)

Definition at line 341 of file fiber.c.

342{
343 DWORD dwFlsIndex;
345 PRTL_FLS_DATA pFlsData;
346
348
349 pFlsData = NtCurrentTeb()->FlsData;
350
351 if (!Peb->FlsCallback &&
352 !(Peb->FlsCallback = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
353 FLS_MAXIMUM_AVAILABLE * sizeof(PVOID))))
354 {
356 dwFlsIndex = FLS_OUT_OF_INDEXES;
357 }
358 else
359 {
360 dwFlsIndex = RtlFindClearBitsAndSet(Peb->FlsBitmap, 1, 1);
361 if (dwFlsIndex != FLS_OUT_OF_INDEXES)
362 {
363 if (!pFlsData &&
364 !(pFlsData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RTL_FLS_DATA))))
365 {
366 RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
367 dwFlsIndex = FLS_OUT_OF_INDEXES;
369 }
370 else
371 {
372 if (!NtCurrentTeb()->FlsData)
373 {
374 NtCurrentTeb()->FlsData = pFlsData;
376 }
377
378 pFlsData->Data[dwFlsIndex] = NULL; /* clear the value */
379 Peb->FlsCallback[dwFlsIndex] = lpCallback;
380
381 if (dwFlsIndex > Peb->FlsHighIndex)
382 Peb->FlsHighIndex = dwFlsIndex;
383 }
384 }
385 else
386 {
388 }
389 }
391 return dwFlsIndex;
392}
#define RtlClearBits
Definition: dbgbitmap.h:331
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
PPEB Peb
Definition: dllmain.c:27
#define InsertTailList(ListHead, Entry)
unsigned long DWORD
Definition: ntddk_ex.h:95
PVOID * FlsCallback
Definition: winternl.h:359
LIST_ENTRY FlsListHead
Definition: winternl.h:360
PRTL_BITMAP FlsBitmap
Definition: winternl.h:361
#define FLS_OUT_OF_INDEXES
Definition: winbase.h:601
#define FLS_MAXIMUM_AVAILABLE
Definition: winnt_old.h:1070

Referenced by init_funcs().

◆ FlsFree()

BOOL WINAPI FlsFree ( DWORD  dwFlsIndex)

Definition at line 400 of file fiber.c.

401{
402 BOOL ret;
404
405 if (dwFlsIndex >= FLS_MAXIMUM_AVAILABLE)
406 {
408 return FALSE;
409 }
410
412
414 {
415 ret = RtlAreBitsSet(Peb->FlsBitmap, dwFlsIndex, 1);
416 if (ret)
417 {
419 PFLS_CALLBACK_FUNCTION lpCallback;
420
421 RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
422 lpCallback = Peb->FlsCallback[dwFlsIndex];
423
424 for (Entry = Peb->FlsListHead.Flink; Entry != &Peb->FlsListHead; Entry = Entry->Flink)
425 {
426 PRTL_FLS_DATA pFlsData;
427
428 pFlsData = CONTAINING_RECORD(Entry, RTL_FLS_DATA, ListEntry);
429 if (pFlsData->Data[dwFlsIndex])
430 {
431 if (lpCallback)
432 {
433 lpCallback(pFlsData->Data[dwFlsIndex]);
434 }
435 pFlsData->Data[dwFlsIndex] = NULL;
436 }
437 }
438 Peb->FlsCallback[dwFlsIndex] = NULL;
439 }
440 else
441 {
443 }
444 }
446 {
448 }
449 _SEH2_END;
450
451 return ret;
452}
#define RtlAreBitsSet
Definition: dbgbitmap.h:328
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
int ret

Referenced by init_funcs().

◆ FlsGetValue()

PVOID WINAPI FlsGetValue ( DWORD  dwFlsIndex)

Definition at line 460 of file fiber.c.

461{
462 PRTL_FLS_DATA pFlsData;
463
464 pFlsData = NtCurrentTeb()->FlsData;
465 if (!dwFlsIndex || dwFlsIndex >= FLS_MAXIMUM_AVAILABLE || !pFlsData)
466 {
468 return NULL;
469 }
470
472 return pFlsData->Data[dwFlsIndex];
473}
#define ERROR_SUCCESS
Definition: deptool.c:10

Referenced by init_funcs().

◆ FlsSetValue()

BOOL WINAPI FlsSetValue ( DWORD  dwFlsIndex,
PVOID  lpFlsData 
)

Definition at line 481 of file fiber.c.

483{
484 PRTL_FLS_DATA pFlsData;
485
486 if (!dwFlsIndex || dwFlsIndex >= FLS_MAXIMUM_AVAILABLE)
487 {
489 return FALSE;
490 }
491
492 pFlsData = NtCurrentTeb()->FlsData;
493
494 if (!NtCurrentTeb()->FlsData &&
495 !(NtCurrentTeb()->FlsData = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
496 sizeof(RTL_FLS_DATA))))
497 {
499 return FALSE;
500 }
501 if (!pFlsData)
502 {
503 pFlsData = NtCurrentTeb()->FlsData;
505 InsertTailList(&NtCurrentPeb()->FlsListHead, &pFlsData->ListEntry);
507 }
508 pFlsData->Data[dwFlsIndex] = lpFlsData;
509 return TRUE;
510}

Referenced by init_funcs().

◆ IsThreadAFiber()

BOOL WINAPI IsThreadAFiber ( VOID  )

Definition at line 330 of file fiber.c.

331{
332 /* Return flag in the TEB */
333 return NtCurrentTeb()->HasFiberData;
334}

Referenced by init_funcs().