Skip to content

Commit

Permalink
Add Platform::SharedPtr, similar to Platform::UniquePtr (#13848)
Browse files Browse the repository at this point in the history
This commit adds a Platform::SharedPtr wrapper for std::shared_ptr,
but using the chip platform allocator, in the pattern of
Platform::UniquePtr.
  • Loading branch information
msandstedt authored and pull[bot] committed Jan 22, 2024
1 parent 04994b7 commit 4804659
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/lib/support/CHIPMem.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ inline UniquePtr<T> MakeUnique(Args &&... args)
return UniquePtr<T>(New<T>(std::forward<Args>(args)...));
}

template <typename T>
using SharedPtr = std::shared_ptr<T>;

template <typename T, typename... Args>
inline SharedPtr<T> MakeShared(Args &&... args)
{
return SharedPtr<T>(New<T>(std::forward<Args>(args)...), Deleter<T>());
}

// See MemoryDebugCheckPointer().
extern bool MemoryInternalCheckPointer(const void * p, size_t min_size);

Expand Down
46 changes: 45 additions & 1 deletion src/lib/support/tests/TestCHIPMem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,57 @@ static void TestMemAlloc_UniquePtr(nlTestSuite * inSuite, void * inContext)
NL_TEST_ASSERT(inSuite, destructorCalled == 1);
}

static void TestMemAlloc_SharedPtr(nlTestSuite * inSuite, void * inContext)
{
// SharedPtr is a wrapper of std::shared_ptr for platform allocators.
int instanceConstructorCalled = 0;
int instanceDestructorCalled = 0;
int otherInstanceConstructorCalled = 0;
int otherInstanceDestructorCalled = 0;

class Cls
{
public:
Cls(int * constructCtr, int * desctructorCtr) : mpDestructorCtr(desctructorCtr) { (*constructCtr)++; }
~Cls() { (*mpDestructorCtr)++; }

private:
int * mpDestructorCtr;
};

// Check constructor call for a block-scoped variable and share our
// reference to a function-scoped variable.
SharedPtr<Cls> otherReference;
{
auto ptr = MakeShared<Cls>(&instanceConstructorCalled, &instanceDestructorCalled);
NL_TEST_ASSERT(inSuite, instanceConstructorCalled == 1);
// Capture a shared reference so we aren't destructed when we leave this scope.
otherReference = ptr;
}

// Verify that by sharing to otherReference, we weren't destructed.
NL_TEST_ASSERT(inSuite, instanceDestructorCalled == 0);

// Now drop our reference.
otherReference = MakeShared<Cls>(&otherInstanceConstructorCalled, &otherInstanceDestructorCalled);

// Verify that the new instance was constructed and the first instance was
// destructed, and that we retain a reference to the new instance.
NL_TEST_ASSERT(inSuite, instanceConstructorCalled == 1);
NL_TEST_ASSERT(inSuite, instanceDestructorCalled == 1);
NL_TEST_ASSERT(inSuite, otherInstanceConstructorCalled == 1);
NL_TEST_ASSERT(inSuite, otherInstanceDestructorCalled == 0);
}

/**
* Test Suite. It lists all the test functions.
*/
static const nlTest sTests[] = { NL_TEST_DEF("Test MemAlloc::Malloc", TestMemAlloc_Malloc),
NL_TEST_DEF("Test MemAlloc::Calloc", TestMemAlloc_Calloc),
NL_TEST_DEF("Test MemAlloc::Realloc", TestMemAlloc_Realloc),
NL_TEST_DEF("Test MemAlloc::UniquePtr", TestMemAlloc_UniquePtr), NL_TEST_SENTINEL() };
NL_TEST_DEF("Test MemAlloc::UniquePtr", TestMemAlloc_UniquePtr),
NL_TEST_DEF("Test MemAlloc::SharedPtr", TestMemAlloc_SharedPtr),
NL_TEST_SENTINEL() };

/**
* Set up the test suite.
Expand Down

0 comments on commit 4804659

Please sign in to comment.