~posulliv/drizzle/optimizer-style-cleanup

« back to all changes in this revision

Viewing changes to plugin/pbxt/src/thread_xt.h

  • Committer: Padraig O'Sullivan
  • Date: 2010-04-17 01:38:47 UTC
  • mfrom: (1237.9.238 bad-staging)
  • Revision ID: osullivan.padraig@gmail.com-20100417013847-ibjioqsfbmf5yg4g
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005 PrimeBase Technologies GmbH
 
2
 *
 
3
 * PrimeBase XT
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * 2005-01-03   Paul McCullagh
 
20
 *
 
21
 * H&G2JCtL
 
22
 */
 
23
 
 
24
#ifndef __xt_thread_h__
 
25
#define __xt_thread_h__
 
26
 
 
27
#include <stdio.h>
 
28
#include <limits.h>
 
29
#ifndef XT_WIN
 
30
#include <sys/param.h>
 
31
#endif
 
32
#include <setjmp.h>
 
33
 
 
34
#include "xt_defs.h"
 
35
#include "xt_errno.h"
 
36
#include "linklist_xt.h"
 
37
#include "memory_xt.h"
 
38
#include "xactlog_xt.h"
 
39
#include "datalog_xt.h"
 
40
#include "lock_xt.h"
 
41
#include "locklist_xt.h"
 
42
#include "sortedlist_xt.h"
 
43
 
 
44
/*
 
45
 * -----------------------------------------------------------------------
 
46
 * Macros and defines
 
47
 */
 
48
 
 
49
#define XT_ERR_MSG_SIZE                                 (PATH_MAX + 200)
 
50
 
 
51
#ifdef DEBUG
 
52
#define ASSERT(expr)                                    ((expr) ? TRUE : xt_assert(self, #expr, __FUNC__, __FILE__, __LINE__))
 
53
#else
 
54
#define ASSERT(expr)                                    ((void) 0)
 
55
#endif
 
56
 
 
57
#ifdef DEBUG
 
58
#define ASSUME(expr)                                    ((expr) ? TRUE : xt_assume(self, #expr, __FUNC__, __FILE__, __LINE__))
 
59
#else
 
60
#define ASSUME(expr)                                    ((void) 0)
 
61
#endif
 
62
 
 
63
#ifdef DEBUG
 
64
#define ASSERT_NS(expr)                                 ((expr) ? TRUE : xt_assert(NULL, #expr, __FUNC__, __FILE__, __LINE__))
 
65
#else
 
66
#define ASSERT_NS(expr)                                 ((void) 0)
 
67
#endif
 
68
 
 
69
#define STATIC_ASSERT(condition)                typedef struct { \
 
70
                                                                                        char static_assertion[condition ? 1 : -1]; \
 
71
                                                                                } static_assertion_t
 
72
 
 
73
#define XT_THROW_ASSERTION(str)                 xt_throw_assertion(self, __FUNC__, __FILE__, __LINE__, str)
 
74
 
 
75
/* Log levels */
 
76
#define XT_LOG_DEFAULT                                  -1
 
77
#define XT_LOG_PROTOCOL                                 0
 
78
#define XT_LOG_FATAL                                    1
 
79
#define XT_LOG_ERROR                                    2
 
80
#define XT_LOG_WARNING                                  3
 
81
#define XT_LOG_INFO                                             4
 
82
#define XT_LOG_TRACE                                    5
 
83
 
 
84
#define XT_PROTOCOL                                             self, "", NULL, 0, XT_LOG_PROTOCOL
 
85
#define XT_WARNING                                              self, "", NULL, 0, XT_LOG_WARNING
 
86
#define XT_INFO                                                 self, "", NULL, 0, XT_LOG_INFO
 
87
#define XT_ERROR                                                self, "", NULL, 0, XT_LOG_ERROR
 
88
#define XT_TRACE                                                self, "", NULL, 0, XT_LOG_TRACE
 
89
 
 
90
#define XT_NT_PROTOCOL                                  NULL, "", NULL, 0, XT_LOG_PROTOCOL
 
91
#define XT_NT_WARNING                                   NULL, "", NULL, 0, XT_LOG_WARNING
 
92
#define XT_NT_INFO                                              NULL, "", NULL, 0, XT_LOG_INFO
 
93
#define XT_NT_ERROR                                             NULL, "", NULL, 0, XT_LOG_ERROR
 
94
#define XT_NT_TRACE                                             NULL, "", NULL, 0, XT_LOG_TRACE
 
95
 
 
96
#define XT_ERROR_CONTEXT(func)                  self, __FUNC__, __FILE__, __LINE__, XT_LOG_ERROR
 
97
 
 
98
/* Thread types */
 
99
#define XT_THREAD_MAIN                                  0
 
100
#define XT_THREAD_WORKER                                1
 
101
 
 
102
/* Thread Priorities: */
 
103
#define XT_PRIORITY_LOW                                 0
 
104
#define XT_PRIORITY_NORMAL                              1
 
105
#define XT_PRIORITY_HIGH                                2
 
106
 
 
107
#define XT_CONTEXT                                              self, __FUNC__, __FILE__, __LINE__
 
108
#define XT_NS_CONTEXT                                   NULL, __FUNC__, __FILE__, __LINE__
 
109
#define XT_REG_CONTEXT                                  __FUNC__, __FILE__, __LINE__
 
110
 
 
111
#define XT_MAX_JMP                                              20
 
112
#define XT_MAX_CALL_STACK                               100                                             /* The number of functions recorded by enter_() and exit() */
 
113
#define XT_RES_STACK_SIZE                               4000                                    /* The size of the stack resource stack in bytes. */
 
114
#define XT_MAX_RESOURCE_USAGE                   5                                               /* The maximum number of temp slots used per routine. */
 
115
#define XT_CATCH_TRACE_SIZE                             1024
 
116
#define XT_MAX_FUNC_NAME_SIZE                   120
 
117
#define XT_SOURCE_FILE_NAME_SIZE                40
 
118
#define XT_THR_NAME_SIZE                                80
 
