ccoroutine.h
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #ifndef __CCOROUTINE_H
00020 #define __CCOROUTINE_H
00021 
00022 #include "simkerneldefs.h"
00023 #include "platdep/platmisc.h"  
00024 
00025 
00026 #ifdef _WIN32
00027 #  define USE_WIN32_FIBERS
00028 #else
00029 #  ifdef HAVE_SWAPCONTEXT
00030 #    define USE_POSIX_COROUTINES
00031 #  else
00032 #    define USE_PORTABLE_COROUTINES
00033 #  endif
00034 #endif
00035 
00036 #ifdef USE_POSIX_COROUTINES
00037 #include <ucontext.h>
00038 #endif
00039 
00040 
00041 NAMESPACE_BEGIN
00042 
00043 #ifdef USE_PORTABLE_COROUTINES
00044 struct _Task;
00045 #endif
00046 
00052 typedef void (*CoroutineFnp)( void * );
00053 
00054 
00055 
00077 class SIM_API cCoroutine
00078 {
00079   protected:
00080 #ifdef USE_WIN32_FIBERS
00081     LPVOID lpFiber;
00082     static LPVOID lpMainFiber;
00083     unsigned stackSize;
00084 #endif
00085 #ifdef USE_POSIX_COROUTINES
00086     static ucontext_t mainContext;
00087     static ucontext_t *curContextPtr;
00088     static unsigned totalStackLimit;
00089     static unsigned totalStackUsage;
00090     unsigned stackSize;
00091     char *stackPtr;
00092     ucontext_t context;
00093 #endif
00094 #ifdef USE_PORTABLE_COROUTINES
00095     _Task *task;
00096 #endif
00097 
00098   public:
00101 
00106     static void init(unsigned total_stack, unsigned main_stack);
00107 
00113     static void switchTo(cCoroutine *cor);
00114 
00118     static void switchToMain();
00120 
00123 
00129     bool setup(CoroutineFnp fnp, void *arg, unsigned stack_size);
00130 
00134     cCoroutine();
00135 
00139     virtual ~cCoroutine();
00141 
00144 
00159     virtual bool hasStackOverflow() const;
00160 
00164     virtual unsigned getStackSize() const;
00165 
00174     virtual unsigned getStackUsage() const;
00176 };
00177 
00178 NAMESPACE_END
00179 
00180 
00181 #endif
00182 
00183