Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Changes to delay freeing buffers associated with vdbe memory cells until either sqlite3_finalize() or sqlite3_release_memory() is called. (CVS 4922) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8c2f69521f13bc24cf005520efbe0589 |
User & Date: | danielk1977 2008-03-26 18:34:43.000 |
Context
2008-03-27
| ||
15:07 | Added the speed4p.test script for testing performance of views and triggers. (CVS 4923) (check-in: adf7645f9a user: drh tags: trunk) | |
2008-03-26
| ||
18:34 | Changes to delay freeing buffers associated with vdbe memory cells until either sqlite3_finalize() or sqlite3_release_memory() is called. (CVS 4922) (check-in: 8c2f69521f user: danielk1977 tags: trunk) | |
17:18 | Work around problems with compilers that do not allow C preprocessor macros with empty arguments. (CVS 4921) (check-in: afe1963ec5 user: drh tags: trunk) | |
Changes
Changes to src/malloc.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** ** $Id: malloc.c,v 1.15 2008/03/26 18:34:43 danielk1977 Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** This routine runs when the memory allocator sees that the |
︙ | ︙ | |||
55 56 57 58 59 60 61 | } /* ** Release memory held by SQLite instances created by the current thread. */ int sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT | > | > | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | } /* ** Release memory held by SQLite instances created by the current thread. */ int sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int nRet = sqlite3VdbeReleaseMemory(n); nRet += sqlite3PagerReleaseMemory(n-nRet); return nRet; #else return SQLITE_OK; #endif } /* |
︙ | ︙ |
Changes to src/mutex.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** exclusion and is thus suitable for use only in applications ** that use SQLite in a single thread. But this implementation ** does do a lot of error checking on mutexes to make sure they ** are called correctly and at appropriate times. Hence, this ** implementation is suitable for testing. ** debugging purposes ** | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ** exclusion and is thus suitable for use only in applications ** that use SQLite in a single thread. But this implementation ** does do a lot of error checking on mutexes to make sure they ** are called correctly and at appropriate times. Hence, this ** implementation is suitable for testing. ** debugging purposes ** ** $Id: mutex.c,v 1.17 2008/03/26 18:34:43 danielk1977 Exp $ */ #include "sqliteInt.h" #ifdef SQLITE_MUTEX_NOOP_DEBUG /* ** In this implementation, mutexes do not provide any mutual exclusion. ** But the error checking is provided. This implementation is useful |
︙ | ︙ | |||
40 41 42 43 44 45 46 | /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. */ sqlite3_mutex *sqlite3_mutex_alloc(int id){ | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* ** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. */ sqlite3_mutex *sqlite3_mutex_alloc(int id){ static sqlite3_mutex aStatic[6]; sqlite3_mutex *pNew = 0; switch( id ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { pNew = sqlite3_malloc(sizeof(*pNew)); if( pNew ){ pNew->id = id; |
︙ | ︙ |
Changes to src/mutex_os2.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2007 August 28 ** ** 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 the C functions that implement mutexes for OS/2 ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2007 August 28 ** ** 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 the C functions that implement mutexes for OS/2 ** ** $Id: mutex_os2.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The code in this file is only used if SQLITE_MUTEX_OS2 is defined. ** See the mutex.h file for details. */ |
︙ | ︙ | |||
92 93 94 95 96 97 98 99 100 101 102 103 104 105 | } } break; } default: { static volatile int isInit = 0; static sqlite3_mutex staticMutexes[] = { { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, }; if ( !isInit ){ | > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | } } break; } default: { static volatile int isInit = 0; static sqlite3_mutex staticMutexes[] = { { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, { OS2_MUTEX_INITIALIZER, }, }; if ( !isInit ){ |
︙ | ︙ |
Changes to src/mutex_unix.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2007 August 28 ** ** 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 the C functions that implement mutexes for pthreads ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2007 August 28 ** ** 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 the C functions that implement mutexes for pthreads ** ** $Id: mutex_unix.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The code in this file is only used if we are compiling threadsafe ** under unix with pthreads. ** |
︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 88 89 90 91 92 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ sqlite3_mutex *sqlite3_mutex_alloc(int iType){ static sqlite3_mutex staticMutexes[] = { { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, }; sqlite3_mutex *p; | > | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ sqlite3_mutex *sqlite3_mutex_alloc(int iType){ static sqlite3_mutex staticMutexes[] = { { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, { PTHREAD_MUTEX_INITIALIZER, }, }; sqlite3_mutex *p; |
︙ | ︙ |
Changes to src/mutex_w32.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2007 August 14 ** ** 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 the C functions that implement mutexes for win32 ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2007 August 14 ** ** 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 the C functions that implement mutexes for win32 ** ** $Id: mutex_w32.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $ */ #include "sqliteInt.h" /* ** The code in this file is only used if we are compiling multithreaded ** on a win32 system. */ |
︙ | ︙ | |||
107 108 109 110 111 112 113 | if( p ){ p->id = iType; InitializeCriticalSection(&p->mutex); } break; } default: { | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | if( p ){ p->id = iType; InitializeCriticalSection(&p->mutex); } break; } default: { static sqlite3_mutex staticMutexes[6]; static int isInit = 0; while( !isInit ){ static long lock = 0; if( InterlockedIncrement(&lock)==1 ){ int i; for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){ InitializeCriticalSection(&staticMutexes[i].mutex); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** ** @(#) $Id: sqlite.h.in,v 1.301 2008/03/26 18:34:43 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 | ** <li> SQLITE_MUTEX_FAST ** <li> SQLITE_MUTEX_RECURSIVE ** <li> SQLITE_MUTEX_STATIC_MASTER ** <li> SQLITE_MUTEX_STATIC_MEM ** <li> SQLITE_MUTEX_STATIC_MEM2 ** <li> SQLITE_MUTEX_STATIC_PRNG ** <li> SQLITE_MUTEX_STATIC_LRU ** </ul> {END} ** ** {F17015} The first two constants cause sqlite3_mutex_alloc() to create ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END} ** The mutex implementation does not need to make a distinction ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does | > | 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 | ** <li> SQLITE_MUTEX_FAST ** <li> SQLITE_MUTEX_RECURSIVE ** <li> SQLITE_MUTEX_STATIC_MASTER ** <li> SQLITE_MUTEX_STATIC_MEM ** <li> SQLITE_MUTEX_STATIC_MEM2 ** <li> SQLITE_MUTEX_STATIC_PRNG ** <li> SQLITE_MUTEX_STATIC_LRU ** <li> SQLITE_MUTEX_STATIC_LRU2 ** </ul> {END} ** ** {F17015} The first two constants cause sqlite3_mutex_alloc() to create ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. {END} ** The mutex implementation does not need to make a distinction ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does |
︙ | ︙ | |||
5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 | #define SQLITE_MUTEX_FAST 0 #define SQLITE_MUTEX_RECURSIVE 1 #define SQLITE_MUTEX_STATIC_MASTER 2 #define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ #define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ /* ** CAPI3REF: Low-Level Control Of Database Files {F11300} ** ** {F11301} The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated ** with a particular database identified by the second argument. {F11302} The | > | 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 | #define SQLITE_MUTEX_FAST 0 #define SQLITE_MUTEX_RECURSIVE 1 #define SQLITE_MUTEX_STATIC_MASTER 2 #define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ #define SQLITE_MUTEX_STATIC_MEM2 4 /* sqlite3_release_memory() */ #define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */ #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ #define SQLITE_MUTEX_STATIC_LRU2 7 /* lru page list */ /* ** CAPI3REF: Low-Level Control Of Database Files {F11300} ** ** {F11301} The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated ** with a particular database identified by the second argument. {F11302} The |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.129 2008/03/26 18:34:43 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
170 171 172 173 174 175 176 | int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG void sqlite3VdbeTrace(Vdbe*,FILE*); #endif void sqlite3VdbeResetStepResult(Vdbe*); | | > | 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 | int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG void sqlite3VdbeTrace(Vdbe*,FILE*); #endif void sqlite3VdbeResetStepResult(Vdbe*); int sqlite3VdbeReset(Vdbe*, int); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int); void sqlite3VdbeCountChanges(Vdbe*); sqlite3 *sqlite3VdbeDb(Vdbe*); void sqlite3VdbeSetSql(Vdbe*, const char *z, int n); void sqlite3VdbeSwap(Vdbe*,Vdbe*); int sqlite3VdbeReleaseMemory(int); UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,void*,int); void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); #ifndef NDEBUG void sqlite3VdbeComment(Vdbe*, const char*, ...); # define VdbeComment(X) sqlite3VdbeComment X #else # define VdbeComment(X) #endif #endif |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
329 330 331 332 333 334 335 336 337 338 339 340 341 342 | FILE *trace; /* Write an execution trace here, if not NULL */ #endif int openedStatement; /* True if this VM has opened a statement journal */ #ifdef SQLITE_SSE int fetchId; /* Statement number used by sqlite3_fetch_statement */ int lru; /* Counter used for LRU cache replacement */ #endif }; /* ** An instance of the following structure holds information about a ** single index record that has already been parsed out into individual ** values. ** | > > > > | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | FILE *trace; /* Write an execution trace here, if not NULL */ #endif int openedStatement; /* True if this VM has opened a statement journal */ #ifdef SQLITE_SSE int fetchId; /* Statement number used by sqlite3_fetch_statement */ int lru; /* Counter used for LRU cache replacement */ #endif #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Vdbe *pLruPrev; Vdbe *pLruNext; #endif }; /* ** An instance of the following structure holds information about a ** single index record that has already been parsed out into individual ** values. ** |
︙ | ︙ | |||
410 411 412 413 414 415 416 417 418 419 420 421 422 423 | int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeOpcodeHasProperty(int, int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); #ifndef NDEBUG void sqlite3VdbeMemSanity(Mem*); #endif int sqlite3VdbeMemTranslate(Mem*, u8); #ifdef SQLITE_DEBUG void sqlite3VdbePrintSql(Vdbe*); | > | 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeOpcodeHasProperty(int, int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); int sqlite3VdbeReleaseBuffers(Vdbe *p); #ifndef NDEBUG void sqlite3VdbeMemSanity(Mem*); #endif int sqlite3VdbeMemTranslate(Mem*, u8); #ifdef SQLITE_DEBUG void sqlite3VdbePrintSql(Vdbe*); |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. */ #include "sqliteInt.h" #include "vdbeInt.h" /* ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program ** that sqlite3_prepare() generates. For example, if new functions or ** collating sequences are registered or if an authorizer function is | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. */ #include "sqliteInt.h" #include "vdbeInt.h" #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* ** The following structure contains pointers to the end points of a ** doubly-linked list of all compiled SQL statements that may be holding ** buffers eligible for release when the sqlite3_release_memory() interface is ** invoked. Access to this list is protected by the SQLITE_MUTEX_STATIC_LRU2 ** mutex. ** ** Statements are added to the end of this list when sqlite3_reset() is ** called. They are removed either when sqlite3_step() or sqlite3_finalize() ** is called. When statements are added to this list, the associated ** register array (p->aMem[1..p->nMem]) may contain dynamic buffers that ** can be freed using sqlite3VdbeReleaseMemory(). ** ** When statements are added or removed from this list, the mutex ** associated with the Vdbe being added or removed (Vdbe.db->mutex) is ** already held. The LRU2 mutex is then obtained, blocking if necessary, ** the linked-list pointers manipulated and the LRU2 mutex relinquished. */ struct StatementLruList { Vdbe *pFirst; Vdbe *pLast; }; static struct StatementLruList sqlite3LruStatements; /* ** Check that the list looks to be internally consistent. This is used ** as part of an assert() statement as follows: ** ** assert( stmtLruCheck() ); */ static int stmtLruCheck(){ Vdbe *p; for(p=sqlite3LruStatements.pFirst; p; p=p->pLruNext){ assert(p->pLruNext || p==sqlite3LruStatements.pLast); assert(!p->pLruNext || p->pLruNext->pLruPrev==p); assert(p->pLruPrev || p==sqlite3LruStatements.pFirst); assert(!p->pLruPrev || p->pLruPrev->pLruNext==p); } return 1; } /* ** Add vdbe p to the end of the statement lru list. It is assumed that ** p is not already part of the list when this is called. The lru list ** is protected by the SQLITE_MUTEX_STATIC_LRU mutex. */ static void stmtLruAdd(Vdbe *p){ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){ sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); return; } assert( stmtLruCheck() ); if( !sqlite3LruStatements.pFirst ){ assert( !sqlite3LruStatements.pLast ); sqlite3LruStatements.pFirst = p; sqlite3LruStatements.pLast = p; }else{ assert( !sqlite3LruStatements.pLast->pLruNext ); p->pLruPrev = sqlite3LruStatements.pLast; sqlite3LruStatements.pLast->pLruNext = p; sqlite3LruStatements.pLast = p; } assert( stmtLruCheck() ); sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); } /* ** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove ** statement p from the least-recently-used statement list. If the ** statement is not currently part of the list, this call is a no-op. */ static void stmtLruRemoveNomutex(Vdbe *p){ if( p->pLruPrev || p->pLruNext || p==sqlite3LruStatements.pFirst ){ assert( stmtLruCheck() ); if( p->pLruNext ){ p->pLruNext->pLruPrev = p->pLruPrev; }else{ sqlite3LruStatements.pLast = p->pLruPrev; } if( p->pLruPrev ){ p->pLruPrev->pLruNext = p->pLruNext; }else{ sqlite3LruStatements.pFirst = p->pLruNext; } p->pLruNext = 0; p->pLruPrev = 0; assert( stmtLruCheck() ); } } /* ** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove ** statement p from the least-recently-used statement list. If the ** statement is not currently part of the list, this call is a no-op. */ static void stmtLruRemove(Vdbe *p){ sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); stmtLruRemoveNomutex(p); sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); } /* ** Try to release n bytes of memory by freeing buffers associated ** with the memory registers of currently unused vdbes. */ int sqlite3VdbeReleaseMemory(int n){ Vdbe *p; Vdbe *pNext; int nFree = 0; sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); for(p=sqlite3LruStatements.pFirst; p && nFree<n; p=pNext){ pNext = p->pLruNext; /* For each statement handle in the lru list, attempt to obtain the ** associated database mutex. If it cannot be obtained, continue ** to the next statement handle. It is not possible to block on ** the database mutex - that could cause deadlock. */ if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){ nFree += sqlite3VdbeReleaseBuffers(p); stmtLruRemoveNomutex(p); sqlite3_mutex_leave(p->db->mutex); } } sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2)); return nFree; } /* ** Call sqlite3Reprepare() on the statement. Remove it from the ** lru list before doing so, as Reprepare() will free all the ** memory register buffers anyway. */ int vdbeReprepare(Vdbe *p){ stmtLruRemove(p); return sqlite3Reprepare(p); } #else /* !SQLITE_ENABLE_MEMORY_MANAGEMENT */ #define stmtLruRemove(x) #define stmtLruAdd(x) #define vdbeReprepare(x) sqlite3Reprepare(x) #endif /* ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program ** that sqlite3_prepare() generates. For example, if new functions or ** collating sequences are registered or if an authorizer function is |
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = v->db->mutex; #endif sqlite3_mutex_enter(mutex); rc = sqlite3VdbeFinalize(v); sqlite3_mutex_leave(mutex); } return rc; } /* | > | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; #ifndef SQLITE_MUTEX_NOOP sqlite3_mutex *mutex = v->db->mutex; #endif sqlite3_mutex_enter(mutex); stmtLruRemove(v); rc = sqlite3VdbeFinalize(v); sqlite3_mutex_leave(mutex); } return rc; } /* |
︙ | ︙ | |||
65 66 67 68 69 70 71 | int sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); | | > | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | int sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v, 0); stmtLruAdd(v); sqlite3VdbeMakeReady(v, -1, 0, 0, 0); assert( (rc & (v->db->errMask))==rc ); sqlite3_mutex_leave(v->db->mutex); } return rc; } |
︙ | ︙ | |||
302 303 304 305 306 307 308 309 310 311 312 313 314 315 | sqlite3OsCurrentTime(db->pVfs, &rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif db->activeVdbeCnt++; p->pc = 0; } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { | > | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | sqlite3OsCurrentTime(db->pVfs, &rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif db->activeVdbeCnt++; p->pc = 0; stmtLruRemove(p); } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { |
︙ | ︙ | |||
373 374 375 376 377 378 379 | if( pStmt ){ int cnt = 0; Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; sqlite3_mutex_enter(db->mutex); while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < 5 | | | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | if( pStmt ){ int cnt = 0; Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; sqlite3_mutex_enter(db->mutex); while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < 5 && vdbeReprepare(v) ){ sqlite3_reset(pStmt); v->expired = 0; } if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){ /* This case occurs after failing to recompile an sql statement. ** The error message from the SQL compiler has already been loaded ** into the database handle. This block copies the error message |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
733 734 735 736 737 738 739 | fflush(pOut); } #endif /* ** Release an array of N Mem elements */ | | > | | > > > > > > > > > > > > > > > > > > > | 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | fflush(pOut); } #endif /* ** Release an array of N Mem elements */ static void releaseMemArray(Mem *p, int N, int freebuffers){ if( p && N ){ sqlite3 *db = p->db; int malloc_failed = db->mallocFailed; while( N-->0 ){ assert( N<2 || p[0].db==p[1].db ); if( freebuffers || p->xDel ){ sqlite3VdbeMemRelease(p); p->flags = MEM_Null; } p++; } db->mallocFailed = malloc_failed; } } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int sqlite3VdbeReleaseBuffers(Vdbe *p){ int ii; int nFree = 0; assert( sqlite3_mutex_held(p->db->mutex) ); for(ii=1; ii<=p->nMem; ii++){ Mem *pMem = &p->aMem[ii]; if( pMem->z && pMem->flags&MEM_Dyn ){ assert( !pMem->xDel ); nFree += sqlite3MallocSize(pMem->z); sqlite3VdbeMemRelease(pMem); } } return nFree; } #endif #ifndef SQLITE_OMIT_EXPLAIN /* ** Give a listing of the program in the virtual machine. ** ** The interface is the same as sqlite3VdbeExec(). But instead of ** running the code, it invokes the callback once for each instruction. |
︙ | ︙ | |||
776 777 778 779 780 781 782 | assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); /* Even though this opcode does not use dynamic strings for ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ | | | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); /* Even though this opcode does not use dynamic strings for ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, p->nMem, 1); do{ i = p->pc++; }while( i<p->nOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); if( i>=p->nOp ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; |
︙ | ︙ | |||
1006 1007 1008 1009 1010 1011 1012 | p->aMem[n].db = db; } } } #ifdef SQLITE_DEBUG for(n=1; n<p->nMem; n++){ assert( p->aMem[n].db==db ); | | | 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 | p->aMem[n].db = db; } } } #ifdef SQLITE_DEBUG for(n=1; n<p->nMem; n++){ assert( p->aMem[n].db==db ); //assert( p->aMem[n].flags==MEM_Null ); } #endif p->pc = -1; p->rc = SQLITE_OK; p->uniqueCnt = 0; p->returnDepth = 0; |
︙ | ︙ | |||
1086 1087 1088 1089 1090 1091 1092 | /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. It also deletes the values of ** variables in the aVar[] array. */ | | < | | 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 | /* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or ** sorters that were left open. It also deletes the values of ** variables in the aVar[] array. */ static void Cleanup(Vdbe *p, int freebuffers){ int i; closeAllCursorsExceptActiveVtabs(p); for(i=1; i<=p->nMem; i++){ MemSetTypeFlag(&p->aMem[i], MEM_Null); } releaseMemArray(&p->aMem[1], p->nMem, freebuffers); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; i<p->contextStackTop; i++){ sqlite3VdbeFifoClear(&p->contextStack[i].sFifo); } sqlite3_free(p->contextStack); } |
︙ | ︙ | |||
1119 1120 1121 1122 1123 1124 1125 | ** execution of the vdbe program so that sqlite3_column_count() can ** be called on an SQL statement before sqlite3_step(). */ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; | | | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | ** execution of the vdbe program so that sqlite3_column_count() can ** be called on an SQL statement before sqlite3_step(). */ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); sqlite3_free(p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = nResColumn; p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n ); if( p->aColName==0 ) return; while( n-- > 0 ){ pColName->flags = MEM_Null; |
︙ | ︙ | |||
1644 1645 1646 1647 1648 1649 1650 | ** After this routine is run, the VDBE should be ready to be executed ** again. ** ** To look at it another way, this routine resets the state of the ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ | | | 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 | ** After this routine is run, the VDBE should be ready to be executed ** again. ** ** To look at it another way, this routine resets the state of the ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ int sqlite3VdbeReset(Vdbe *p, int freebuffers){ sqlite3 *db; db = p->db; /* If the VM did not run to completion or if it encountered an ** error, then it might not have been halted properly. So halt ** it now. */ |
︙ | ︙ | |||
1683 1684 1685 1686 1687 1688 1689 | sqlite3Error(db, p->rc, 0); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free); p->zErrMsg = 0; } /* Reclaim all memory used by the VDBE */ | | | 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 | sqlite3Error(db, p->rc, 0); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3_free); p->zErrMsg = 0; } /* Reclaim all memory used by the VDBE */ Cleanup(p, freebuffers); /* Save profiling information from this VDBE run. */ #ifdef VDBE_PROFILE { FILE *out = fopen("vdbe_profile.out", "a"); if( out ){ |
︙ | ︙ | |||
1721 1722 1723 1724 1725 1726 1727 | /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ | | > | 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 | /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p, 1); assert( (rc & p->db->errMask)==rc ); }else if( p->magic!=VDBE_MAGIC_INIT ){ return SQLITE_MISUSE; } releaseMemArray(&p->aMem[1], p->nMem, 1); sqlite3VdbeDelete(p); return rc; } /* ** Call the destructor for each auxdata entry in pVdbeFunc for which ** the corresponding bit in mask is clear. Auxdata entries beyond 31 |
︙ | ︙ | |||
1755 1756 1757 1758 1759 1760 1761 | /* ** Delete an entire VDBE. */ void sqlite3VdbeDelete(Vdbe *p){ int i; if( p==0 ) return; | | | | | 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 | /* ** Delete an entire VDBE. */ void sqlite3VdbeDelete(Vdbe *p){ int i; if( p==0 ) return; Cleanup(p, 1); if( p->pPrev ){ p->pPrev->pNext = p->pNext; }else{ assert( p->db->pVdbe==p ); p->db->pVdbe = p->pNext; } if( p->pNext ){ p->pNext->pPrev = p->pPrev; } if( p->aOp ){ Op *pOp = p->aOp; for(i=0; i<p->nOp; i++, pOp++){ freeP4(pOp->p4type, pOp->p4.p); #ifdef SQLITE_DEBUG sqlite3_free(pOp->zComment); #endif } sqlite3_free(p->aOp); } releaseMemArray(p->aVar, p->nVar, 1); sqlite3_free(p->aLabel); if( p->aMem ){ sqlite3_free(&p->aMem[1]); } releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); sqlite3_free(p->aColName); sqlite3_free(p->zSql); p->magic = VDBE_MAGIC_DEAD; sqlite3_free(p); } /* |
︙ | ︙ |