119
 
 
120
typedef struct XTException {
 
121
        int                                             e_xt_err;                                                                       /* The XT error number (ALWAYS non-zero on error, else zero) */
 
122
        int                                             e_sys_err;                                                                      /* The system error number (0 if none) */
 
123
        char                                    e_err_msg[XT_ERR_MSG_SIZE];                                     /* The error message text (0 terminated string) */
 
124
        char                                    e_func_name[XT_MAX_FUNC_NAME_SIZE];                     /* The name of the function in which the exception occurred */
 
125
        char                                    e_source_file[XT_SOURCE_FILE_NAME_SIZE];        /* The source file in which the exception was thrown */
 
126
        u_int                                   e_source_line;                                                          /* The source code line number on which the exception was thrown */
 
127
        char                                    e_catch_trace[XT_CATCH_TRACE_SIZE];                     /* A string of the catch trace. */
 
128
} XTExceptionRec, *XTExceptionPtr;
 
129
 
 
130
struct XTThread;
 
131
struct XTSortedList;
 
132
struct XTXactLog;
 
133
struct XTXactData;
 
134
struct XTDatabase;
 
135
struct XTOpenTable;
 
136
 
 
137
typedef void (*XTThreadFreeFunc)(struct XTThread *self, void *data);
 
138
 
 
139
typedef struct XTResourceArgs {
 
140
        void                                    *ra_p1;
 
141
        xtWord4                                 ra_p2;
 
142
} XTResourceArgsRec, *XTResourceArgsPtr;
 
143
 
 
144
/* This structure represents a temporary resource on the resource stack.
 
145
 * Resource are automatically freed if an exception occurs.
 
146
 */
 
147
typedef struct XTResource {
 
148
        xtWord4                                 r_prev_size;                                    /* The size of the previous resource on the stack (must be first!) */
 
149
        void                                    *r_data;                                                /* A pointer to the resource data (this may be on the resource stack) */
 
150
        XTThreadFreeFunc                r_free_func;                                    /* The function used to free the resource. */
 
151
} XTResourceRec, *XTResourcePtr;
 
152
 
 
153
typedef struct XTJumpBuf {
 
154
        XTResourcePtr                   jb_res_top;
 
155
        int                                             jb_call_top;
 
156
        jmp_buf                                 jb_buffer;
 
157
} XTJumpBufRec, *XTJumpBufPtr;
 
158
 
 
159
typedef struct XTCallStack {
 
160
        c_char                                  *cs_func;
 
161
        c_char                                  *cs_file;
 
162
        u_int                                   cs_line;
 
163
} XTCallStackRec, *XTCallStackPtr;
 
164
 
 
165
typedef struct XTIOStats {
 
166
        u_int                                   ts_read;                                                /* The number of bytes read. */
 
167
        u_int                                   ts_write;                                               /* The number of bytes written. */
 
168
        xtWord8                                 ts_flush_time;                                  /* The accumulated flush time. */
 
169
        xtWord8                                 ts_flush_start;                                 /* Start time, non-zero if a timer is running. */
 
170
#ifdef XT_TIME_DISK_WRITES
 
171
        xtWord8                                 ts_write_time;                                  /* The accumulated write time. */
 
172
        xtWord8                                 ts_write_start;                                 /* Start write time, non-zero if a timer is running. */
 
173
#endif
 
174
#ifdef XT_TIME_DISK_READS
 
175
        xtWord8                                 ts_read_time;                                   /* The accumulated read time. */
 
176
        xtWord8                                 ts_read_start;                                  /* Start read time, non-zero if a timer is running. */
 
177
#endif
 
178
        u_int                                   ts_flush;                                               /* The number of flush operations. */
 
179
} XTIOStatsRec, *XTIOStatsPtr;
 
180
 
 
181
#ifdef XT_TIME_DISK_WRITES
 
182
#define ACC_WRITE_TIME(x, y)            (x).ts_write_time += (y).ts_write_time;
 
183
#else
 
184
#define ACC_WRITE_TIME(x, y)
 
185
#endif
 
186
 
 
187
#ifdef XT_TIME_DISK_WRITES
 
188
#define ACC_READ_TIME(x, y)             (x).ts_read_time += (y).ts_read_time;
 
189
#else
 
190
#define ACC_READ_TIME(x, y)
 
191
#endif
 
192
 
 
193
#define XT_ADD_STATS(x, y)      { \
 
194
        (x).ts_read += (y).ts_read; \
 
195
        ACC_WRITE_TIME(x, y) \
 
196
        ACC_READ_TIME(x, y) \
 
197
        (x).ts_write += (y).ts_write; \
 
198
        (x).ts_flush_time += (y).ts_flush_time; \
 
199
        (x).ts_flush += (y).ts_flush; \
 
200
}
 
201
 
 
202
typedef struct XTStatistics {
 
203
        u_int                                   st_commits;
 
204
        u_int                                   st_rollbacks;
 
205
        u_int                                   st_stat_read;
 
206
        u_int                                   st_stat_write;
 
207
 
 
208
        XTIOStatsRec                    st_rec;
 
209
        u_int                                   st_rec_cache_hit;
 
210
        u_int                                   st_rec_cache_miss;
 
211
        u_int                                   st_rec_cache_frees;
 
212
 
 
213
        XTIOStatsRec                    st_ind;
 
214
        u_int                                   st_ind_cache_hit;
 
215
        u_int                                   st_ind_cache_miss;
 
216
        XTIOStatsRec                    st_ilog;
 
217
 
 
218
        XTIOStatsRec                    st_xlog;
 
219
        u_int                                   st_xlog_cache_hit;
 
220
        u_int                                   st_xlog_cache_miss;
 
221
 
 
222
        XTIOStatsRec                    st_data;
 
223
 
 
224
        XTIOStatsRec                    st_x;
 
225
 
 
226
        u_int                                   st_scan_index;
 
227
        u_int                                   st_scan_table;
 
228
        u_int                                   st_row_select;
 
229
        u_int                                   st_row_insert;
 
230
        u_int                                   st_row_update;
 
231
        u_int                                   st_row_delete;
 
232
 
 
233
        u_int                                   st_wait_for_xact;
 
234
        u_int                                   st_retry_index_scan;
 
235
        u_int                                   st_reread_record_list;
 
236
        XTIOStatsRec                    st_ind_flush_time;
 
237
        xtInt8                                  st_ind_cache_dirty;
 
238
} XTStatisticsRec, *XTStatisticsPtr;
 
239
 
 
240
struct XTThread;
 
241
class XTTask;
 
242
 
 
243
/* Run a task. The thread input is the thread that is running the task. */
 
