summaryrefslogtreecommitdiffstats
path: root/third_party/sqlite/os_common.h
blob: 0c54405efacd0dba67054318d638f83e131fd9b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
** 2004 May 22
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
******************************************************************************
**
** This file contains macros and a little bit of code that is common to
** all of the platform-specific files (os_*.c) and is #included into those
** files.
**
** This file should be #included by the os_*.c files only.  It is not a
** general purpose header file.
*/

/*
** At least two bugs have slipped in because we changed the MEMORY_DEBUG
** macro to SQLITE_DEBUG and some older makefiles have not yet made the
** switch.  The following code should catch this problem at compile-time.
*/
#ifdef MEMORY_DEBUG
# error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
#endif


/*
 * When testing, this global variable stores the location of the
 * pending-byte in the database file.
 */
#ifdef SQLITE_TEST
unsigned int sqlite3_pending_byte = 0x40000000;
#endif

#ifdef SQLITE_DEBUG
int sqlite3_os_trace = 0;
#define OSTRACE1(X)         if( sqlite3_os_trace ) sqlite3DebugPrintf(X)
#define OSTRACE2(X,Y)       if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y)
#define OSTRACE3(X,Y,Z)     if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z)
#define OSTRACE4(X,Y,Z,A)   if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A)
#define OSTRACE5(X,Y,Z,A,B) if( sqlite3_os_trace ) sqlite3DebugPrintf(X,Y,Z,A,B)
#define OSTRACE6(X,Y,Z,A,B,C) \
    if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C)
#define OSTRACE7(X,Y,Z,A,B,C,D) \
    if(sqlite3_os_trace) sqlite3DebugPrintf(X,Y,Z,A,B,C,D)
#else
#define OSTRACE1(X)
#define OSTRACE2(X,Y)
#define OSTRACE3(X,Y,Z)
#define OSTRACE4(X,Y,Z,A)
#define OSTRACE5(X,Y,Z,A,B)
#define OSTRACE6(X,Y,Z,A,B,C)
#define OSTRACE7(X,Y,Z,A,B,C,D)
#endif

/*
** Macros for performance tracing.  Normally turned off.  Only works
** on i486 hardware.
*/
#ifdef SQLITE_PERFORMANCE_TRACE
__inline__ unsigned long long int hwtime(void){
  unsigned long long int x;
  __asm__("rdtsc\n\t"
          "mov %%edx, %%ecx\n\t"
          :"=A" (x));
  return x;
}
static unsigned long long int g_start;
static unsigned int elapse;
#define TIMER_START       g_start=hwtime()
#define TIMER_END         elapse=hwtime()-g_start
#define TIMER_ELAPSED     elapse
#else
#define TIMER_START
#define TIMER_END
#define TIMER_ELAPSED     0
#endif

/*
** If we compile with the SQLITE_TEST macro set, then the following block
** of code will give us the ability to simulate a disk I/O error.  This
** is used for testing the I/O recovery logic.
*/
#ifdef SQLITE_TEST
int sqlite3_io_error_hit = 0;
int sqlite3_io_error_pending = 0;
int sqlite3_io_error_persist = 0;
int sqlite3_diskfull_pending = 0;
int sqlite3_diskfull = 0;
#define SimulateIOError(CODE)  \
  if( sqlite3_io_error_pending || sqlite3_io_error_hit ) \
     if( sqlite3_io_error_pending-- == 1 \
         || (sqlite3_io_error_persist && sqlite3_io_error_hit) ) \
                { local_ioerr(); CODE; }
static void local_ioerr(){
  IOTRACE(("IOERR\n"));
  sqlite3_io_error_hit = 1;
}
#define SimulateDiskfullError(CODE) \
   if( sqlite3_diskfull_pending ){ \
     if( sqlite3_diskfull_pending == 1 ){ \
       local_ioerr(); \
       sqlite3_diskfull = 1; \
       sqlite3_io_error_hit = 1; \
       CODE; \
     }else{ \
       sqlite3_diskfull_pending--; \
     } \
   }
#else
#define SimulateIOError(A)
#define SimulateDiskfullError(A)
#endif

/*
** When testing, keep a count of the number of open files.
*/
#ifdef SQLITE_TEST
int sqlite3_open_file_count = 0;
#define OpenCounter(X)  sqlite3_open_file_count+=(X)
#else
#define OpenCounter(X)
#endif

/*
** sqlite3GenericMalloc
** sqlite3GenericRealloc
** sqlite3GenericOsFree
** sqlite3GenericAllocationSize
**
** Implementation of the os level dynamic memory allocation interface in terms
** of the standard malloc(), realloc() and free() found in many operating
** systems. No rocket science here.
**
** There are two versions of these four functions here. The version
** implemented here is only used if memory-management or memory-debugging is
** enabled. This version allocates an extra 8-bytes at the beginning of each
** block and stores the size of the allocation there.
**
** If neither memory-management or debugging is enabled, the second
** set of implementations is used instead.
*/
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || defined (SQLITE_MEMDEBUG)
void *sqlite3GenericMalloc(int n){
  char *p = (char *)malloc(n+8);
  assert(n>0);
  assert(sizeof(int)<=8);
  if( p ){
    *(int *)p = n;
    p += 8;
  }
  return (void *)p;
}
void *sqlite3GenericRealloc(void *p, int n){
  char *p2 = ((char *)p - 8);
  assert(n>0);
  p2 = (char*)realloc(p2, n+8);
  if( p2 ){
    *(int *)p2 = n;
    p2 += 8;
  }
  return (void *)p2;
}
void sqlite3GenericFree(void *p){
  assert(p);
  free((void *)((char *)p - 8));
}
int sqlite3GenericAllocationSize(void *p){
  return p ? *(int *)((char *)p - 8) : 0;
}
#else
void *sqlite3GenericMalloc(int n){
  char *p = (char *)malloc(n);
  return (void *)p;
}
void *sqlite3GenericRealloc(void *p, int n){
  assert(n>0);
  p = realloc(p, n);
  return p;
}
void sqlite3GenericFree(void *p){
  assert(p);
  free(p);
}
/* Never actually used, but needed for the linker */
int sqlite3GenericAllocationSize(void *p){ return 0; }
#endif

/*
** The default size of a disk sector
*/
#ifndef PAGER_SECTOR_SIZE
# define PAGER_SECTOR_SIZE 512
#endif