00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CCOR_H
00021 #define __CCOR_H
00022
00023 #include "cobject.h"
00024
00025
00026
00027
00028
00029 #if !defined(__BORLANDC__) || defined(__FLAT__) || defined(__DPMI16__)
00030 # define PORTABLE_COROUTINES
00031 #endif
00032
00033
00034 #if defined(_AIX)
00035 typedef struct {char regblk[240];} my_jmp_buf[1];
00036 extern "C" {
00037 int my_setjmp(my_jmp_buf b);
00038 void my_longjmp(my_jmp_buf b, int retv);
00039 };
00040 #define JMP_BUF my_jmp_buf
00041 #define SETJMP my_setjmp
00042 #define LONGJMP my_longjmp
00043 #else
00044 #include <setjmp.h>
00045 #define JMP_BUF jmp_buf
00046 #define SETJMP setjmp
00047 #define LONGJMP longjmp
00048 #endif
00049
00050
00051 #define SAFETY_AREA 512
00052 #define MIN_STACKSIZE 1024
00053
00054
00060 typedef void (*CoroutineFnp)( void * );
00061
00062
00063 #ifdef PORTABLE_COROUTINES
00064
00065 struct _Task;
00066
00067 #else
00068
00069 extern "C"
00070 {
00071 void set_sp_reg(int *sp);
00072 int *get_sp_reg();
00073 };
00074
00075 #endif
00076
00077
00078
00094 class SIM_API cCoroutine
00095 {
00096 private:
00097 #ifdef PORTABLE_COROUTINES
00098 _Task *task;
00099 bool started;
00100 #else
00101 CoroutineFnp fnp;
00102 void *arg;
00103 int stack_size;
00104 int *stack;
00105 int *stkbeg;
00106 int *stklow;
00107 int *sp;
00108 JMP_BUF jmpbuf;
00109 bool started;
00110 #endif
00111
00112 public:
00117 static void init( unsigned total_stack, unsigned main_stack);
00118
00124 static void switchTo( cCoroutine *cor );
00125
00129 static void switchtoMain();
00130
00134 cCoroutine();
00135
00139 ~cCoroutine();
00140
00144 cCoroutine& operator=(const cCoroutine& cor);
00145
00151 bool setup( CoroutineFnp fnp, void *arg, unsigned stack_size );
00152
00156 void destroy();
00157
00161 void restart();
00162
00173 bool stackOverflow() const;
00174
00179 unsigned stackSize() const;
00180
00186 unsigned stackUsage() const;
00187
00191 int stackLeft() const;
00192
00196 bool stackLow() const;
00197
00201 static int *getMainSP();
00202 };
00203
00204 #ifdef PORTABLE_COROUTINES
00205 inline int cCoroutine::stackLeft() const {return 0;}
00206 inline bool cCoroutine::stackLow() const {return false;}
00207
00208 #else
00209 inline int cCoroutine::stackLeft() const {return (char *)sp - (char *)stkbeg;}
00210 inline bool cCoroutine::stackLow() const {return sp<stklow;}
00211
00212 #endif
00213
00214 #endif
00215