/ Check-in [391c9b85]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Change the definition of SQLITE_CONFIG_SCRATCH so that at most one scratch buffer is used per thread. Use the generic heap memory allocator for the WalIterator object when running a checkpoint.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 391c9b85abcb5ba300fb2e116384639310c69ed2
User & Date: drh 2014-11-04 14:22:27
Context
2014-11-04
17:23
Add various requirements evidence marks for sqlite3_config() options. check-in: d423349d user: drh tags: trunk
14:22
Change the definition of SQLITE_CONFIG_SCRATCH so that at most one scratch buffer is used per thread. Use the generic heap memory allocator for the WalIterator object when running a checkpoint. check-in: 391c9b85 user: drh tags: trunk
13:41
Improved documentation and addition of source-code evidence marks for the sqlite3_config() interface. check-in: 681031a4 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  6646   6646     ** Allocate space for memory structures
  6647   6647     */
  6648   6648     szScratch =
  6649   6649          nMaxCells*sizeof(u8*)                       /* apCell */
  6650   6650        + nMaxCells*sizeof(u16)                       /* szCell */
  6651   6651        + pBt->pageSize;                              /* aSpace1 */
  6652   6652   
  6653         -  /* EVIDENCE-OF: R-37926-08392 SQLite will never request a scratch buffer
  6654         -  ** that is more than 6 times the database page size, except when
  6655         -  ** performing a checkpoint in WAL mode when the scratch buffer request
  6656         -  ** size is a small fraction of the size of the WAL file. */
         6653  +  /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
         6654  +  ** that is more than 6 times the database page size. */
  6657   6655     assert( szScratch<=6*pBt->pageSize );
  6658         -
  6659   6656     apCell = sqlite3ScratchMalloc( szScratch ); 
  6660   6657     if( apCell==0 ){
  6661   6658       rc = SQLITE_NOMEM;
  6662   6659       goto balance_cleanup;
  6663   6660     }
  6664   6661     szCell = (u16*)&apCell[nMaxCells];
  6665   6662     aSpace1 = (u8*)&szCell[nMaxCells];

Changes to src/malloc.c.

   373    373       }
   374    374       sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
   375    375     }
   376    376     assert( sqlite3_mutex_notheld(mem0.mutex) );
   377    377   
   378    378   
   379    379   #if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
   380         -  /* Verify that no more than two scratch allocations per thread
   381         -  ** are outstanding at one time.  (This is only checked in the
   382         -  ** single-threaded case since checking in the multi-threaded case
   383         -  ** would be much more complicated.) */
   384         -  assert( scratchAllocOut<=1 );
          380  +  /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
          381  +  ** buffers per thread.
          382  +  **
          383  +  ** This can only be checked in single-threaded mode.
          384  +  */
          385  +  assert( scratchAllocOut==0 );
   385    386     if( p ) scratchAllocOut++;
   386    387   #endif
   387    388   
   388    389     return p;
   389    390   }
   390    391   void sqlite3ScratchFree(void *p){
   391    392     if( p ){

Changes to src/sqlite.h.in.

  1537   1537   ** that SQLite can use for scratch memory.  ^(There are three arguments
  1538   1538   ** to SQLITE_CONFIG_SCRATCH:  A pointer an 8-byte
  1539   1539   ** aligned memory buffer from which the scratch allocations will be
  1540   1540   ** drawn, the size of each scratch allocation (sz),
  1541   1541   ** and the maximum number of scratch allocations (N).)^
  1542   1542   ** The first argument must be a pointer to an 8-byte aligned buffer
  1543   1543   ** of at least sz*N bytes of memory.
  1544         -** ^SQLite will not use more than two scratch buffers per thread and not
  1545         -** more than one scratch buffer per thread when not performing
  1546         -** a [checkpoint] in [WAL mode].
         1544  +** ^SQLite will not use more than one scratch buffers per thread.
  1547   1545   ** ^SQLite will never request a scratch buffer that is more than 6
  1548         -** times the database page size, except when performing a [checkpoint]
  1549         -** in [WAL mode] when the scratch buffer request size is a small fraction
  1550         -** of the size of the WAL file.
         1546  +** times the database page size.
  1551   1547   ** ^If SQLite needs needs additional
  1552   1548   ** scratch memory beyond what is provided by this configuration option, then 
  1553   1549   ** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
  1554   1550   ** ^When the application provides any amount of scratch memory using
  1555   1551   ** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
  1556   1552   ** [sqlite3_malloc|heap allocations].
  1557   1553   ** This can help [Robson proof|prevent memory allocation failures] due to heap

Changes to src/wal.c.

  1500   1500   #endif
  1501   1501   }
  1502   1502   
  1503   1503   /* 
  1504   1504   ** Free an iterator allocated by walIteratorInit().
  1505   1505   */
  1506   1506   static void walIteratorFree(WalIterator *p){
  1507         -  sqlite3ScratchFree(p);
         1507  +  sqlite3_free(p);
  1508   1508   }
  1509   1509   
  1510   1510   /*
  1511   1511   ** Construct a WalInterator object that can be used to loop over all 
  1512   1512   ** pages in the WAL in ascending order. The caller must hold the checkpoint
  1513   1513   ** lock.
  1514   1514   **
................................................................................
  1535   1535     iLast = pWal->hdr.mxFrame;
  1536   1536   
  1537   1537     /* Allocate space for the WalIterator object. */
  1538   1538     nSegment = walFramePage(iLast) + 1;
  1539   1539     nByte = sizeof(WalIterator) 
  1540   1540           + (nSegment-1)*sizeof(struct WalSegment)
  1541   1541           + iLast*sizeof(ht_slot);
  1542         -  p = (WalIterator *)sqlite3ScratchMalloc(nByte);
         1542  +  p = (WalIterator *)sqlite3_malloc(nByte);
  1543   1543     if( !p ){
  1544   1544       return SQLITE_NOMEM;
  1545   1545     }
  1546   1546     memset(p, 0, nByte);
  1547   1547     p->nSegment = nSegment;
  1548   1548   
  1549   1549     /* Allocate temporary space used by the merge-sort routine. This block
  1550   1550     ** of memory will be freed before this function returns.
  1551   1551     */
  1552         -  aTmp = (ht_slot *)sqlite3ScratchMalloc(
         1552  +  aTmp = (ht_slot *)sqlite3_malloc(
  1553   1553         sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
  1554   1554     );
  1555   1555     if( !aTmp ){
  1556   1556       rc = SQLITE_NOMEM;
  1557   1557     }
  1558   1558   
  1559   1559     for(i=0; rc==SQLITE_OK && i<nSegment; i++){
................................................................................
  1582   1582         walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
  1583   1583         p->aSegment[i].iZero = iZero;
  1584   1584         p->aSegment[i].nEntry = nEntry;
  1585   1585         p->aSegment[i].aIndex = aIndex;
  1586   1586         p->aSegment[i].aPgno = (u32 *)aPgno;
  1587   1587       }
  1588   1588     }
  1589         -  sqlite3ScratchFree(aTmp);
         1589  +  sqlite3_free(aTmp);
  1590   1590   
  1591   1591     if( rc!=SQLITE_OK ){
  1592   1592       walIteratorFree(p);
  1593   1593     }
  1594   1594     *pp = p;
  1595   1595     return rc;
  1596   1596   }