1434
|
1 /*
|
|
2 ** 2004 May 22
|
|
3 **
|
|
4 ** The author disclaims copyright to this source code. In place of
|
|
5 ** a legal notice, here is a blessing:
|
|
6 **
|
|
7 ** May you do good and not evil.
|
|
8 ** May you find forgiveness for yourself and forgive others.
|
|
9 ** May you share freely, never taking more than you give.
|
|
10 **
|
|
11 ******************************************************************************
|
|
12 **
|
|
13 ** This file contains macros and a little bit of code that is common to
|
|
14 ** all of the platform-specific files (os_*.c) and is #included into those
|
|
15 ** files.
|
|
16 **
|
|
17 ** This file should be #included by the os_*.c files only. It is not a
|
|
18 ** general purpose header file.
|
|
19 */
|
|
20
|
|
21 /*
|
|
22 ** At least two bugs have slipped in because we changed the MEMORY_DEBUG
|
|
23 ** macro to SQLITE_DEBUG and some older makefiles have not yet made the
|
|
24 ** switch. The following code should catch this problem at compile-time.
|
|
25 */
|
|
26 #ifdef MEMORY_DEBUG
|
|
27 # error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead."
|
|
28 #endif
|
|
29
|
|
30
|
|
31 /*
|
|
32 * When testing, this global variable stores the location of the
|
|
33 * pending-byte in the database file.
|
|
34 */
|
|
35 #ifdef SQLITE_TEST
|
|
36 unsigned int sqlite3_pending_byte = 0x40000000;
|
|
37 #endif
|
|
38
|
|
39 int sqlite3_os_trace = 0;
|
|
40 #ifdef SQLITE_DEBUG
|
|
41 static int last_page = 0;
|
|
42 #define SEEK(X) last_page=(X)
|
|
43 #define TRACE1(X) if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
|
|
44 #define TRACE2(X,Y) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
|
|
45 #define TRACE3(X,Y,Z) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
|
|
46 #define TRACE4(X,Y,Z,A) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
|
|
47 #define TRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
|
|
48 #define TRACE6(X,Y,Z,A,B,C) if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
|
|
49 #define TRACE7(X,Y,Z,A,B,C,D) \
|
|
50 if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
|
|
51 #else
|
|
52 #define SEEK(X)
|
|
53 #define TRACE1(X)
|
|
54 #define TRACE2(X,Y)
|
|
55 #define TRACE3(X,Y,Z)
|
|
56 #define TRACE4(X,Y,Z,A)
|
|
57 #define TRACE5(X,Y,Z,A,B)
|
|
58 #define TRACE6(X,Y,Z,A,B,C)
|
|
59 #define TRACE7(X,Y,Z,A,B,C,D)
|
|
60 #endif
|
|
61
|
|
62 /*
|
|
63 ** Macros for performance tracing. Normally turned off. Only works
|
|
64 ** on i486 hardware.
|
|
65 */
|
|
66 #ifdef SQLITE_PERFORMANCE_TRACE
|
|
67 __inline__ unsigned long long int hwtime(void){
|
|
68 unsigned long long int x;
|
|
69 __asm__("rdtsc\n\t"
|
|
70 "mov %%edx, %%ecx\n\t"
|
|
71 :"=A" (x));
|
|
72 return x;
|
|
73 }
|
|
74 static unsigned long long int g_start;
|
|
75 static unsigned int elapse;
|
|
76 #define TIMER_START g_start=hwtime()
|
|
77 #define TIMER_END elapse=hwtime()-g_start
|
|
78 #define TIMER_ELAPSED elapse
|
|
79 #else
|
|
80 #define TIMER_START
|
|
81 #define TIMER_END
|
|
82 #define TIMER_ELAPSED 0
|
|
83 #endif
|
|
84
|
|
85 /*
|
|
86 ** If we compile with the SQLITE_TEST macro set, then the following block
|
|
87 ** of code will give us the ability to simulate a disk I/O error. This
|
|
88 ** is used for testing the I/O recovery logic.
|
|
89 */
|
|
90 #ifdef SQLITE_TEST
|
|
91 int sqlite3_io_error_hit = 0;
|
|
92 int sqlite3_io_error_pending = 0;
|
|
93 int sqlite3_diskfull_pending = 0;
|
|
94 int sqlite3_diskfull = 0;
|
|
95 #define SimulateIOError(A) \
|
|
96 if( sqlite3_io_error_pending ) \
|
|
97 if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
|
|
98 static void local_ioerr(){
|
|
99 sqlite3_io_error_hit = 1; /* Really just a place to set a breakpoint */
|
|
100 }
|
|
101 #define SimulateDiskfullError \
|
|
102 if( sqlite3_diskfull_pending ){ \
|
|
103 if( sqlite3_diskfull_pending == 1 ){ \
|
|
104 local_ioerr(); \
|
|
105 sqlite3_diskfull = 1; \
|
|
106 return SQLITE_FULL; \
|
|
107 }else{ \
|
|
108 sqlite3_diskfull_pending--; \
|
|
109 } \
|
|
110 }
|
|
111 #else
|
|
112 #define SimulateIOError(A)
|
|
113 #define SimulateDiskfullError
|
|
114 #endif
|
|
115
|
|
116 /*
|
|
117 ** When testing, keep a count of the number of open files.
|
|
118 */
|
|
119 #ifdef SQLITE_TEST
|
|
120 int sqlite3_open_file_count = 0;
|
|
121 #define OpenCounter(X) sqlite3_open_file_count+=(X)
|
|
122 #else
|
|
123 #define OpenCounter(X)
|
|
124 #endif
|
|
125
|
|
126 /*
|
|
127 ** sqlite3GenericMalloc
|
|
128 ** sqlite3GenericRealloc
|
|
129 ** sqlite3GenericOsFree
|
|
130 ** sqlite3GenericAllocationSize
|
|
131 **
|
|
132 ** Implementation of the os level dynamic memory allocation interface in terms
|
|
133 ** of the standard malloc(), realloc() and free() found in many operating
|
|
134 ** systems. No rocket science here.
|
|
135 **
|
|
136 ** There are two versions of these four functions here. The version
|
|
137 ** implemented here is only used if memory-management or memory-debugging is
|
|
138 ** enabled. This version allocates an extra 8-bytes at the beginning of each
|
|
139 ** block and stores the size of the allocation there.
|
|
140 **
|
|
141 ** If neither memory-management or debugging is enabled, the second
|
|
142 ** set of implementations is used instead.
|
|
143 */
|
|
144 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || defined (SQLITE_MEMDEBUG)
|
|
145 void *sqlite3GenericMalloc(int n){
|
|
146 char *p = (char *)malloc(n+8);
|
|
147 assert(n>0);
|
|
148 assert(sizeof(int)<=8);
|
|
149 if( p ){
|
|
150 *(int *)p = n;
|
|
151 p += 8;
|
|
152 }
|
|
153 return (void *)p;
|
|
154 }
|
|
155 void *sqlite3GenericRealloc(void *p, int n){
|
|
156 char *p2 = ((char *)p - 8);
|
|
157 assert(n>0);
|
|
158 p2 = (char*)realloc(p2, n+8);
|
|
159 if( p2 ){
|
|
160 *(int *)p2 = n;
|
|
161 p2 += 8;
|
|
162 }
|
|
163 return (void *)p2;
|
|
164 }
|
|
165 void sqlite3GenericFree(void *p){
|
|
166 assert(p);
|
|
167 free((void *)((char *)p - 8));
|
|
168 }
|
|
169 int sqlite3GenericAllocationSize(void *p){
|
|
170 return p ? *(int *)((char *)p - 8) : 0;
|
|
171 }
|
|
172 #else
|
|
173 void *sqlite3GenericMalloc(int n){
|
|
174 char *p = (char *)malloc(n);
|
|
175 return (void *)p;
|
|
176 }
|
|
177 void *sqlite3GenericRealloc(void *p, int n){
|
|
178 assert(n>0);
|
|
179 p = realloc(p, n);
|
|
180 return p;
|
|
181 }
|
|
182 void sqlite3GenericFree(void *p){
|
|
183 assert(p);
|
|
184 free(p);
|
|
185 }
|
|
186 /* Never actually used, but needed for the linker */
|
|
187 int sqlite3GenericAllocationSize(void *p){ return 0; }
|
|
188 #endif
|