244
typedef xtBool (*XTDoTaskFunc)(struct XTTask *task_data, struct XTThread *thread);
 
245
typedef void (*XTFreeTaskFunc)(struct XTTask *task_data);
 
246
 
 
247
class XTTask {
 
248
        public:
 
249
        XTTask() : 
 
250
                tk_task_list_next(NULL),
 
251
                tk_running(false),
 
252
                tk_success(false),
 
253
                tk_out_of_memory(false),
 
254
                tk_exception(NULL)
 
255
        { 
 
256
                tk_waiting_threads.pl_setup_ns();
 
257
                tk_notify_threads.pl_setup_ns();
 
258
        }
 
259
 
 
260
        virtual ~XTTask() { 
 
261
                if (tk_exception)
 
262
                        xt_free_ns(tk_exception);
 
263
                tk_waiting_threads.pl_exit();
 
264
                tk_notify_threads.pl_exit();
 
265
        }
 
266
 
 
267
        virtual void    tk_init(struct XTThread *) { }
 
268
        virtual void    tk_exit() { delete this; }
 
269
        virtual void    tk_lock() { }
 
270
        virtual void    tk_unlock() { }
 
271
        virtual void    tk_reference() { }
 
272
        virtual void    tk_release() { }
 
273
 
 
274
        virtual bool    tk_is_running() { return tk_running; }
 
275
        virtual xtBool  tk_task(struct XTThread *) { return OK; }       /* Function called to performance the work of the task. */
 
276
 
 
277
        XTPointerList           tk_waiting_threads;                                     /* A list of threads waiting for task completion. */
 
278
        XTPointerList           tk_notify_threads;                                      /* A list of threads waiting for "early" notification. */
 
279
 
 
280
        /* Linked list of tasks to be done by the thread pool: */
 
281
        XTTask                          *tk_task_list_next;
 
282
 
 
283
        /* Result of task: */
 
284
        bool                            tk_running;
 
285
        bool                            tk_success;                                                     /* TRUE if the task succeeded. */
 
286
        bool                            tk_out_of_memory;                                       /* TRUE of ran out of memory when trying to allocate the exception.
 
287
                                                                                                                         * In this case, the error will be logged.
 
288
                                                                                                                         */
 
289
        XTExceptionPtr          tk_exception;                                           /* The exception details (NULL if no exception). */
 
290
};
 
291
 
 
292
class XTLockTask : public XTTask {
 
293
        xt_mutex_type           lt_mutex;
 
294
 
 
295
        public:
 
296
        virtual void tk_init(struct XTThread *self);
 
297
        virtual void tk_exit();
 
298
        virtual void tk_lock();
 
299
        virtual void tk_unlock();
 
300
};
 
301
 
 
302
/*
 
303
 * PBXT supports COMMITTED READ and REPEATABLE READ.
 
304
 *
 
305
 * As Jim says, multi-versioning cannot implement SERIALIZABLE. Basically
 
306
 * you need locking to do this. Although phantom reads do not occur with
 
307
 * MVCC, it is still not serializable.
 
308
 *
 
309
 * This can be seen from the following example:
 
310
 *
 
311
 * T1: INSERT t1 VALUE (1, 1);
 
312
 * T2: INSERT t1 VALUE (2, 2);
 
313
 * T1: UPDATE t1 SET b = 3 WHERE a IN (1, 2);
 
314
 * T2: UPDATE t1 SET b = 4 WHERE a IN (1, 2);
 
315
 * Serialized result (T1, T2) or (T2, T1):
 
316
 * a   b        or      a   b
 
317
 * 1   4                1   3
 
318
 * 2   4                1   3
 
319
 * Non-serialized (MVCC) result:
 
320
 * a   b
 
321
 * 1   3
 
322
 * 2   4
 
323
 */
 
324
#define XT_XACT_UNCOMMITTED_READ        0
 
325
#define XT_XACT_COMMITTED_READ          1
 
326
#define XT_XACT_REPEATABLE_READ         2                                               /* Guarentees rows already read will not change. */
 
327
#define XT_XACT_SERIALIZABLE            3                                               
 
328
 
 
329
#define XT_IMP_NO_IMPORT                        0
 
330
#define XT_IMP_COPY_TABLE                       1                                               /* An import statement that copies all data in the table. */
 
331
#define XT_IMP_LOAD_TABLE                       2                                               /* The LOAD DATA INFILE STATEMENT. */
 
