/ Check-in [242ce7cf]
Login

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: 242ce7cff416a87d57d4eb624cb79fa4e2215559
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
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

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 ){