Fibers
Fibers are threadlike constructs that are scheduled within the application instead of by the scheduler. Fibers, like threads, have their own stack and execution context. The difference is that the application must manage and manually switch between a set of fibers so that each one gets the appropriate amount of time to run.An application creates a fiber by first creating a thread. The thread calls a function to turn itself into a fiber. The thread, now a single fiber, can then create multiple fibers from itself. The operating system schedules all of the fibers as a single thread, the thread that was originally converted to the first fiber. So the system allocates the time scheduled for the original thread to whichever fiber the application chooses. When the application chooses, it can stop a particular fiber and schedule another. This switch is transparent to Windows CE because all it considers is the quantum and the priority of the original thread. Fibers aren't more efficient than a well-designed multithreaded application, but they do allow applications to micromanage the scheduling of code execution within the application.To create a set of fibers, an application first creates a thread. The thread then calls ConvertThreadToFiber, which is prototyped asLPVOID WINAPI ConvertThreadToFiber (LPVOID lpParameter);
The single parameter is an application-defined value that can be retrieved by the fiber using the macro GetFiberData. The value returned is the pointer to the fiber data for this fiber. This value will be used when another fiber wants to schedule this fiber. If the return value is 0, the call failed.Upon return from the function, the thread is now a fiber. One significant restriction on converting a thread to a fiber is that the thread must use the default stack size for its stack. If the thread has a different stack size from the main thread in the process, the call to ConvertThreadToFiber will fail.Once the original thread has been converted to a fiber, it can spawn additional fibers with the following call:
LPVOID WINAPI CreateFiber (DWORD dwStackSize,
LPFIBER_START_ROUTINE lpStartAddress,
LPVOID lpParameter);
The dwStackSize parameter is ignored. The lpStartAddress parameter is the entry point of the new fiber being created. The final parameter is an application-defined value that is passed to the entry point of the new fiber. The return value from CreateFiber is the pointer to the fiber data for this new fiber. This value will be used to switch to the newly created fiber.The function prototype of the fiber entry point looks similar to the entry point of a thread. It is
VOID CALLBACK FiberProc (PVOID lpParameter);
The one parameter is the value passed from the CreateFiber call. This parameter can also be retrieved by the fiber by calling GetFiberData. Note that no return value is defined for the fiber procedure. A fiber procedure should never return. If it does, the system exits the thread that is the basis for all fibers spawned by that thread.The new fiber does not immediately start execution. Instead, the fiber calling CreateFiber must explicitly switch to the new fiber by calling
VOID WINAPI SwitchToFiber (LPVOID lpFiber);
The single parameter is the pointer to the fiber data for the fiber to be switched to. When this call is made, the calling fiber is suspended and the new fiber is enabled to run.The DeleteFiber function is used to destroy a fiber. It looks like this:
VOID WINAPI DeleteFiber (LPVOID lpFiber);
The single parameter is the pointer to the fiber data of the fiber to destroy. If a fiber calls DeleteFiber on itself, the thread is exited and all fibers associated with that thread are also terminated.
It's critical that fibers clean up after themselves. Each fiber should be deleted by another fiber in the set, and then the final fiber can delete itself and properly exit the thread. If the thread is exited without deletion of all fibers, the memory committed to support each of the undeleted fibers will not be freed, resulting in a memory leak for the application.Fibers are interesting but are they necessary? The short answer is, not really. Fibers were added to Windows CE for two reasons. First, it makes it easier to port applications from Unix style operating systems where something akin to fibers is used frequently. The second reason for adding them was a request from an internal group within Microsoft that wanted to use fibers when they ported their Windows XP application to Windows CE.I doubt either of these reasons inspires hoards of developers to start using fibers. A couple of major groups within Microsoft have decided. Fibers are not supported on the Pocket PC 2003 devices, nor are they part of the Standard SDK configuration promoted by the embedded team. Even so, if your system needs fiber support, Windows CE does provide it.