332
 
 
333
typedef struct XTThread {
 
334
        XTLinkedItemRec                 t_links;                                                /* Required to be a member of a double-linked list. */
 
335
 
 
336
        char                                    t_name[XT_THR_NAME_SIZE];               /* The name of the thread. */
 
337
        xtBool                                  t_main;                                                 /* TRUE if this is the main (initial) thread */
 
338
        xtBool                                  t_quit;                                                 /* TRUE if this thread should stop running. */
 
339
        xtBool                                  t_daemon;                                               /* TRUE if this thread is a daemon. */
 
340
        xtThreadID                              t_id;                                                   /* The thread ID (0=main), index into thread array. */
 
341
        pthread_t                               t_pthread;                                              /* The pthread associated with xt thread */
 
342
        xtBool                                  t_disable_interrupts;                   /* TRUE if interrupts are disabled. */
 
343
        int                                             t_delayed_signal;                               /* Throw this signal as soon as you can! */
 
344
 
 
345
        void                                    *t_data;                                                /* Data passed to the thread. */
 
346
        XTThreadFreeFunc                t_free_data;                                    /* Routine used to free the thread data */
 
347
 
 
348
        int                                             t_call_top;                                             /* A pointer to the top of the call stack. */
 
349
        XTCallStackRec                  t_call_stack[XT_MAX_CALL_STACK];/* Records the function under execution (to be output on error). */
 
350
 
 
351
        XTResourcePtr                   t_res_top;                                              /* The top of the resource stack (reference next free space). */
 
352
        union {
 
353
                char                            t_res_stack[XT_RES_STACK_SIZE]; /* Temporary data to be freed if an exception occurs. */
 
354
                xtWord4                         t_align_res_stack;
 
355
        } x;
 
356
 
 
357
        int                                             t_jmp_depth;                                    /* The current jump depth */
 
358
        XTJumpBufRec                    t_jmp_env[XT_MAX_JMP];                  /* The process environment to be restored on exception */
 
359
        int                                             t_in_handler;                                   /* True if we are in the exception handler. */
 
360
        XTExceptionRec                  t_exception;                                    /* The exception details. */
 
361
 
 
362
        xt_cond_type                    t_cond;                                                 /* The pthread condition used for suspending the thread. */
 
363
        xt_mutex_type                   t_lock;                                                 /* Thread lock, used for operations on a thread that may be done by other threads.
 
364
                                                                                                                         * for example xt_unuse_database().
 
365
                                                                                                                         */
 
366
 
 
367
        /* Async tasks and thread pool. */
 
368
        XTPointerList                   st_tasks_todo;                                  /* Store the list of tasks to be done here. */
 
369
        XTPointerList                   st_tasks_done;                                  /* Store the list of results here. */
 
370
        struct XTThread                 *st_pool_next;                                  /* Next in the thread pool. */
 
371
 
 
372
        /* Application specific data: */
 
373
        struct XTDatabase               *st_database;                                   /* The database in use by the thread. */
 
374
        u_int                                   st_lock_count;                                  /* We count the number of locks MySQL has set in order to know when they are all released. */
 
375
        u_int                                   st_stat_count;                                  /* start statement count. */
 
376
        xtWord4                                 st_visible_time;                                /* Transactions committed before this time are visible. */
 
377
        XTDataLogBufferRec              st_dlog_buf;
 
378
        
 
379
        /* A list of the last 10 transactions run by this connection: */
 
380
#ifdef XT_WAIT_FOR_CLEANUP
 
381
        u_int                                   st_last_xact;
 
382
        xtXactID                                st_prev_xact[XT_MAX_XACT_BEHIND];
 
383
#endif
 
384
 
 
385
        struct XTXactData               *st_xact_data;                                  /* The transaction data, not NULL if the transaction performs an update. */
 
386
        time_t                                  st_xact_write_time;                             /* Approximate first write time (uses xt_db_approximate_time). */
 
387
        int                                             st_xact_mode;                                   /* The transaction mode. */
 
388
        xtBool1                                 st_xact_writer;                                 /* TRUE if the transaction has written somthing to the log. */
 
389
        xtBool1                                 st_xact_long_running;                   /* TRUE if this is a long running writer transaction. */
 
390
 
 
391
        xtBool1                                 st_ignore_fkeys;                                /* TRUE if we must ignore foreign keys. */
 
392
        xtBool1                                 st_auto_commit;                                 /* TRUE if this is an auto-commit transaction. */
 
393
        xtBool1                                 st_table_trans;                                 /* TRUE transactions is a result of LOCK TABLES. */
 
394
        xtBool1                                 st_abort_trans;                                 /* TRUE if the transaction should be aborted. */
 
395
        xtBool1                                 st_stat_ended;                                  /* TRUE if the statement was ended. */
 
396
        xtBool1                                 st_stat_trans;                                  /* TRUE if a statement transaction is running (started on UPDATE). */
 
397
        xtBool1                                 st_stat_modify;                                 /* TRUE if the statement is an INSERT/UPDATE/DELETE */
 
398
        xtBool1                                 st_non_temp_opened;                             /* TRUE if a non-temp tables was opened! */
 
399
        xtWord1                                 st_import_stat;                                 /* Non-zero if this is an import statement (ALTER, LOAD, REPAIR, etc). */
 
400
#ifdef XT_IMPLEMENT_NO_ACTION
 
401
        XTBasicListRec                  st_restrict_list;                               /* These records have been deleted and should have no reference. */
 
402
#endif
 
403
        /* Local thread list. */
 
404
        u_int                                   st_thread_list_count;
 
405
        u_int                                   st_thread_list_size;
 
406
        xtThreadID                              *st_thread_list;
 
407
 
 
408
        /* Used to prevent a record from being updated twice in one statement. */
 
409
        struct XTOpenTable              *st_is_update;                                  /* TRUE if this is an UPDATE statement.  {UPDATE-STACK} */
 
410
 
 
411
        XTRowLockListRec                st_lock_list;                                   /* The thread row lock list (drop locks on transaction end). */
 
412
        XTStatisticsRec                 st_statistics;                                  /* Accumulated statistics for this thread. */
 
413
#ifdef XT_THREAD_LOCK_INFO
 
414
        /* list of locks (spins, mutextes, etc) that this thread currently holds (debugging) */
 
415
        XTThreadLockInfoPtr             st_thread_lock_list[XT_THREAD_LOCK_INFO_MAX_COUNT];
 
416
        int                                             st_thread_lock_count;
 
417
#endif
 
418
} XTThreadRec, *XTThreadPtr;
 
419
 
 
420
typedef struct XTWaitThread {
 
421
        /* The wait condition of the thread. */
 
422
        xt_mutex_type                   wt_lock;
 
423
        xt_cond_type                    wt_cond;
 
424
 
 
425
        /* The list of threads waiting for this thread. */
 
426
        XTSpinLockRec                   wt_wait_list_lock;
 
427
        u_int                                   wt_wait_list_count;
 
428
        u_int                                   wt_wait_list_size;
 
429
        xtThreadID                              *wt_wait_list;
 
430
} XTWaitThreadRec, *XTWaitThreadPtr;
 
431
 
 
432
typedef struct XTThreadData {
 
433
        XTThreadPtr                             td_thread;
 
434
        XTWaitThreadPtr                 td_waiting;
 
435
} XTThreadDataRec, *XTThreadDataPtr;
 
436
 
 
437
/*
 
438
 * -----------------------------------------------------------------------
 
439
 * Call stack
 
440
 */
 
441
 
 
442
#define XT_INIT_CHECK_STACK             char xt_chk_buffer[512]; memset(xt_chk_buffer, 0xFE, 512);
 
443
#define XT_RE_CHECK_STACK               memset(xt_chk_buffer, 0xFE, 512);
 
444
 
 
445
/*
 
446
 * This macro must be placed at the start of every function.
 
447
 * It records the current context so that we can
 
448
 * dump a type of stack trace later if necessary.
 
449
 *
 
450
 * It also sets up the current thread pointer 'self'.
 
451
 */
 
452
#ifdef DEBUG
 
453
#define XT_STACK_TRACE
 
454
#endif
 
455
 
 
456
/*
 
457
 * These macros generate a stack trace which can be used
 
458
 * to locate an error on exception.
 
459
 */
 
460
#ifdef XT_STACK_TRACE
 
