~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merged vcol stuff.

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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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)(XTTask *task_data, XTThread *thread);
245
 
typedef void (*XTFreeTaskFunc)(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 *XT_UNUSED(self)) { }
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_updated;                    /* TRUE if a non-temp tables was updated! */
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)               do { xt_slock_rwlock_ns(i); (void) (o); } while(0)
656
 
#define THR_ARRAY_WRITE_LOCK(i, o)              do { xt_xlock_rwlock_ns(i); (void) (o); } while(0)
657
 
#define THR_ARRAY_UNLOCK(i, o)                  do { xt_unlock_rwlock_ns(i); (void) (o); } while(0)
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