]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove extraneous result-code SAB slots. Doc additions.
authorstephan <stephan@noemail.net>
Tue, 20 Sep 2022 10:11:52 +0000 (10:11 +0000)
committerstephan <stephan@noemail.net>
Tue, 20 Sep 2022 10:11:52 +0000 (10:11 +0000)
FossilOrigin-Name: 88de20712bbe3e11ea74af95edc34e9ab9f346f9aa0a30931e5a9e1f96ce57b0

ext/wasm/GNUmakefile
ext/wasm/api/sqlite3-api-opfs.js
ext/wasm/sqlite3-opfs-async-proxy.js
manifest
manifest.uuid

index ae416cb46942c433cf8f813a8fac4e36e4af972c..cff5af5944f2548fa7168cae2af5ca4092656352 100644 (file)
@@ -434,18 +434,20 @@ push-fiddle: $(fiddle_files)
 # painful.
 
 .PHONY: o0 o1 o2 o3 os oz
+o-xtra :=
+#o-xtra += -flto
 o0:
-       $((MAKE) clean; $(MAKE) -e "emcc_opt=-O0 -flto" fiddle_opt=-O0
+       $(MAKE) clean; $(MAKE) -e "emcc_opt=-O0 $(o-xtra)" fiddle_opt=-O0
 o1:
-       $(MAKE) clean; $(MAKE) -e "emcc_opt=-O1 -flto" fiddle_opt=-O1
+       $(MAKE) clean; $(MAKE) -e "emcc_opt=-O1 $(o-xtra)" fiddle_opt=-O1
 o2:
-       $(MAKE) clean; $(MAKE) -e "emcc_opt=-O2 -flto" fiddle_opt=-O2
+       $(MAKE) clean; $(MAKE) -e "emcc_opt=-O2 $(o-xtra)" fiddle_opt=-O2
 o3:
-       $(MAKE) clean; $(MAKE) -e "emcc_opt=-O3 -flto" fiddle_opt=-O3
+       $(MAKE) clean; $(MAKE) -e "emcc_opt=-O3 $(o-xtra)" fiddle_opt=-O3
 os:
-       $(MAKE) clean; $(MAKE) -e "emcc_opt=-Os -flto" fiddle_opt=-Os
+       $(MAKE) clean; $(MAKE) -e "emcc_opt=-Os $(o-xtra)" fiddle_opt=-Os
 oz:
-       $(MAKE) clean; $(MAKE) -e "emcc_opt=-Oz -flto" fiddle_opt=-Oz
+       $(MAKE) clean; $(MAKE) -e "emcc_opt=-Oz $(o-xtra)" fiddle_opt=-Oz
 
 ########################################################################
 # Sub-makes...
index 52777c5f3d93881021bf05a601cf235b7a709589..a0630d8e760c99fc4636c578ad31c9d9498cb7ca 100644 (file)
@@ -165,6 +165,38 @@ sqlite3.installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri)
       }
     }/*metrics*/;      
 
+    const pDVfs = capi.sqlite3_vfs_find(null)/*pointer to default VFS*/;
+    const dVfs = pDVfs
+          ? new sqlite3_vfs(pDVfs)
+          : null /* dVfs will be null when sqlite3 is built with
+                    SQLITE_OS_OTHER. Though we cannot currently handle
+                    that case, the hope is to eventually be able to. */;
+    const opfsVfs = new sqlite3_vfs();
+    const opfsIoMethods = new sqlite3_io_methods();
+    opfsVfs.$iVersion = 2/*yes, two*/;
+    opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
+    opfsVfs.$mxPathname = 1024/*sure, why not?*/;
+    opfsVfs.$zName = wasm.allocCString("opfs");
+    // All C-side memory of opfsVfs is zeroed out, but just to be explicit:
+    opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null;
+    opfsVfs.ondispose = [
+      '$zName', opfsVfs.$zName,
+      'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null),
+      'cleanup opfsIoMethods', ()=>opfsIoMethods.dispose()
+    ];
+    /**
+       Pedantic sidebar about opfsVfs.ondispose: the entries in that array
+       are items to clean up when opfsVfs.dispose() is called, but in this
+       environment it will never be called. The VFS instance simply
+       hangs around until the WASM module instance is cleaned up. We
+       "could" _hypothetically_ clean it up by "importing" an
+       sqlite3_os_end() impl into the wasm build, but the shutdown order
+       of the wasm engine and the JS one are undefined so there is no
+       guaranty that the opfsVfs instance would be available in one
+       environment or the other when sqlite3_os_end() is called (_if_ it
+       gets called at all in a wasm build, which is undefined).
+    */
+
     /**
        State which we send to the async-api Worker or share with it.
        This object must initially contain only cloneable or sharable
@@ -187,54 +219,64 @@ sqlite3.installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri)
     const state = Object.create(null);
     state.littleEndian = true;
     state.verbose = options.verbose;
+    /* Size of file I/O buffer block. 64k = max sqlite3 page size. */
     state.fileBufferSize =