461
 
 
462
/*
 
463
 * Place this call at the top of a function,
 
464
 * after the declaration of local variable, and
 
465
 * before the first code is executed.
 
466
 */
 
467
#define enter_()                        int xt_frame = self->t_call_top++; \
 
468
                                                        do { \
 
469
                                                                if (xt_frame < XT_MAX_CALL_STACK) { \
 
470
                                                                        self->t_call_stack[xt_frame].cs_func = __FUNC__; \
 
471
                                                                        self->t_call_stack[xt_frame].cs_file = __FILE__; \
 
472
                                                                        self->t_call_stack[xt_frame].cs_line = __LINE__; \
 
473
                                                                } \
 
474
                                                        } while (0)
 
475
 
 
476
#define outer_()                        self->t_call_top = xt_frame;
 
477
 
 
478
/*
 
479
 * On exit to a function, either exit_() or
 
480
 * return_() must be called.
 
481
 */
 
482
#define exit_()                         do { \
 
483
                                                                outer_(); \
 
484
                                                                return; \
 
485
                                                        } while (0)
 
486
        
 
487
#define return_(x)                      do { \
 
488
                                                                outer_(); \
 
489
                                                                return(x); \
 
490
                                                        } while (0)
 
491
 
 
492
#define returnc_(x, typ)        do { \
 
493
                                                                typ rv; \
 
494
                                                                rv = (x); \
 
495
                                                                outer_(); \
 
496
                                                                return(rv); \
 
497
                                                        } while (0)
 
498
 
 
499
/*
 
500
 * Sets the line number before a call to get a better
 
501
 * stack trace;
 
502
 */
 
503
#define call_(x)                        do { self->t_call_stack[xt_frame].cs_line = __LINE__; x; } while (0)
 
504
 
 
505
#else
 
506
#define enter_()
 
507
#define outer_()
 
508
#define exit_()                         return;
 
509
#define return_(x)                      return (x)
 
510
#define returnc_(x, typ)        return (x)
 
511
#define call_(x)                        x
 
512
#endif
 
513
 
 
514
/*
 
515
 * -----------------------------------------------------------------------
 
516
 * Throwing and catching
 
517
 */
 
518
 
 
519
int prof_setjmp(void);
 
520
 
 
521
#define TX_CHK_JMP()            if ((self)->t_jmp_depth < 0 || (self)->t_jmp_depth >= XT_MAX_JMP) xt_throw_xterr(self, __FUNC__, __FILE__, __LINE__, XT_ERR_JUMP_OVERFLOW)
 
522
#ifdef PROFILE
 
523
#define profile_setjmp          prof_setjmp()
 
524
#else
 
525
#define profile_setjmp                  
 
526
#endif
 
527
 
 
528
#define try_(n)                         TX_CHK_JMP(); \
 
529
                                                        (self)->t_jmp_env[(self)->t_jmp_depth].jb_res_top = (self)->t_res_top; \
 
530
                                                        (self)->t_jmp_env[(self)->t_jmp_depth].jb_call_top = (self)->t_call_top; \
 
531
                                                        (self)->t_jmp_depth++; profile_setjmp; if (setjmp((self)->t_jmp_env[(self)->t_jmp_depth-1].jb_buffer)) goto catch_##n;
 
532
#define catch_(n)                       (self)->t_jmp_depth--; goto cont_##n; catch_##n: (self)->t_jmp_depth--; xt_caught(self);
 
533
#define cont_(n)                        cont_##n:
 
534
#define throw_()                        xt_throw(self)
 
535
 
 
536
/*
 
537
 * -----------------------------------------------------------------------
 
538
 * Resource stack
 
539
 */
 
540
 
 
541
//#define DEBUG_RESOURCE_STACK
 
542
 
 
543
#ifdef DEBUG_RESOURCE_STACK
 
544
#define CHECK_RS                        if ((char *) (self)->t_res_top < (self)->x.t_res_stack) xt_bug(self);
 
545
#define CHECK_NS_RS                     { XTThreadPtr self = xt_get_self(); CHECK_RS; }
 
546
#else
 
547
#define CHECK_RS                        remove this!
 
548
#define CHECK_NS_RS                     remove this!
 
549
#endif
 
550
 
 
551
/*
 
552
 * Allocate a resource on the resource stack. The resource will be freed
 
553
 * automatocally if an exception occurs. Before exiting the current
 
554
 * procedure you must free the resource using popr_() or freer_().
 
555
 * v = value to be set to the resource,
 
556
 * f = function which frees the resource,
 
557
 * s = the size of the resource,
 
558
 */
 
559
 
 
560
/* GOTCHA: My experience is that contructs such as *((xtWordPS *) &(v)) = (xtWordPS) (x)
 
561
 * cause optimised versions to crash?!
 
562
 */
 
563
#define allocr_(v, f, s, t)             do { \
 
564
                                                                        if (((char *) (self)->t_res_top) > (self)->x.t_res_stack + XT_RES_STACK_SIZE - sizeof(XTResourceRec) + (s) + 4) \
 
565
                                                                                xt_throw_xterr(self, __FUNC__, __FILE__, __LINE__, XT_ERR_RES_STACK_OVERFLOW); \
 
566
                                                                        v = (t) (((char *) (self)->t_res_top) + sizeof(XTResourceRec)); \
 
567
                                                                        (self)->t_res_top->r_data = (v); \
 
568
                                                                        (self)->t_res_top->r_free_func = (XTThreadFreeFunc) (f); \
 
569
                                                                        (self)->t_res_top = (XTResourcePtr) (((char *) (self)->t_res_top) + sizeof(XTResourceRec) + (s)); \
 
570
                                                                        (self)->t_res_top->r_prev_size = sizeof(XTResourceRec) + (s); \
 
571
                                                                } while (0)
 
572
 
 
573
#define alloczr_(v, f, s, t)    do { allocr_(v, f, s, t); \
 
574
                                                                        memset(v, 0, s); } while (0)
 
575
 
 
576
/* Push and set a resource:
 
577
 * v = value to be set to the resource,
 
578
 * f = function which frees the resource,
 
579
 * r = the resource,
 
580
 * NOTE: the expression (r) must come first because it may contain
 
581
 * calls which use the resource stack!!
 
582
 */
 
583
#define pushsr_(v, f, r)        do { \
 
