/ Check-in [44f8e313]
Login

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

Overview
Comment:Add a runtime interface to enable memory-management features. (CVS 2894)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:44f8e3139aa3ad3fcce9028565dd9ad23bbe62a2
User & Date: danielk1977 2006-01-09 09:59:49
Context
2006-01-09
16:12
Fix some errors to do with attached databases and text encodings in shared-cache mode. (CVS 2895) check-in: 3e75d3d5 user: danielk1977 tags: trunk
09:59
Add a runtime interface to enable memory-management features. (CVS 2894) check-in: 44f8e313 user: danielk1977 tags: trunk
06:29
Rename DbSchema to "Schema" and SqliteTsd to "ThreadData". (CVS 2893) check-in: 82b81f69 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
6500
6501
6502
6503
6504
6505
6506
6507
6508








6509
6510

6511
6512
6513
6514
** a legal notice, here is a blessing:
**
**    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: btree.c,v 1.287 2006/01/09 06:29:48 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Enable the shared pager and schema features.
*/
int sqlite3_enable_shared_cache(int enable){
  ThreadData *pTsd = sqlite3ThreadData();
  if( pTsd->pPager ){








    return SQLITE_MISUSE;
  }

  pTsd->useSharedData = enable;
  return SQLITE_OK;
}
#endif







|







 







|
<
>
>
>
>
>
>
>
>


>
|



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
6500
6501
6502
6503
6504
6505
6506
6507

6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
** a legal notice, here is a blessing:
**
**    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: btree.c,v 1.288 2006/01/09 09:59:49 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
}

#ifndef SQLITE_OMIT_SHARED_CACHE
/*
** Enable the shared pager and schema features.
*/
int sqlite3_enable_shared_cache(int enable){
  ThreadData *pTd = sqlite3ThreadData();

  
  /* It is only legal to call sqlite3_enable_shared_cache() when there
  ** are no currently open b-trees that were opened by the calling thread.
  ** This condition is only easy to detect if the shared-cache were 
  ** previously enabled (and is being disabled). 
  */
  if( pTd->pBtree && !enable ){
    assert( pTd->useSharedData );
    return SQLITE_MISUSE;
  }

  pTd->useSharedData = enable;
  return SQLITE_OK;
}
#endif

Changes to src/pager.c.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1619
1620
1621
1622
1623
1624
1625

1626

1627
1628
1629
1630
1631
1632
1633
....
1719
1720
1721
1722
1723
1724
1725


1726
1727


1728
1729
1730
1731
1732
1733
1734
....
2084
2085
2086
2087
2088
2089
2090
2091
2092

2093
2094
2095
2096
2097
2098

2099
2100
2101
2102
2103
2104
2105
** 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.232 2006/01/09 06:29:49 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
  char zTemp[SQLITE_TEMPNAME_SIZE];

  ThreadData *pTsd = sqlite3ThreadData();


  /* If malloc() has already failed return SQLITE_NOMEM. Before even
  ** testing for this, set *ppPager to NULL so the caller knows the pager
  ** structure was never allocated. 
  */
  *ppPager = 0;
  if( sqlite3ThreadData()->mallocFailed ){
................................................................................
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);
  pPager->sectorSize = PAGER_SECTOR_SIZE;
  pPager->pBusyHandler = 0;
  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  *ppPager = pPager;


  pPager->pNext = pTsd->pPager;
  pTsd->pPager = pPager;


  return SQLITE_OK;
}

/*
** Set the busy handler function.
*/
void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
................................................................................
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  /* Remove the pager from the linked list of pagers starting at 
  ** ThreadData.pPager.
  */

  if( pPager==pTsd->pPager ){
    pTsd->pPager = pPager->pNext;
  }else{
    Pager *pTmp;
    for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext);
    pTmp->pNext = pPager->pNext;

  }
#endif

  sqliteFree(pPager);
  return SQLITE_OK;
}








|







 







>

>







 







>
>
|
|
>
>







 







