P1031 low level file i/o and filesystem library for the C++ standard

Related tags

File System llfio
Overview

This is the post-peer-review LLFIO v2 rewrite. You can view its documentation at https://ned14.github.io/llfio/

master branch develop branch

CMake dashboard: https://my.cdash.org/index.php?project=Boost.AFIO

PREBUILT BINARIES FOR LINUX (x64 and ARM), MAC OS AND WINDOWS CAN BE FOUND AT https://github.com/ned14/llfio/releases

USAGE AND CONFIGURATION INSTRUCTIONS CAN BE FOUND AT https://ned14.github.io/llfio/

Immediate todos in order of priority:

  • Implement new custom C++ exception synthesis support from Outcome.

  • Finish trivial vector, which is unfinished and currently segfaults.

  • Run clang-tidy fix pass, it's got a bit untidy recently.

  • Add OS X support to storage_profile, this should complete the Mac OS port.

  • Fix all known bugs in Outcome, plus reorg source code in prep for status_code.

  • Scatter-gather buffers to use https://github.com/martinmoene/byte-lite

  • Make lazy the stat fetch during file/dir open.

  • Implement SG14 status_code as a standalone library and test in LLFIO.

  • Single include generation now we're on status_code and it's safe.

  • Implement SIGBUS/EXCEPTION_IN_PAGE_ERROR RAII catcher.

  • Implement symlink_handle already!

  • atomic_append isn't actually being tested in shared_fs_mutex

  • Implement a non-toy ACID key-value BLOB store and send it to Boost for peer review.

    • For this need to implement a file-based B+ tree. And for that, need to implement a page allocator out of a single file. Some notes:

    B+ trees would be based on the 4Kb page for memory mapping, and thus allocate and release whole 4Kb pages.

    A simple page allocator from a file might simply keep some magic at the top, and then a list of offsets to free pages for the remainder of the page. That might be (4096 – 12) / 4 = 1021 slots (remember these are 42 bit offsets, so simply limit to 32 bit offsets << 12).

    Each free page links to its next free page. Freeing a page means modulus its address >> 12 with 1021, and CASing it into its “slot” as its linked list.

    Allocating pages involves iterating a round robin index, pulling free pages off the top. Only if no free pages remain do we atomic append 1021 * 4096 = 4,182,016 bytes and refill the free page index.

  • All time based kernel tests need to use soak test based API and auto adjust to valgrind.

  • In DEBUG builds, have io_handle always not fill buffers passed to remind people to use pointers returned!

  • KernelTest needs to be generating each test kernel as a standalone DLL so it can be fuzzed, coverage calculated, bloat calculated, ABI dumped etc

clang AST parser based todos which await me getting back into the clang AST parser:

  • C bindings for all LLFIO v2 APIs. Write libclang parser which autogenerates SWIG interface files from the .hpp files using custom attributes to fill in the missing gaps.
  • Much better coverage is to permute the valid parameter inputs of the kernel deduced from examining the kernel parameter API and figure out what minimum set of calling parameters will induce execution of the entire potential call graph. This approach is a poor man's symbolic execution SMT solver, it uses brute force rather than constrained solution. Idea is that when someone releases a proper C++ capable KLEE for open source use we can use that instead.
    • -fsanitize-coverage=trace-pc -O3 will have clang (works also on winclang) call a user supplied __sanitizer_cov_trace_pc() and __sanitizer_cov_trace_pc_indirect(void *callee) function. This would simply atomically append the delta of the program counter from the previously stored one to a memory mapped file. You should use a tagged encoding, so leading byte specifies length and type of record.
    • One also needs to replace syscalls with stubs (easy on Windows DLLs) and permute their potential return codes and effects to maximise edge execution. Either monkey patching or a custom DLL loader would work.
    • One then generates a default KernelTest permutation set for that kernel which can be freshened (probably via commenting out stale entries and appending new entries) by an automated tooling run
    • A freebie feature from this work is an automatic possible error returns calculator for the documentation
    • Another freebie feature is automatic calculation of the number of malloc + free performed.
    • Can we even figure out O type complexities from the call graph? e.g. doubling an input parameter quadruples edges executed? Could generate an O() complexity per input parameter for the documentation?

Known bugs and problems:

  • algorithm::atomic_append needs improvements:
    • Trap if append exceeds 2^63 and do something useful with that
    • Fix the known inefficiencies in the implementation:
      • We should use byte range locks when concurrency*entities is low
      • We have an extra read() during locking between the scanning for our lock request and scanning for other lock requests
      • During scan when hashes mismatch we reload a suboptimal range
      • We should use memory maps until a SMB/NFS/QNX/OpenBSD lock_request comes in whereafter we should degrade to normal i/o gracefully
  • Add native BSD kqueues to POSIX AIO backend as is vastly more efficient.
  • Port to Linux KAIO
  • Don't run the cpu and sys tests if cpu and sys ids already in fs_probe_results.yaml
    • Need to uniquely fingerprint a machine somehow?
  • Add monitoring of CPU usage to tests. See GetThreadTimes. Make sure worker thread times are added into results.
  • Configurable tracking of op latency and throughput (bytes) for all handles on some storage i.e. storage needs to be kept in a global map.
    • Something which strongly resembles the memory bandwidth test
    • Should have decile bucketing e.g. percentage in bottom 10%, percentage in next 10% etc. Plus mean and stddev.
    • Should either be resettable or subtractable i.e. points can be diffed.
  • Output into YAML comparable hashes for OS + device + FS + flags so we can merge partial results for some combo into the results database.
  • Write YAML parsing tool which merges fs_probe_results.yaml into the results directory where flags and OS get its own directory and each YAML file is named FS + device e.g.