584
                                                                if (((char *) (self)->t_res_top) > (self)->x.t_res_stack + XT_RES_STACK_SIZE - sizeof(XTResourceRec) + 4) \
 
585
                                                                        xt_throw_xterr(self, __FUNC__, __FILE__, __LINE__, XT_ERR_RES_STACK_OVERFLOW); \
 
586
                                                                v = (r); \
 
587
                                                                (self)->t_res_top->r_data = (v); \
 
588
                                                                (self)->t_res_top->r_free_func = (XTThreadFreeFunc) (f); \
 
589
                                                                (self)->t_res_top = (XTResourcePtr) (((char *) (self)->t_res_top) + sizeof(XTResourceRec)); \
 
590
                                                                (self)->t_res_top->r_prev_size = sizeof(XTResourceRec); \
 
591
                                                        } while (0)
 
592
 
 
593
/* Push a resource. In the event of an exception it will be freed
 
594
 * the free routine.
 
595
 * f = function which frees the resource,
 
596
 * r = a pointer to the resource,
 
597
 */
 
598
#define pushr_(f, r)            do { \
 
599
                                                                if (((char *) (self)->t_res_top) > (self)->x.t_res_stack + XT_RES_STACK_SIZE - sizeof(XTResourceRec) + 4) \
 
600
                                                                        xt_throw_xterr(self, __FUNC__, __FILE__, __LINE__, XT_ERR_RES_STACK_OVERFLOW); \
 
601
                                                                (self)->t_res_top->r_data = (r); \
 
602
                                                                (self)->t_res_top->r_free_func = (XTThreadFreeFunc) (f); \
 
603
                                                                (self)->t_res_top = (XTResourcePtr) (((char *) (self)->t_res_top) + sizeof(XTResourceRec)); \
 
604
                                                                (self)->t_res_top->r_prev_size = sizeof(XTResourceRec); \
 
605
                                                        } while (0)
 
606
 
 
607
/* Pop a resource without freeing it: */
 
608
#ifdef DEBUG_RESOURCE_STACK
 
609
#define popr_()                         do { \
 
610
                                                                (self)->t_res_top = (XTResourcePtr) (((char *) (self)->t_res_top) - (self)->t_res_top->r_prev_size); \
 
611
                                                                if ((char *) (self)->t_res_top < (self)->x.t_res_stack) \
 
612
                                                                        xt_bug(self); \
 
613
                                                        } while (0)
 
614
#else
 
615
#define popr_()                         do { (self)->t_res_top = (XTResourcePtr) (((char *) (self)->t_res_top) - (self)->t_res_top->r_prev_size); } while (0)
 
616
#endif
 
617
 
 
618
#define setr_(r)                        do { ((XTResourcePtr) (((char *) (self)->t_res_top) - (self)->t_res_top->r_prev_size))->r_data = (r); } while (0)
 
619
 
 
620
/* Pop and free a resource: */
 
621
#ifdef DEBUG_RESOURCE_STACK
 
622
#define freer_()                        do {  \
 
623
                                                                register XTResourcePtr  rp; \
 
624
                                                                rp = (XTResourcePtr) (((char *) (self)->t_res_top) - (self)->t_res_top->r_prev_size); \
 
625
                                                                if ((char *) rp < (self)->x.t_res_stack) \
 
626
                                                                        xt_bug(self); \
 
627
                                                                (rp->r_free_func)((self), rp->r_data); \
 
628
                                                                (self)->t_res_top = rp; \
 
629
                                                        } while (0)
 
630
#else
 
631
#define freer_()                        do {  \
 
632
                                                                register XTResourcePtr  rp; \
 
633
                                                                rp = (XTResourcePtr) (((char *) (self)->t_res_top) - (self)->t_res_top->r_prev_size); \
 
634
                                                                (rp->r_free_func)((self), rp->r_data); \
 
635
                                                                (self)->t_res_top = rp; \
 
636
                                                        } while (0)
 
637
#endif
 
638
 
 
639
/*
 
640
 * -----------------------------------------------------------------------
 
641
 * Thread globals
 
642
 */
 
643
 
 
644
#ifdef XT_NO_ATOMICS
 
645
#define THR_ARRAY_USE_PTHREAD_RW
 
646
#else
 
647
//#define RR_FLUSH_USE_PTHREAD_RW
 
648
#define THR_ARRAY_USE_XSMUTEX
 
649
#endif
 
650
 
 
651
#if defined(THR_ARRAY_USE_PTHREAD_RW)
 
652
#define THR_ARRAY_LOCK_TYPE                             xt_rwlock_type
 
653
#define THR_ARRAY_INIT_LOCK(s, i)               xt_init_rwlock_with_autoname(s, i)
 
654
#define THR_ARRAY_FREE_LOCK(s, i)               xt_free_rwlock(i)       
 
655
#define THR_ARRAY_READ_LOCK(i, o)               xt_slock_rwlock_ns(i)
 
656
#define THR_ARRAY_WRITE_LOCK(i, o)              xt_xlock_rwlock_ns(i)
 
657
#define THR_ARRAY_UNLOCK(i, o)                  xt_unlock_rwlock_ns(i)
 
658
#elif defined(THR_ARRAY_USE_XSMUTEX)
 
659
#define THR_ARRAY_LOCK_TYPE                             XTMutexXSLockRec
 
660
#define THR_ARRAY_INIT_LOCK(s, i)               xt_xsmutex_init_with_autoname(s, i)
 
661
#define THR_ARRAY_FREE_LOCK(s, i)               xt_xsmutex_free(s, i)   
 
662
#define THR_ARRAY_READ_LOCK(i, o)               xt_xsmutex_slock(i, o)
 
663
#define THR_ARRAY_WRITE_LOCK(i, o)              xt_xsmutex_xlock(i, o)
 
664
#define THR_ARRAY_UNLOCK(i, o)                  xt_xsmutex_unlock(i, o)
 
665
#else
 
666
#error Please define the lock type
 
667
#endif
 
668
 
 
669
extern u_int                            xt_thr_maximum_threads;
 
670
extern u_int                            xt_thr_current_thread_count;
 
671
extern u_int                            xt_thr_current_max_threads;
 
672
extern THR_ARRAY_LOCK_TYPE      xt_thr_array_resize_lock;
 
673
extern XTThreadDataRec          *xt_thr_array;
 
674
 
 
675
/*
 
676
 * -----------------------------------------------------------------------
 
677
 * Function prototypes
 
678
 */
 