-      1024 * 64 /* size of aFileHandle.sab. 64k = max sqlite3 page
-                   size. */;
+      1024 * 64;
     state.sabS11nOffset = state.fileBufferSize;
-    state.sabS11nSize = 2048;
+    /**
+       The size of the block in our SAB for serializing arguments and
+       result values. Need to be large enough to hold serialized
+       values of any of the proxied APIs. Filenames are the largest
+       part but are limited to opfsVfs.$mxPathname bytes.
+    */
+    state.sabS11nSize = opfsVfs.$mxPathname * 2;
+    /**
+       The SAB used for all data I/O (files and arg/result s11n).
+    */
     state.sabIO = new SharedArrayBuffer(
-      state.fileBufferSize
-        + state.sabS11nSize/* arg/result serialization block */
+      state.fileBufferSize/* file i/o block */
+      + state.sabS11nSize/* argument/result serialization block */
     );
     state.opIds = Object.create(null);
-    state.rcIds = Object.create(null);
     const metrics = Object.create(null);
     {
+      /* Indexes for use in our SharedArrayBuffer... */
       let i = 0;
+      /* SAB slot used to communicate which operation is desired
+         between both workers. This worker writes to it and the other
+         listens for changes. */
       state.opIds.whichOp = i++;
+      /* Slot for storing return values. This work listens to that
+         slot and the other worker writes to it. */
+      state.opIds.rc = i++;
+      /* Each function gets an ID which this worker writes to
+         the whichOp slot. The async-api worker uses Atomic.wait()
+         on the whichOp slot to figure out which operation to run
+         next. */
       state.opIds.xAccess = i++;
-      state.rcIds.xAccess = i++;
       state.opIds.xClose = i++;
-      state.rcIds.xClose = i++;
       state.opIds.xDelete = i++;
-      state.rcIds.xDelete = i++;
       state.opIds.xDeleteNoWait = i++;
-      state.rcIds.xDeleteNoWait = i++;
       state.opIds.xFileSize = i++;
-      state.rcIds.xFileSize = i++;
       state.opIds.xOpen = i++;
-      state.rcIds.xOpen = i++;
       state.opIds.xRead = i++;
-      state.rcIds.xRead = i++;
       state.opIds.xSleep = i++;
-      state.rcIds.xSleep = i++;
       state.opIds.xSync = i++;
-      state.rcIds.xSync = i++;
       state.opIds.xTruncate = i++;
-      state.rcIds.xTruncate = i++;
       state.opIds.xWrite = i++;
-      state.rcIds.xWrite = i++;
       state.opIds.mkdir = i++;
-      state.rcIds.mkdir = i++;
       state.opIds.xFileControl = i++;
-      state.rcIds.xFileControl = i++;
       state.sabOP = new SharedArrayBuffer(i * 4/*sizeof int32*/);
       opfsUtil.metrics.reset();
     }
 
+    /**
+       SQLITE_xxx constants to export to the async worker
+       counterpart...
+    */
     state.sq3Codes = Object.create(null);
     state.sq3Codes._reverse = Object.create(null);