Algorithms library LLFIO_V2_NAMESPACE::algorithm todo:

  • Add vector<T> which adapts a mapped_view<T>.
  • Add some primitive which intelligently copies/moves between views and vectors. Specifically, if resizing, if type is trivially copyable, skip memory copying during resize via remapping.
  • Add an intelligent on demand memory mapper:
    • Use one-two-three level page system, so 4Kb/2Mb/1Gb. Files under 2Mb need just one indirection.
    • Page tables need to also live in a potentially mapped file
    • Could speculatively map 4Kb chunks lazily and keep an internal map of 4Kb offsets to map. This allows more optimal handing of growing files.
    • WOULD BE NICE: Copy on Write support which collates a list of dirtied 4Kb pages and could write those out as a delta.
      • Perhaps Snappy compression could be useful? It is continuable from a base if you dump out the dictionary i.e. 1Mb data compressed, then add 4Kb delta, you can compress the additional 4Kb very quickly using the dictionary from the 1Mb.
      • LATER: Use guard pages to toggle dirty flag per initial COW
  • Store in EA or a file called .spookyhashes or .spookyhash the 128 bit hash of a file and the time it was calculated. This can save lots of hashing work later.
  • Correct directory hierarchy delete i.e.:
    • Delete files first tips to trunk, retrying for some given timeout. If fail to immediately delete, rename to base directory under a long random hex name, try to delete again.
    • Only after all files have been deleted, delete directories. If new files appear during directory deletion, loop.
    • Options:
      • Rename base directory(ies) to something random to atomically prevent lookup.
      • Delete all or nothing (i.e. rename all files into another tree checking permissions etc, if successful only then delete)
  • Correct directory hierarchy copy
    • Optional backup semantics (i.e. copy all ACLs, metadata etc)
    • Intelligent retry for some given timeout before failing.
    • Optional fixup of any symbolic links pointing into copied tree.
    • Optional copy directory structure but hard or symbolic linking files.
      • Symbolic links optionally are always absolute paths instead of relative.
    • Optional deference all hard links and/or symbolic links into real files.
  • Correct directory hierarchy move
  • Correct directory hierarchy update (i.e. changes only)
  • Make directory tree C by cloning tree B to tree B, and then updating tree C with changes from tree A. The idea is for an incremental backup of changes over time but saving storage where possible.
  • Replace all content (including EA) duplicate files in a tree with hardlinks.
  • Figure out all hard linked file entries for some inode.
  • Generate list of all hard linked files in a tree (i.e. refcount>1) and which are the same inode.

