From ac1f10458b9ab22ee0679ba8e4bff3a046e1a0ca Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Nov 2013 00:27:29 +0000 Subject: [PATCH] Add experimental sqlite3_config option to control the native Win32 heap size. FossilOrigin-Name: f09f11e94b5a7c2e51d99c3700d2acd2f3903de9 --- manifest | 24 +++++++++------ manifest.uuid | 2 +- src/main.c | 7 +++++ src/os_win.c | 16 +++++++--- src/sqlite.h.in | 8 +++++ src/test_config.c | 6 ++++ src/test_malloc.c | 28 +++++++++++++++++ test/win32heap.test | 74 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 test/win32heap.test diff --git a/manifest b/manifest index d0cb9d093e..cdad278b03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2013-11-22T21:32:44.862 +C Add\sexperimental\ssqlite3_config\soption\sto\scontrol\sthe\snative\sWin32\sheap\ssize. +D 2013-11-23T00:27:29.844 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 32bf1e6e164a6fa0ddf1bf2616c6eafbefd6e9b0 +F src/main.c 68e5b72cc2cdc2a0101c3bf7a1112fc39a4c6441 F src/malloc.c 543a8eb5508eaf4cadf55a9b503379eba2088128 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -206,7 +206,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9 -F src/os_win.c ef091b347d682cb24fc575ac9a6290341af62e2b +F src/os_win.c 39e9fc083fc35caedeb72f7724791a089722f896 F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca @@ -221,7 +221,7 @@ F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c c4d06a9238a515ff4bc86b8626139633c09a00a2 -F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e +F src/sqlite.h.in 1399855c547dbe3cbc556f5423067834e0945b88 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 @@ -242,7 +242,7 @@ F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16 -F src/test_config.c e825cd6a4a8f498be246fc5934fe5fd702b9441f +F src/test_config.c 10d0e00dd6315879a6d9fac20bd063c7bbbfb8f8 F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -253,7 +253,7 @@ F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61 F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e -F src/test_malloc.c eba4e1c5847cc98e7edc98f62265cd2abafba7a6 +F src/test_malloc.c eec5258da8ca468e3165bfa5e2e4461fe08ed385 F src/test_multiplex.c 9f304bf04170c91c0318238d512df2da039eb1c8 F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f @@ -1083,6 +1083,7 @@ F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test 2a3d5181decc801b36600fa1c40b0dad2ccc267f F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c +F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test e2aafc07e6990fe86c69be22a3d1a0e210cd329b F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1141,7 +1142,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 22144c9df260910c4b67960b0e6a6bd5a6758cd7 -R a6046c7308cc14b222954cb363712891 +P f336c18fb72ab90e93640b12ac540d41accc7658 +R 4fb7e3d2adbb1a56917a356c46494b14 +T *branch * winHeapSize +T *sym-winHeapSize * +T -sym-trunk * U mistachkin -Z 1a138036d5d9c73c4e767d01f06aef9f +Z 570dda2e20bfd9c30436e58012ccd873 diff --git a/manifest.uuid b/manifest.uuid index f3f95c10e6..18b1640e79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f336c18fb72ab90e93640b12ac540d41accc7658 \ No newline at end of file +f09f11e94b5a7c2e51d99c3700d2acd2f3903de9 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5e03662d38..61d06fdb78 100644 --- a/src/main.c +++ b/src/main.c @@ -515,6 +515,13 @@ int sqlite3_config(int op, ...){ break; } +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) + case SQLITE_CONFIG_HEAP_SIZE: { + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + break; + } +#endif + default: { rc = SQLITE_ERROR; break; diff --git a/src/os_win.c b/src/os_win.c index a2f5513a2b..a1c3a04d7b 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1401,14 +1401,20 @@ static int winMemInit(void *pAppData){ #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE if( !pWinMemData->hHeap ){ + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; + if( dwMaximumSize==0 ){ + dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; + }else if( dwInitialSize>dwMaximumSize ){ + dwInitialSize = dwMaximumSize; + } pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, - SQLITE_WIN32_HEAP_INIT_SIZE, - SQLITE_WIN32_HEAP_MAX_SIZE); + dwInitialSize, dwMaximumSize); if( !pWinMemData->hHeap ){ sqlite3_log(SQLITE_NOMEM, - "failed to HeapCreate (%lu), flags=%u, initSize=%u, maxSize=%u", - osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, - SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); + "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, + dwMaximumSize); return SQLITE_NOMEM; } pWinMemData->bOwned = TRUE; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index e6dcfaba9a..7c39f4efe9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1682,6 +1682,13 @@ struct sqlite3_mem_methods { ** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ ** ^If either argument to this option is negative, then that argument is ** changed to its compile-time default. +** +** [[SQLITE_CONFIG_HEAP_SIZE]] +**
SQLITE_CONFIG_HEAP_SIZE +**
^This option is only available if SQLite is compiled for Windows +** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. +** SQLITE_CONFIG_HEAP_SIZE takes a 32-bit integer value that specifies +** the maximum size of the heap. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1706,6 +1713,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_HEAP_SIZE 23 /* int nByte */ /* ** CAPI3REF: Database Connection Configuration Options diff --git a/src/test_config.c b/src/test_config.c index 8d871aa74c..f44be40508 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -63,6 +63,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "curdir", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_WIN32_MALLOC + Tcl_SetVar2(interp, "sqlite_options", "win32malloc", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "win32malloc", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_DEBUG Tcl_SetVar2(interp, "sqlite_options", "debug", "1", TCL_GLOBAL_ONLY); #else diff --git a/src/test_malloc.c b/src/test_malloc.c index f513e24bf4..0c2d6ba223 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1130,6 +1130,33 @@ static int test_config_heap( return TCL_OK; } +/* +** Usage: sqlite3_config_heap_size NBYTE +*/ +static int test_config_heap_size( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int nByte; /* Size to pass to sqlite3_config() */ + int rc; /* Return code of sqlite3_config() */ + + Tcl_Obj * CONST *aArg = &objv[1]; + int nArg = objc-1; + + if( nArg!=1 ){ + Tcl_WrongNumArgs(interp, 1, objv, "NBYTE"); + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR; + + rc = sqlite3_config(SQLITE_CONFIG_HEAP_SIZE, nByte); + + Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); + return TCL_OK; +} + /* ** Usage: sqlite3_config_error [DB] ** @@ -1473,6 +1500,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ { "sqlite3_db_status", test_db_status ,0 }, { "install_malloc_faultsim", test_install_malloc_faultsim ,0 }, { "sqlite3_config_heap", test_config_heap ,0 }, + { "sqlite3_config_heap_size", test_config_heap_size ,0 }, { "sqlite3_config_memstatus", test_config_memstatus ,0 }, { "sqlite3_config_lookaside", test_config_lookaside ,0 }, { "sqlite3_config_error", test_config_error ,0 }, diff --git a/test/win32heap.test b/test/win32heap.test new file mode 100644 index 0000000000..b92f8040e6 --- /dev/null +++ b/test/win32heap.test @@ -0,0 +1,74 @@ +# 2013 November 22 +# +# The author disclaims copyright to this source code. In place of +# 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. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this script is recovery from transient manditory locks +# that sometimes appear on database files due to anti-virus software. +# + +if {$tcl_platform(platform)!="windows"} return + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !win32malloc { + finish_test + return +} + +set testprefix win32heap + +do_test 1.1 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap_size 1048576 + sqlite3_initialize +} {SQLITE_OK} + +do_test 1.2 { + sqlite3 db test.db + catchsql { + CREATE TABLE t1(x); + } +} {0 {}} + +do_test 1.3 { + catchsql { + INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576)); + } +} {1 {out of memory}} + +do_test 1.4 { + catchsql { + SELECT COUNT(*) FROM t1; + } +} {0 0} + +do_test 1.5 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap_size 0 + sqlite3_initialize +} {SQLITE_OK} + +do_test 1.6 { + sqlite3 db test.db + catchsql { + INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576)); + } +} {0 {}} + +do_test 1.7 { + catchsql { + SELECT COUNT(*) FROM t1; + } +} {0 1} + +finish_test