/ Check-in [d025866b]
Login

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

Overview
Comment:Fix the functionality associated with sqlite3_release_memory() and sqlite3_soft_heap_limit(). It is automatically disabled if the SQLITE_CONFIG_PAGECACHE option is used. (CVS 5576)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d025866b09352b32a6d35b97144eaad2fafb7165
User & Date: danielk1977 2008-08-21 12:19:44
Context
2008-08-21
12:32
Patch to mkfunction to try and detect miscompiles. Add an unimportant assert back to pcache.c. (CVS 5577) check-in: a2f375ff user: drh tags: trunk
12:19
Fix the functionality associated with sqlite3_release_memory() and sqlite3_soft_heap_limit(). It is automatically disabled if the SQLITE_CONFIG_PAGECACHE option is used. (CVS 5576) check-in: d025866b user: danielk1977 tags: trunk
04:41
Move an assert() in sqlite3PcacheDirtyPage() so that it does not occur before local variable declarations. Ticket #3325. (CVS 5575) check-in: 899fa19d user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to src/malloc.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
58
59
60
61
62
63
64


65

66
67
68
69
70
71
72
73
**    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.35 2008/08/20 14:49:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** This routine runs when the memory allocator sees that the
................................................................................
/*
** Attempt to release up to n bytes of non-essential memory currently
** held by SQLite. An example of non-essential memory is memory used to
** cache database pages that are not currently in use.
*/
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
}

/*







|







 







>
>
|
>
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
**    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.36 2008/08/21 12:19:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** This routine runs when the memory allocator sees that the
................................................................................
/*
** Attempt to release up to n bytes of non-essential memory currently
** held by SQLite. An example of non-essential memory is memory used to
** cache database pages that are not currently in use.
*/
int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  int nRet = 0;
#if 0
  nRet += sqlite3VdbeReleaseMemory(n);
#endif
  nRet += sqlite3PcacheReleaseMemory(n-nRet);
  return nRet;
#else
  return SQLITE_OK;
#endif
}

/*

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
2449
2450
2451
2452
2453
2454
2455
2456
2457

2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472



2473
2474
2475
2476
2477
2478
2479
....
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.472 2008/08/21 04:35:19 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
** by the pcache layer.
*/
static int pagerStress(void *p){
  Pager *pPager = (Pager *)p;
  PgHdr *pPg = sqlite3PcacheDirtyPage(pPager->pPCache);
  int rc = SQLITE_OK;

  if( pPg && pPager->errCode==SQLITE_OK ){
    assert( pPg->flags&PGHDR_DIRTY );

    if( pPg->flags&PGHDR_NEED_SYNC ){
      rc = syncJournal(pPager);
      if( rc==SQLITE_OK && pPager->fullSync 
       && !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
      ){
        pPager->nRec = 0;
        rc = writeJournalHdr(pPager);
      }
    }
    if( rc==SQLITE_OK ){
      rc = pager_write_pagelist(pPg);
    }
    if( rc!=SQLITE_OK ){
      pager_error(pPager, rc);
    }



  }
  return rc;
}


/*
** Return 1 if there is a hot journal on the given pager.
................................................................................
      }
    }
  }

  return rc;
}

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
** held by the pager system. Memory in use by any SQLite pager allocated
** by the current thread may be sqlite3_free()ed.
**
** nReq is the number of bytes of memory required. Once this much has
** been released, the function returns. The return value is the total number 
** of bytes of memory released.
*/
int sqlite3PagerReleaseMemory(int nReq){
  return 0;
}
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */

/*
** Read the content of page pPg out of the database file.
*/
static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
  int rc;
  i64 offset;
  assert( MEMDB==0 );







|







 







|

>
|
|
|
|











>
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
....
2523
2524
2525
2526
2527
2528
2529















2530
2531
2532
2533
2534
2535
2536
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.473 2008/08/21 12:19:44 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"

/*
** Macros for troubleshooting.  Normally turned off
*/
................................................................................
** by the pcache layer.
*/
static int pagerStress(void *p){
  Pager *pPager = (Pager *)p;
  PgHdr *pPg = sqlite3PcacheDirtyPage(pPager->pPCache);
  int rc = SQLITE_OK;

  if( pPg ){
    assert( pPg->flags&PGHDR_DIRTY );
    if( pPager->errCode==SQLITE_OK ){
      if( pPg->flags&PGHDR_NEED_SYNC ){
        rc = syncJournal(pPager);
        if( rc==SQLITE_OK && pPager->fullSync && 
          !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND)
        ){
          pPager->nRec = 0;
          rc = writeJournalHdr(pPager);
        }
      }
      if( rc==SQLITE_OK ){
        rc = pager_write_pagelist(pPg);
      }
      if( rc!=SQLITE_OK ){
        pager_error(pPager, rc);
      }
    }else{
      sqlite3PcacheMakeClean(pPg);
    }
  }
  return rc;
}


