|
ds@1952
|
1 |
/* |
|
ds@1952
|
2 |
** 2004 May 22 |
|
ds@1952
|
3 |
** |
|
ds@1952
|
4 |
** The author disclaims copyright to this source code. In place of |
|
ds@1952
|
5 |
** a legal notice, here is a blessing: |
|
ds@1952
|
6 |
** |
|
ds@1952
|
7 |
** May you do good and not evil. |
|
ds@1952
|
8 |
** May you find forgiveness for yourself and forgive others. |
|
ds@1952
|
9 |
** May you share freely, never taking more than you give. |
|
ds@1952
|
10 |
** |
|
ds@1952
|
11 |
****************************************************************************** |
|
ds@1952
|
12 |
** |
|
ds@1952
|
13 |
** This file contains macros and a little bit of code that is common to |
|
ds@1952
|
14 |
** all of the platform-specific files (os_*.c) and is #included into those |
|
ds@1952
|
15 |
** files. |
|
ds@1952
|
16 |
** |
|
ds@1952
|
17 |
** This file should be #included by the os_*.c files only. It is not a |
|
ds@1952
|
18 |
** general purpose header file. |
|
ds@1952
|
19 |
*/ |
|
ds@1952
|
20 |
|
|
ds@1952
|
21 |
/* |
|
ds@1952
|
22 |
** At least two bugs have slipped in because we changed the MEMORY_DEBUG |
|
ds@1952
|
23 |
** macro to SQLITE_DEBUG and some older makefiles have not yet made the |
|
ds@1952
|
24 |
** switch. The following code should catch this problem at compile-time. |
|
ds@1952
|
25 |
*/ |
|
ds@1952
|
26 |
#ifdef MEMORY_DEBUG |
|
ds@1952
|
27 |
# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." |
|
ds@1952
|
28 |
#endif |
|
ds@1952
|
29 |
|
|
ds@1952
|
30 |
|
|
ds@1952
|
31 |
/* |
|
ds@1952
|
32 |
* When testing, this global variable stores the location of the |
|
ds@1952
|
33 |
* pending-byte in the database file. |
|
ds@1952
|
34 |
*/ |
|
ds@1952
|
35 |
#ifdef SQLITE_TEST |
|
ds@1952
|
36 |
unsigned int sqlite3_pending_byte = 0x40000000; |
|
ds@1952
|
37 |
#endif |
|
ds@1952
|
38 |
|
|
ds@1952
|
39 |
#ifdef SQLITE_DEBUG |
|
ds@1952
|
40 |
int sqlite3_os_trace = 0; |
|
ds@1952
|
41 |
#define OSTRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X) |
|
ds@1952
|
42 |
#define OSTRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y) |
|
ds@1952
|
43 |
#define OSTRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z) |
|
ds@1952
|
44 |
#define OSTRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A) |
|
ds@1952
|
45 |
#define OSTRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B) |
|
ds@1952
|
46 |
#define OSTRACE6(X,Y,Z,A,B,C) \ |
|
ds@1952
|
47 |
if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C) |
|
ds@1952
|
48 |
#define OSTRACE7(X,Y,Z,A,B,C,D) \ |
|
ds@1952
|
49 |
if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D) |
|
ds@1952
|
50 |
#else |
|
ds@1952
|
51 |
#define OSTRACE1(X) |
|
ds@1952
|
52 |
#define OSTRACE2(X,Y) |
|
ds@1952
|
53 |
#define OSTRACE3(X,Y,Z) |
|
ds@1952
|
54 |
#define OSTRACE4(X,Y,Z,A) |
|
ds@1952
|
55 |
#define OSTRACE5(X,Y,Z,A,B) |
|
ds@1952
|
56 |
#define OSTRACE6(X,Y,Z,A,B,C) |
|
ds@1952
|
57 |
#define OSTRACE7(X,Y,Z,A,B,C,D) |
|
ds@1952
|
58 |
#endif |
|
ds@1952
|
59 |
|
|
ds@1952
|
60 |
/* |
|
ds@1952
|
61 |
** Macros for performance tracing. Normally turned off. Only works |
|
ds@1952
|
62 |
** on i486 hardware. |
|
ds@1952
|
63 |
*/ |
|
ds@1952
|
64 |
#ifdef SQLITE_PERFORMANCE_TRACE |
|
ds@1952
|
65 |
__inline__ unsigned long long int hwtime(void){ |
|
ds@1952
|
66 |
unsigned long long int x; |
|
ds@1952
|
67 |
__asm__("rdtsc\n\t" |
|
ds@1952
|
68 |
"mov %%edx, %%ecx\n\t" |
|
ds@1952
|
69 |
:"=A" (x)); |
|
ds@1952
|
70 |
return x; |
|
ds@1952
|
71 |
} |
|
ds@1952
|
72 |
static unsigned long long int g_start; |
|
ds@1952
|
73 |
static unsigned int elapse; |
|
ds@1952
|
74 |
#define TIMER_START g_start=hwtime() |
|
ds@1952
|
75 |
#define TIMER_END elapse=hwtime()-g_start |
|
ds@1952
|
76 |
#define TIMER_ELAPSED elapse |
|
ds@1952
|
77 |
#else |
|
ds@1952
|
78 |
#define TIMER_START |
|
ds@1952
|
79 |
#define TIMER_END |
|
ds@1952
|
80 |
#define TIMER_ELAPSED 0 |
|
ds@1952
|
81 |
#endif |
|
ds@1952
|
82 |
|
|
ds@1952
|
83 |
/* |
|
ds@1952
|
84 |
** If we compile with the SQLITE_TEST macro set, then the following block |
|
ds@1952
|
85 |
** of code will give us the ability to simulate a disk I/O error. This |
|
ds@1952
|
86 |
** is used for testing the I/O recovery logic. |
|
ds@1952
|
87 |
*/ |
|
ds@1952
|
88 |
#ifdef SQLITE_TEST |
|
ds@1952
|
89 |
int sqlite3_io_error_hit = 0; |
|
ds@1952
|
90 |
int sqlite3_io_error_pending = 0; |
|
ds@1952
|
91 |
int sqlite3_io_error_persist = 0; |
|
ds@1952
|
92 |
int sqlite3_diskfull_pending = 0; |
|
ds@1952
|
93 |
int sqlite3_diskfull = 0; |
|
ds@1952
|
94 |
#define SimulateIOError(CODE) \ |
|
ds@1952
|
95 |
if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \ |
|
ds@1952
|
96 |
if( sqlite3_io_error_pending-- == 1 \ |
|
ds@1952
|
97 |
|| (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \ |
|
ds@1952
|
98 |
{ local_ioerr(); CODE; } |
|
ds@1952
|
99 |
static void local_ioerr(){ |
|
ds@1952
|
100 |
IOTRACE(("IOERR\n")); |
|
ds@1952
|
101 |
sqlite3_io_error_hit = 1; |
|
ds@1952
|
102 |
} |
|
ds@1952
|
103 |
#define SimulateDiskfullError(CODE) \ |
|
ds@1952
|
104 |
if( sqlite3_diskfull_pending ){ \ |
|
ds@1952
|
105 |
if( sqlite3_diskfull_pending == 1 ){ \ |
|
ds@1952
|
106 |
local_ioerr(); \ |
|
ds@1952
|
107 |
sqlite3_diskfull = 1; \ |
|
ds@1952
|
108 |
sqlite3_io_error_hit = 1; \ |
|
ds@1952
|
109 |
CODE; \ |
|
ds@1952
|
110 |
}else{ \ |
|
ds@1952
|
111 |
sqlite3_diskfull_pending--; \ |
|
ds@1952
|
112 |
} \ |
|
ds@1952
|
113 |
} |
|
ds@1952
|
114 |
#else |
|
ds@1952
|
115 |
#define SimulateIOError(A) |
|
ds@1952
|
116 |
#define SimulateDiskfullError(A) |
|
ds@1952
|
117 |
#endif |
|
ds@1952
|
118 |
|
|
ds@1952
|
119 |
/* |
|
ds@1952
|
120 |
** When testing, keep a count of the number of open files. |
|
ds@1952
|
121 |
*/ |
|
ds@1952
|
122 |
#ifdef SQLITE_TEST |
|
ds@1952
|
123 |
int sqlite3_open_file_count = 0; |
|
ds@1952
|
124 |
#define OpenCounter(X) sqlite3_open_file_count+=(X) |
|
ds@1952
|
125 |
#else |
|
ds@1952
|
126 |
#define OpenCounter(X) |
|
ds@1952
|
127 |
#endif |