1
/* Copyright (C) 2005 PrimeBase Technologies GmbH
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.
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.
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
19
* 2005-01-03 Paul McCullagh
24
#ifndef __xt_thread_h__
25
#define __xt_thread_h__
30
#include <sys/param.h>
36
#include "linklist_xt.h"
37
#include "memory_xt.h"
38
#include "xactlog_xt.h"
39
#include "datalog_xt.h"
41
#include "locklist_xt.h"
42
#include "sortedlist_xt.h"
45
* -----------------------------------------------------------------------
49
#define XT_ERR_MSG_SIZE (PATH_MAX + 200)
52
#define ASSERT(expr) ((expr) ? TRUE : xt_assert(self, #expr, __FUNC__, __FILE__, __LINE__))
54
#define ASSERT(expr) ((void) 0)
58
#define ASSUME(expr) ((expr) ? TRUE : xt_assume(self, #expr, __FUNC__, __FILE__, __LINE__))
60
#define ASSUME(expr) ((void) 0)
64
#define ASSERT_NS(expr) ((expr) ? TRUE : xt_assert(NULL, #expr, __FUNC__, __FILE__, __LINE__))
66
#define ASSERT_NS(expr) ((void) 0)
69
#define STATIC_ASSERT(condition) typedef struct { \
70
char static_assertion[condition ? 1 : -1]; \
73
#define XT_THROW_ASSERTION(str) xt_throw_assertion(self, __FUNC__, __FILE__, __LINE__, str)
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
82
#define XT_LOG_TRACE 5
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
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
96
#define XT_ERROR_CONTEXT(func) self, __FUNC__, __FILE__, __LINE__, XT_LOG_ERROR
99
#define XT_THREAD_MAIN 0
100
#define XT_THREAD_WORKER 1
102
/* Thread Priorities: */
103
#define XT_PRIORITY_LOW 0
104
#define XT_PRIORITY_NORMAL 1
105
#define XT_PRIORITY_HIGH 2
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__
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
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;
137
typedef void (*XTThreadFreeFunc)(struct XTThread *self, void *data);
139
typedef struct XTResourceArgs {
142
} XTResourceArgsRec, *XTResourceArgsPtr;
144
/* This structure represents a temporary resource on the resource stack.
145
* Resource are automatically freed if an exception occurs.
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;
153
typedef struct XTJumpBuf {
154
XTResourcePtr jb_res_top;
157
} XTJumpBufRec, *XTJumpBufPtr;
159
typedef struct XTCallStack {
163
} XTCallStackRec, *XTCallStackPtr;
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. */
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. */
178
u_int ts_flush; /* The number of flush operations. */
179
} XTIOStatsRec, *XTIOStatsPtr;
181
#ifdef XT_TIME_DISK_WRITES
182
#define ACC_WRITE_TIME(x, y) (x).ts_write_time += (y).ts_write_time;
184
#define ACC_WRITE_TIME(x, y)
187
#ifdef XT_TIME_DISK_WRITES
188
#define ACC_READ_TIME(x, y) (x).ts_read_time += (y).ts_read_time;
190
#define ACC_READ_TIME(x, y)
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; \
202
typedef struct XTStatistics {
209
u_int st_rec_cache_hit;
210
u_int st_rec_cache_miss;
211
u_int st_rec_cache_frees;
214
u_int st_ind_cache_hit;
215
u_int st_ind_cache_miss;
216
XTIOStatsRec st_ilog;
218
XTIOStatsRec st_xlog;
219
u_int st_xlog_cache_hit;
220
u_int st_xlog_cache_miss;
222
XTIOStatsRec st_data;
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;
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);
250
tk_task_list_next(NULL),
253
tk_out_of_memory(false),
256
tk_waiting_threads.pl_setup_ns();
257
tk_notify_threads.pl_setup_ns();
262
xt_free_ns(tk_exception);
263
tk_waiting_threads.pl_exit();
264
tk_notify_threads.pl_exit();
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() { }
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. */
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. */
280
/* Linked list of tasks to be done by the thread pool: */
281
XTTask *tk_task_list_next;
283
/* Result of task: */
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.
289
XTExceptionPtr tk_exception; /* The exception details (NULL if no exception). */
292
class XTLockTask : public XTTask {
293
xt_mutex_type lt_mutex;
296
virtual void tk_init(struct XTThread *self);
297
virtual void tk_exit();
298
virtual void tk_lock();
299
virtual void tk_unlock();
303
* PBXT supports COMMITTED READ and REPEATABLE READ.
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.
309
* This can be seen from the following example:
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):
319
* Non-serialized (MVCC) result:
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
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. */
333
typedef struct XTThread {
334
XTLinkedItemRec t_links; /* Required to be a member of a double-linked list. */
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! */
345
void *t_data; /* Data passed to the thread. */
346
XTThreadFreeFunc t_free_data; /* Routine used to free the thread data */
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). */
351
XTResourcePtr t_res_top; /* The top of the resource stack (reference next free space). */
353
char t_res_stack[XT_RES_STACK_SIZE]; /* Temporary data to be freed if an exception occurs. */
354
xtWord4 t_align_res_stack;
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. */
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().
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. */
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;
379
/* A list of the last 10 transactions run by this connection: */
380
#ifdef XT_WAIT_FOR_CLEANUP
382
xtXactID st_prev_xact[XT_MAX_XACT_BEHIND];
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. */
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. */
403
/* Local thread list. */
404
u_int st_thread_list_count;
405
u_int st_thread_list_size;
406
xtThreadID *st_thread_list;
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} */
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;
418
} XTThreadRec, *XTThreadPtr;
420
typedef struct XTWaitThread {
421
/* The wait condition of the thread. */
422
xt_mutex_type wt_lock;
423
xt_cond_type wt_cond;
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;
432
typedef struct XTThreadData {
433
XTThreadPtr td_thread;
434
XTWaitThreadPtr td_waiting;
435
} XTThreadDataRec, *XTThreadDataPtr;
438
* -----------------------------------------------------------------------
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);
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.
450
* It also sets up the current thread pointer 'self'.
453
#define XT_STACK_TRACE
457
* These macros generate a stack trace which can be used
458
* to locate an error on exception.
460
#ifdef XT_STACK_TRACE
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.
467
#define enter_() int xt_frame = self->t_call_top++; \
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__; \
476
#define outer_() self->t_call_top = xt_frame;
479
* On exit to a function, either exit_() or
480
* return_() must be called.
482
#define exit_() do { \
487
#define return_(x) do { \
492
#define returnc_(x, typ) do { \
500
* Sets the line number before a call to get a better
503
#define call_(x) do { self->t_call_stack[xt_frame].cs_line = __LINE__; x; } while (0)
508
#define exit_() return;
509
#define return_(x) return (x)
510
#define returnc_(x, typ) return (x)
515
* -----------------------------------------------------------------------
516
* Throwing and catching
519
int prof_setjmp(void);
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)
523
#define profile_setjmp prof_setjmp()
525
#define profile_setjmp
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)
537
* -----------------------------------------------------------------------
541
//#define DEBUG_RESOURCE_STACK
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; }
547
#define CHECK_RS remove this!
548
#define CHECK_NS_RS remove this!
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,
560
/* GOTCHA: My experience is that contructs such as *((xtWordPS *) &(v)) = (xtWordPS) (x)
561
* cause optimised versions to crash?!
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); \
573
#define alloczr_(v, f, s, t) do { allocr_(v, f, s, t); \
574
memset(v, 0, s); } while (0)
576
/* Push and set a resource:
577
* v = value to be set to the resource,
578
* f = function which frees the resource,
580
* NOTE: the expression (r) must come first because it may contain
581
* calls which use the resource stack!!
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); \
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); \
593
/* Push a resource. In the event of an exception it will be freed
595
* f = function which frees the resource,
596
* r = a pointer to the resource,
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); \
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) \
615
#define popr_() do { (self)->t_res_top = (XTResourcePtr) (((char *) (self)->t_res_top) - (self)->t_res_top->r_prev_size); } while (0)
618
#define setr_(r) do { ((XTResourcePtr) (((char *) (self)->t_res_top) - (self)->t_res_top->r_prev_size))->r_data = (r); } while (0)
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) \
627
(rp->r_free_func)((self), rp->r_data); \
628
(self)->t_res_top = rp; \
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; \
640
* -----------------------------------------------------------------------
645
#define THR_ARRAY_USE_PTHREAD_RW
647
//#define RR_FLUSH_USE_PTHREAD_RW
648
#define THR_ARRAY_USE_XSMUTEX
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)
666
#error Please define the lock type
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;
676
* -----------------------------------------------------------------------
677
* Function prototypes
680
/* OpenSolaris has thr_main in /usr/include/thread.h (name conflict)
681
* Thanks for the tip Monty!
683
extern "C" void *xt_thread_main(void *data);
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);
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);
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);
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);
736
void xt_log_errno(XTThreadPtr self, c_char *func, c_char *file, u_int line, int err);
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);
741
XTThreadPtr xt_init_threading();
742
void xt_exit_threading(XTThreadPtr self);
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);
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);
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);
779
#ifdef XT_THREAD_LOCK_INFO
780
#define xt_init_rwlock_with_autoname(a,b) xt_init_rwlock(a,b,LOCKLIST_ARG_SUFFIX(b))
782
#define xt_init_rwlock_with_autoname(a,b) xt_init_rwlock(a,b)
785
#ifdef XT_THREAD_LOCK_INFO
786
xtBool xt_init_rwlock(XTThreadPtr self, xt_rwlock_type *rwlock, const char *name);
788
xtBool xt_init_rwlock(XTThreadPtr self, xt_rwlock_type *rwlock);
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);
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);
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);
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);
808
pthread_cond_t *xt_new_cond(XTThreadPtr self);
809
void xt_delete_cond(XTThreadPtr self, pthread_cond_t *cond);
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);
819
xtBool xt_set_key(pthread_key_t key, const void *value, XTExceptionPtr e);
820
void *xt_get_key(pthread_key_t key);
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);
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();
831
#define xt_timed_wait_cond_ns(a, b, c) xt_timed_wait_cond(NULL, a, b, c)