/*
** Return 1 if there is a hot journal on the given pager.
................................................................................
      }
    }
  }

  return rc;
}
















/*
** Read the content of page pPg out of the database file.
*/
static int readDbPage(Pager *pPager, PgHdr *pPg, Pgno pgno){
  int rc;
  i64 offset;
  assert( MEMDB==0 );

Changes to src/pager.h.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.78 2008/08/20 14:49:25 danielk1977 Exp $
*/

#ifndef _PAGER_H_
#define _PAGER_H_

/*
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
................................................................................
int sqlite3PagerLockingMode(Pager *, int);
int sqlite3PagerJournalMode(Pager *, int);
i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerSync(Pager *pPager);
void sqlite3PagerAlwaysRollback(Pager *pPager);

#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
  int sqlite3PagerReleaseMemory(int);
#endif

#ifdef SQLITE_HAS_CODEC
  void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
#endif

#if !defined(NDEBUG) || defined(SQLITE_TEST)
  Pgno sqlite3PagerPagenumber(DbPage*);
  int sqlite3PagerIswriteable(DbPage*);







|







 







<
<
<
<







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
111
112
113
114
115
116
117




118
119
120
121
122
123
124
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.79 2008/08/21 12:19:44 danielk1977 Exp $
*/

#ifndef _PAGER_H_
#define _PAGER_H_

/*
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
................................................................................
int sqlite3PagerLockingMode(Pager *, int);
int sqlite3PagerJournalMode(Pager *, int);
i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerSync(Pager *pPager);
void sqlite3PagerAlwaysRollback(Pager *pPager);





#ifdef SQLITE_HAS_CODEC
  void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
#endif

#if !defined(NDEBUG) || defined(SQLITE_TEST)
  Pgno sqlite3PagerPagenumber(DbPage*);
  int sqlite3PagerIswriteable(DbPage*);

Changes to src/pcache.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
327
328
329
330
331
332
333


334

335
336
337
338
339
340
341
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
...
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471































472
473
474
475
476
477
478
479
480
481
482
483
....
1137
1138
1139
1140
1141
1142
1143


























**    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 implements that page cache.
**
** @(#) $Id: pcache.c,v 1.3 2008/08/21 04:41:02 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** A complete page cache is an instance of this structure.
*/
struct PCache {
................................................................................
  if( sz<=pcache.szSlot && pcache.pFree ){
    PgFreeslot *p = pcache.pFree;
    pcache.pFree = p->pNext;
    sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, sz);
    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
    return (void*)p;
  }else{


    void *p = sqlite3Malloc(sz);

    if( p ){
      sz = sqlite3MallocSize(p);
      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
    }
    return p;
  }
}
................................................................................
  }
  pcacheFree(p->apSave[0]);
  pcacheFree(p->apSave[1]);
  pcacheFree(p);
}