-    [ // SQLITE_xxx constants to export to the async worker counterpart...
+    [
       'SQLITE_ERROR', 'SQLITE_IOERR',
       'SQLITE_NOTFOUND', 'SQLITE_MISUSE',
       'SQLITE_IOERR_READ', 'SQLITE_IOERR_SHORT_READ',
@@ -252,22 +294,21 @@ sqlite3.installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri)
     const isWorkerErrCode = (n)=>!!state.sq3Codes._reverse[n];
 
     /**
-       Runs the given operation in the async worker counterpart, waits
-       for its response, and returns the result which the async worker
-       writes to the given op's index in state.sabOPView. The 2nd argument
-       must be a single object or primitive value, depending on the
-       given operation's signature in the async API counterpart.
+       Runs the given operation (by name) in the async worker
+       counterpart, waits for its response, and returns the result
+       which the async worker writes to SAB[state.opIds.rc]. The
+       2nd and subsequent arguments must be the aruguments for the
+       async op.
     */
     const opRun = (op,...args)=>{
-      const rcNdx = state.rcIds[op] || toss("Invalid rc ID:",op);
       const opNdx = state.opIds[op] || toss("Invalid op ID:",op);
       state.s11n.serialize(...args);
-      Atomics.store(state.sabOPView, rcNdx, -1);
+      Atomics.store(state.sabOPView, state.opIds.rc, -1);
       Atomics.store(state.sabOPView, state.opIds.whichOp, opNdx);
       Atomics.notify(state.sabOPView, state.opIds.whichOp) /* async thread will take over here */;
       const t = performance.now();
-      Atomics.wait(state.sabOPView, rcNdx, -1);
-      const rc = Atomics.load(state.sabOPView, rcNdx);
+      Atomics.wait(state.sabOPView, state.opIds.rc, -1);
+      const rc = Atomics.load(state.sabOPView, state.opIds.rc);
       metrics[op].wait += performance.now() - t;
       return rc;
     };
@@ -348,38 +389,6 @@ sqlite3.installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri)
        Map of sqlite3_file pointers to objects constructed by xOpen().
     */
     const __openFiles = Object.create(null);
