00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #pragma once
00031 #ifndef __CSGLOBAL_H__
00032 #define __CSGLOBAL_H__
00033
00034 #include "CSDefs.h"
00035 #include "CSObject.h"
00036 #include "CSThread.h"
00037
00038
00039
00040 #define CS_CONTEXT __FUNC__, __FILE__, __LINE__
00041
00042 #ifdef DEBUG
00043 int cs_assert(const char *func, const char *file, int line, const char *message);
00044 int cs_hope(const char *func, const char *file, int line, const char *message);
00045
00046 #define ASSERT(x) ((x) ? 1 : cs_assert(CS_CONTEXT, #x))
00047 #define HOPE(x) ((x) ? 1 : cs_hope(CS_CONTEXT, #x))
00048 #else
00049 #define ASSERT(x)
00050 #define ASSERT(x)
00051 #endif
00052
00053 #ifdef DEBUG
00054 #define retain() retain(__FUNC__, __FILE__, __LINE__)
00055 #define release() release(__FUNC__, __FILE__, __LINE__)
00056 #endif
00057
00058 #define new_(v, t) do { v = new t; if (!v) CSException::throwOSError(CS_CONTEXT, ENOMEM); } while (0)
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #ifdef DEBUG
00073 #define STACK_CHECK CSReleasePtr self_reltop = self->relTop
00074 #else
00075 #define STACK_CHECK
00076 #endif
00077
00078 #define inner_() int cs_frame = self->callTop++; \
00079 STACK_CHECK ; \
00080 do { \
00081 if (cs_frame< CS_CALL_STACK_SIZE) { \
00082 self->callStack[cs_frame].cs_func = __FUNC__; \
00083 self->callStack[cs_frame].cs_file = __FILE__; \
00084 self->callStack[cs_frame].cs_line = __LINE__; \
00085 } \
00086 } while (0)
00087
00088 #define outer_() self->callTop = cs_frame; \
00089 ASSERT(self->relTop == self_reltop);
00090
00091 #define enter_() CSThread *self = CSThread::getSelf(); \
00092 inner_()
00093
00094
00095
00096
00097
00098 #define exit_() do { \
00099 outer_(); \
00100 return; \
00101 } while (0)
00102
00103
00104 #define return_(x) do { \
00105 outer_(); \
00106 return(x); \
00107 } while (0)
00108
00109
00110
00111
00112
00113
00114
00115 int prof_setjmp(void);
00116
00117 #define TX_CHK_JMP() if ((self)->jumpDepth < 0 || (self)->jumpDepth >= CS_JUMP_STACK_SIZE) CSException::throwCoreError(__FUNC__, __FILE__, __LINE__, CS_ERR_JUMP_OVERFLOW)
00118 #ifdef PROFILE
00119 #define profile_setjmp prof_setjmp()
00120 #else
00121 #define profile_setjmp
00122 #endif
00123
00124 #define throw_() (self)->throwException()
00125 #define try_(n) int throw_##n; throw_##n = 0; TX_CHK_JMP(); \
00126 (self)->jumpEnv[(self)->jumpDepth].jb_res_top = (self)->relTop; \
00127 (self)->jumpEnv[(self)->jumpDepth].jb_call_top = (self)->callTop; \
00128 (self)->jumpDepth++; profile_setjmp; \
00129 if (setjmp((self)->jumpEnv[(self)->jumpDepth-1].jb_buffer)) goto catch_##n;
00130 #define catch_(n) (self)->jumpDepth--; goto cont_##n; catch_##n: (self)->jumpDepth--; self->caught();
00131 #define cont_(n) if (throw_##n) throw_(); cont_##n:
00132 #define finally_(n) (self)->jumpDepth--; goto final_##n; catch_##n: throw_##n = 1; (self)->jumpDepth--; self->caught(); final_##n: {
00133 #define finally_end_block(n) } if (throw_##n) throw_();
00134 #define finally_end_block_no_throw(n) }
00135
00136
00137
00138
00139
00140
00141 #define push_(r) do { \
00142 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00143 CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00144 } \
00145 (self)->relTop->r_type = CS_RELEASE_OBJECT; \
00146 (self)->relTop->x.r_object = (r); \
00147 (self)->relTop++; \
00148 } while (0)
00149
00150 #define push_ptr_(r) do { \
00151 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00152 CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00153 } \
00154 (self)->relTop->r_type = CS_RELEASE_MEM; \
00155 (self)->relTop->x.r_mem = (r); \
00156 (self)->relTop++; \
00157 } while (0)
00158
00159 #define push_ref_(r) do { \
00160 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00161 CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00162 } \
00163 (self)->relTop->r_type = CS_RELEASE_OBJECT_PTR; \
00164 (self)->relTop->x.r_objectPtr = (CSObject **)&(r); \
00165 (self)->relTop++; \
00166 } while (0)
00167
00168 #define pop_(r) do { \
00169 ASSERT((self)->relTop > (self)->relStack); \
00170 if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
00171 ASSERT(((self)->relTop - 1)->x.r_object == ((CSObject *) r)); \
00172 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX) {\
00173 ASSERT(((self)->relTop - 1)->x.r_mutex == ((CSMutex *) r)); \
00174 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_POOLED) {\
00175 ASSERT(((self)->relTop - 1)->x.r_pooled == ((CSPooled *) r)); \
00176 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
00177 ASSERT(((self)->relTop - 1)->x.r_mem == ((void *) r)); \
00178 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
00179 ASSERT(((self)->relTop - 1)->x.r_objectPtr == ((CSObject **) &(r))); \
00180 } else {\
00181 ASSERT(false); \
00182 } \
00183 (self)->relTop--; \
00184 } while (0)
00185
00186 #define retain_(r) do { \
00187 (r)->retain(); \
00188 push_(r); \
00189 } while (0)
00190
00191 #define release_(r) do { \
00192 ASSERT((self)->relTop > (self)->relStack); \
00193 if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
00194 register CSObject *rp; \
00195 rp = ((self)->relTop - 1)->x.r_object; \
00196 ASSERT(rp == (CSObject *)(r)); \
00197 (self)->relTop--; \
00198 rp->release(); \
00199 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
00200 register void *mem; \
00201 mem = ((self)->relTop - 1)->x.r_mem; \
00202 ASSERT(mem == (void *)(r)); \
00203 (self)->relTop--; \
00204 cs_free(mem); \
00205 } else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
00206 register CSObject **rp; \
00207 rp = ((self)->relTop - 1)->x.r_objectPtr; \
00208 ASSERT(rp == (CSObject **)&(r)); \
00209 (self)->relTop--; \
00210 if(*rp) (*rp)->release(); \
00211 } else {\
00212 ASSERT(false); \
00213 } \
00214 } while (0)
00215
00216 #define lock_(r) do { \
00217 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00218 CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00219 } \
00220 (r)->lock(); \
00221 (self)->relTop->r_type = CS_RELEASE_MUTEX; \
00222 (self)->relTop->x.r_mutex = (r); \
00223 (self)->relTop++; \
00224 } while (0)
00225
00226 #define locked_(r) do { \
00227 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) \
00228 CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00229 (self)->relTop->r_type = CS_RELEASE_MUTEX; \
00230 (self)->relTop->x.r_mutex = (r); \
00231 (self)->relTop++; \
00232 } while (0)
00233
00234 #define unlock_(r) do { \
00235 register CSMutex *rp; \
00236 ASSERT((self)->relTop > (self)->relStack); \
00237 ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX); \
00238 rp = ((self)->relTop - 1)->x.r_mutex; \
00239 ASSERT(rp == (r)); \
00240 (self)->relTop--; \
00241 rp->unlock(); \
00242 } while (0)
00243
00244 #define frompool_(r) do { \
00245 if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
00246 CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
00247 } \
00248 (self)->relTop->r_type = CS_RELEASE_POOLED; \
00249 (self)->relTop->x.r_pooled = (r); \
00250 (self)->relTop++; \
00251 } while (0)
00252
00253 #define backtopool_(r) do { \
00254 register CSPooled *rp; \
00255 ASSERT((self)->relTop > (self)->relStack); \
00256 ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_POOLED); \
00257 rp = ((self)->relTop - 1)->x.r_pooled; \
00258 ASSERT(rp == (r)); \
00259 (self)->relTop--; \
00260 rp->returnToPool(); \
00261 } while (0)
00262
00263 #endif