/*
** Obtain space for a page. Try to recycle an old page if the limit on the 
** number of pages has been reached. If the limit has not been reached or
** there are no pages eligible for recycling, allocate a new page.
**
** Return a pointer to the new page, or NULL if an OOM condition occurs.
*/
static PgHdr *pcacheRecycleOrAlloc(PCache *pCache){
  PgHdr *p = 0;

  int szPage = pCache->szPage;
  int szExtra = pCache->szExtra;
  int bPurg = pCache->bPurgeable;

  assert( pcache.isInit );
  assert( sqlite3_mutex_notheld(pcache.mutex_lru) );

  pcacheEnterGlobal();

  if( (pcache.mxPage && pcache.nPage>=pcache.mxPage) 
   || (!pcache.mxPage && bPurg && pcache.nPurgeable>=pcache.mxPagePurgeable)
  ){
    PCache *pCsr;

    /* If the above test succeeds, then a page will be obtained by recycling
    ** an existing page.
    */
    if( !pcache.pLruTail && SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){

      /* Invoke xStress() callbacks until the LRU list contains at least one
      ** page that can be reused or until the xStress() callback of all
      ** caches has been invoked.
      */
      for(pCsr=pcache.pAll; pCsr&&!pcache.pLruTail; pCsr=pCsr->pNextAll){
................................................................................
        pCsr->iInUseMM = 0;
      }

      sqlite3_mutex_leave(pcache.mutex_mem2);
    }

    p = pcache.pLruTail;
  }

  if( p ){
    pcacheRemoveFromLruList(p);
    pcacheRemoveFromHash(p);
    pcacheRemoveFromList(&p->pCache->pClean, p);

    /* If the always-rollback flag is set on the page being recycled, set 
    ** the always-rollback flag on the corresponding pager.
    */
    if( p->flags&PGHDR_ALWAYS_ROLLBACK ){
      assert(p->pPager);
      sqlite3PagerAlwaysRollback(p->pPager);
    }
































    if( p->pCache->szPage!=szPage || p->pCache->szExtra!=szExtra ){
      pcachePageFree(p);
      p = 0;
    }
  }

  if( !p ){
    /* Allocate a new page object. */
    p = pcachePageAlloc(szPage, szExtra, bPurg);
  }

  pcacheExitGlobal();
................................................................................
/*
** Unlock a pager-cache.
*/
void sqlite3PcacheUnlock(PCache *pCache){
  pCache->iInUseDB--;
  assert( pCache->iInUseDB>=0 );
}

































|







 







>
>
|
>







 







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<







 







<













|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431







432
433
434
435
436
437
438
...
446
447
448
449
450
451
452

453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

502
503
504
505
506
507
508
....
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
**    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 implements that page cache.
**
** @(#) $Id: pcache.c,v 1.4 2008/08/21 12:19:44 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** A complete page cache is an instance of this structure.
*/
struct PCache {
................................................................................
  if( sz<=pcache.szSlot && pcache.pFree ){
    PgFreeslot *p = pcache.pFree;
    pcache.pFree = p->pNext;
    sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, sz);
    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
    return (void*)p;
  }else{
    void *p;
    pcacheExitGlobal();
    p = sqlite3Malloc(sz);
    pcacheEnterGlobal();
    if( p ){
      sz = sqlite3MallocSize(p);
      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
    }
    return p;
  }
}
................................................................................
  }
  pcacheFree(p->apSave[0]);
  pcacheFree(p->apSave[1]);
  pcacheFree(p);
}

/*
** Return the number of bytes that will be returned to the heap when
** the argument is passed to pcachePageFree().
*/
static int pcachePageSize(PgHdr *p){
  assert( sqlite3_mutex_held(pcache.mutex_lru) );
  assert( !pcache.pStart );
  assert( p->apSave[0]==0 );
  assert( p->apSave[1]==0 );
  assert( p && p->pCache );
  return sqlite3MallocSize(p);
}

static PgHdr *pcacheRecycle(PCache *pCache){
  PCache *pCsr;
  PgHdr *p = 0;

  assert( pcache.isInit );
  assert( sqlite3_mutex_held(pcache.mutex_lru) );








  if( !pcache.pLruTail && SQLITE_OK==sqlite3_mutex_try(pcache.mutex_mem2) ){

    /* Invoke xStress() callbacks until the LRU list contains at least one
    ** page that can be reused or until the xStress() callback of all
    ** caches has been invoked.
    */
    for(pCsr=pcache.pAll; pCsr&&!pcache.pLruTail; pCsr=pCsr->pNextAll){
................................................................................
      pCsr->iInUseMM = 0;
    }

    sqlite3_mutex_leave(pcache.mutex_mem2);
  }

  p = pcache.pLruTail;


  if( p ){
    pcacheRemoveFromLruList(p);
    pcacheRemoveFromHash(p);
    pcacheRemoveFromList(&p->pCache->pClean, p);

    /* If the always-rollback flag is set on the page being recycled, set 
    ** the always-rollback flag on the corresponding pager.
    */
    if( p->flags&PGHDR_ALWAYS_ROLLBACK ){
      assert(p->pPager);
      sqlite3PagerAlwaysRollback(p->pPager);
    }
  }

  return p;
}