|

>
|
|
|
|
|
|
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
....
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
....
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
....
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
** 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.233 2006/01/09 09:59:49 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
................................................................................
  int i;
  int tempFile = 0;
  int memDb = 0;
  int readOnly = 0;
  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
  char zTemp[SQLITE_TEMPNAME_SIZE];
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  ThreadData *pTsd = sqlite3ThreadData();
#endif

  /* If malloc() has already failed return SQLITE_NOMEM. Before even
  ** testing for this, set *ppPager to NULL so the caller knows the pager
  ** structure was never allocated. 
  */
  *ppPager = 0;
  if( sqlite3ThreadData()->mallocFailed ){
................................................................................
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->nExtra = FORCE_ALIGNMENT(nExtra);
  pPager->sectorSize = PAGER_SECTOR_SIZE;
  pPager->pBusyHandler = 0;
  memset(pPager->aHash, 0, sizeof(pPager->aHash));
  *ppPager = pPager;
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  if( pTsd->useMemoryManagement ){
    pPager->pNext = pTsd->pPager;
    pTsd->pPager = pPager;
  }
#endif
  return SQLITE_OK;
}

/*
** Set the busy handler function.
*/
void sqlite3pager_set_busyhandler(Pager *pPager, BusyHandler *pBusyHandler){
................................................................................
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
  ** }
  */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  /* Remove the pager from the linked list of pagers starting at 
  ** ThreadData.pPager if memory-management is enabled.
  */
  if( pTsd->useMemoryManagement ){
    if( pPager==pTsd->pPager ){
      pTsd->pPager = pPager->pNext;
    }else{
      Pager *pTmp;
      for(pTmp = pTsd->pPager; pTmp->pNext!=pPager; pTmp=pTmp->pNext);
      pTmp->pNext = pPager->pNext;
    }
  }
#endif

  sqliteFree(pPager);
  return SQLITE_OK;
}

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
....
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348


































1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
**    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 library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.152 2005/12/30 16:28:02 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
** Place a "soft" limit on the amount of heap memory that may be allocated by
** SQLite within the current thread. If an internal allocation is requested 
** that would exceed the specified limit, sqlite3_release_memory() is invoked
** one or more times to free up some space before the allocation is made.
**
** The limit is called "soft", because if sqlite3_release_memory() cannot free
** sufficient memory to prevent the limit from being exceeded, the memory is
** allocated anyway and the current operation proceeds.
**
** This function is only available if the library was compiled without the 
** SQLITE_OMIT_MEMORY_MANAGEMENT option set.
*/
void sqlite3_soft_heap_limit(sqlite_int64);

/*
** Register a callback function with the database connection identified by the 
** first argument to be invoked whenever a row is updated, inserted or deleted.
** Any callback set by a previous call to this function for the same 
** database connection is overridden.
**
** The second argument is a pointer to the function to invoke when a 
................................................................................
** rolled back if an explicit "ROLLBACK" statement is executed, or
** an error or constraint causes an implicit rollback to occur. The 
** callback is not invoked if a transaction is automatically rolled
** back because the database connection is closed.
*/
void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);

int sqlite3_release_memory(int);

/*
** This function is only available if the library is compiled without
** the SQLITE_OMIT_SHARED_CACHE macro defined. It is used to enable or
** disable (if the argument is true or false, respectively) the 
** "shared pager" feature.
*/
int sqlite3_enable_shared_cache(int);



































/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif







|







 







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







 







<
<








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1272
1273
1274
1275
1276
1277
1278















1279
1280
1281
1282
1283
1284
1285
....
1317
1318
1319
1320
1321
1322
1323


1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
**    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 library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.153 2006/01/09 09:59:49 danielk1977 Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** Return the sqlite3* database handle to which the prepared statement given
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
















