Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Remove the mutex counter and the logic that attempts to verify that btree mutexes are held continuously. We are not making that assumption at this time. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
242ce7cff416a87d57d4eb624cb79fa4 |
User & Date: | drh 2011-04-05 17:31:56 |
Context
2011-04-05
| ||
18:34 | Remove dead code from the OP_JournalMode opcode in the VDBE. This code seems to have been useless since [f88c6367d2] on 2010-08-07. check-in: a89f24e2 user: drh tags: trunk | |
17:31 | Remove the mutex counter and the logic that attempts to verify that btree mutexes are held continuously. We are not making that assumption at this time. check-in: 242ce7cf user: drh tags: trunk | |
16:09 | When committing a WAL transaction, do not write any pages to the WAL file with page numbers greater than the size of the database image in pages. check-in: 311d0b61 user: dan tags: trunk | |
Changes
Changes to src/btmutex.c.
41 41 static void unlockBtreeMutex(Btree *p){ 42 42 BtShared *pBt = p->pBt; 43 43 assert( p->locked==1 ); 44 44 assert( sqlite3_mutex_held(pBt->mutex) ); 45 45 assert( sqlite3_mutex_held(p->db->mutex) ); 46 46 assert( p->db==pBt->db ); 47 47 48 - pBt->iMutexCounter++; 49 48 sqlite3_mutex_leave(pBt->mutex); 50 49 p->locked = 0; 51 50 } 52 51 53 -#ifdef SQLITE_DEBUG 54 -/* 55 -** Return the number of times that the mutex has been exited for 56 -** the given btree. 57 -** 58 -** This is a small circular counter that wraps around to zero on 59 -** overflow. It is used only for sanity checking - to verify that 60 -** mutexes are held continously by asserting that the value of 61 -** this counter at the beginning of a region is the same as at 62 -** the end. 63 -*/ 64 -u32 sqlite3BtreeMutexCounter(Btree *p){ 65 - assert( p->locked==1 || p->sharable==0 ); 66 - return p->pBt->iMutexCounter; 67 -} 68 -#endif 69 - 70 52 /* 71 53 ** Enter a mutex on the given BTree object. 72 54 ** 73 55 ** If the object is not sharable, then no mutex is ever required 74 56 ** and this routine is a no-op. The underlying mutex is non-recursive. 75 57 ** But we keep a reference count in Btree.wantToLock so the behavior 76 58 ** of this interface is recursive. ................................................................................ 107 89 ** should already be set correctly. */ 108 90 assert( (p->locked==0 && p->sharable) || p->pBt->db==p->db ); 109 91 110 92 if( !p->sharable ) return; 111 93 p->wantToLock++; 112 94 if( p->locked ) return; 113 95 114 - /* Increment the mutex counter on all locked btrees in the same 115 - ** database connection. This simulates the unlocking that would 116 - ** occur on a worst-case mutex dead-lock avoidance scenario. 117 - */ 118 -#ifdef SQLITE_DEBUG 119 - { 120 - int ii; 121 - sqlite3 *db = p->db; 122 - Btree *pOther; 123 - for(ii=0; ii<db->nDb; ii++){ 124 - if( ii==1 ) continue; 125 - pOther = db->aDb[ii].pBt; 126 - if( pOther==0 || pOther->sharable==0 || pOther->locked==0 ) continue; 127 - pOther->pBt->iMutexCounter++; 128 - } 129 - } 130 -#endif 131 - 132 96 /* In most cases, we should be able to acquire the lock we 133 97 ** want without having to go throught the ascending lock 134 98 ** procedure that follows. Just be sure not to block. 135 99 */ 136 100 if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ 137 101 p->pBt->db = p->db; 138 102 p->locked = 1;
Changes to src/btree.h.
217 217 void sqlite3BtreeLeaveCursor(BtCursor*); 218 218 void sqlite3BtreeLeaveAll(sqlite3*); 219 219 #ifndef NDEBUG 220 220 /* These routines are used inside assert() statements only. */ 221 221 int sqlite3BtreeHoldsMutex(Btree*); 222 222 int sqlite3BtreeHoldsAllMutexes(sqlite3*); 223 223 int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); 224 - u32 sqlite3BtreeMutexCounter(Btree*); 225 224 #endif 226 225 #else 227 226 228 227 # define sqlite3BtreeLeave(X) 229 -# define sqlite3BtreeMutexCounter(X) 0 230 228 # define sqlite3BtreeEnterCursor(X) 231 229 # define sqlite3BtreeLeaveCursor(X) 232 230 # define sqlite3BtreeLeaveAll(X) 233 231 234 232 # define sqlite3BtreeHoldsMutex(X) 1 235 233 # define sqlite3BtreeHoldsAllMutexes(X) 1 236 -# define sqlite3BtreeSchemaMutexHeld(X,Y) 1 234 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 237 235 #endif 238 236 239 237 240 238 #endif /* _BTREE_H_ */
Changes to src/btreeInt.h.
431 431 #ifndef SQLITE_OMIT_SHARED_CACHE 432 432 int nRef; /* Number of references to this structure */ 433 433 BtShared *pNext; /* Next on a list of sharable BtShared structs */ 434 434 BtLock *pLock; /* List of locks held on this shared-btree struct */ 435 435 Btree *pWriter; /* Btree with currently open write transaction */ 436 436 u8 isExclusive; /* True if pWriter has an EXCLUSIVE lock on the db */ 437 437 u8 isPending; /* If waiting for read-locks to clear */ 438 - u16 iMutexCounter; /* The number of mutex_leave(mutex) calls */ 439 438 #endif 440 439 u8 *pTmpSpace; /* BtShared.pageSize bytes of space for tmp use */ 441 440 }; 442 441 443 442 /* 444 443 ** An instance of the following structure is used to hold information 445 444 ** about a cell. The parseCellPtr() function fills in this structure
Changes to src/vdbe.c.
1390 1390 if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ 1391 1391 assert( pOp>aOp ); 1392 1392 assert( pOp[-1].p4type==P4_COLLSEQ ); 1393 1393 assert( pOp[-1].opcode==OP_CollSeq ); 1394 1394 ctx.pColl = pOp[-1].p4.pColl; 1395 1395 } 1396 1396 (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */ 1397 - sqlite3VdbeMutexResync(p); 1398 1397 if( db->mallocFailed ){ 1399 1398 /* Even though a malloc() has failed, the implementation of the 1400 1399 ** user function may have called an sqlite3_result_XXX() function 1401 1400 ** to return a value. The following call releases any resources 1402 1401 ** associated with such a value. 1403 1402 */ 1404 1403 sqlite3VdbeMemRelease(&ctx.s); ................................................................................ 2656 2655 if( rc!=SQLITE_OK ){ 2657 2656 goto abort_due_to_error; 2658 2657 } 2659 2658 } 2660 2659 if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ 2661 2660 sqlite3ExpirePreparedStatements(db); 2662 2661 sqlite3ResetInternalSchema(db, -1); 2663 - sqlite3VdbeMutexResync(p); 2664 2662 db->flags = (db->flags | SQLITE_InternChanges); 2665 2663 } 2666 2664 } 2667 2665 2668 2666 /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all 2669 2667 ** savepoints nested inside of the savepoint being operated on. */ 2670 2668 while( db->pSavepoint!=pSavepoint ){ ................................................................................ 5194 5192 if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ 5195 5193 assert( pOp>p->aOp ); 5196 5194 assert( pOp[-1].p4type==P4_COLLSEQ ); 5197 5195 assert( pOp[-1].opcode==OP_CollSeq ); 5198 5196 ctx.pColl = pOp[-1].p4.pColl; 5199 5197 } 5200 5198 (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */ 5201 - sqlite3VdbeMutexResync(p); 5202 5199 if( ctx.isError ){ 5203 5200 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s)); 5204 5201 rc = ctx.isError; 5205 5202 } 5206 5203 5207 - /* The app-defined function has done something that as caused this 5208 - ** statement to expire. (Perhaps the function called sqlite3_exec() 5209 - ** with a CREATE TABLE statement.) 5210 - */ 5211 -#if 0 5212 - if( p->expired ){ 5213 - rc = SQLITE_ABORT; 5214 - break; 5215 - } 5216 -#endif 5217 - 5218 5204 sqlite3VdbeMemRelease(&ctx.s); 5219 5205 5220 5206 break; 5221 5207 } 5222 5208 5223 5209 /* Opcode: AggFinal P1 P2 * P4 * 5224 5210 ** ................................................................................ 5234 5220 */ 5235 5221 case OP_AggFinal: { 5236 5222 Mem *pMem; 5237 5223 assert( pOp->p1>0 && pOp->p1<=p->nMem ); 5238 5224 pMem = &aMem[pOp->p1]; 5239 5225 assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); 5240 5226 rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); 5241 - sqlite3VdbeMutexResync(p); 5242 5227 if( rc ){ 5243 5228 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem)); 5244 - }else if( p->expired ){ 5245 - rc = SQLITE_ABORT; 5246 5229 } 5247 5230 sqlite3VdbeChangeEncoding(pMem, encoding); 5248 5231 UPDATE_MAX_BLOBSIZE(pMem); 5249 5232 if( sqlite3VdbeMemTooBig(pMem) ){ 5250 5233 goto too_big; 5251 5234 } 5252 5235 break;
Changes to src/vdbeInt.h.
299 299 u8 minWriteFileFormat; /* Minimum file format for writable database files */ 300 300 u8 inVtabMethod; /* See comments above */ 301 301 u8 usesStmtJournal; /* True if uses a statement journal */ 302 302 u8 readOnly; /* True for read-only statements */ 303 303 u8 isPrepareV2; /* True if prepared with prepare_v2() */ 304 304 int nChange; /* Number of db changes made since last reset */ 305 305 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ 306 - u32 iMutexCounter; /* Mutex counter upon sqlite3VdbeEnter() */ 307 306 int iStatement; /* Statement number (or 0 if has not opened stmt) */ 308 307 int aCounter[3]; /* Counters used by sqlite3_stmt_status() */ 309 308 #ifndef SQLITE_OMIT_TRACE 310 309 i64 startTime; /* Time when query started - used for profiling */ 311 310 #endif 312 311 i64 nFkConstraint; /* Number of imm. FK constraints this VM */ 313 312 i64 nStmtDefCons; /* Number of def. constraints when stmt started */ ................................................................................ 383 382 int sqlite3VdbeMemFinalize(Mem*, FuncDef*); 384 383 const char *sqlite3OpcodeName(int); 385 384 int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); 386 385 int sqlite3VdbeCloseStatement(Vdbe *, int); 387 386 void sqlite3VdbeFrameDelete(VdbeFrame*); 388 387 int sqlite3VdbeFrameRestore(VdbeFrame *); 389 388 void sqlite3VdbeMemStoreType(Mem *pMem); 389 + 390 +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 390 391 void sqlite3VdbeEnter(Vdbe*); 391 392 void sqlite3VdbeLeave(Vdbe*); 392 -void sqlite3VdbeMutexResync(Vdbe*); 393 +#else 394 +# define sqlite3VdbeEnter(X) 395 +# define sqlite3VdbeLeave(X) 396 +#endif 393 397 394 398 #ifdef SQLITE_DEBUG 395 399 void sqlite3VdbeMemPrepareToChange(Vdbe*,Mem*); 396 400 #endif 397 401 398 402 #ifndef SQLITE_OMIT_FOREIGN_KEY 399 403 int sqlite3VdbeCheckFk(Vdbe *, int);
Changes to src/vdbeaux.c.
956 956 */ 957 957 void sqlite3VdbeUsesBtree(Vdbe *p, int i){ 958 958 assert( i>=0 && i<p->db->nDb && i<sizeof(yDbMask)*8 ); 959 959 assert( i<(int)sizeof(p->btreeMask)*8 ); 960 960 p->btreeMask |= ((yDbMask)1)<<i; 961 961 } 962 962 963 -/* 964 -** Compute the sum of all mutex counters for all btrees in the 965 -** given prepared statement. 966 -*/ 967 -#ifndef SQLITE_OMIT_SHARED_CACHE 968 -static u32 mutexCounterSum(Vdbe *p){ 969 - u32 cntSum = 0; 970 -#ifdef SQLITE_DEBUG 971 - int i; 972 - yDbMask mask; 973 - sqlite3 *db = p->db; 974 - Db *aDb = db->aDb; 975 - int nDb = db->nDb; 976 - for(i=0, mask=1; i<nDb; i++, mask += mask){ 977 - if( i!=1 && (mask & p->btreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ 978 - cntSum += sqlite3BtreeMutexCounter(aDb[i].pBt); 979 - } 980 - } 981 -#else 982 - UNUSED_PARAMETER(p); 983 -#endif 984 - return cntSum; 985 -} 986 -#endif 987 - 963 +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 988 964 /* 989 965 ** If SQLite is compiled to support shared-cache mode and to be threadsafe, 990 966 ** this routine obtains the mutex associated with each BtShared structure 991 967 ** that may be accessed by the VM passed as an argument. In doing so it also 992 968 ** sets the BtShared.db member of each of the BtShared structures, ensuring 993 969 ** that the correct busy-handler callback is invoked if required. 994 970 ** ................................................................................ 1003 979 ** The p->btreeMask field is a bitmask of all btrees that the prepared 1004 980 ** statement p will ever use. Let N be the number of bits in p->btreeMask 1005 981 ** corresponding to btrees that use shared cache. Then the runtime of 1006 982 ** this routine is N*N. But as N is rarely more than 1, this should not 1007 983 ** be a problem. 1008 984 */ 1009 985 void sqlite3VdbeEnter(Vdbe *p){ 1010 -#ifndef SQLITE_OMIT_SHARED_CACHE 1011 986 int i; 1012 987 yDbMask mask; 1013 988 sqlite3 *db = p->db; 1014 989 Db *aDb = db->aDb; 1015 990 int nDb = db->nDb; 1016 991 for(i=0, mask=1; i<nDb; i++, mask += mask){ 1017 992 if( i!=1 && (mask & p->btreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ 1018 993 sqlite3BtreeEnter(aDb[i].pBt); 1019 994 } 1020 995 } 1021 - p->iMutexCounter = mutexCounterSum(p); 1022 -#else 1023 - UNUSED_PARAMETER(p); 996 +} 1024 997 #endif 1025 -} 1026 998 999 +#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 1027 1000 /* 1028 1001 ** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). 1029 1002 */ 1030 1003 void sqlite3VdbeLeave(Vdbe *p){ 1031 -#ifndef SQLITE_OMIT_SHARED_CACHE 1032 1004 int i; 1033 1005 yDbMask mask; 1034 1006 sqlite3 *db = p->db; 1035 1007 Db *aDb = db->aDb; 1036 1008 int nDb = db->nDb; 1037 1009 1038 - /* Assert that the all mutexes have been held continously since 1039 - ** the most recent sqlite3VdbeEnter() or sqlite3VdbeMutexResync(). 1040 - */ 1041 - assert( mutexCounterSum(p) == p->iMutexCounter ); 1042 - 1043 1010 for(i=0, mask=1; i<nDb; i++, mask += mask){ 1044 1011 if( i!=1 && (mask & p->btreeMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ 1045 1012 sqlite3BtreeLeave(aDb[i].pBt); 1046 1013 } 1047 1014 } 1048 -#else 1049 - UNUSED_PARAMETER(p); 1015 +} 1050 1016 #endif 1051 -} 1052 - 1053 -/* 1054 -** Recompute the sum of the mutex counters on all btrees used by the 1055 -** prepared statement p. 1056 -** 1057 -** Call this routine while holding a sqlite3VdbeEnter() after doing something 1058 -** that might cause one or more of the individual mutexes held by the 1059 -** prepared statement to be released. Calling sqlite3BtreeEnter() on 1060 -** any BtShared mutex which is not used by the prepared statement is one 1061 -** way to cause one or more of the mutexes in the prepared statement 1062 -** to be temporarily released. The anti-deadlocking logic in 1063 -** sqlite3BtreeEnter() can cause mutexes to be released temporarily then 1064 -** reacquired. 1065 -** 1066 -** Calling this routine is an acknowledgement that some of the individual 1067 -** mutexes in the prepared statement might have been released and reacquired. 1068 -** So checks to verify that mutex-protected content did not change 1069 -** unexpectedly should accompany any call to this routine. 1070 -*/ 1071 -void sqlite3VdbeMutexResync(Vdbe *p){ 1072 -#if !defined(SQLITE_OMIT_SHARED_CACHE) && defined(SQLITE_DEBUG) 1073 - p->iMutexCounter = mutexCounterSum(p); 1074 -#else 1075 - UNUSED_PARAMETER(p); 1076 -#endif 1077 -} 1078 1017 1079 1018 #if defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) 1080 1019 /* 1081 1020 ** Print a single opcode. This routine is used for debugging only. 1082 1021 */ 1083 1022 void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ 1084 1023 char *zP4; ................................................................................ 2279 2218 /* Rollback or commit any schema changes that occurred. */ 2280 2219 if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){ 2281 2220 sqlite3ResetInternalSchema(db, -1); 2282 2221 db->flags = (db->flags | SQLITE_InternChanges); 2283 2222 } 2284 2223 2285 2224 /* Release the locks */ 2286 - sqlite3VdbeMutexResync(p); 2287 2225 sqlite3VdbeLeave(p); 2288 2226 } 2289 2227 2290 2228 /* We have successfully halted and closed the VM. Record this fact. */ 2291 2229 if( p->pc>=0 ){ 2292 2230 db->activeVdbeCnt--; 2293 2231 if( !p->readOnly ){