Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: third_party/sqlite/sqlite-src-3100200/src/mem5.c

Issue 1610543003: [sql] Import reference version of SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 ** 2007 October 14 2 ** 2007 October 14
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
11 ************************************************************************* 11 *************************************************************************
12 ** This file contains the C functions that implement a memory 12 ** This file contains the C functions that implement a memory
13 ** allocation subsystem for use by SQLite. 13 ** allocation subsystem for use by SQLite.
14 ** 14 **
15 ** This version of the memory allocation subsystem omits all 15 ** This version of the memory allocation subsystem omits all
16 ** use of malloc(). The application gives SQLite a block of memory 16 ** use of malloc(). The application gives SQLite a block of memory
17 ** before calling sqlite3_initialize() from which allocations 17 ** before calling sqlite3_initialize() from which allocations
18 ** are made and returned by the xMalloc() and xRealloc() 18 ** are made and returned by the xMalloc() and xRealloc()
19 ** implementations. Once sqlite3_initialize() has been called, 19 ** implementations. Once sqlite3_initialize() has been called,
20 ** the amount of memory available to SQLite is fixed and cannot 20 ** the amount of memory available to SQLite is fixed and cannot
21 ** be changed. 21 ** be changed.
22 ** 22 **
23 ** This version of the memory allocation subsystem is included 23 ** This version of the memory allocation subsystem is included
24 ** in the build only if SQLITE_ENABLE_MEMSYS5 is defined. 24 ** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
25 ** 25 **
26 ** This memory allocator uses the following algorithm: 26 ** This memory allocator uses the following algorithm:
27 ** 27 **
28 ** 1. All memory allocations sizes are rounded up to a power of 2. 28 ** 1. All memory allocation sizes are rounded up to a power of 2.
29 ** 29 **
30 ** 2. If two adjacent free blocks are the halves of a larger block, 30 ** 2. If two adjacent free blocks are the halves of a larger block,
31 ** then the two blocks are coalesced into the single larger block. 31 ** then the two blocks are coalesced into the single larger block.
32 ** 32 **
33 ** 3. New memory is allocated from the first available free block. 33 ** 3. New memory is allocated from the first available free block.
34 ** 34 **
35 ** This algorithm is described in: J. M. Robson. "Bounds for Some Functions 35 ** This algorithm is described in: J. M. Robson. "Bounds for Some Functions
36 ** Concerning Dynamic Storage Allocation". Journal of the Association for 36 ** Concerning Dynamic Storage Allocation". Journal of the Association for
37 ** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499. 37 ** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499.
38 ** 38 **
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 u64 totalExcess; /* Total internal fragmentation */ 110 u64 totalExcess; /* Total internal fragmentation */
111 u32 currentOut; /* Current checkout, including internal fragmentation */ 111 u32 currentOut; /* Current checkout, including internal fragmentation */
112 u32 currentCount; /* Current number of distinct checkouts */ 112 u32 currentCount; /* Current number of distinct checkouts */
113 u32 maxOut; /* Maximum instantaneous currentOut */ 113 u32 maxOut; /* Maximum instantaneous currentOut */
114 u32 maxCount; /* Maximum instantaneous currentCount */ 114 u32 maxCount; /* Maximum instantaneous currentCount */
115 u32 maxRequest; /* Largest allocation (exclusive of internal frag) */ 115 u32 maxRequest; /* Largest allocation (exclusive of internal frag) */
116 116
117 /* 117 /*
118 ** Lists of free blocks. aiFreelist[0] is a list of free blocks of 118 ** Lists of free blocks. aiFreelist[0] is a list of free blocks of
119 ** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2. 119 ** size mem5.szAtom. aiFreelist[1] holds blocks of size szAtom*2.
120 ** and so forth. 120 ** aiFreelist[2] holds free blocks of size szAtom*4. And so forth.
121 */ 121 */
122 int aiFreelist[LOGMAX+1]; 122 int aiFreelist[LOGMAX+1];
123 123
124 /* 124 /*
125 ** Space for tracking which blocks are checked out and the size 125 ** Space for tracking which blocks are checked out and the size
126 ** of each block. One byte per block. 126 ** of each block. One byte per block.
127 */ 127 */
128 u8 *aCtrl; 128 u8 *aCtrl;
129 129
130 } mem5; 130 } mem5;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize]; 176 x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize];
177 MEM5LINK(i)->prev = -1; 177 MEM5LINK(i)->prev = -1;
178 if( x>=0 ){ 178 if( x>=0 ){
179 assert( x<mem5.nBlock ); 179 assert( x<mem5.nBlock );
180 MEM5LINK(x)->prev = i; 180 MEM5LINK(x)->prev = i;
181 } 181 }
182 mem5.aiFreelist[iLogsize] = i; 182 mem5.aiFreelist[iLogsize] = i;
183 } 183 }
184 184
185 /* 185 /*
186 ** If the STATIC_MEM mutex is not already held, obtain it now. The mutex 186 ** Obtain or release the mutex needed to access global data structures.
187 ** will already be held (obtained by code in malloc.c) if
188 ** sqlite3GlobalConfig.bMemStat is true.
189 */ 187 */
190 static void memsys5Enter(void){ 188 static void memsys5Enter(void){
191 sqlite3_mutex_enter(mem5.mutex); 189 sqlite3_mutex_enter(mem5.mutex);
192 } 190 }
193 static void memsys5Leave(void){ 191 static void memsys5Leave(void){
194 sqlite3_mutex_leave(mem5.mutex); 192 sqlite3_mutex_leave(mem5.mutex);
195 } 193 }
196 194
197 /* 195 /*
198 ** Return the size of an outstanding allocation, in bytes. The 196 ** Return the size of an outstanding allocation, in bytes.
199 ** size returned omits the 8-byte header overhead. This only 197 ** This only works for chunks that are currently checked out.
200 ** works for chunks that are currently checked out.
201 */ 198 */
202 static int memsys5Size(void *p){ 199 static int memsys5Size(void *p){
203 int iSize = 0; 200 int iSize, i;
204 if( p ){ 201 assert( p!=0 );
205 int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom); 202 i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
206 assert( i>=0 && i<mem5.nBlock ); 203 assert( i>=0 && i<mem5.nBlock );
207 iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE)); 204 iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
208 }
209 return iSize; 205 return iSize;
210 } 206 }
211 207
212 /* 208 /*
213 ** Return a block of memory of at least nBytes in size. 209 ** Return a block of memory of at least nBytes in size.
214 ** Return NULL if unable. Return NULL if nBytes==0. 210 ** Return NULL if unable. Return NULL if nBytes==0.
215 ** 211 **
216 ** The caller guarantees that nByte is positive. 212 ** The caller guarantees that nByte is positive.
217 ** 213 **
218 ** The caller has obtained a mutex prior to invoking this 214 ** The caller has obtained a mutex prior to invoking this
219 ** routine so there is never any chance that two or more 215 ** routine so there is never any chance that two or more
220 ** threads can be in this routine at the same time. 216 ** threads can be in this routine at the same time.
221 */ 217 */
222 static void *memsys5MallocUnsafe(int nByte){ 218 static void *memsys5MallocUnsafe(int nByte){
223 int i; /* Index of a mem5.aPool[] slot */ 219 int i; /* Index of a mem5.aPool[] slot */
224 int iBin; /* Index into mem5.aiFreelist[] */ 220 int iBin; /* Index into mem5.aiFreelist[] */
225 int iFullSz; /* Size of allocation rounded up to power of 2 */ 221 int iFullSz; /* Size of allocation rounded up to power of 2 */
226 int iLogsize; /* Log2 of iFullSz/POW2_MIN */ 222 int iLogsize; /* Log2 of iFullSz/POW2_MIN */
227 223
228 /* nByte must be a positive */ 224 /* nByte must be a positive */
229 assert( nByte>0 ); 225 assert( nByte>0 );
230 226
231 /* Keep track of the maximum allocation request. Even unfulfilled 227 /* Keep track of the maximum allocation request. Even unfulfilled
232 ** requests are counted */ 228 ** requests are counted */
233 if( (u32)nByte>mem5.maxRequest ){ 229 if( (u32)nByte>mem5.maxRequest ){
230 /* Abort if the requested allocation size is larger than the largest
231 ** power of two that we can represent using 32-bit signed integers. */
232 if( nByte > 0x40000000 ) return 0;
234 mem5.maxRequest = nByte; 233 mem5.maxRequest = nByte;
235 } 234 }
236 235
237 /* Abort if the requested allocation size is larger than the largest
238 ** power of two that we can represent using 32-bit signed integers.
239 */
240 if( nByte > 0x40000000 ){
241 return 0;
242 }
243
244 /* Round nByte up to the next valid power of two */ 236 /* Round nByte up to the next valid power of two */
245 for(iFullSz=mem5.szAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){ } 237 for(iFullSz=mem5.szAtom,iLogsize=0; iFullSz<nByte; iFullSz*=2,iLogsize++){}
246 238
247 /* Make sure mem5.aiFreelist[iLogsize] contains at least one free 239 /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
248 ** block. If not, then split a block of the next larger power of 240 ** block. If not, then split a block of the next larger power of
249 ** two in order to create a new free block of size iLogsize. 241 ** two in order to create a new free block of size iLogsize.
250 */ 242 */
251 for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){} 243 for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){}
252 if( iBin>LOGMAX ){ 244 if( iBin>LOGMAX ){
253 testcase( sqlite3GlobalConfig.xLog!=0 ); 245 testcase( sqlite3GlobalConfig.xLog!=0 );
254 sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); 246 sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
255 return 0; 247 return 0;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 assert( pPrior!=0 ); 384 assert( pPrior!=0 );
393 assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */ 385 assert( (nBytes&(nBytes-1))==0 ); /* EV: R-46199-30249 */
394 assert( nBytes>=0 ); 386 assert( nBytes>=0 );
395 if( nBytes==0 ){ 387 if( nBytes==0 ){
396 return 0; 388 return 0;
397 } 389 }
398 nOld = memsys5Size(pPrior); 390 nOld = memsys5Size(pPrior);
399 if( nBytes<=nOld ){ 391 if( nBytes<=nOld ){
400 return pPrior; 392 return pPrior;
401 } 393 }
402 memsys5Enter(); 394 p = memsys5Malloc(nBytes);
403 p = memsys5MallocUnsafe(nBytes);
404 if( p ){ 395 if( p ){
405 memcpy(p, pPrior, nOld); 396 memcpy(p, pPrior, nOld);
406 memsys5FreeUnsafe(pPrior); 397 memsys5Free(pPrior);
407 } 398 }
408 memsys5Leave();
409 return p; 399 return p;
410 } 400 }
411 401
412 /* 402 /*
413 ** Round up a request size to the next valid allocation size. If 403 ** Round up a request size to the next valid allocation size. If
414 ** the allocation is too large to be handled by this allocation system, 404 ** the allocation is too large to be handled by this allocation system,
415 ** return 0. 405 ** return 0.
416 ** 406 **
417 ** All allocations must be a power of two and must be expressed by a 407 ** All allocations must be a power of two and must be expressed by a
418 ** 32-bit signed integer. Hence the largest allocation is 0x40000000 408 ** 32-bit signed integer. Hence the largest allocation is 0x40000000
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 memsys5Size, 557 memsys5Size,
568 memsys5Roundup, 558 memsys5Roundup,
569 memsys5Init, 559 memsys5Init,
570 memsys5Shutdown, 560 memsys5Shutdown,
571 0 561 0
572 }; 562 };
573 return &memsys5Methods; 563 return &memsys5Methods;
574 } 564 }
575 565
576 #endif /* SQLITE_ENABLE_MEMSYS5 */ 566 #endif /* SQLITE_ENABLE_MEMSYS5 */
OLDNEW
« no previous file with comments | « third_party/sqlite/sqlite-src-3100200/src/mem3.c ('k') | third_party/sqlite/sqlite-src-3100200/src/memjournal.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698