/*
** Register a callback function with the database connection identified by the 
** first argument to be invoked whenever a row is updated, inserted or deleted.
** Any callback set by a previous call to this function for the same 
** database connection is overridden.
**
** The second argument is a pointer to the function to invoke when a 
................................................................................
** rolled back if an explicit "ROLLBACK" statement is executed, or
** an error or constraint causes an implicit rollback to occur. The 
** callback is not invoked if a transaction is automatically rolled
** back because the database connection is closed.
*/
void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);



/*
** This function is only available if the library is compiled without
** the SQLITE_OMIT_SHARED_CACHE macro defined. It is used to enable or
** disable (if the argument is true or false, respectively) the 
** "shared pager" feature.
*/
int sqlite3_enable_shared_cache(int);

/*
** This function is only available if the library is compiled without
** the SQLITE_OMIT_MEMORY_MANAGEMENT macro defined. It is used to enable or
** disable (if the argument is true or false, respectively) the 
** "memory management" features (accessed via the sqlite3_soft_heap_limit()
** and sqlite3_release_memory() APIs).
*/
int sqlite3_enable_memory_management(int);

/*
** Attempt to free N bytes of heap memory by deallocating non-essential
** memory allocations held by the database library (example: memory 
** used to cache database pages to improve performance).
**
** This function is a no-op unless memory-management has been enabled.
*/
int sqlite3_release_memory(int);

/*
** Place a "soft" limit on the amount of heap memory that may be allocated by
** SQLite within the current thread. If an internal allocation is requested 
** that would exceed the specified limit, sqlite3_release_memory() is invoked
** one or more times to free up some space before the allocation is made.
**
** The limit is called "soft", because if sqlite3_release_memory() cannot free
** sufficient memory to prevent the limit from being exceeded, the memory is
** allocated anyway and the current operation proceeds.
**
** This function is only available if the library was compiled without the 
** SQLITE_OMIT_MEMORY_MANAGEMENT option set. It is a no-op unless 
** memory-management has been enabled.
*/
void sqlite3_soft_heap_limit(sqlite_int64);

/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
#ifdef SQLITE_OMIT_FLOATING_POINT
# undef double
#endif

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif
#endif

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
290
291
292
293
294
295
296

297
298
299
300
301
302
303
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.454 2006/01/09 06:29:49 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
*/
struct ThreadData {
  u8 isInit;               /* True if structure has been initialised */
  u8 mallocFailed;         /* True after a malloc() has failed */
  u8 disableReleaseMemory; /* True to make sqlite3_release_memory() a no-op */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT

  i64 nSoftHeapLimit;      /* Suggested max mem allocation.  No limit if <0 */
  i64 nAlloc;              /* Number of bytes currently allocated */
  Pager *pPager;           /* Linked list of all pagers in this thread */
#endif

#ifndef SQLITE_OMIT_SHARED_CACHE
  u8 useSharedData;        /* True if shared pagers and schemas are enabled */







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.455 2006/01/09 09:59:49 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Extra interface definitions for those who need them
*/
................................................................................
*/
struct ThreadData {
  u8 isInit;               /* True if structure has been initialised */
  u8 mallocFailed;         /* True after a malloc() has failed */
  u8 disableReleaseMemory; /* True to make sqlite3_release_memory() a no-op */

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  u8 useMemoryManagement;  /* True if memory-management is enabled */
  i64 nSoftHeapLimit;      /* Suggested max mem allocation.  No limit if <0 */
  i64 nAlloc;              /* Number of bytes currently allocated */
  Pager *pPager;           /* Linked list of all pagers in this thread */
#endif

#ifndef SQLITE_OMIT_SHARED_CACHE
  u8 useSharedData;        /* True if shared pagers and schemas are enabled */

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
899
900
901
902
903
904
905
906
907
908
909
910
911

912
913
914
915
916
917
918
919
920

921
922
923
924
925
926
927
928
929






930
931
932
933
934
935
936

937
938
939
940
941
942
943
944
945
946
947


948



949



950




951
952
953
954
955
956
957
958
959
960
961
962

963
964
965
966
967
968
969
....
3410
3411
3412
3413
3414
3415
3416
3417




3418
3419
3420
3421
3422
3423
3424
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.184 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  ClientData clientData,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  extern int sqlite3OutstandingMallocs(Tcl_Interp *interp);

