~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSGlobal.h

Possible solution to longjump clobber problem.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 *
15
15
 * You should have received a copy of the GNU General Public License
16
16
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
18
 *
19
19
 * Original author: Paul McCullagh (H&G2JCtL)
20
20
 * Continued development: Barry Leslie
31
31
#define __CSGLOBAL_H__
32
32
 
33
33
#include "CSDefs.h"
34
 
#include "CSObject.h"
35
34
#include "CSThread.h"
36
35
 
 
36
/* Those compilers that support the function
 
37
 * macro (in particular the "pretty" function
 
38
 * macro must be defined here.
 
39
 */
 
40
#ifdef __MWERKS__
 
41
#define __FUNC__                        __PRETTY_FUNCTION__
 
42
#else
 
43
#define __FUNC__                        __FUNCTION__
 
44
#endif
37
45
 
38
46
/* This is the call context: */
39
47
#define CS_CONTEXT                      __FUNC__, __FILE__, __LINE__
49
57
#define ASSERT(x)
50
58
#endif
51
59
 
52
 
#ifdef DEBUG
53
 
#define retain()                        retain(__FUNC__, __FILE__, __LINE__)
54
 
#define release()                       release(__FUNC__, __FILE__, __LINE__)
55
 
#endif
56
 
 
57
60
#define new_(v, t)                      do { v = new t; if (!v) CSException::throwOSError(CS_CONTEXT, ENOMEM); } while (0)
58
61
 
59
62
/*
68
71
 *
69
72
 * It also sets up the current thread pointer 'self'.
70
73
 */
71
 
#ifdef DEBUG
72
 
#define STACK_CHECK    CSReleasePtr self_reltop = self->relTop
73
 
#else
74
 
#define STACK_CHECK   
75
 
#endif
76
 
 
77
74
#define inner_()                        int                     cs_frame = self->callTop++; \
78
 
                                                        STACK_CHECK ; \
79
75
                                                        do { \
80
76
                                                                if (cs_frame< CS_CALL_STACK_SIZE) { \
81
77
                                                                        self->callStack[cs_frame].cs_func = __FUNC__; \
84
80
                                                                } \
85
81
                                                        } while (0)
86
82
 
87
 
#define outer_()                        self->callTop = cs_frame; \
88
 
                                                        ASSERT(self->relTop == self_reltop); 
 
83
#define outer_()                        self->callTop = cs_frame;
89
84
 
90
85
#define enter_()                        CSThread        *self = CSThread::getSelf(); \
91
86
                                                        inner_()
111
106
 * Throwing and catching (the jump stack)
112
107
 */
113
108
 
 
109
/*
 
110
 * Quote from the C99 spec on setjmp:
 
111
 * All accessible objects have values, and all other components of the abstract 
 
112
 * machine have state, as of the time the longjmp function was called, except that 
 
113
 * the values of objects of automatic storage duration that are local to the function 
 
114
 * containing the invocation of the corresponding setjmp macro that do not have 
 
115
 * volatile-qualified type and have been changed between the setjmp invocation and 
 
116
 * longjmp call are indeterminate. 
 
117
 *
 
118
 * This means that any local variable that is declared before a try_() block and then
 
119
 * used again after must be declared volatile because after the longjump you can not be
 
120
 * sure what may be in the register where it is expecting the local variable to be.
 
121
 */
 
122
#define NOCLOBBER       volatile
 
123
 
114
124
int prof_setjmp(void);
115
125
 
116
126
#define TX_CHK_JMP()            if ((self)->jumpDepth < 0 || (self)->jumpDepth >= CS_JUMP_STACK_SIZE) CSException::throwCoreError(__FUNC__, __FILE__, __LINE__, CS_ERR_JUMP_OVERFLOW)
146
156
                                                                (self)->relTop++; \
147
157
                                                        } while (0)
148
158
 
149
 
#define push_ptr_(r)                    do { \
150
 
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
151
 
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
152
 
                                                                } \
153
 
                                                                (self)->relTop->r_type = CS_RELEASE_MEM; \
154
 
                                                                (self)->relTop->x.r_mem = (r); \
155
 
                                                                (self)->relTop++; \
156
 
                                                        } while (0)
157
 
 
158
 
