From: mistachkin Date: Wed, 24 Aug 2011 16:13:57 +0000 (+0000) Subject: Experimental work to allow SQLite to use the native Win32 heap API. X-Git-Tag: version-3.7.8~42^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1b186a9947fabd9b6f2cdb0648c4bd8671813c81;p=thirdparty%2Fsqlite.git Experimental work to allow SQLite to use the native Win32 heap API. FossilOrigin-Name: bf3d0ab53829350637283442f75071fe6d925245 --- diff --git a/Makefile.msc b/Makefile.msc index 60fe09dcd1..9617281cb8 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -48,6 +48,11 @@ TCC = $(TCC) -DNDEBUG # TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS +# +# Use native Win32 heap. +# +TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1 + # The locations of the Tcl header and library files. Also, the library that # non-stubs enabled programs using Tcl must link against. These variables # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment diff --git a/manifest b/manifest index 0615137744..1cc1391048 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Updates\sto\sthe\ssqlite3_mem_methods\sdocumentation. -D 2011-08-24T15:18:16.947 +C Experimental\swork\sto\sallow\sSQLite\sto\suse\sthe\snative\sWin32\sheap\sAPI. +D 2011-08-24T16:13:57.329 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8c930e7b493d59099ea1304bd0f2aed152eb3315 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 386444f1e1a1536d19a426030d93fd6e03b7d3b5 +F Makefile.msc 8ebd89ed4493641a9e2316a941d776e2bcc5ad39 F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION f724de7326e87b7f3b0a55f16ef4b4d993680d54 @@ -166,7 +166,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 65a897143b64667d23ed329a7984b9b405accb58 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 81341980c52a44106b10c1e28a0d5c5247476452 -F src/os_win.c 4eb6fa00ee28f6d7bad0526edcbe5a60d297c67a +F src/os_win.c a9950bf0f32753418ab6f74417aebd432bde2383 F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -183,7 +183,7 @@ F src/select.c d219c4b68d603cc734b6f9b1e2780fee12a1fa0d F src/shell.c bbe7818ff5bc8614105ceb81ad67b8bdc0b671dd F src/sqlite.h.in 0a6c9c23337fd1352c5c75a613ff9533aa7d91cb F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 -F src/sqliteInt.h ba4a6d6288efb25b84bc0d7d0aaf80f9b42523ba +F src/sqliteInt.h 137c2af01e5913f9673e226b0822392cc4655b98 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -961,7 +961,10 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 46f5a68bfa4199a4bd398030bf88bfbb4df3d5ca -R 153cb3ab6156bae4555a624a64dd86d1 -U drh -Z 489994766712dfe3d3bf81175cae5684 +P 988998fe7b0a21ed113b67f812e51f357045bef4 +R 0396c522791d26a46580a50de4d03044 +T *branch * winNativeHeap +T *sym-winNativeHeap * +T -sym-trunk * +U mistachkin +Z 6f33f4bfa3c296caae6e295d0a3da4b8 diff --git a/manifest.uuid b/manifest.uuid index 1206faf6ce..e1ad382845 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -988998fe7b0a21ed113b67f812e51f357045bef4 \ No newline at end of file +bf3d0ab53829350637283442f75071fe6d925245 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index a006627bf9..73db98ad2d 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -119,6 +119,51 @@ struct winFile { #endif }; +/* + * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the + * various Win32 API heap functions instead of our own. + */ +#ifdef SQLITE_WIN32_MALLOC +/* + * The initial size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_INIT_SIZE +# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \ + (SQLITE_DEFAULT_PAGE_SIZE) + 4194304) +#endif + +/* + * The maximum size of the Win32-specific heap. This value may be zero. + */ +#ifndef SQLITE_WIN32_HEAP_MAX_SIZE +# define SQLITE_WIN32_HEAP_MAX_SIZE (0) +#endif + +/* +** The winMemData structure stores information required by the Win32-specific +** sqlite3_mem_methods implementation. +*/ +typedef struct winMemData winMemData; +struct winMemData { + u32 magic; /* Magic number to detect structure corruption. */ + HANDLE hHeap; /* The handle to our heap. */ + BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */ +}; + +#define WINMEM_MAGIC 0x42b2830b + +static struct winMemData win_mem_data = { WINMEM_MAGIC, NULL, FALSE }; + +static void *winMemMalloc(int nBytes); +static void winMemFree(void *pPrior); +static void *winMemRealloc(void *pPrior, int nBytes); +static int winMemSize(void *p); +static int winMemRoundup(int n); +static int winMemInit(void *pAppData); +static void winMemShutdown(void *pAppData); + +const sqlite3_mem_methods *sqlite3MemGetWin32(void); +#endif /* SQLITE_WIN32_MALLOC */ /* ** Forward prototypes. @@ -171,6 +216,159 @@ static int sqlite3_os_type = 0; } #endif /* SQLITE_OS_WINCE */ +#ifdef SQLITE_WIN32_MALLOC +/* +** Allocate nBytes of memory. +*/ +static void *winMemMalloc(int nBytes){ + HANDLE hHeap; + + assert( win_mem_data.magic==WINMEM_MAGIC ); + hHeap = win_mem_data.hHeap; + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, 0, NULL) ); +#endif + assert( nBytes>=0 ); + return HeapAlloc(hHeap, 0, (SIZE_T)nBytes); +} + +/* +** Free memory. +*/ +static void winMemFree(void *pPrior){ + HANDLE hHeap; + + assert( win_mem_data.magic==WINMEM_MAGIC ); + hHeap = win_mem_data.hHeap; + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, 0, pPrior) ); +#endif + if (!pPrior) return; /* Passing NULL to HeapFree is undefined. */ + HeapFree(hHeap, 0, pPrior); +} + +/* +** Change the size of an existing memory allocation +*/ +static void *winMemRealloc(void *pPrior, int nBytes){ + HANDLE hHeap; + + assert( win_mem_data.magic==WINMEM_MAGIC ); + hHeap = win_mem_data.hHeap; + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, 0, pPrior) ); +#endif + assert( nBytes>=0 ); + if (!pPrior) return HeapAlloc(hHeap, 0, (SIZE_T)nBytes); + return HeapReAlloc(hHeap, 0, pPrior, (SIZE_T)nBytes); +} + +/* +** Return the size of an outstanding allocation, in bytes. +*/ +static int winMemSize(void *p){ + HANDLE hHeap; + SIZE_T n; + + assert( win_mem_data.magic==WINMEM_MAGIC ); + hHeap = win_mem_data.hHeap; + assert( hHeap!=0 ); + assert( hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert ( HeapValidate(hHeap, 0, NULL) ); +#endif + if (!p) return 0; + n = HeapSize(hHeap, 0, p); + assert( n<=INT_MAX ); + return (int)n; +} + +/* +** Round up a request size to the next valid allocation size. +*/ +static int winMemRoundup(int n){ + return n; +} + +/* +** Initialize this module. +*/ +static int winMemInit(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if (!pWinMemData) return SQLITE_ERROR; + assert( pWinMemData->magic==WINMEM_MAGIC ); + if (!pWinMemData->hHeap){ + pWinMemData->hHeap = HeapCreate(0, SQLITE_WIN32_HEAP_INIT_SIZE, + SQLITE_WIN32_HEAP_MAX_SIZE); + if (!pWinMemData->hHeap){ + return SQLITE_NOMEM; + } + pWinMemData->bOwned = TRUE; + } + assert( pWinMemData->hHeap!=0 ); + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert( HeapValidate(pWinMemData->hHeap, 0, NULL) ); +#endif + return SQLITE_OK; +} + +/* +** Deinitialize this module. +*/ +static void winMemShutdown(void *pAppData){ + winMemData *pWinMemData = (winMemData *)pAppData; + + if (!pWinMemData) return; + if (pWinMemData->hHeap){ + assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE ); +#ifdef SQLITE_WIN32_MALLOC_VALIDATE + assert( HeapValidate(pWinMemData->hHeap, 0, NULL) ); +#endif + if (pWinMemData->bOwned){ + if (!HeapDestroy(pWinMemData->hHeap)){ + /* TODO: Log this? */ + } + pWinMemData->bOwned = FALSE; + } + pWinMemData->hHeap = NULL; + } +} + +/* +** Populate the low-level memory allocation function pointers in +** sqlite3GlobalConfig.m with pointers to the routines in this file. The +** arguments specify the block of memory to manage. +** +** This routine is only called by sqlite3_config(), and therefore +** is not required to be threadsafe (it is not). +*/ +const sqlite3_mem_methods *sqlite3MemGetWin32(void){ + static const sqlite3_mem_methods winMemMethods = { + winMemMalloc, + winMemFree, + winMemRealloc, + winMemSize, + winMemRoundup, + winMemInit, + winMemShutdown, + &win_mem_data + }; + return &winMemMethods; +} + +void sqlite3MemSetDefault(void){ + sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); +} +#endif /* SQLITE_WIN32_MALLOC */ + /* ** Convert a UTF-8 string to microsoft unicode (UTF-16?). ** diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bcf6a591af..8c9b179d44 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -147,6 +147,7 @@ ** specify which memory allocation subsystem to use. ** ** SQLITE_SYSTEM_MALLOC // Use normal system malloc() +** SQLITE_WIN32_MALLOC // Use Win32 native heap API ** SQLITE_MEMDEBUG // Debugging version of system malloc() ** ** (Historical note: There used to be several other options, but we've @@ -155,11 +156,11 @@ ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. */ -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)>1 +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1 # error "At most one of the following compile-time configuration options\ is allows: SQLITE_SYSTEM_MALLOC, SQLITE_MEMDEBUG" #endif -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_MEMDEBUG)==0 +#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0 # define SQLITE_SYSTEM_MALLOC 1 #endif