  if( objc!=1 && objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?");
    return TCL_ERROR;
  }

  if( objc==2 ){

    const char *zArg = Tcl_GetString(objv[1]);
    if( 0==strcmp(zArg, "-bytes") ){
      Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3ThreadData()->nAlloc));
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
    }else if( 0==strcmp(zArg, "-maxbytes") ){
      Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3ThreadData()->nMaxAlloc));
    }else if( 0==strcmp(zArg, "-clearmaxbytes") ){
      sqlite3ThreadData()->nMaxAlloc = sqlite3ThreadData()->nAlloc;
#endif

    }else{
      Tcl_AppendResult(interp, "bad option \"", zArg, 
        "\": must be -bytes, -maxbytes or -clearmaxbytes", 0
      );
      return TCL_ERROR;
    }

    return TCL_OK;
  }







  return sqlite3OutstandingMallocs(interp);
}
#endif

/*
** Usage: sqlite3_enable_shared_cache BOOLEAN

**
*/
#ifndef SQLITE_OMIT_SHARED_CACHE
static int test_enable_shared_cache(
  ClientData clientData,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int rc;
  int enable;


  ThreadData *pTsd = sqlite3ThreadData();



  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pTsd->useSharedData));








  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
    return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
    return TCL_ERROR;
  }
  rc = sqlite3_enable_shared_cache(enable);
  if( rc!=SQLITE_OK ){
    Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
    return TCL_ERROR;
  }

  return TCL_OK;
}
#endif

/*
** Usage:  sqlite_abort
**
................................................................................
#endif
#ifdef SQLITE_MEMDEBUG
     { "sqlite_malloc_outstanding", sqlite_malloc_outstanding, 0},
#endif
     { "sqlite3_test_errstr",     test_errstr, 0             },
     { "tcl_variable_type",       tcl_variable_type, 0       },
#ifndef SQLITE_OMIT_SHARED_CACHE
     { "sqlite3_enable_shared_cache", test_enable_shared_cache, 0},




#endif
  };
  static int bitmask_size = sizeof(Bitmask)*8;
  int i;
  extern int sqlite3_os_trace;
  extern int sqlite3_where_trace;
  extern int sqlite3_sync_count, sqlite3_fullsync_count;







|







 







|
<
<
<
<

>


|
<

|

<
<
>









>
>
>
>
>
>






|
>


|
|
|






>
>

>
>
>
|
>
>
>
|
>
>
>
>







|




>







 







|
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
899
900
901
902
903
904
905
906




907
908
909
910
911

912
913
914


915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
....
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.185 2006/01/09 09:59:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
  ClientData clientData,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  extern int sqlite3OutstandingMallocs(Tcl_Interp *interp);

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT




  if( objc==2 ){
    ThreadData *pTd = sqlite3ThreadData();
    const char *zArg = Tcl_GetString(objv[1]);
    if( 0==strcmp(zArg, "-bytes") ){
      Tcl_SetObjResult(interp, Tcl_NewIntObj(pTd->nAlloc));

    }else if( 0==strcmp(zArg, "-maxbytes") ){
      Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pTd->nMaxAlloc));
    }else if( 0==strcmp(zArg, "-clearmaxbytes") ){


      pTd->nMaxAlloc = pTd->nAlloc;
    }else{
      Tcl_AppendResult(interp, "bad option \"", zArg, 
        "\": must be -bytes, -maxbytes or -clearmaxbytes", 0
      );
      return TCL_ERROR;
    }

    return TCL_OK;
  }
#endif

  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?");
    return TCL_ERROR;
  }

  return sqlite3OutstandingMallocs(interp);
}
#endif

/*
** Usage: sqlite3_enable_shared_cache      BOOLEAN
** Usage: sqlite3_enable_memory_management BOOLEAN
**
*/
#if !defined(SQLITE_OMIT_SHARED_CACHE)||!defined(SQLITE_OMIT_MEMORY_MANAGEMENT)
static int test_enable(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int rc;
  int enable;
  int ret = 0;
  int (*xFunc)(int) = (int(*)(int))clientData;
  ThreadData *pTsd = sqlite3ThreadData();

#ifndef SQLITE_OMIT_SHARED_CACHE
  if( xFunc==sqlite3_enable_shared_cache ){
    ret = pTsd->useSharedData;
  }else
#endif
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
  {
    assert( xFunc==sqlite3_enable_memory_management );
    ret = pTsd->useMemoryManagement;
  }
#endif
  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
    return TCL_ERROR;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
    return TCL_ERROR;
  }
  rc = xFunc(enable);
  if( rc!=SQLITE_OK ){
    Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
    return TCL_ERROR;
  }
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(ret));
  return TCL_OK;
}
#endif

