// Fiber test by Gynvael Coldwind of Vexillium // http://gynvael.coldwind.pl // http://vexillium.org // mailto: gynvael@vexillium.org // // Note: // This code was created for educational purposes, so don't expect // fireworks. // // License (BSD): // Copyright (c) 2008, Gynvael Coldwind of Vexillium // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of the Gynvael Coldwind nor Vexillium nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY Gynvael Coldwind ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL Gynvael Coldwind BE LIABLE FOR ANY // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include // Some constants #define FIBER_COUNT 4 // Some variables LPVOID FiberScheduler; LPVOID Fibers[FIBER_COUNT]; int FiberDone[FIBER_COUNT]; // Fiber Scheduler void __stdcall MyScheduler(void *Param) { int i; int CurrentFiber = -1; puts("S: start"); while(1) { int DoneCount = 0; puts("S: schedule loop begining"); // Check if all done for(i = 0; i < FIBER_COUNT; i++) DoneCount += FiberDone[i]; if(DoneCount == FIBER_COUNT) break; // Switch to next av. fiber // There has to be at least one do { CurrentFiber++; if(CurrentFiber == FIBER_COUNT) CurrentFiber = 0; } while(FiberDone[CurrentFiber]); // Switch to it printf("S: schedule loop switching to fiber %i\n", CurrentFiber); SwitchToFiber(Fibers[CurrentFiber]); printf("S: schedule loop back from fiber %i\n", CurrentFiber); } puts("S: done"); } // Fiber Worker void __stdcall MyFiber(void* Param) { int i; int FiberNr = (int)Param; printf("%i: start\n", FiberNr); for(i = 0; i < 2; i++) { printf("%i: in loop %i, before switch\n", FiberNr, i); SwitchToFiber(FiberScheduler); printf("%i: in loop %i, back from switch\n", FiberNr, i); } printf("%i: done\n", FiberNr); fflush(stdout); FiberDone[FiberNr] = 1; SwitchToFiber(FiberScheduler); } // Main function int main(void) { // Create fibers int i; puts("M: creating scheduler fiber"); FiberScheduler = CreateFiber(0, MyScheduler, NULL); puts("M: creating work fibers"); for(i = 0; i < FIBER_COUNT; i++) Fibers[i] = CreateFiber(0, MyFiber, (void*)i); // Convert to fiber and launch scheduler puts("M: converting to fiber and switching to scheduler"); ConvertThreadToFiber(NULL); SwitchToFiber(FiberScheduler); puts("M: done (the execution should never reach here)"); return 0; }