Skip to content

Commit

Permalink
Replace SHAMapTreeNodes with intrusive pointers:
Browse files Browse the repository at this point in the history
This branch has a long history. About two years ago I wrote a patch to
remove the mutex from shamap inner nodes (ref:
https://github.com/seelabs/rippled/tree/lockfree-tagged-cache). At the
time I measured a large memory savings of about 2 gig. Unfortunately,
the code required using the `folly` library, and I was hesitant to
introduce such a large dependency into rippled (especially one that was
so hard to build). This branch resurrects that old work and removes the
`folly` dependency.

The old branch used a lockless atomic shared pointer. This new branch
introduces a intrusive pointer type. Unlike boost's intrusive pointer,
this intrusive pointer can handle both strong and weak pointers (needed
for the tagged cache). Since this is an intrusive pointer type, in order
to support weak pointers, the object is not destroyed when the strong
count goes to zero. Instead, it is "partially destroyed" (for example,
inner nodes will reset their children). This intrusive pointer takes
32-bits for both the strong and weak counts, and takes one 64-bit
pointer to point at the object. This is much smaller than a
std::shared_pointer, which needs a control block to hold the strong and
weak counts (and potentially other objects), as well as an extra pointer
to point at the control block. The intrusive shared pointer also has
optional support for atomic operations. These atomic operations can be
used instead of the lock when changing inner node pointers in the shamap.

Note: The space savings is independent from removing the locks from
shamap inner node. Therefor this work is divided into two phases. In the
first phase a non-atomic intrusive pointer is introduced and the locks
are kept. In the second phases an atomic intrusive pointer is introduced
and the locks will be removed. Some of the code in this patch is written
with the upcoming atomic work in mind (for example, using exchange in
places).

Note: Intrusive pointer will be 16 bytes. The shared_ptr will be around
40 bytes, depending on implementation.
  • Loading branch information
seelabs committed Nov 14, 2023
1 parent 574efd0 commit 05554c7
Show file tree
Hide file tree
Showing 30 changed files with 3,477 additions and 341 deletions.
1 change: 1 addition & 0 deletions Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ if (tests)
src/test/basics/DetectCrash_test.cpp
src/test/basics/Expected_test.cpp
src/test/basics/FileUtilities_test.cpp
src/test/basics/IntrusiveShared_test.cpp
src/test/basics/IOUAmount_test.cpp
src/test/basics/KeyCache_test.cpp
src/test/basics/Number_test.cpp
Expand Down
2 changes: 2 additions & 0 deletions src/ripple/app/ledger/Ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
#include <ripple/protocol/UintTypes.h>
#include <ripple/protocol/digest.h>
#include <ripple/protocol/jss.h>

#include <boost/optional.hpp>

#include <cassert>
#include <utility>
#include <vector>
Expand Down
2 changes: 2 additions & 0 deletions src/ripple/app/main/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ template <
class Key,
class T,
bool IsKeyCache,
class SharedWeakUnionPointer,
class SharedPointerType,
class Hash,
class KeyEqual,
class Mutex>
Expand Down
1 change: 1 addition & 0 deletions src/ripple/app/misc/SHAMapStoreImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/rdb/State.h>
#include <ripple/app/rdb/backend/SQLiteDatabase.h>
#include <ripple/basics/TaggedCache.ipp>
#include <ripple/beast/core/CurrentThreadName.h>
#include <ripple/core/ConfigSections.h>
#include <ripple/core/Pg.h>
Expand Down
Loading

0 comments on commit 05554c7

Please sign in to comment.