-    
-    const pDVfs = capi.sqlite3_vfs_find(null)/*pointer to default VFS*/;
-    const dVfs = pDVfs
-          ? new sqlite3_vfs(pDVfs)
-          : null /* dVfs will be null when sqlite3 is built with
-                    SQLITE_OS_OTHER. Though we cannot currently handle
-                    that case, the hope is to eventually be able to. */;
-    const opfsVfs = new sqlite3_vfs();
-    const opfsIoMethods = new sqlite3_io_methods();
-    opfsVfs.$iVersion = 2/*yes, two*/;
-    opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
-    opfsVfs.$mxPathname = 1024/*sure, why not?*/;
-    opfsVfs.$zName = wasm.allocCString("opfs");
-    // All C-side memory of opfsVfs is zeroed out, but just to be explicit:
-    opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null;
-    opfsVfs.ondispose = [
-      '$zName', opfsVfs.$zName,
-      'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null),
-      'cleanup opfsIoMethods', ()=>opfsIoMethods.dispose()
-    ];
-    /**
-       Pedantic sidebar about opfsVfs.ondispose: the entries in that array
-       are items to clean up when opfsVfs.dispose() is called, but in this
-       environment it will never be called. The VFS instance simply
-       hangs around until the WASM module instance is cleaned up. We
-       "could" _hypothetically_ clean it up by "importing" an
-       sqlite3_os_end() impl into the wasm build, but the shutdown order
-       of the wasm engine and the JS one are undefined so there is no
-       guaranty that the opfsVfs instance would be available in one
-       environment or the other when sqlite3_os_end() is called (_if_ it
-       gets called at all in a wasm build, which is undefined).
-    */
 
     /**
        Installs a StructBinder-bound function pointer member of the
@@ -798,7 +807,7 @@ sqlite3.installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri)
         vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
         rc = wasm.getMemValue(pOut,'i32');
         if(rc) toss("Expecting 0 from xAccess(",dbFile,") after xDelete().");
-        log("End of OPFS sanity checks.");
+        warn("End of OPFS sanity checks.");
       }finally{
         sq3File.dispose();
         wasm.scopedAllocPop(scope);
index a2e0dc52331ceb982dd03a17a26eeb80a0a90de2..6caf21597a974742f42c4216c159aada28372e54 100644 (file)
@@ -134,9 +134,9 @@ const getDirForPath = async function f(absFilename, createDirs = false){
    and then Atomics.notify()'s it.
 */
 const storeAndNotify = (opName, value)=>{
-  log(opName+"() => notify(",state.rcIds[opName],",",value,")");
-  Atomics.store(state.sabOPView, state.rcIds[opName], value);
-  Atomics.notify(state.sabOPView, state.rcIds[opName]);
+  log(opName+"() => notify(",state.opIds.rc,",",value,")");
+  Atomics.store(state.sabOPView, state.opIds.rc, value);
+  Atomics.notify(state.sabOPView, state.opIds.rc);
 };
 
 /**
@@ -460,17 +460,19 @@ const initS11n = ()=>{
 
 const waitLoop = async function f(){
   const opHandlers = Object.create(null);
-  for(let k of Object.keys(state.rcIds)){
+  for(let k of Object.keys(state.opIds)){
+    const vi = vfsAsyncImpls[k];
+    if(!vi) continue;
     const o = Object.create(null);
     opHandlers[state.opIds[k]] = o;
     o.key = k;
-    o.f = vfsAsyncImpls[k];// || toss("No vfsAsyncImpls[",k,"]");
+    o.f = vi;// || toss("No vfsAsyncImpls[",k,"]");
   }
   let metricsTimer = self.location.port>=1024 ? performance.now() : 0;
   // ^^^ in dev environment, dump out these metrics one time after a delay.
   while(true){
     try {
-      if('timed-out'===Atomics.wait(state.sabOPView, state.opIds.whichOp, 0, 150)){
+      if('timed-out'===Atomics.wait(state.sabOPView, state.opIds.whichOp, 0, 500)){
         continue;
       }
       const opId = Atomics.load(state.sabOPView, state.opIds.whichOp);
@@ -513,7 +515,6 @@ navigator.storage.getDirectory().then(function(d){
           state.sabFileBufView = new Uint8Array(state.sabIO, 0, state.fileBufferSize);
           state.sabS11nView = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
           state.opIds = opt.opIds;
-          state.rcIds = opt.rcIds;
           state.sq3Codes = opt.sq3Codes;
           Object.keys(vfsAsyncImpls).forEach((k)=>{
             if(!Number.isFinite(state.opIds[k])){
index dadba80e1acf447c5af52e5e754f88bab21be18b..4943ef8ef2d0f146e6217e05d33279565568c974 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C An\salternative\smessaging\sstrategy\sfor\sthe\sOPFS\sVFS\sproxy\swhich\suses\sonly\sSharedArrayBuffer\sand\sAtomics,\sinstead\sof\sworker\smessages,\sfor\scommunication\s(only\sthe\sinitial\sone-time\shandshake\sduring\sinitialization\suses\sworker\smessages).\sIt\sruns\sspeedtest1\sapprox.\s15-20%\sfaster\sbut\sstill\s20-ish%\sslower\sthan\sWASMFS.
-D 2022-09-20T08:27:57.073
+C Remove\sextraneous\sresult-code\sSAB\sslots.\sDoc\sadditions.
+D 2022-09-20T10:11:52.007
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -474,7 +474,7 @@ F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
 F ext/wasm/EXPORTED_FUNCTIONS.fiddle 7fb73f7150ab79d83bb45a67d257553c905c78cd3d693101699243f36c5ae6c3
 F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02
-F ext/wasm/GNUmakefile b65cd280059febd4f034b856139fde52f7edb7326133f7e0588b8efcf396709c
+F ext/wasm/GNUmakefile 5b848d4d20c31b2aac3dcfabaf5deaf56fe9db9ca1299a4dede1bcd27821426b
 F ext/wasm/README.md e1ee1e7c321c6a250bf78a84ca6f5882890a237a450ba5a0649c7a8399194c52
 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 150a793a47205b8009ac934f3b6d6ebf67b965c072339aaa25ce808a19e116cc
 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
@@ -484,7 +484,7 @@ F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a
 F ext/wasm/api/sqlite3-api-cleanup.js 8564a6077cdcaea9a9f428a019af8a05887f0131e6a2a1e72a7ff1145fadfe77
 F ext/wasm/api/sqlite3-api-glue.js 366d580c8e5bf7fcf4c6dee6f646c31f5549bd417ea03a59a0acca00e8ecce30
 F ext/wasm/api/sqlite3-api-oo1.js 2d13dddf0d2b4168a9249f124134d37924331e5b55e05dba18b6d661fbeefe48
-F ext/wasm/api/sqlite3-api-opfs.js 1df64b2a11b7f71ba5c7a5807b4d62727e2c712e537eb563caedc67c5a38d149
+F ext/wasm/api/sqlite3-api-opfs.js 8611680362619cac2425fd77fa9bff00690c80a17a6b95cdd1a39c2cc33e11d0
 F ext/wasm/api/sqlite3-api-prologue.js 0d2639387b94c30f492d4aea6e44fb7b16720808678464559458fd2ae3759655
 F ext/wasm/api/sqlite3-api-worker1.js ee4cf149cbacb63d06b536674f822aa5088b7e022cdffc69f1f36cebe2f9fea0
 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
@@ -519,7 +519,7 @@ F ext/wasm/speedtest1.html 512addeb3c27c94901178b7bcbde83a6f95c093f9ebe16a2959a0
 F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
 F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
 F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
-F ext/wasm/sqlite3-opfs-async-proxy.js 038ecd8558abc3f46cfedd560093fef4d460af8c0d0009ab84f2abdc10916a6a
+F ext/wasm/sqlite3-opfs-async-proxy.js e3c5e1b6416e9c08c713c43fa98319b06fac622ecb813f294b047072b089fba6
 F ext/wasm/sqlite3-worker1-promiser.js 4fd0465688a28a75f1d4ee4406540ba494f49844e3cad0670d0437a001943365
 F ext/wasm/sqlite3-worker1.js 0c1e7626304543969c3846573e080c082bf43bcaa47e87d416458af84f340a9e
 F ext/wasm/test-opfs-vfs.html eb69dda21eb414b8f5e3f7c1cc0f774103cc9c0f87b2d28a33419e778abfbab5
@@ -2026,11 +2026,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 5ca412ced24b4e3af5f467e710a597ed440badf7b8335346aade11d3cad3d1a1
-R eef8f82c266e71b1fc83e097c56f095e
-T *branch * opfs-proxy-atomics
-T *sym-opfs-proxy-atomics *
-T -sym-fiddle-opfs * Cancelled\sby\sbranch.
+P a83ee3082d89439ea3ad5737e63e25bebb0f91895aca006ce5fecf5b93a2651a
+R bb080f9a3495e6fa47cacc332af06e26
 U stephan
-Z 1c049de5a4413363c0d5cd656309295d
+Z e5fc885edbb6664192b4f06eefccf3e5
 # Remove this line to create a well-formed Fossil manifest.
index cf2c4e76427b7835a34263880dc0f8c9d58f2d78..16e232c3faf340dda2d40f46c516ead7d79eca1c 100644 (file)
@@ -1 +1 @@
-a83ee3082d89439ea3ad5737e63e25bebb0f91895aca006ce5fecf5b93a2651a
\ No newline at end of file
+88de20712bbe3e11ea74af95edc34e9ab9f346f9aa0a30931e5a9e1f96ce57b0
\ No newline at end of file