#define push_ref_(r)                    do { \
159
 
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) {\
160
 
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
161
 
                                                                } \
162
 
                                                                (self)->relTop->r_type = CS_RELEASE_OBJECT_PTR; \
163
 
                                                                (self)->relTop->x.r_objectPtr = (CSObject **)&(r); \
164
 
                                                                (self)->relTop++; \
165
 
                                                        } while (0)
166
 
 
167
159
#define pop_(r)                         do { \
168
160
                                                                ASSERT((self)->relTop > (self)->relStack); \
169
161
                                                                if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
170
162
                                                                        ASSERT(((self)->relTop - 1)->x.r_object == ((CSObject *) r)); \
171
163
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MUTEX) {\
172
164
                                                                        ASSERT(((self)->relTop - 1)->x.r_mutex == ((CSMutex *) r)); \
173
 
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_POOLED) {\
 
165
                                                                } else {\
174
166
                                                                        ASSERT(((self)->relTop - 1)->x.r_pooled == ((CSPooled *) r)); \
175
 
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
176
 
                                                                        ASSERT(((self)->relTop - 1)->x.r_mem == ((void *) r)); \
177
 
                                                                }  else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
178
 
                                                                        ASSERT(((self)->relTop - 1)->x.r_objectPtr == ((CSObject **) &(r))); \
179
 
                                                                }  else {\
180
 
                                                                        ASSERT(false); \
181
167
                                                                } \
182
168
                                                                (self)->relTop--; \
183
169
                                                        } while (0)
188
174
                                                        } while (0)
189
175
 
190
176
#define release_(r)                     do {  \
 
177
                                                                register CSObject *rp; \
191
178
                                                                ASSERT((self)->relTop > (self)->relStack); \
192
 
                                                                if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT) {\
193
 
                                                                        register CSObject *rp; \
194
 
                                                                        rp = ((self)->relTop - 1)->x.r_object; \
195
 
                                                                        ASSERT(rp == (CSObject *)(r)); \
196
 
                                                                        (self)->relTop--; \
197
 
                                                                        rp->release(); \
198
 
                                                                } else if (((self)->relTop - 1)->r_type == CS_RELEASE_MEM) {\
199
 
                                                                        register void *mem; \
200
 
                                                                        mem = ((self)->relTop - 1)->x.r_mem; \
201
 
                                                                        ASSERT(mem == (void *)(r)); \
202
 
                                                                        (self)->relTop--; \
203
 
                                                                        cs_free(mem); \
204
 
                                                                }  else if (((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT_PTR) {\
205
 
                                                                        register CSObject **rp; \
206
 
                                                                        rp = ((self)->relTop - 1)->x.r_objectPtr; \
207
 
                                                                        ASSERT(rp == (CSObject **)&(r)); \
208
 
                                                                        (self)->relTop--; \
209
 
                                                                        if(*rp) (*rp)->release(); \
210
 
                                                                } else {\
211
 
                                                                        ASSERT(false); \
212
 
                                                                } \
 
179
                                                                ASSERT(((self)->relTop - 1)->r_type == CS_RELEASE_OBJECT); \
 
180
                                                                rp = ((self)->relTop - 1)->x.r_object; \
 
181
                                                                ASSERT(rp == (r)); \
 
182
                                                                (self)->relTop--; \
 
183
                                                                rp->release(); \
213
184
                                                        } while (0)
214
185
 
215
186
#define lock_(r)                        do { \
222
193
                                                                (self)->relTop++; \
223
194
                                                        } while (0)
224
195
 
225
 
#define locked_(r)                      do { \
226
 
                                                                if ((self)->relTop >= (self)->relStack + CS_RELEASE_STACK_SIZE) \
227
 
                                                                        CSException::throwCoreError(CS_CONTEXT, CS_ERR_RELEASE_OVERFLOW); \
228
 
                                                                (self)->relTop->r_type = CS_RELEASE_MUTEX; \
229
 
                                                                (self)->relTop->x.r_mutex = (r); \
230
 
                                                                (self)->relTop++; \
231
 
                                                        } while (0)
232
 
 
233
196
#define unlock_(r)                      do {  \
234
197
                                                                register CSMutex *rp; \
235
198
                                                                ASSERT((self)->relTop > (self)->relStack); \