From: drh <> Date: Mon, 20 Jul 2026 11:50:37 +0000 (+0000) Subject: Performance improvement in the sqlite3_initialize() interface. X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=27a20bafd4e10e131a8a81e9d863dd9f199fa979;p=thirdparty%2Fsqlite.git Performance improvement in the sqlite3_initialize() interface. FossilOrigin-Name: 4ad701b085ce1b9ada41441f560e55580f0dd33e8145857afce6c665aa974ad0 --- diff --git a/manifest b/manifest index 0bbf74071a..8d2c41e340 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sboundary\scases\sof\srowid\slookup\susing\svery\slarge\sfloating\spoint\svalues\s-\nvalues\snear\sthe\sminimum\sand\smaximum\s64-bit\ssigned\sinteger.\n[forum:/info/2026-07-19T07:31:46Z|Forum\s2026-07-19T07:31:46Z]. -D 2026-07-19T19:49:24.674 +C Performance\simprovement\sin\sthe\ssqlite3_initialize()\sinterface. +D 2026-07-20T11:50:37.472 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -706,7 +706,7 @@ F src/insert.c e6e9b574b4863649e2c433f2260f226183e697df1ab73fcb8da9a85d5abcd390 F src/json.c e4af4d799e4e7630c633b3b356d65e92d1781e42343ab77b8ef747c932762012 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 5cd4cd7ec6e1a46416806899086363fbf95eecd3bfb9a388b436c9a77243c902 -F src/main.c b0a4b497d0bf4414bdcd5dda81c49851fca7b6781e9e485ac4c360b291f6dbb8 +F src/main.c 2af1793f14ae547168e11682720aefc360d3fec75bc1dbabd9565ca09b02c8ab F src/malloc.c 422f7e0498e1c9ef967f06283b6f2c0b16db6b905d8e06f6dbc8baaa3e4e6c5a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 @@ -2215,8 +2215,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 436cf63e941b3db936a01d4584c9e3cc9675ce9ef4b6689530218c27252c170d -R d5f2585f74441642eac52f7b29db0d93 +P 987ba5a3dc5f2a2294b77ef3ec1ea06682f0530a7268777c6b64985dd0e90d40 +R 225576c20d8aa54d888d7e314b9b6b32 U drh -Z 7d9a924e268268fab71b80580c8683dc +Z dff319d19633fb41fe302187d5c63413 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5e80288db0..c7be5d35b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -987ba5a3dc5f2a2294b77ef3ec1ea06682f0530a7268777c6b64985dd0e90d40 +4ad701b085ce1b9ada41441f560e55580f0dd33e8145857afce6c665aa974ad0 diff --git a/src/main.c b/src/main.c index ec04f20685..8d7b47e8f9 100644 --- a/src/main.c +++ b/src/main.c @@ -159,17 +159,29 @@ char *sqlite3_data_directory = 0; /* ** Initialize SQLite. ** -** This routine must be called to initialize the memory allocation, -** VFS, and mutex subsystems prior to doing any serious work with -** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT +** The sqlite3_initialize() routine must be called to initialize the +** memory allocation, VFS, and mutex subsystems prior to doing any +** serious work. As long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as ** sqlite3_open(). ** ** This routine is a no-op except on its very first call for the process, -** or for the first call after a call to sqlite3_shutdown. +** or for the first call after a call to sqlite3_shutdown. Most calls +** to sqlite3_initialize() are, in fact, no-ops. For that reason, the +** routine is broken into two pieces: ** -** The first thread to call this routine runs the initialization to -** completion. If subsequent threads call this routine before the first +** sqlite3Initialize() Does the actual work of initialization +** +** sqlite3_initialize() Checks to see if initialization is needed +** and invokes sqlite3Initialize() if it is. +** +** The sqlite3_initialize() interface is called frequently, but +** sqlite3Initialize() runs rarely. The function is broken up this way +** to avoid wasting CPU cycles with unnecessary stack setup for local +** variables in cases where it is not needed. +** +** The first thread to call sqlite3_initialize() runs the initialization to +** completion. If subsequent threads call sqlite3_initialize() before the first ** thread has finished the initialization process, then the subsequent ** threads must block until the first thread finishes with the initialization. ** @@ -177,44 +189,29 @@ char *sqlite3_data_directory = 0; ** calls to this routine should not block, of course. Otherwise the ** initialization process would never complete. ** -** Let X be the first thread to enter this routine. Let Y be some other -** thread. Then while the initial invocation of this routine by X is -** incomplete, it is required that: +** Let X be the first thread to enter sqlite3_initialize(). Let Y be some +** other thread. While the initial invocation of sqlite3_initialize() by X +** is incomplete, it is required that: ** -** * Calls to this routine from Y must block until the outer-most +** * Calls to sqlite3_initialize() from Y must block until the outer-most ** call by X completes. ** -** * Recursive calls to this routine from thread X return immediately -** without blocking. +** * Recursive calls to sqlite3_initialize() from thread X return +** immediately without blocking. */ -int sqlite3_initialize(void){ - MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */ - int rc; /* Result code */ +static SQLITE_NOINLINE int sqlite3Initialize(void){ + MUTEX_LOGIC( sqlite3_mutex *pMainMtx; ) /* The main static mutex */ + int rc; /* Result code */ #ifdef SQLITE_EXTRA_INIT - int bRunExtraInit = 0; /* Extra initialization needed */ -#endif - -#ifdef SQLITE_OMIT_WSD - rc = sqlite3_wsd_init(4096, 24); - if( rc!=SQLITE_OK ){ - return rc; - } + int bRunExtraInit = 0; /* Extra initialization needed */ #endif /* If the following assert() fails on some obscure processor/compiler - ** combination, the work-around is to set the correct pointer - ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */ - assert( SQLITE_PTRSIZE==sizeof(char*) ); - - /* If SQLite is already completely initialized, then this call - ** to sqlite3_initialize() should be a no-op. But the initialization - ** must be complete. So isInit must not be set until the very end - ** of this routine. + ** combination to warn that SQLite has been mis-compiled. If you hit + ** this assert(), that means you need to recompile with the + ** -DSQLITE_PTRSIZE=n compile-time option to set the correct pointer size. */ - if( sqlite3GlobalConfig.isInit ){ - sqlite3MemoryBarrier(); - return SQLITE_OK; - } + assert( SQLITE_PTRSIZE==sizeof(char*) ); /* Make sure the mutex subsystem is initialized. If unable to ** initialize the mutex subsystem, return early with the error. @@ -360,6 +357,26 @@ int sqlite3_initialize(void){ #endif return rc; } +SQLITE_API int sqlite3_initialize(void){ + /* If this build does not support writable static data (WSD) natively + ** then we have to invoke the (application-supplied) WSD initialization + ** routine before doing anything else. */ +#ifdef SQLITE_OMIT_WSD + rc = sqlite3_wsd_init(4096, 24); + if( rc!=SQLITE_OK ){ + return rc; + } +#endif + + if( sqlite3GlobalConfig.isInit ){ + /* SQLite has already been initialized. Fast early-out. */ + sqlite3MemoryBarrier(); + return SQLITE_OK; + }else{ + /* Invoke sqlite3Initialize() to do the actual work. */ + return sqlite3Initialize(); + } +} /* ** Undo the effects of sqlite3_initialize(). Must not be called while