/ Check-in [31eb4abc]
Login

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

Overview
Comment:Add asserts on sqlite3_mutex_held() to the zero-malloc memory allocator, in order to prove that the mutex is held when it is needed. (CVS 4534)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 31eb4abc89e9c0fd90fde5486d4008f9d09fdf4e
User & Date: drh 2007-11-07 15:13:25
Context
2007-11-11
18:36
Fix the code generation for UPDATE and DELETE so that BEFORE triggers that use RAISE(IGNORE) do not leave extra values on the stack. Ticket #2767 (CVS 4535) check-in: 3391f413 user: drh tags: trunk
2007-11-07
15:13
Add asserts on sqlite3_mutex_held() to the zero-malloc memory allocator, in order to prove that the mutex is held when it is needed. (CVS 4534) check-in: 31eb4abc user: drh tags: trunk
01:23
Changes the asynchronous I/O test module so that it can be appended to the end of the amalgamation. (CVS 4533) check-in: c1fe27de user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/mem3.c.

    16     16   ** use of malloc().  All dynamically allocatable memory is
    17     17   ** contained in a static array, mem.aPool[].  The size of this
    18     18   ** fixed memory pool is SQLITE_MEMORY_SIZE bytes.
    19     19   **
    20     20   ** This version of the memory allocation subsystem is used if
    21     21   ** and only if SQLITE_MEMORY_SIZE is defined.
    22     22   **
    23         -** $Id: mem3.c,v 1.5 2007/10/20 16:36:31 drh Exp $
           23  +** $Id: mem3.c,v 1.6 2007/11/07 15:13:25 drh Exp $
    24     24   */
    25     25   
    26     26   /*
    27     27   ** This version of the memory allocator is used only when 
    28     28   ** SQLITE_MEMORY_SIZE is defined.
    29     29   */
    30     30   #if defined(SQLITE_MEMORY_SIZE)