/*
** Usage:  sqlite_abort
**
................................................................................
#endif
#ifdef SQLITE_MEMDEBUG
     { "sqlite_malloc_outstanding", sqlite_malloc_outstanding, 0},
#endif
     { "sqlite3_test_errstr",     test_errstr, 0             },
     { "tcl_variable_type",       tcl_variable_type, 0       },
#ifndef SQLITE_OMIT_SHARED_CACHE
     { "sqlite3_enable_shared_cache", test_enable, sqlite3_enable_shared_cache},
#endif
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
     { "sqlite3_enable_memory_management", test_enable, 
       sqlite3_enable_memory_management},
#endif
  };
  static int bitmask_size = sizeof(Bitmask)*8;
  int i;
  extern int sqlite3_os_trace;
  extern int sqlite3_where_trace;
  extern int sqlite3_sync_count, sqlite3_fullsync_count;

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
....
1303
1304
1305
1306
1307
1308
1309

1310

1311
1312
1313
1314
1315
1316
1317
....
1320
1321
1322
1323
1324
1325
1326



















1327
1328
1329
1330
1331
1332
1333
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.163 2006/01/09 06:29:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
................................................................................
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nAlloc += (i64)n;
  if( n>0 && pTsd->nSoftHeapLimit>0 ){
    while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
  }
}
#else
#define handleSoftLimit()
#endif

/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
................................................................................

/*
** Return a pointer to the ThreadData associated with the calling thread.
*/
ThreadData *sqlite3ThreadData(){
  ThreadData *pTsd = sqlite3OsThreadSpecificData(sizeof(ThreadData));
  if( pTsd && !pTsd->isInit ){

    pTsd->nSoftHeapLimit = -1;

#ifndef NDEBUG
    pTsd->mallocAllowed = 1;
#endif
    pTsd->isInit = 1;
  }
  return pTsd;
}
................................................................................
** Clear the "mallocFailed" flag. This should be invoked before exiting any
** entry points that may have called sqliteMalloc().
*/
void sqlite3MallocClearFailed(){
  sqlite3ThreadData()->mallocFailed = 0;
}





















#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){







|







 







|







 







>

>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
....
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
....
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.164 2006/01/09 09:59:49 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <stdarg.h>
#include <ctype.h>

/*
................................................................................
  ThreadData *pTsd = sqlite3ThreadData();
  pTsd->nAlloc += (i64)n;
  if( n>0 && pTsd->nSoftHeapLimit>0 ){
    while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
  }
}
#else
#define handleSoftLimit(x)
#endif

/*
** Allocate and return N bytes of uninitialised memory by calling
** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory 
** by calling sqlite3_release_memory().
*/
................................................................................