679
 
 
680
/* OpenSolaris has thr_main in /usr/include/thread.h (name conflict)
 
681
 * Thanks for the tip Monty!
 
682
 */
 
683
extern "C" void *xt_thread_main(void *data);
 
684
 
 
685
void                    xt_get_now(char *buffer, size_t len);
 
686
xtBool                  xt_init_logging(void);
 
687
void                    xt_exit_logging(void);
 
688
void                    xt_log_flush(XTThreadPtr self);
 
689
void                    xt_logf(XTThreadPtr self, c_char *func, c_char *file, u_int line, int level, c_char *fmt, ...);
 
690
void                    xt_log(XTThreadPtr self, c_char *func, c_char *file, u_int line, int level, c_char *string);
 
691
int                             xt_log_errorf(XTThreadPtr self, c_char *func, c_char *file, u_int line, int level, int xt_err, int sys_err, c_char *fmt, ...);
 
692
int                             xt_log_error(XTThreadPtr self, c_char *func, c_char *file, u_int line, int level, int xt_err, int sys_err, c_char *string);
 
693
void                    xt_log_exception(XTThreadPtr self, XTExceptionPtr e, int level);
 
694
void                    xt_clear_exception(XTThreadPtr self);
 
695
void                    xt_log_and_clear_exception(XTThreadPtr self);
 
696
void                    xt_log_and_clear_exception_ns(void);
 
697
void                    xt_log_and_clear_warning(XTThreadPtr self);
 
698
void                    xt_log_and_clear_warning_ns(void);
 
699
 
 
700
void                    xt_bug(XTThreadPtr self);
 
701
void                    xt_caught(XTThreadPtr self);
 
702
void                    xt_throw(XTThreadPtr self);
 
703
void                    xt_enter_exception_handler(XTThreadPtr self, XTExceptionPtr e);
 
704
void                    xt_exit_exception_handler(XTThreadPtr self, XTExceptionPtr e);
 
705
void                    xt_throwf(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, int sys_err, c_char *format, ...);
 
706
void                    xt_throw_error(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, int sys_err, c_char *message);
 
707
void                    xt_throw_i2xterr(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, c_char *item, c_char *item2);
 
708
void                    xt_throw_ixterr(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, c_char *item);
 
709
void                    xt_throw_tabcolerr(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, XTPathStrPtr tab_item, c_char *item2);
 
710
void                    xt_throw_taberr(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, XTPathStrPtr tab_item);
 
711
void                    xt_throw_ulxterr(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, u_long value);
 
712
void                    xt_throw_sulxterr(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, c_char *item, u_long value);
 
713
void                    xt_throw_xterr(XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err);
 
714
void                    xt_throw_errno(XTThreadPtr self, c_char *func, c_char *file, u_int line, int err_no);
 
715
void                    xt_throw_ferrno(XTThreadPtr self, c_char *func, c_char *file, u_int line, int err_no, c_char *path);
 
716
void                    xt_throw_assertion(XTThreadPtr self, c_char *func, c_char *file, u_int line, c_char *str);
 
717
void                    xt_throw_signal(XTThreadPtr self, c_char *func, c_char *file, u_int line, int sig);
 
718
xtBool                  xt_throw_delayed_signal(XTThreadPtr self, c_char *func, c_char *file, u_int line);
 
719
 
 
720
void                    xt_registerf(c_char *func, c_char *file, u_int line, int xt_err, int sys_err, c_char *fmt, ...);
 
721
void                    xt_register_i2xterr(c_char *func, c_char *file, u_int line, int xt_err, c_char *item, c_char *item2);
 
722
void                    xt_register_ixterr(c_char *func, c_char *file, u_int line, int xt_err, c_char *item);
 
723
void                    xt_register_tabcolerr(c_char *func, c_char *file, u_int line, int xt_err, XTPathStrPtr tab_item, c_char *item2);
 
724
void                    xt_register_taberr(c_char *func, c_char *file, u_int line, int xt_err, XTPathStrPtr tab_item);
 
725
void                    xt_register_ulxterr(c_char *func, c_char *file, u_int line, int xt_err, u_long value);
 
726
xtBool                  xt_register_ferrno(c_char *func, c_char *file, u_int line, int err, c_char *path);
 
727
void                    xt_register_error(c_char *func, c_char *file, u_int line, int xt_err, int sys_err, c_char *msg);
 
728
xtBool                  xt_register_errno(c_char *func, c_char *file, u_int line, int err);
 
729
void                    xt_register_xterr(c_char *func, c_char *file, u_int line, int xt_err);
 
730
 
 
731
void                    xt_exceptionf(XTExceptionPtr e, XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, int sys_err, c_char *fmt, ...);
 
732
void                    xt_exception_error(XTExceptionPtr e, XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err, int sys_err, c_char *msg);
 
733
xtBool                  xt_exception_errno(XTExceptionPtr e, XTThreadPtr self, c_char *func, c_char *file, u_int line, int err);
 
734
void                    xt_exception_xterr(XTExceptionPtr e, XTThreadPtr self, c_char *func, c_char *file, u_int line, int xt_err);
 
735
 
 
736
void                    xt_log_errno(XTThreadPtr self, c_char *func, c_char *file, u_int line, int err);
 
737
 
 
738
xtBool                  xt_assert(XTThreadPtr self, c_char *expr, c_char *func, c_char *file, u_int line);
 
739
xtBool                  xt_assume(XTThreadPtr self, c_char *expr, c_char *func, c_char *file, u_int line);
 
740
 
 
741
XTThreadPtr             xt_init_threading();
 
742
void                    xt_exit_threading(XTThreadPtr self);
 
743
 
 
744
XTThreadPtr             xt_create_thread(c_char *name, xtBool main_thread, xtBool temp_thread, XTExceptionPtr e);
 
745
XTThreadPtr             xt_create_daemon_ns(c_char *name);
 
746
XTThreadPtr             xt_create_daemon(XTThreadPtr parent, c_char *name);
 
747
void                    xt_free_thread(XTThreadPtr self);
 
748
void                    xt_set_thread_data(XTThreadPtr self, void *data, XTThreadFreeFunc free_func);
 
749
xtBool                  xt_run_thread_ns(XTThreadPtr child, void *(*start_routine)(XTThreadPtr));
 