Eventual transactional key-blob store:

  • What's the least possible complex implementation based on files and directories?
    • store/index is 48 bit counter + r/w mutex + open hash map of 128 bit key to blob identifier (64 bits). Blob identifier is top 6 bits file id:

      • 0 means large file, values 1-15 are reserved for future use (large file deltas).
      • Values 16-63 are the smallfile.
      1. store/small/01-3f for blobs <= 65512 bytes (8 bytes tail, 16 bytes key). Each blob is padded to 64 byte multiple and tail record with 16 bytes of key, 6 byte (48 bit) counter + 2 byte size aligned at end + optional 16 byte hash. There are 48 of these used to maximise write concurrency (use the thread id to select a smallfile on open, use exclusive lock probing to figure out a small file not in use, hold shared lock on chosen small file until exit).

      Remaining 58 bits of blob identifier is the offset into the smallfile of the end of the tail record (shifted left 6 bits, all records in smallfiles are at 64 byte multiples).

      1. store/large/* for blobs > 65512 under the assumption that one day we'll implement 4Kb dirty delta page with compression support.
      • store/large/hexkey/48bithexcounter stores each blob
      • Last 64 bytes contains magic, size, optional hash.

      Blob identifier is top 6 bits zero. Next 10 bits is 4 bits mantissa shifted left 6 bits of shift (0-63) for approx size. Remaining 48 bits is counter.

    • store/config keeps:

      • transactions enabled or not.
      • mmap enable or not (i.e. can be used over network drive)
      • content hash used e.g. SpookyHash
      • compression used e.g. pithy
      • dirty flag i.e. do fsck on next first open
        • O_SYNC was on or not last open (affects severity of any fsck).
      • shared lock kept on config so we know last user exit/first user enter
  • Start a transaction = atomic increment current 48 bit counter
    • Write the changes making up this transaction under this counter
    • When ready, lock the open hash map's r/w mutex for exclusive access.
    • Check that all the keys we are modifying have not been changed since the transaction began.
    • If all good, update all the keys with their new values and unlock the r/w mutex QUESTION: Can forcing all map users to lock the mutex each access be avoided? e.g. atomic swapping in a pointer to an updated table? One could COW the 4Kb pages being changed in the current table, then update the map, then swap pointers and leave the old table hang around for a while.
  • Garbage collecting in this design is easy enough, write all current small values into a single file, then update the map in a single shot, then hole punch all the other small files.
  • Live resizing the open hash map I think is impossible however unless we use that atomic swapping design.
  • You may need compression, https://github.com/johnezang/pithy looks easily convertible into header-only C++ and has a snappy-like performance to compression ratio. Make sure you merge the bug fixes from the forks first.

Commits and tags in this git repository can be verified using:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2

mDMEVvMacRYJKwYBBAHaRw8BAQdAp+Qn6djfxWQYtAEvDmv4feVmGALEQH/pYpBC
llaXNQe0WE5pYWxsIERvdWdsYXMgKHMgW3VuZGVyc2NvcmVdIHNvdXJjZWZvcmdl
IHthdH0gbmVkcHJvZCBbZG90XSBjb20pIDxzcGFtdHJhcEBuZWRwcm9kLmNvbT6I
eQQTFggAIQUCVvMacQIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRCELDV4
Zvkgx4vwAP9gxeQUsp7ARMFGxfbR0xPf6fRbH+miMUg2e7rYNuHtLQD9EUoR32We
V8SjvX4r/deKniWctvCi5JccgfUwXkVzFAk=
=puFk
-----END PGP PUBLIC KEY BLOCK-----
Comments
  • Binary links are dead.

    Binary links are dead.

    Download links are broken for llfio-v2.0-binaries-win64-latest.zip and llfio-v2.0-binaries-linux64-latest.tgz:

    Index of /static/files/
    ../
    boost.outcome/                                     11-May-2017 15:50                   -
    llfio/                                             02-Jul-2020 23:00                   -
    other/                                             11-Jul-2019 20:30                   -
    outcome/                                           22-Jun-2020 23:00                   -
    upload/                                            18-Sep-2019 23:04                   -
    boost.outcome-v1.0-source-latest.tar.xz            11-May-2017 15:50             1075620
    llfio-v2.0-binaries-linux64-latest.tgz             18-Sep-2019 23:04                  78
    llfio-v2.0-binaries-win64-latest.zip               18-Sep-2019 23:04                  76
    llfio-v2.0-source-latest.tar.xz                    02-Jul-2020 23:04            52981904
    outcome-v2.0-source-latest.tar.xz                  22-Jun-2020 23:01            14831504
    
    opened by doctor-claw 9
  • Filesystem linkage with clang/libc++

    Filesystem linkage with clang/libc++

    Hey again, got another clang/libc++ issue but I think this one should be a lot simpler than my other one. I notice here there is some logic for determining which filesystem library needs to be linked.

    From the clang docs:

    Prior to LLVM 9.0, libc++ provides the implementation of the filesystem library in a separate static library. Users of and <experimental/filesystem> are required to link -lc++fs. Prior to libc++ 7.0, users of <experimental/filesystem> were required to link libc++experimental.

    So incidentally, these lines suggest that for llfio_dl we may be doing the right thing for the wrong reason in some cases.

    This is a bit tedious to be sure, but not too terrible. I've had to patch a CML.txt to handle this in the past. Once you've established that clang/libcxx is in use you should be able to use COMPILER_VERSION_LESS to pick if you need c++experimental, c++fs, or nothing at all.

    opened by cstratopoulos 9
  • Make llfio more packager friendly

    Make llfio more packager friendly

    Hi Niall, I mentioned this in Prague, and I know you said there was an open issue, but I couldn't find it. So I'm going to list the issues I had packaging lfio (and cppquicklib) here.

    • llfio won't use cppquicklib unless cppquicklib was installed with the default cmakeConfig install path (the cppquicklib bootstrap needs to do find_package(cppquicklib CONFIG) and check cppquicklib_FOUND instead of searching through CMKAE_MODULE_PATH for cppquicklib/cmakelib)

    • both llfio and cppquick lib need to build without cloning any submodules (this means they need to be able to find their dependencies even if their dependencies headers are not in ${PROJECT_SOURCE_DIR}/include

    • cppquicklib and llfio need to be build-able with the same version of their common dependencies

    opened by barcharcraz 9
  • Please be more explicit with this error message

    Please be more explicit with this error message

    FATAL: You must set a binary directory that is different from your source directory.
           You might consider D:/llfio/build or D:/llfio-build
    

    ... originating from:

    message("FATAL: You must set a binary directory that is different from your source directory.")
    message("       You might consider ${CMAKE_SOURCE_DIR}/build or ${_parent}/${_leaf}-build")
    

    The solution to this is very unobvious (or perhaps it is, if you're working with CMake on a daily basis which I am not).

    I first tried setting CMAKE_INSTALL_PREFIX and looking if any cache existed (which it did not), so reran and got the same error.

    Only after searching the whole folder for the first line of the error message I thought I had figured out that apparently CMAKE_BINARY_DIR should be set to one of the suggested values. Alas, that one also didn't work. I no longer have an idea what exactly I am supposed to set there.

    But I am not sure if this is an issue of this project or some other project. So first filing it here.

    Thanks for reading and thanks for bringing the world this library, Niall!

    With best regards,

    Oliver

    enhancement 
    opened by assarbad 9
  • Converting extended file_io_error to status_code

    Converting extended file_io_error to status_code

    When file_io_error contains extra info (i.e. LLFIO_DISABLE_PATHS_IN_FAILURE_INFO == 1), how does one convert it to a normal status_code? It contains the correct domain, and file_io_error_value_type contains the error code, so this ought to be possible. But the following doesn't compile:

    status_result<void> foo() {
        auto result = llfio::file({}, "foo");
        if (!result)
            return std::move(result).error(); // <---
    }
    

    Using MSVC 19.31 if that makes a difference.

    bug 
    opened by gix 8
  • Simplify the selection for the dynamic thread pool implementation

    Simplify the selection for the dynamic thread pool implementation

    • If on window use native OS APIs (libdispatch isn't available anyways).
    • If on linux use the superior custom implementation unless the user explicitly requests libdispatch (which is incompatible with gcc).
    • Otherwise require libdispatch.

    Note that I opted to use the custom implementation on linux by default even if libdispatch is available in order to prevent ODR violations caused mixing of gcc and clang.

    Fixes #94

    opened by BurningEnlightenment 7
  • Avoiding infinite recursion with path_view

    Avoiding infinite recursion with path_view

    I've stumbled upon an interesting problem when working with std::filesystem::path. Consider the following example (https://godbolt.org/z/wDoxgT):

    #include <filesystem>
    #include <iostream>
    
    template< class T >
    concept Range = requires(T&& t) {
      std::begin(std::forward<T>(t));
      std::end  (std::forward<T>(t));
    };
    
    template <typename T>
    void print(const T& value) {
      std::cout << value;
    }
    
    template <Range R>
    void print(const R& range) {
      for (const auto& elem: range) {
        print(elem);
      }
    }
    
    int main() {
      print(std::filesystem::path("foo"));
    }
    

    Running it gives stack overflow because a single-element path is a range that contains itself as an element which causes infinite recursion. Unfortunately we cannot solve this problem in std::filesystem::path but would it be possible for path_view to do better, for example, by splitting path_view into two types such as path_view and path_view_component with the latter having all features of the former but not being a range?

    enhancement 
    opened by vitaut 7
  • [coroutine] data race issue

    [coroutine] data race issue

    I'm not familiar with AFIO, but by viewing the code, I suspect there's a data race between the IO thread and the thread running the coroutine.

    In async_file_handle, the completion handle has some shared state (i.e. _suspended and _result). When the completion handle is called in the IO thread, the await_xxx() may be called in the coroutine's thread simultaneously, hence the data race on the shared state.

    Of course, if the coroutine always runs on the same IO thread, you'll be fine, but I don't think AFIO wants to impose such a limitation, does it?

    opened by jamboree 7
  • char8_t emulation on clang-9

    char8_t emulation on clang-9

    Hello!

    Just ran into what seems like an awkward intersection of case/version checking when using clang-9 and libcxx. Judging by https://github.com/ned14/llfio/commit/5cceb1a49dce9d6daf619890c888ed3c10f48816 this has already been a bit of a headache and looks like it may continue to be one.

    This snippet should illustrate the main points of the issue https://godbolt.org/z/eGFK7d

    • __cplusplus still corresponds to C++17 when -std=c++2a is passed (N.B.: -std=c++20 is as yet unsupported, maybe they're waiting til then to bump __cplusplus)
    • __CHAR8_TYPE__ does not ever appear to be defined, although __cpp_char8_t is, and vexingly,
    • fno-char8_t is recognized at the command line but only changes whether __cpp_char8_t is defined, not whether you can in fact define a char8_t in your code.

    This creates a bit of a mess and may require more than just LLFIO_PATH_VIEW_CHAR8_TYPE_EMULATED I fear. To expand a bit, due to the __CHAR8_TYPE__/__cplusplus thing outlined above, LLFIO deduces it needs to emulate char8_t with clang-9, making struct char8_t an illegal definition. Correct deduction of LLFIO_PATH_VIEW_CHAR8_TYPE_EMULATED can be obtained by checking for __cpp_char8_t as well though:

    -     || (defined(__clang__) && !defined(__CHAR8_TYPE__) && (__cplusplus < 202000L || __clang_major__ < 9))
    +     || (defined(__clang__) && (!defined(__CHAR8_TYPE__) && !defined(__cpp_char8_t)) && (__cplusplus < 202000L || __clang_major__ < 9))
    

    The next issue, then, is that LLFIO_PATH_VIEW_CHAR8_TYPE_EMULATED is used to dispatch llfio::detail::_codecvt, and to determine if an invalid conversion has been requested for clang with libc++. Clang C++ status reports support for char8_t but the paper they link mentions codecvt specializations for char8_t and, for clang-9/libc++ at least, you'll find no mention of char8_t in any header to do with codecvt.

    For my local tests I did the stupid workaround of

       wchar_t *reencode_path_to(size_t &toallocate, wchar_t *dest_buffer, size_t dest_buffer_length, const char8_t *src_buffer, size_t src_buffer_length)
       {
    -#if LLFIO_PATH_VIEW_CHAR8_TYPE_EMULATED
    +#if 1 //LLFIO_PATH_VIEW_CHAR8_TYPE_EMULATED
     #if defined(_LIBCPP_VERSION)
    

    With this I was successfully able to build llfio_sl for clang-9/libc++.

    However I wonder if it might be necessary to fix detail::_codecvt in some cases too. Right now we have a full specialization for the fallthrough

      template <> struct _codecvt<char8_t, char> : std::codecvt<char, char, std::mbstate_t> { 
    

    but this is only #if LLFIO_PATH_VIEW_CHAR8_TYPE_EMULATED. I think it might be necessary instead to do a partial specialization along the lines of

    template<typename ExternT> struct _codecvt<char8_t, ExternT> : std::codecvt<char, ExternT, std::mbstate_t> {
    

    to handle clang-9 libc++ having no codecvt specializations for char8_t. I think this is valid as per p0482 which proposes

    New char8_t based specializations of codecvt and codecvt_byname for converting between UTF-16, UTF-32, and UTF-8. The existing char based specializations are deprecated. The new specializations are functionally identical to the deprecated ones.

    opened by cstratopoulos 6
  • How to set the share mode?

    How to set the share mode?

    I'm playing with LLFIO to implement a toy HTTP downloader, it works, but I'm surprised that I can delete the file during downloading.

    It's opened this way:

                    auto file = fio::async_file(io, {}, filename.native(),
                        fio::io_handle::mode::write,
                        fio::io_handle::creation::if_needed,
                        fio::io_handle::caching::all).value();
    

    Is there a way to set the share mode when opening the file?

    enhancement 
    opened by jamboree 6
  • MSVC compiler regression

    MSVC compiler regression

    Since Visual Studio 16.11.4 (verified for MSVC [19.29.30133; 19.29.30136]) compiling the sl target fails:

    C:\PROGRA~2\MICROS~1\2019\ENTERP~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe
        /TP
    
        -DLLFIO_DYNAMIC_THREAD_POOL_GROUP_USING_GCD=0
        -DLLFIO_ENABLE_TEST_IO_MULTIPLEXERS=1
        -DLLFIO_EXPERIMENTAL_STATUS_CODE=1
        -DLLFIO_INCLUDE_STORAGE_PROFILE=1
        -DLLFIO_SOURCE=1
        -DLLFIO_STATIC_LINK=1
        -DQUICKCPPLIB_ENABLE_VALGRIND=1
        -D_WIN32_WINNT=0x601
    
        /nologo
        /DWIN32
        /D_WINDOWS
        /W3
        /utf-8
        /MP
        /utf-8
        /Zc:__cplusplus
        /std:c++latest
        -ID:/devel/source/vcpkg/installed/x64-windows-ltcg-static/include
        /D_DEBUG
        /MTd
        /Z7
        /Ob0
        /Od
        /RTC1
        /EHsc
        /MDd
        /W4
        /showIncludes
        /FoCMakeFiles\llfio_sl.dir\src\llfio.cpp.obj
        /FdCMakeFiles\llfio_sl.dir\llfio_sl.pdb
        /FS
        -c
        D:\devel\source\vcpkg\buildtrees\llfio\src\d3799d14b8-90055f6d12.clean\src\llfio.cpp
    

    with the following error message

    cl : Command line warning D9025 : overriding '/MTd' with '/MDd'
    cl : Command line warning D9025 : overriding '/W3' with '/W4'
    D:\devel\source\vcpkg\buildtrees\llfio\src\d3799d14b8-90055f6d12.clean\include\llfio\v2.0\algorithm\handle_adapter\../../map_handle.hpp(954): error C2440: 'return': cannot convert from 'std::shared_ptr<llfio_v2_7238591f::detail::map_handle_allocate_registered_buffer::<lambda_1>::<lambda_invoker_cdecl>::registered_buffer_type_indirect> (__cdecl *)(llfio_v2_7238591f::map_handle)' to 'std::shared_ptr<llfio_v2_7238591f::detail::map_handle_allocate_registered_buffer::<lambda_1>::()::registered_buffer_type_indirect> (__cdecl *)(llfio_v2_7238591f::map_handle)'
    D:\devel\source\vcpkg\buildtrees\llfio\src\d3799d14b8-90055f6d12.clean\include\llfio\v2.0\algorithm\handle_adapter\../../map_handle.hpp(954): note: This conversion requires a reinterpret_cast, a C-style cast or function-style cast
    D:\devel\source\vcpkg\buildtrees\llfio\src\d3799d14b8-90055f6d12.clean\include\llfio\v2.0\algorithm\handle_adapter\../../map_handle.hpp(954): error C2440: 'return': cannot convert from 'std::shared_ptr<llfio_v2_7238591f::detail::map_handle_allocate_registered_buffer::<lambda_1>::<lambda_invoker_vectorcall>::registered_buffer_type_indirect> (__vectorcall *)(llfio_v2_7238591f::map_handle)' to 'std::shared_ptr<llfio_v2_7238591f::detail::map_handle_allocate_registered_buffer::<lambda_1>::()::registered_buffer_type_indirect> (__vectorcall *)(llfio_v2_7238591f::map_handle)'
    D:\devel\source\vcpkg\buildtrees\llfio\src\d3799d14b8-90055f6d12.clean\include\llfio\v2.0\algorithm\handle_adapter\../../map_handle.hpp(954): note: This conversion requires a reinterpret_cast, a C-style cast or function-style cast
    

    The code in question: https://github.com/ned14/llfio/blob/707493a81a42aaab273b2e5af37e6d968c615abd/include/llfio/v2.0/map_handle.hpp#L957-L969

    So it looks like they changed something related to their lambda name mangling, lambda type representation or type deduction. I worked around this by explicitly specifying the return type to be a shared_ptr to the base class:

    index 89e616c..d5d61e9 100644
    --- a/include/llfio/v2.0/map_handle.hpp
    +++ b/include/llfio/v2.0/map_handle.hpp
    @@ -939,7 +939,7 @@ namespace detail
       {
         try
         {
    -      auto make_shared = [](map_handle h) {
    +      auto make_shared = [](map_handle h) -> io_handle::registered_buffer_type {
             struct registered_buffer_type_indirect : io_multiplexer::_registered_buffer_type
             {
               map_handle h;
    

    I'm aware of the cl : Command line warning D9025 : overriding '/MTd' with '/MDd' which is caused by a bad interaction between vcpkg and quickcpplib. I'll open a seperate issue for that.

    opened by BurningEnlightenment 5
  • CMake build failed: `unknown argument -fconcepts` with Clang 15

    CMake build failed: `unknown argument -fconcepts` with Clang 15

    FetchContent_Declare(llfio
            GIT_REPOSITORY https://github.com/ned14/llfio
            GIT_TAG 82ea3ddb718d5a8f9633a7ee786d2a4961ade4f3
    )
    FetchContent_MakeAvailable(llfio)
    
    target_link_libraries(myapp
            PRIVATE llfio)
    
    build] FAILED: _deps/llfio-build/CMakeFiles/llfio_dl.dir/src/llfio.cpp.o 
    [build] /usr/bin/ccache /usr/bin/clang++ -DLLFIO_DYN_LINK=1 -DLLFIO_ENABLE_TEST_IO_MULTIPLEXERS=1 -DLLFIO_INCLUDE_STORAGE_PROFILE=1 -DLLFIO_SOURCE=1 -DQUICKCPPLIB_ENABLE_VALGRIND=1 -Dllfio_dl_EXPORTS -isystem /home/user/projects/seastar-demo/build/install/include -g -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -fcolor-diagnostics -fexceptions -frtti -fstack-protector-strong -Wall -Wextra -Wdocumentation -fcomment-block-commands=raceguarantees,complexity,exceptionmodel -fconcepts -std=gnu++20 -MD -MT _deps/llfio-build/CMakeFiles/llfio_dl.dir/src/llfio.cpp.o -MF _deps/llfio-build/CMakeFiles/llfio_dl.dir/src/llfio.cpp.o.d -o _deps/llfio-build/CMakeFiles/llfio_dl.dir/src/llfio.cpp.o -c /home/user/projects/seastar-demo/build/_deps/llfio-src/src/llfio.cpp
    [build] clang-15: error: unknown argument: '-fconcepts'
    
    opened by GavinRay97 3
  • `algorithm::traverse` uses a `vector<list<move-only-type>>` which isn't guaranteed to work

    `algorithm::traverse` uses a `vector>` which isn't guaranteed to work

    According to Stephan T. Lavavej container<container<move-only-type>> types are not guaranteed to compile due to a longstanding bug in the C++ Standard. The algorithm::traverse() implementation triggers this defect with MSVC:

    list(862): note: while compiling class template member function 'std::list<workitem,std::allocator<workitem>>::list(const std::list<workitem,std::allocator<workitem>> &)'
    xmemory(682): note: see reference to function template instantiation 'std::list<workitem,std::allocator<workitem>>::list(const std::list<workitem,std::allocator<workitem>> &)' being compiled
    llfio\v2.0\algorithm\../detail/impl/traverse.ipp(580): note: see reference to class template instantiation 'std::list<workitem,std::allocator<workitem>>' being compiled
    xmemory(682): error C2280: 'workitem::workitem(const workitem &)': attempting to reference a deleted function
    llfio\v2.0\algorithm\../detail/impl/traverse.ipp(172): note: see declaration of 'workitem::workitem'
    llfio\v2.0\algorithm\../detail/impl/traverse.ipp(172): note: 'workitem::workitem(const workitem &)': function was explicitly deleted
    

    https://github.com/ned14/llfio/blob/7986b92283e2d92991fbbc77850faf6025932dc4/include/llfio/v2.0/detail/impl/traverse.ipp#L205

    The current workaround is to define a moving copy constructor: https://github.com/ned14/llfio/blob/7986b92283e2d92991fbbc77850faf6025932dc4/include/llfio/v2.0/detail/impl/traverse.ipp#L165-L173

    In any case, the workaround selector is too restrictive. It is unclear whether this will be fixed at all, but definitly not earlier than the next MSVC ABI break (see also microsoft/STL#1036).

    bug 
    opened by BurningEnlightenment 0
  • `glibc` 2.36 `sys/mount.h` incompatibility with `linux/mount.h`

    `glibc` 2.36 `sys/mount.h` incompatibility with `linux/mount.h`

    Building llfio with glibc 2.36 fails due to detail/impl/posix/storage_profile.ipp including linux/fs.h (including linux/mount.h) and detail/impl/posix/statfs.ipp including sys/mount.h:

    /usr/sbin/c++ -DLLFIO_DYNAMIC_THREAD_POOL_GROUP_USING_GCD=0 -DLLFIO_ENABLE_TEST_IO_MULTIPLEXERS=1 -DLLFIO_INCLUDE_STORAGE_PROFILE=1 -DLLFIO_SOURCE=1 -DLLFIO_STATIC_LINK=1 -DQUICKCPPLIB_ENABLE_VALGRIND=1 -isystem /root/ldevel/vcpkg/installed/x64-linux/include -fPIC -g -fPIC -fexceptions -frtti -fstack-protector-strong -fconcepts -fcoroutines -Wall -Wextra -std=gnu++20 -MD -MT CMakeFiles/llfio_sl.dir/src/llfio.cpp.o -MF CMakeFiles/llfio_sl.dir/src/llfio.cpp.o.d -o CMakeFiles/llfio_sl.dir/src/llfio.cpp.o -c /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/llfio.cpp
    In file included from /usr/include/linux/fs.h:19,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/detail/impl/posix/storage_profile.ipp:32,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/detail/impl/storage_profile.ipp:1371,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/storage_profile.hpp:407,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/llfio.hpp:74,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/llfio.hpp:18,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/llfio.cpp:7:
    /usr/include/linux/mount.h:95:6: error: multiple definition of ‘enum fsconfig_command’
       95 | enum fsconfig_command {
          |      ^~~~~~~~~~~~~~~~
    In file included from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/detail/impl/../../detail/impl/../../detail/impl/posix/statfs.ipp:32,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/detail/impl/../../detail/impl/../../statfs.hpp:157,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/detail/impl/../../detail/impl/path_discovery.ipp:28,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/detail/impl/../../file_handle.hpp:552,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/detail/impl/dynamic_thread_pool_group.ipp:27,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/dynamic_thread_pool_group.hpp:526,
                     from /root/ldevel/vcpkg/buildtrees/llfio/src/c8406280fa-2f2d7fa4bd.clean/src/../include/llfio/v2.0/llfio.hpp:67:
    /usr/include/sys/mount.h:191:6: note: previous definition here
      191 | enum fsconfig_command
          |      ^~~~~~~~~~~~~~~~
    /usr/include/linux/mount.h:129:8: error: redefinition of ‘struct mount_attr’
      129 | struct mount_attr {
          |        ^~~~~~~~~~
    /usr/include/sys/mount.h:162:8: note: previous definition of ‘struct mount_attr’
      162 | struct mount_attr
          |        ^~~~~~~~~~
    

    This new incompatibility has been documented in the glibc wiki. According to this mailing thread the glibc maintainers are aware of this and will likely workaround this within the glibc sources in a few weeks. Currently this only affects rolling linux distributions living at the bleeding edge like Arch Linux. So I don't think it's worth to be patched here.

    opened by BurningEnlightenment 0
  • Win32 / Clang-14 / libc++: error: use of undeclared identifier 'in6addr_loopback'

    Win32 / Clang-14 / libc++: error: use of undeclared identifier 'in6addr_loopback'

    I'm getting a few issues on this platform, would you know why that may be the case ? Maybe it's an issue with the MinGW API headers ?

    In file included from D:/a/1/s/3rdparty/llfio/include/llfio.hpp:1:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/llfio.hpp:18:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/llfio.hpp:73:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/tls_socket_handle.hpp:28:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/../../byte_socket_handle.hpp:1123:
    D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/byte_socket_handle.ipp:56:120: error: use of undeclared identifier 'in6addr_loopback'
        return (is_v4() && 0 == memcmp(ipv4._addr, loopback4, sizeof(ipv4._addr))) || (is_v6() && 0 == memcmp(ipv6._addr, &in6addr_loopback, sizeof(ipv6._addr)));
                                                                                                                           ^
    D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/byte_socket_handle.ipp:220:120: error: use of undeclared identifier 'in6addr_any'
      LLFIO_HEADERS_ONLY_MEMFUNC_SPEC address_v6 address_v6::any() noexcept { return address_v6(bytes_type{(const byte *) &in6addr_any, 16}); }
                                                                                                                           ^
    D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/byte_socket_handle.ipp:221:125: error: use of undeclared identifier 'in6addr_loopback'
      LLFIO_HEADERS_ONLY_MEMFUNC_SPEC address_v6 address_v6::loopback() noexcept { return address_v6(bytes_type{(const byte *) &in6addr_loopback, 16}); }
                                                                                                                                ^
    In file included from D:/a/1/s/build/src/lib/CMakeFiles/score_lib_base.dir/Unity/unity_0_cxx.cxx:139:
    In file included from D:/a/1/s/src/lib/score/tools/RecursiveWatch.cpp:24:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio.hpp:1:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/llfio.hpp:18:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/llfio.hpp:73:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/tls_socket_handle.hpp:28:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/../../byte_socket_handle.hpp:1123:
    In file included from D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/byte_socket_handle.ipp:302:
    D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/windows/byte_socket_handle.ipp:133:49: error: incompatible pointer types assigning to '::ADDRINFOEXW *' (aka 'addrinfoExW *') from 'struct addrinfoexW *'
            for(auto *p = res; p != nullptr; p = p->ai_next)
                                                 ~~~^~~~~~~
    D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/windows/byte_socket_handle.ipp:196:9: error: use of undeclared identifier 'GetAddrInfoExCancel'
            GetAddrInfoExCancel(&p->ophandle);
            ^
    D:/a/1/s/3rdparty/llfio/include/llfio/v2.0/detail/impl/windows/byte_socket_handle.ipp:232:20: error: use of undeclared identifier 'GetAddrInfoExOverlappedResult'
        auto retcode = GetAddrInfoExOverlappedResult(&self->ol);
    
    
    bug 
    opened by jcelerier 6
  • ff-probe segfault on macOS

    ff-probe segfault on macOS

    Here's the output from the program and backtrace from LLDB:

    (lldb) run
    Process 67173 launched: '/Users/godtamit/src/llfio/programs/build/bin/fs-probe' (x86_64)
    Writing 17Gb of temporary test files, this will take a while ...
    Attempting to flush all modified data in system and drop all filesystem caches ...
       WARNING: Failed due to Operation not supported
    Waiting for hard drive to quieten after temp files written ...
    
    direct=0 sync=0:
    Running test system:os:name ...
       system:os:name = Darwin
    Running test system:os:ver ...
       system:os:ver = 21.2.0
    Running test system:cpu:name ...
       system:cpu:name = GenuineIntel Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
    Running test system:cpu:architecture ...
       system:cpu:architecture = x86_64
    Running test system:cpu:physical_cores ...
       system:cpu:physical_cores = 4
    Running test system:mem:max_bandwidth ...
    llfio: Large page allocation successful
    Process 67173 stopped
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xffffffffffffffff)
        frame #0: 0x00007ff81e520669 libsystem_platform.dylib`_platform_bzero$VARIANT$Haswell + 41
    libsystem_platform.dylib`_platform_bzero$VARIANT$Haswell:
    ->  0x7ff81e520669 <+41>: rep    stosb	%al, %es:(%rdi)
        0x7ff81e52066b <+43>: movq   %rdx, %rax
        0x7ff81e52066e <+46>: popq   %rbp
        0x7ff81e52066f <+47>: retq
    Target 0: (fs-probe) stopped.
    (lldb) bt
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xffffffffffffffff)
      * frame #0: 0x00007ff81e520669 libsystem_platform.dylib`_platform_bzero$VARIANT$Haswell + 41
        frame #1: 0x000000010002dfe3 fs-probe`llfio_v2_713b9dc8::storage_profile::system::mem(sp=0x00000001001ac160, h=0x00007ff7bfeff248) at storage_profile.ipp:189:11
        frame #2: 0x0000000100060dd5 fs-probe`llfio_v2_713b9dc8::storage_profile::item<unsigned long long>::operator(this=0x00000001001ac3e8, sp=0x00000001001ac160, h=0x00007ff7bfeff248)(llfio_v2_713b9dc8::storage_profile::storage_profile&, llfio_v2_713b9dc8::file_handle&) const at storage_profile.hpp:129:14
        frame #3: 0x0000000100060c92 fs-probe`auto llfio_v2_713b9dc8::storage_profile::item_erased::operator(this=0x00007ff7bfefefc0, item=0x00000001001ac3e8)(llfio_v2_713b9dc8::storage_profile::storage_profile&, llfio_v2_713b9dc8::file_handle&) const::'lambda'(auto&)::operator()<llfio_v2_713b9dc8::storage_profile::item<unsigned long long> const>(auto&) const at storage_profile.hpp:168:52
        frame #4: 0x0000000100060b7d fs-probe`auto llfio_v2_713b9dc8::storage_profile::item_erased::invoke<llfio_v2_713b9dc8::storage_profile::item_erased::operator()(llfio_v2_713b9dc8::storage_profile::storage_profile&, llfio_v2_713b9dc8::file_handle&) const::'lambda'(auto&)>(this=0x00000001001ac3e8, f=0x00007ff7bfefefc0) const at storage_profile.hpp:151:16
        frame #5: 0x000000010000571f fs-probe`llfio_v2_713b9dc8::storage_profile::item_erased::operator(this=0x00000001001ac3e8, sp=0x00000001001ac160, h=0x00007ff7bfeff248)(llfio_v2_713b9dc8::storage_profile::storage_profile&, llfio_v2_713b9dc8::file_handle&) const at storage_profile.hpp:168:14
        frame #6: 0x0000000100003705 fs-probe`main(argc=1, argv=0x00007ff7bfeff7f0) at main.cpp:168:25
        frame #7: 0x00000001004594fe dyld`start + 462
    
    bug 
    opened by GodTamIt 1
  • Feature Suggestion: Force unlinking of read only/immutable files.

    Feature Suggestion: Force unlinking of read only/immutable files.

    I'm currently prototyping a command line utility around your directory reducer and noticed that by default it can't cope with filesystem entries which have FILE_ATTRIBUTE_READONLY set on windows. The algorithm also doesn't report this specific error, but (unsuccessfully) retries to delete the entries until it hits the timeout deadline.

    Therefore I'd love to be able to nudge fs_handle::unlink() and friends towards trying a bit harder. Maybe something akin to flag::win_disable_unlink_emulation would fit the bill (though this isn't windows specific -- linux, BSD, and its derivatives have an immutable attribute).

    However, thanks to the flexible visitor architecture it's easy enough to work around in my case and I've a hunch that the immutable file attribute is way more commonly found on windows than on any other OS. I'm attaching the workaround snippet in case someone else stumbles on this.

    ::BY_HANDLE_FILE_INFORMATION fileInfo{};
    if (!::GetFileInformationByHandle(unmanagedHandle.h, &fileInfo))
    {
        return llfio::error_info(win32_error());
    }
    if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
    {
        return false;
    }
    
    ::FILE_BASIC_INFO changedFileInfo{
            .CreationTime = as_large_integer(fileInfo.ftCreationTime),
            .LastAccessTime = as_large_integer(fileInfo.ftLastAccessTime),
            .LastWriteTime = as_large_integer(fileInfo.ftLastWriteTime),
            .ChangeTime = as_large_integer(fileInfo.ftLastWriteTime),
            .FileAttributes = fileInfo.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY};
    if (!::SetFileInformationByHandle(unmanagedHandle.h, FileBasicInfo,
                                        &changedFileInfo,
                                        sizeof(changedFileInfo)))
    {
        return llfio::error_info(win32_error());
    }
    
    enhancement 
    opened by BurningEnlightenment 1
An implementation of C++17 std::filesystem for C++11 /C++14/C++17/C++20 on Windows, macOS, Linux and FreeBSD.

Filesystem Motivation Why the namespace GHC? Platforms Tests Usage Downloads Using it as Single-File-Header Using it as Forwarding-/Implementation-Hea

null 1k Jan 6, 2023
πfs - the data-free filesystem!

πfs - the data-free filesystem!

Philip Langdale 6k Jan 6, 2023
LoomIO is an object-level coordination system for distributed file systems.

LoomIO is an object-level coordination system for distributed file systems. It adopts wait-free design to enable interfering object requests self-organizing and obtain an optimized scheduling decision. Currently, LoomIO is implemented and integrated in Ceph.

null 2 Jun 19, 2022
A small C library with that portably invokes native file open, folder select and file save dialogs.

Cross platform (Windows, Mac, Linux) native file dialog library with C and C++ bindings, based on mlabbe/nativefiledialog.

Bernard Teo 299 Dec 23, 2022
Cross-platform C++11 header-only library for memory mapped file IO

mio An easy to use header-only cross-platform C++11 memory mapping library with an MIT license. mio has been created with the goal to be easily includ

null 1.4k Dec 30, 2022
Lightweight, portable and easy to integrate C directory and file reader

TinyDir Lightweight, portable and easy to integrate C directory and file reader. TinyDir wraps dirent for POSIX and FindFirstFile for Windows. Windows

Cong 703 Jan 2, 2023
Lightweight, portable and easy to integrate C directory and file reader

TinyDir Lightweight, portable and easy to integrate C directory and file reader. TinyDir wraps dirent for POSIX and FindFirstFile for Windows. Windows

Cong 702 Dec 31, 2022
localfuse - File system implemented on Linux using C and libfuse

localfuse - File system implemented on Linux using C and libfuse Use pure C to have a simple file system of your own on the linux system Install and b

null 4 Sep 23, 2021
FSearch is a fast file search utility for Unix-like systems based on GTK+3

FSearch is a fast file search utility, inspired by Everything Search Engine. It's written in C and based on GTK3.

Christian Boxdörfer 2.2k Jan 8, 2023
WineFS is a file system for Persistent Memory (PM) which is aimed at maximizing the performance of memory-mapped applications.

WineFS WineFS is a file system for Persistent Memory (PM) which is aimed at maximizing the performance of memory-mapped applications. WineFS uses a no

UT Systems and Storage Lab 23 Oct 2, 2022
PoC of a native Linux file system to mount container images.

composefs PoC of a native Linux file system to mount container images. It is unfinished and just a few days of work. The idea is to pass a binary blob

Giuseppe Scrivano 0 Dec 8, 2022
C++ implementation of a platform independent endian safe binary file stream

EndianSafeBinaryStream A C++ implementation of a platform independent endian safe binary file stream that can save primitive types and is easily exten

Corbinian Gruber 2 Mar 22, 2022
The MHS Filesystem- A very simple linked-list based file system designed for recoverability and low data redundancy. Public domain filesystem (Version 1)

MHS Filesystem The MHS filesystem. Features: can be modified to work with any size of disk or sector, even non powers of two! Allocation bitmap stored

DMHSW 8 Sep 17, 2022
Legion Low Level Rendering Interface provides a graphics API agnostic rendering interface with minimal CPU overhead and low level access to verbose GPU operations.

Legion-LLRI Legion-LLRI, or “Legion Low Level Rendering Interface” is a rendering API that aims to provide a graphics API agnostic approach to graphic

Rythe Interactive 25 Dec 6, 2022
✔️The smallest header-only GUI library(4 KLOC) for all platforms

Welcome to GUI-lite The smallest header-only GUI library (4 KLOC) for all platforms. 中文 Lightweight ✂️ Small: 4,000+ lines of C++ code, zero dependenc

null 6.6k Jan 8, 2023
A water tank level sensor **Built With WisBlock** to detect overflow and low level conditions.

RAK12014 Laser TOF sensor coming soon WisBlock Watertank Level Sensor Watertank Overflow detection using the RAKwireless WisBlock modules. It implemen

Bernd Giesecke 3 Feb 3, 2022
High-level interface for low-level programming

Singeli Singeli is now able to compile useful programs to C, but it's very rough around the edges, with poor error reporting. We are beginning to use

Marshall Lochbaum 40 Dec 30, 2022
Proof of concept userspace filesystem that executes filenames as shell commands and makes the result accessible though reading the file.

ExecFS Proof of concept userspace filesystem that executes filenames as shell commands and makes the result accessible though reading the file. $ ./ex

Camel Coder 42 Jan 7, 2023
A modern cross-platform low-level graphics library and rendering framework

Diligent Engine A Modern Cross-Platform Low-Level 3D Graphics Library Diligent Engine is a lightweight cross-platform graphics API abstraction library

Diligent Graphics 2.6k Dec 30, 2022
Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal

Low Level Graphics Library (LLGL) Documentation NOTE: This repository receives bug fixes only, but no major updates. Pull requests may still be accept

Lukas Hermanns 1.5k Jan 8, 2023