/*
** Obtain space for a page. Try to recycle an old page if the limit on the 
** number of pages has been reached. If the limit has not been reached or
** there are no pages eligible for recycling, allocate a new page.
**
** Return a pointer to the new page, or NULL if an OOM condition occurs.
*/
static PgHdr *pcacheRecycleOrAlloc(PCache *pCache){
  PgHdr *p = 0;

  int szPage = pCache->szPage;
  int szExtra = pCache->szExtra;
  int bPurg = pCache->bPurgeable;

  assert( pcache.isInit );
  assert( sqlite3_mutex_notheld(pcache.mutex_lru) );

  pcacheEnterGlobal();

  if( (pcache.mxPage && pcache.nPage>=pcache.mxPage) 
   || (!pcache.mxPage && bPurg && pcache.nPurgeable>=pcache.mxPagePurgeable)
  ){
    /* If the above test succeeds, then try to obtain a buffer by recycling
    ** an existing page. */
    p = pcacheRecycle(pCache);
  }

  if( p && (p->pCache->szPage!=szPage || p->pCache->szExtra!=szExtra) ){
    pcachePageFree(p);
    p = 0;
  }


  if( !p ){
    /* Allocate a new page object. */
    p = pcachePageAlloc(szPage, szExtra, bPurg);
  }

  pcacheExitGlobal();
................................................................................
/*
** Unlock a pager-cache.
*/
void sqlite3PcacheUnlock(PCache *pCache){
  pCache->iInUseDB--;
  assert( pCache->iInUseDB>=0 );
}

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** This function is called to free superfluous dynamically allocated memory
** held by the pager system. Memory in use by any SQLite pager allocated
** by the current thread may be sqlite3_free()ed.
**
** nReq is the number of bytes of memory required. Once this much has
** been released, the function returns. The return value is the total number 
** of bytes of memory released.
*/
int sqlite3PcacheReleaseMemory(int nReq){
  int nFree = 0;
  if( pcache.pStart==0 ){
    PgHdr *p;
    pcacheEnterGlobal();
    while( (nReq<0 || nFree<nReq) && (p=pcacheRecycle(0)) ){
      nFree += pcachePageSize(p);
      pcachePageFree(p);
    }
    pcacheExitGlobal();
  }
  return nFree;
}
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */

Changes to src/pcache.h.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
166
167
168
169
170
171
172


173
174
175
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem. 
**
** @(#) $Id: pcache.h,v 1.1 2008/08/20 14:49:25 danielk1977 Exp $
*/

#ifndef _PCACHE_H_

typedef struct PgHdr PgHdr;
typedef struct PCache PCache;

................................................................................
/* Lock and unlock a pager-cache object. The PcacheLock() function may 
** block if the lock is temporarily available. While a pager-cache is locked,
** the system guarantees that any configured xStress() callback will not
** be invoked by any thread other than the one holding the lock.
*/
void sqlite3PcacheLock(PCache *);
void sqlite3PcacheUnlock(PCache *);



#endif /* _PCACHE_H_ */








|







 







>
>



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
166
167
168
169
170
171
172
173
174
175
176
177
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem. 
**
** @(#) $Id: pcache.h,v 1.2 2008/08/21 12:19:44 danielk1977 Exp $
*/

#ifndef _PCACHE_H_

typedef struct PgHdr PgHdr;
typedef struct PCache PCache;

................................................................................
/* Lock and unlock a pager-cache object. The PcacheLock() function may 
** block if the lock is temporarily available. While a pager-cache is locked,
** the system guarantees that any configured xStress() callback will not
** be invoked by any thread other than the one holding the lock.
*/
void sqlite3PcacheLock(PCache *);
void sqlite3PcacheUnlock(PCache *);

int sqlite3PcacheReleaseMemory(int);

#endif /* _PCACHE_H_ */

Changes to src/vdbeapi.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.139 2008/08/11 18:44:58 drh Exp $
*/
#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.
**







|




|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains code use to implement APIs that are part of the
** VDBE.
**
** $Id: vdbeapi.c,v 1.140 2008/08/21 12:19:44 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"

#if 0 && defined(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.
**

Changes to test/mutex1.test.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#
#    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.
#
#***********************************************************************
#
# $Id: mutex1.test,v 1.11 2008/08/20 14:49:25 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

if {[info exists tester_do_binarylog]} {
  finish_test
  return
................................................................................
set enable_shared_cache [sqlite3_enable_shared_cache 1]
ifcapable threadsafe {
  foreach {mode mutexes} {
    singlethread {}
    multithread  {fast static_lru static_master static_mem static_mem2 static_prng }
    serialized   {fast recursive static_lru static_master static_mem static_mem2 static_prng }
  } {
    ifcapable memorymanage {
      if {$mode ne "singlethread"} {
        lappend mutexes static_lru static_lru2 static_mem2
      }
    }

    do_test mutex1.2.$mode.1 {
      catch {db close}
      sqlite3_shutdown
      sqlite3_config $mode
    } SQLITE_OK








|







 







<
<
<
<
<







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
95
96
97
98
99
100
101





102
103
104
105
106
107
108
#
#    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.
#
#***********************************************************************
#
# $Id: mutex1.test,v 1.12 2008/08/21 12:19:44 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

if {[info exists tester_do_binarylog]} {
  finish_test
  return
................................................................................
set enable_shared_cache [sqlite3_enable_shared_cache 1]
ifcapable threadsafe {
  foreach {mode mutexes} {
    singlethread {}
    multithread  {fast static_lru static_master static_mem static_mem2 static_prng }
    serialized   {fast recursive static_lru static_master static_mem static_mem2 static_prng }
  } {






    do_test mutex1.2.$mode.1 {
      catch {db close}
      sqlite3_shutdown
      sqlite3_config $mode
    } SQLITE_OK