750
void                    xt_run_thread(XTThreadPtr parent, XTThreadPtr child, void *(*start_routine)(XTThreadPtr));
 
751
void                    xt_exit_thread(XTThreadPtr self, void *result);
 
752
void                    *xt_wait_for_thread_to_exit(xtThreadID tid, xtBool ignore_error);
 
753
void                    xt_signal_all_threads(XTThreadPtr self, int sig);
 
754
void                    xt_do_to_all_threads(XTThreadPtr self, void (*do_func_ptr)(XTThreadPtr self, XTThreadPtr to_thr, void *thunk), void *thunk);
 
755
void                    xt_kill_thread(pthread_t t1);
 
756
XTThreadPtr             xt_get_self(void);
 
757
void                    xt_set_self(XTThreadPtr self);
 
758
void                    xt_wait_for_all_threads(XTThreadPtr self);
 
759
void                    xt_busy_wait(void);
 
760
void                    xt_critical_wait(void);
 
761
void                    xt_yield(void);
 
762
void                    xt_sleep_milli_second(u_int t);
 
763
xtBool                  xt_suspend(XTThreadPtr self);
 
764
xtBool                  xt_unsuspend(XTThreadPtr target);
 
765
void                    xt_lock_thread(XTThreadPtr thread);
 
766
void                    xt_unlock_thread(XTThreadPtr thread);
 
767
xtBool                  xt_wait_thread(XTThreadPtr thread);
 
768
xtBool                  xt_timed_wait_thread(XTThreadPtr thread, u_long milli_sec);
 
769
void                    xt_signal_thread(XTThreadPtr target);
 
770
void                    xt_terminate_thread(XTThreadPtr self, XTThreadPtr target);
 
771
xtProcID                xt_getpid();
 
772
xtBool                  xt_process_exists(xtProcID pid);
 
773
 
 
774
xtBool                  xt_add_to_wakeup_list(xtThreadID waiting_id, xtThreadID wait_for_id);
 
775
void                    xt_wakeup_waiting_threads(XTThreadPtr thread);
 
776
void                    xt_wakeup_thread_list(XTThreadPtr thread);
 
777
void                    xt_wakeup_thread(xtThreadID thd_id, XTThreadPtr thread);
 
778
 
 
779
#ifdef XT_THREAD_LOCK_INFO
 
780
#define xt_init_rwlock_with_autoname(a,b)       xt_init_rwlock(a,b,LOCKLIST_ARG_SUFFIX(b))
 
781
#else
 
782
#define xt_init_rwlock_with_autoname(a,b)       xt_init_rwlock(a,b)
 
783
#endif
 
784
 
 
785
#ifdef XT_THREAD_LOCK_INFO
 
786
xtBool                  xt_init_rwlock(XTThreadPtr self, xt_rwlock_type *rwlock, const char *name);
 
787
#else
 
788
xtBool                  xt_init_rwlock(XTThreadPtr self, xt_rwlock_type *rwlock);
 
789
#endif
 
790
void                    xt_free_rwlock(xt_rwlock_type *rwlock);
 
791
xt_rwlock_type  *xt_slock_rwlock(XTThreadPtr self, xt_rwlock_type *rwlock);
 
792
xt_rwlock_type  *xt_xlock_rwlock(XTThreadPtr self, xt_rwlock_type *rwlock);
 
793
void                    xt_unlock_rwlock(XTThreadPtr self, xt_rwlock_type *rwlock);
 
794
 
 
795
xt_mutex_type   *xt_new_mutex(XTThreadPtr self);
 
796
void                    xt_delete_mutex(XTThreadPtr self, xt_mutex_type *mx);
 
797
#ifdef XT_THREAD_LOCK_INFO
 
798
#define                 xt_init_mutex_with_autoname(a,b) xt_init_mutex(a,b,LOCKLIST_ARG_SUFFIX(b))
 
799
xtBool                  xt_init_mutex(XTThreadPtr self, xt_mutex_type *mx, const char *name);
 
800
#else
 
801
#define                 xt_init_mutex_with_autoname(a,b) xt_init_mutex(a,b)
 
802
xtBool                  xt_init_mutex(XTThreadPtr self, xt_mutex_type *mx);
 
803
#endif
 
804
void                    xt_free_mutex(xt_mutex_type *mx);
 
805
xtBool                  xt_lock_mutex(XTThreadPtr self, xt_mutex_type *mx);
 
806
void                    xt_unlock_mutex(XTThreadPtr self, xt_mutex_type *mx);
 
807
 
 
808
pthread_cond_t  *xt_new_cond(XTThreadPtr self);
 
809
void                    xt_delete_cond(XTThreadPtr self, pthread_cond_t *cond);
 
810
 
 
811
xtBool                  xt_init_cond(XTThreadPtr self, pthread_cond_t *cond);
 
812
void                    xt_free_cond(pthread_cond_t *cond);
 
813
xtBool                  xt_wait_cond(XTThreadPtr self, pthread_cond_t *cond, xt_mutex_type *mutex);
 
814
xtBool                  xt_timed_wait_cond(XTThreadPtr self, pthread_cond_t *cond, xt_mutex_type *mutex, u_long milli_sec);
 
815
xtBool                  xt_signal_cond(XTThreadPtr self, pthread_cond_t *cond);
 
816
void                    xt_broadcast_cond(XTThreadPtr self, pthread_cond_t *cond);
 
817
xtBool                  xt_broadcast_cond_ns(xt_cond_type *cond);
 
818
 
 
819
xtBool                  xt_set_key(pthread_key_t key, const void *value, XTExceptionPtr e);
 
820
void                    *xt_get_key(pthread_key_t key);
 
821
 
 
822
void                    xt_set_low_priority(XTThreadPtr self);
 
823
void                    xt_set_normal_priority(XTThreadPtr self);
 
824
void                    xt_set_high_priority(XTThreadPtr self);
 
825
void                    xt_set_priority(XTThreadPtr self, int priority);
 
826
 
 
827
void                    xt_gather_statistics(XTStatisticsPtr stats);
 
828
u_llong                 xt_get_statistic(XTStatisticsPtr stats, struct XTDatabase *db, u_int rec_id);
 
829
int                             xt_get_index_cache_dirty_perc();
 
830
 
 
831
#define xt_timed_wait_cond_ns(a, b, c)  xt_timed_wait_cond(NULL, a, b, c)
 
832
 
 
833
#endif
 
834