#pragma once #include "machine.h" #include #include #include class AppendOnlyBuffer { static constexpr size_t AOB_PAGE_SIZE = 1024 * 1024; static constexpr size_t AOB_PAGE_MAX_COUNT = 256; uint8_t *pages[AOB_PAGE_MAX_COUNT]{}; emscripten_lock_t appenderLock; alignas(CACHE_LINE_SIZE) uint32_t atomicSize{}; alignas(CACHE_LINE_SIZE) uint32_t atomicPageCount{}; AppendOnlyBuffer(const AppendOnlyBuffer &) = delete; AppendOnlyBuffer &operator=(const AppendOnlyBuffer &) = delete; AppendOnlyBuffer(AppendOnlyBuffer &&) = delete; AppendOnlyBuffer &operator=(AppendOnlyBuffer &&) = delete; public: AppendOnlyBuffer(); ~AppendOnlyBuffer(); // read() and size(): // - may return stale values // - size() is a guaranteed lower bound // with respect to subsequent calls to read() // - are lock-free and wait-free // - permit concurrent calls size_t size() const; size_t read(size_t offset, size_t count, uint8_t *out); // all calls to append() are serialized by a lock void append(size_t count, const uint8_t *data); };