/*
** Return a pointer to the ThreadData associated with the calling thread.
*/
ThreadData *sqlite3ThreadData(){
  ThreadData *pTsd = sqlite3OsThreadSpecificData(sizeof(ThreadData));
  if( pTsd && !pTsd->isInit ){
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
    pTsd->nSoftHeapLimit = -1;
#endif
#ifndef NDEBUG
    pTsd->mallocAllowed = 1;
#endif
    pTsd->isInit = 1;
  }
  return pTsd;
}
................................................................................
** Clear the "mallocFailed" flag. This should be invoked before exiting any
** entry points that may have called sqliteMalloc().
*/
void sqlite3MallocClearFailed(){
  sqlite3ThreadData()->mallocFailed = 0;
}

#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
/*
** Enable the shared pager and schema features.
*/
int sqlite3_enable_memory_management(int enable){
  ThreadData *pTsd = sqlite3ThreadData();

  /* It is only legal to call sqlite3_enable_memory_management() when there
  ** are no currently open connections that were opened by the calling 
  ** thread. This condition is only easy to detect if the feature were
  ** previously enabled (and is being disabled). 
  */
  if( pTsd->pPager && !enable ){
    return SQLITE_MISUSE;
  }
  pTsd->useMemoryManagement = enable;
  return SQLITE_OK;
}
#endif

#ifndef NDEBUG
/*
** This function sets a flag in the thread-specific-data structure that will
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
*/
void sqlite3MallocDisallow(){

Changes to test/malloc5.test.

8
9
10
11
12
13
14
15
16
17
18
19
20

21
22
23

24
25
26
27
28
29
30









31
32
33
34
35
36
37
...
201
202
203
204
205
206
207
208
209




#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains test cases focused on the two memory-management APIs, 
# sqlite3_soft_heap_limit() and sqlite3_release_memory().
#
# $Id: malloc5.test,v 1.4 2006/01/05 15:50:07 drh Exp $

#---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR
#
#---------------------------------------------------------------------------


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


# Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} {
   puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
   finish_test
   return
}










do_test malloc5-1.1 {
  # Simplest possible test. Call sqlite3_release_memory when there is exactly
  # one unused page in a single pager cache. This test case set's the 
  # value of the ::pgalloc variable, which is used in subsequent tests.
  #
  # Note: Even though executing this statement on an empty database 
................................................................................
  execsql {
    SELECT count(*), sum(a), sum(b) FROM abc;
  }
} [list 20000 [expr int(20000.0 * 4999.5)] [expr int(20000.0 * 4999.5)]]

# Restore the soft heap limit.
sqlite3_soft_heap_limit $::soft_limit

finish_test











|





>



>







>
>
>
>
>
>
>
>
>







 







<

>
>
>
>
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
212
213
214
215
216
217
218

219
220
221
222
223
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains test cases focused on the two memory-management APIs, 
# sqlite3_soft_heap_limit() and sqlite3_release_memory().
#
# $Id: malloc5.test,v 1.5 2006/01/09 09:59:49 danielk1977 Exp $

#---------------------------------------------------------------------------
# NOTES ON EXPECTED BEHAVIOUR
#
#---------------------------------------------------------------------------


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

# Only run these tests if memory debugging is turned on.
if {[info command sqlite_malloc_stat]==""} {
   puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
   finish_test
   return
}

# Skip these tests if OMIT_MEMORY_MANAGEMENT was defined at compile time.
ifcapable !memorymanage {
   finish_test
   return
}

sqlite3_enable_memory_management 1
sqlite3 db test.db

do_test malloc5-1.1 {
  # Simplest possible test. Call sqlite3_release_memory when there is exactly
  # one unused page in a single pager cache. This test case set's the 
  # value of the ::pgalloc variable, which is used in subsequent tests.
  #
  # Note: Even though executing this statement on an empty database 
................................................................................
  execsql {
    SELECT count(*), sum(a), sum(b) FROM abc;
  }
} [list 20000 [expr int(20000.0 * 4999.5)] [expr int(20000.0 * 4999.5)]]

# Restore the soft heap limit.
sqlite3_soft_heap_limit $::soft_limit

finish_test

catch {db close}
sqlite3_enable_memory_management 0