From: dan Date: Fri, 30 Nov 2018 16:26:39 +0000 (+0000) Subject: Merge the mutex-free PRNG change into this branch. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b5c67f78485dbef431d996577bdc5b9f4371ffb;p=thirdparty%2Fsqlite.git Merge the mutex-free PRNG change into this branch. FossilOrigin-Name: 81e626f4a44be75425cf916ec61b6b36df0907ebac4adbf6786f87ad4f3a0674 --- diff --git a/manifest b/manifest index e89604258e..4fafda0823 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\sbegin-concurrent\schanges\sinto\sthis\sbranch. -D 2018-11-26T07:34:33.644 +C Merge\sthe\smutex-free\sPRNG\schange\sinto\sthis\sbranch. +D 2018-11-30T16:26:39.800 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in b730006b54c990461d864c5387f2e6f13aadb0236804555fb010ed6865a5f058 @@ -465,7 +465,7 @@ F src/delete.c cec65c0e74be7492cafba1b77580732b0b1a41a4dbc4ac70909ac44b65b2a20b F src/expr.c 9aacc0b72348ba90010b672dcbbbe2fa56e1182043bc917a3a147b2bc57a5497 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 972a4ba14296bef2303a0abbad1e3d82bc3c61f9e6ce4e8e9528bdee68748812 -F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f +F src/func.c 8efa2c813b3f6a831a070311b5bcbc97993b79cbcd274bdb49bde56ccd3d37bc F src/global.c 9bf034fd560bdd514715170ed8460bb7f823cec113f0569ef3f18a20c7ccd128 F src/hash.c 931ec82d7e070654a8facb42549bbb3a25720171d73ba94c3d3160580d01ef1f F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -474,7 +474,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 6b81aae27b196925d8ff78824f4bbd435d6a40cd38dc324685e21735bb402109 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e F src/loadext.c 448eab53ecdb566a1259ee2d45ebff9c0bc4a2cf393774488775c33e4fbe89bf -F src/main.c 47b8f0411812b3dd7c41fddf09420638aabfb838c6134de0ec5c18df381ecd28 +F src/main.c b23c7b1eeca05ee3af56dacdc0efdf61484dc17194c82233fb98b42ee8e807b8 F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -507,15 +507,15 @@ F src/pragma.c a2eab23fbf7c70c28f3a22629de2662d052c22853649430be302b910719574de F src/pragma.h 7003ea8e45e5da0a7cd6d35846214f9ae9ecf5be66b268415ceea5855324af11 F src/prepare.c f81f8d707e583192c28fea0b2e19385415b7d188123b23f49b038076408d7a69 F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381 -F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 +F src/random.c f27af4099afaea7284ade5c206224dcfdb2334cfd119d018b470d46356b3f27d F src/resolve.c bc8c79e56439b111e7d9415e44940951f7087e9466c3a9d664558ef0faf31073 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 61e867a906f140b73baf4ce7a201ad6dcba30820969f5618ee40e9a0d32c6f5f +F src/select.c e1cad752987c476a9d1d053682558caec048ea799ef7ba1b6e38e2266451010d F src/shell.c.in 6a9d8a56700d136addc14d1cd25863b8112e5c12e1877f373750bda476ff6314 F src/sqlite.h.in 41dfd60cf62d4f8756991517c1a9d2ff4977ca04f7798c10b0c16dcf884cbc7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683 -F src/sqliteInt.h b9f89d79c047df09c1efe2dfe054512cf956780af468daef9d368b319dc68aa7 +F src/sqliteInt.h ca2d5f030547a1677a74bce26338ca70ebd6747b7d500a9edc00146c61ff2376 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -592,7 +592,7 @@ F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 F src/vtab.c 70188a745dc4e57d26e942681ff4b2912b7c8249ad5de3f60f0677b4337bcfaa F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 41de67424237a3dd097a093057ba454ccfef26c452f6263fecd5591a15dd5a9a +F src/wal.c f53ac2b6ec6f23960471b4402632b8276d8b80c1ac31a28ea08500c56a9cc5c9 F src/wal.h f325a5856b669f5ba449157485915816103857c8574efc746ac55eba3335c5e0 F src/walker.c fb94aadc9099ff9c6506d0a8b88d51266005bcaa265403f3d7caf732a562eb66 F src/where.c 3818e8a736a05d2cb194e64399af707e367fbcc5c251d785804d02eaf121288e @@ -1791,7 +1791,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6f3dd9809fdef7d6195f1f93428a662d5a8c01dba9815daa22d1b94059a2eb43 28a615a2e0f48b0fee3eaf7841ff902e069fa6c221df6ad9a57b8709c88561fb -R c73a7474a8ba36fb4e79620530d56018 +P 76608f750ab13c0a165def9672759fee43cf4e9895df3bfa21765e08358b07a0 +Q +8b1fc4b9f3e743bffcfbbb8e26991240441778e10512fb502b8eaec460184296 +R 05d3a3eaadb134c59c94e4d5941647d0 U dan -Z 4a9121244def783d11e1880a226f98cc +Z 45ce6d06a747e646527aeb46f6440480 diff --git a/manifest.uuid b/manifest.uuid index 04bacb7327..ade3e7b765 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -76608f750ab13c0a165def9672759fee43cf4e9895df3bfa21765e08358b07a0 \ No newline at end of file +81e626f4a44be75425cf916ec61b6b36df0907ebac4adbf6786f87ad4f3a0674 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 0504a8f026..d8233835a2 100644 --- a/src/func.c +++ b/src/func.c @@ -485,8 +485,9 @@ static void randomFunc( sqlite3_value **NotUsed2 ){ sqlite_int64 r; + sqlite3 *db = sqlite3_context_db_handle(context); UNUSED_PARAMETER2(NotUsed, NotUsed2); - sqlite3_randomness(sizeof(r), &r); + sqlite3FastRandomness(&db->sPrng, sizeof(r), &r); if( r<0 ){ /* We need to prevent a random number of 0x8000000000000000 ** (or -9223372036854775808) since when you do abs() of that @@ -512,6 +513,7 @@ static void randomBlob( ){ int n; unsigned char *p; + sqlite3 *db = sqlite3_context_db_handle(context); assert( argc==1 ); UNUSED_PARAMETER(argc); n = sqlite3_value_int(argv[0]); @@ -520,7 +522,7 @@ static void randomBlob( } p = contextMalloc(context, n); if( p ){ - sqlite3_randomness(n, p); + sqlite3FastRandomness(&db->sPrng, n, p); sqlite3_result_blob(context, (char*)p, n, sqlite3_free); } } diff --git a/src/main.c b/src/main.c index 19831abfc7..38b056d93b 100644 --- a/src/main.c +++ b/src/main.c @@ -3023,7 +3023,7 @@ static int openDatabase( db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; db->lookaside.bDisable = 1; - + sqlite3FastPrngInit(&db->sPrng); assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; diff --git a/src/random.c b/src/random.c index d4ae77c435..dd971ab655 100644 --- a/src/random.c +++ b/src/random.c @@ -106,6 +106,28 @@ void sqlite3_randomness(int N, void *pBuf){ sqlite3_mutex_leave(mutex); } +/* +** Initialize a fast PRNG. A Fast PRNG is called "fast" because it does +** not need a mutex to operate, though it does use a mutex to initialize. +** The quality of the randomness is not as good as the global PRNG. +*/ +void sqlite3FastPrngInit(FastPrng *pPrng){ + sqlite3_randomness(sizeof(*pPrng), pPrng); + pPrng->x |= 1; +} + +/* +** Generate N bytes of pseudo-randomness using a FastPrng +*/ +void sqlite3FastRandomness(FastPrng *pPrng, int N, void *P){ + unsigned char *pOut = (unsigned char*)P; + while( N-->0 ){ + pPrng->x = ((pPrng->x)>>1) ^ ((1+~((pPrng->x)&1)) & 0xd0000001); + pPrng->y = (pPrng->y)*1103515245 + 12345; + *(pOut++) = (pPrng->x ^ pPrng->y) & 0xff; + } +} + #ifndef SQLITE_UNTESTABLE /* ** For testing purposes, we sometimes want to preserve the state of diff --git a/src/select.c b/src/select.c index c60ff27001..5cd1630785 100644 --- a/src/select.c +++ b/src/select.c @@ -1993,7 +1993,7 @@ int sqlite3ColumnsFromExprList( if( zName[j]==':' ) nName = j; } zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); - if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); + if( cnt>3 ) sqlite3FastRandomness(&db->sPrng, sizeof(cnt), &cnt); } pCol->zName = zName; sqlite3ColumnPropertiesFromName(0, pCol); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 12a9f38867..410cc74c52 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1089,6 +1089,7 @@ typedef struct Parse Parse; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; typedef struct RenameToken RenameToken; +typedef struct FastPrng FastPrng; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; @@ -1189,6 +1190,14 @@ typedef int VList; # define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS #endif +/* +** State of a simple PRNG used for the per-connection and per-pager +** pseudo-random number generators. +*/ +struct FastPrng { + unsigned int x, y; +}; + /* ** Each database file to be accessed by the system is an instance ** of the following structure. There are normally two of these structures @@ -1398,6 +1407,7 @@ struct sqlite3 { u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ + FastPrng sPrng; /* State of the per-connection PRNG */ int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ @@ -3997,6 +4007,8 @@ Vdbe *sqlite3GetVdbe(Parse*); void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); #endif +void sqlite3FastPrngInit(FastPrng*); +void sqlite3FastRandomness(FastPrng*, int N, void *P); void sqlite3RollbackAll(sqlite3*,int); void sqlite3CodeVerifySchema(Parse*, int); void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); diff --git a/src/wal.c b/src/wal.c index 031389ea6f..c67bd9dcac 100644 --- a/src/wal.c +++ b/src/wal.c @@ -474,6 +474,7 @@ struct Wal { u32 nPriorFrame; /* For sqlite3WalInfo() */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ + FastPrng sPrng; /* Random number generator */ #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ #endif @@ -1380,6 +1381,7 @@ int sqlite3WalOpen( pRet->syncHeader = 1; pRet->padToSectorBoundary = 1; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); + sqlite3FastPrngInit(&pRet->sPrng); /* Open file handle on the write-ahead log file. */ flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); @@ -1926,7 +1928,7 @@ static int walCheckpoint( rc = SQLITE_BUSY; }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ u32 salt1; - sqlite3_randomness(4, &salt1); + sqlite3FastRandomness(&pWal->sPrng, 4, &salt1); assert( pInfo->nBackfill==pWal->hdr.mxFrame ); rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); if( rc==SQLITE_OK ){ @@ -3373,7 +3375,7 @@ static int walRestartLog(Wal *pWal){ assert( pInfo->nBackfill==pWal->hdr.mxFrame ); if( pInfo->nBackfill>0 ){ u32 salt1; - sqlite3_randomness(4, &salt1); + sqlite3FastRandomness(&pWal->sPrng, 4, &salt1); rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); if( rc==SQLITE_OK ){ /* If all readers are using WAL_READ_LOCK(0) (in other words if no @@ -3589,7 +3591,7 @@ int sqlite3WalFrames( sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); sqlite3Put4byte(&aWalHdr[8], szPage); sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); - if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); + if( pWal->nCkpt==0 ) sqlite3FastRandomness(&pWal->sPrng, 8, pWal->hdr.aSalt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); sqlite3Put4byte(&aWalHdr[24], aCksum[0]);