|
| 1 | +# PThreadFS File Packager Manual |
| 2 | + |
| 3 | +The PThreadFS file packager adapts [Emscripten's file packager](https://emscripten.org/docs/porting/files/packaging_files.html) for PThreadFS. Support for PThreadFS is activated with the switch `--use-pthreadfs`, e.g. |
| 4 | +``` |
| 5 | +python3 file_packager.py --preload ./input/files@/persistent --use_pthreadfs --js-output=my_package.js my_package.data |
| 6 | +``` |
| 7 | + |
| 8 | +The packaged files can be loaded into PThreadFS via multiple paths. In the remainder of this manual, `my_package.js` will be the _javascript helper_ file generated by the file packager (i.e., the file specified in the `--js-output=` switch). The generated `mypackage.data` file is called the _package_ and may hold multiple files. |
| 9 | + |
| 10 | +## Howto for common scenarios |
| 11 | + |
| 12 | +### Loading files on startup |
| 13 | +If files need to be available before the first file I/O (or very early during the program's execution), they can be loaded as soon as PThreadFS initializes. This can be achieved by running `my_package.js` before the Wasm module is instantiated (e.g. during `--pre-js`). |
| 14 | + |
| 15 | +It is possible to load multiple packages at startup by adding all of their respective javascript helpers before instantiation. |
| 16 | + |
| 17 | +See `examples/preloading.cpp` for an example. |
| 18 | + |
| 19 | +### Loading files during execution (synchronously) |
| 20 | +Additional packages can be loaded synchronously during execution by running the following from the WebAssembly module |
| 21 | +```c++ |
| 22 | +#include "pthreadfs.h" |
| 23 | +// [other code] |
| 24 | +pthreadfs_load_package("my_package.js"); |
| 25 | +``` |
| 26 | +This command can also be triggered from the Javascript side by exporting the `pthreadfs_load_package` function. Calling `pthreadfs_load_package` from the Javascript's main thread is *unsupported*, since doing so may block the main thread. See the next section for alternatives. |
| 27 | +
|
| 28 | +See `examples/load_package_sync.cpp` for an example. |
| 29 | +
|
| 30 | +### Loading files during execution (asynchronously) |
| 31 | +
|
| 32 | +It is possible to asynchronously load packages from a Javascript context. The first step is to execute `my_package.js` script (e.g. by using `importScripts()` in workers, or any other method). Right after that, it suffices to run the following code: |
| 33 | +``` |
| 34 | +// This requires a JS context that has defined the `Module` object. |
| 35 | +await PThreadFS.init('persistent'); |
| 36 | +let load_fct = Module["pthreadfs_available_packages"].pop(); |
| 37 | +await load_fct(); |
| 38 | +``` |
| 39 | +Due to limitations of OPFS Access Handles, loading packages from the main thread may be quite slow. The expected slowdown is between 200% and 1000%. The same applies to calling PThreadFS functions such as `PThreadFS.writeFile()` directly. Asynchronously loading files during execution from a worker thread should not experience any slowdown when compared to loading on startup. |
| 40 | +
|
| 41 | +See `examples/load_package_async.cpp` for an example. |
| 42 | +
|
| 43 | +### Compiling the examples |
| 44 | +
|
| 45 | +The examples for the file packager are found in `examples/packager-tests`. |
| 46 | +Building the packager tests requires manual creation of the following files: |
| 47 | +- packager-tests/input/small/smallfile.txt: Size 188 bytes, first line "These are the contents of a very small file." |
| 48 | +- packager-tests/input/mediumlarge/subfolder/mediumfile.txt: Size 138670 bytes, first line "Begin mediumfile.txt -------------------------------------------" |
| 49 | +- packager-tests/input/mediumlarge/bigfile.txt: Size 212992000 bytes, first line "Begin bigfile.txt ----------------------------------------------" |
| 50 | +
|
| 51 | +After creating these files, the tests can be built by running `make packager-tests`. |
| 52 | +
|
| 53 | +## Known limitations |
| 54 | +- File packager options `--embed` and `--lz4` cannot be used. |
| 55 | +- Asynchronously loading packages is not possible when using the MEMFS backend |
0 commit comments