................................................................................
   129    129   /*
   130    130   ** Unlink the chunk at mem.aPool[i] from list it is currently
   131    131   ** on.  *pRoot is the list that i is a member of.
   132    132   */
   133    133   static void memsys3UnlinkFromList(int i, int *pRoot){
   134    134     int next = mem.aPool[i].u.list.next;
   135    135     int prev = mem.aPool[i].u.list.prev;
          136  +  assert( sqlite3_mutex_held(mem.mutex) );
   136    137     if( prev==0 ){
   137    138       *pRoot = next;
   138    139     }else{
   139    140       mem.aPool[prev].u.list.next = next;
   140    141     }
   141    142     if( next ){
   142    143       mem.aPool[next].u.list.prev = prev;
................................................................................
   147    148   
   148    149   /*
   149    150   ** Unlink the chunk at index i from 
   150    151   ** whatever list is currently a member of.
   151    152   */
   152    153   static void memsys3Unlink(int i){
   153    154     int size, hash;
          155  +  assert( sqlite3_mutex_held(mem.mutex) );
   154    156     size = mem.aPool[i-1].u.hdr.size;
   155    157     assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
   156    158     assert( size>=2 );
   157    159     if( size <= MX_SMALL ){
   158    160       memsys3UnlinkFromList(i, &mem.aiSmall[size-2]);
   159    161     }else{
   160    162       hash = size % N_HASH;
................................................................................
   163    165   }
   164    166   
   165    167   /*
   166    168   ** Link the chunk at mem.aPool[i] so that is on the list rooted
   167    169   ** at *pRoot.
   168    170   */
   169    171   static void memsys3LinkIntoList(int i, int *pRoot){
          172  +  assert( sqlite3_mutex_held(mem.mutex) );
   170    173     mem.aPool[i].u.list.next = *pRoot;
   171    174     mem.aPool[i].u.list.prev = 0;
   172    175     if( *pRoot ){
   173    176       mem.aPool[*pRoot].u.list.prev = i;
   174    177     }
   175    178     *pRoot = i;
   176    179   }
................................................................................
   177    180   
   178    181   /*
   179    182   ** Link the chunk at index i into either the appropriate
   180    183   ** small chunk list, or into the large chunk hash table.
   181    184   */
   182    185   static void memsys3Link(int i){
   183    186     int size, hash;
          187  +  assert( sqlite3_mutex_held(mem.mutex) );
   184    188     size = mem.aPool[i-1].u.hdr.size;
   185    189     assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
   186    190     assert( size>=2 );
   187    191     if( size <= MX_SMALL ){
   188    192       memsys3LinkIntoList(i, &mem.aiSmall[size-2]);
   189    193     }else{
   190    194       hash = size % N_HASH;
................................................................................
   255    259   
   256    260   /*
   257    261   ** Called when we are unable to satisfy an allocation of nBytes.
   258    262   */
   259    263   static void memsys3OutOfMemory(int nByte){
   260    264     if( !mem.alarmBusy ){
   261    265       mem.alarmBusy = 1;
          266  +    assert( sqlite3_mutex_held(mem.mutex) );
   262    267       sqlite3_mutex_leave(mem.mutex);
   263    268       sqlite3_release_memory(nByte);
   264    269       sqlite3_mutex_enter(mem.mutex);
   265    270       mem.alarmBusy = 0;
   266    271     }
   267    272   }
   268    273   
................................................................................
   279    284   
   280    285   /*
   281    286   ** Chunk i is a free chunk that has been unlinked.  Adjust its 
   282    287   ** size parameters for check-out and return a pointer to the 
   283    288   ** user portion of the chunk.
   284    289   */
   285    290   static void *memsys3Checkout(int i, int nBlock){
          291  +  assert( sqlite3_mutex_held(mem.mutex) );
   286    292     assert( mem.aPool[i-1].u.hdr.size==nBlock );
   287    293     assert( mem.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
   288    294     mem.aPool[i-1].u.hdr.size = -nBlock;
   289    295     mem.aPool[i+nBlock-1].u.hdr.prevSize = -nBlock;
   290    296     return &mem.aPool[i];
   291    297   }
   292    298   
   293    299   /*
   294    300   ** Carve a piece off of the end of the mem.iMaster free chunk.
   295    301   ** Return a pointer to the new allocation.  Or, if the master chunk
   296    302   ** is not large enough, return 0.
   297    303   */
   298    304   static void *memsys3FromMaster(int nBlock){
          305  +  assert( sqlite3_mutex_held(mem.mutex) );
   299    306     assert( mem.szMaster>=nBlock );
   300    307     if( nBlock>=mem.szMaster-1 ){
   301    308       /* Use the entire master */
   302    309       void *p = memsys3Checkout(mem.iMaster, mem.szMaster);
   303    310       mem.iMaster = 0;
   304    311       mem.szMaster = 0;
   305    312       mem.mnMaster = 0;
................................................................................
   336    343   ** affairs, of course.  The calling routine must link the master
   337    344   ** chunk before invoking this routine, then must unlink the (possibly
   338    345   ** changed) master chunk once this routine has finished.
   339    346   */
   340    347   static void memsys3Merge(int *pRoot){
   341    348     int iNext, prev, size, i;
   342    349   
          350  +  assert( sqlite3_mutex_held(mem.mutex) );
   343    351     for(i=*pRoot; i>0; i=iNext){
   344    352       iNext = mem.aPool[i].u.list.next;
   345    353       size = mem.aPool[i-1].u.hdr.size;
   346    354       assert( size>0 );
   347    355       if( mem.aPool[i-1].u.hdr.prevSize>0 ){
   348    356         memsys3UnlinkFromList(i, pRoot);
   349    357         prev = i - mem.aPool[i-1].u.hdr.prevSize;
................................................................................
   370    378   ** Return NULL if unable.
   371    379   */
   372    380   static void *memsys3Malloc(int nByte){
   373    381     int i;
   374    382     int nBlock;
   375    383     int toFree;
   376    384   
          385  +  assert( sqlite3_mutex_held(mem.mutex) );
   377    386     assert( sizeof(Mem3Block)==8 );
   378    387     if( nByte<=0 ){
   379    388       nBlock = 2;
   380    389     }else{
   381    390       nBlock = (nByte + 15)/8;
   382    391     }
   383    392     assert( nBlock >= 2 );
................................................................................
   447    456   /*
   448    457   ** Free an outstanding memory allocation.
   449    458   */
   450    459   void memsys3Free(void *pOld){
   451    460     Mem3Block *p = (Mem3Block*)pOld;
   452    461     int i;
   453    462     int size;
          463  +  assert( sqlite3_mutex_held(mem.mutex) );
   454    464     assert( p>mem.aPool && p<&mem.aPool[SQLITE_MEMORY_SIZE/8] );
   455    465     i = p - mem.aPool;
   456    466     size = -mem.aPool[i-1].u.hdr.size;
   457    467     assert( size>=2 );
   458    468     assert( mem.aPool[i+size-1].u.hdr.prevSize==-size );
   459    469     mem.aPool[i-1].u.hdr.size = size;
   460    470     mem.aPool[i+size-1].u.hdr.prevSize = size;