Skip to content

Commit

Permalink
Add CHIP_CONFIG_DYNAMIC_GLOBALS option to enable dynamic allocation o…
Browse files Browse the repository at this point in the history
…f Global<T>s
  • Loading branch information
nk-shelly committed Jul 29, 2024
1 parent 8542101 commit be87822
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
6 changes: 3 additions & 3 deletions src/app/reporting/ReportSchedulerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class ReportSchedulerImpl : public ReportScheduler
* solely based on its ReadHandler's state. Therefore, no synchronization action on the ICDState is needed in this
* implementation.
*/
void OnTransitionToIdle() override {};
void OnTransitionToIdle() override{};

/**
* @brief When the ICD transitions to Active mode, this implementation will trigger a report emission on each ReadHandler that
Expand All @@ -88,13 +88,13 @@ class ReportSchedulerImpl : public ReportScheduler
* @brief Similar to the OnTransitionToIdle() method, this implementation does not attempt any synchronization on ICD events,
* therefore no action is needed on the ICDModeChange() method.
*/
void OnICDModeChange() override {};
void OnICDModeChange() override{};

/**
* @brief This implementation does not attempt any synchronization on this ICD event, therefore no action is needed on
* ICDEnterIdleMode()
*/
void OnEnterIdleMode() override {};
void OnEnterIdleMode() override{};

// ReadHandlerObserver

Expand Down
12 changes: 12 additions & 0 deletions src/lib/core/CHIPConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,18 @@
#define CHIP_CONFIG_GLOBALS_NO_DESTRUCT 0
#endif // CHIP_CONFIG_GLOBALS_NO_DESTRUCT

/**
* @def CHIP_CONFIG_DYNAMIC_GLOBALS
*
* @brief
* Whether to use dynamic allocation for chip::Global objects.
*
* The default is to use static allocation.
*/
#ifndef CHIP_CONFIG_DYNAMIC_GLOBALS
#define CHIP_CONFIG_DYNAMIC_GLOBALS 0
#endif // CHIP_CONFIG_DYNAMIC_GLOBALS

/**
* @def CHIP_CONFIG_SHA256_CONTEXT_SIZE
*
Expand Down
41 changes: 31 additions & 10 deletions src/lib/core/Global.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,12 @@ class Global
/// NOT thread-safe, external synchronization is required.
T & get() { return _get(); }
T * operator->() { return &_get(); }

template <class U = typename std::remove_extent<T>::type>
template <class U = std::remove_extent_t<T>>
U & operator[](std::size_t i)
{
return _get()[i];
}
template <std::size_t N = std::extent<T>::value>
template <std::size_t N = std::extent_v<T>>
constexpr std::size_t size() const
{
return N;
Expand All @@ -110,35 +109,57 @@ class Global
private:
// Zero-initialize everything. We should technically leave mStorage uninitialized,
// but that can sometimes cause clang to be unable to constant-initialize the object.
#if CHIP_CONFIG_DYNAMIC_GLOBALS
unsigned char * mStorage = nullptr;
#else
alignas(T) unsigned char mStorage[sizeof(T)] = {};
#endif // CHIP_CONFIG_DYNAMIC_GLOBALS
OnceStrategy mOnce;

T & _get()
{
T * value = reinterpret_cast<T *>(mStorage);
mOnce.call(&create, value);
return *value;
#if CHIP_CONFIG_DYNAMIC_GLOBALS
mOnce.call(&create, &mStorage);
#else
mOnce.call(&create, mStorage);
#endif // CHIP_CONFIG_DYNAMIC_GLOBALS
return *reinterpret_cast<T *>(mStorage);
}
static void create(void * value)
{
#if CHIP_CONFIG_DYNAMIC_GLOBALS
unsigned char ** storage = static_cast<unsigned char **>(value);
value = *storage = new unsigned char[sizeof(T)];
#endif // CHIP_CONFIG_DYNAMIC_GLOBALS
new (value) T();
#if !CHIP_CONFIG_GLOBALS_NO_DESTRUCT
CHIP_CXA_ATEXIT(&destroy, value);
#endif // CHIP_CONFIG_GLOBALS_NO_DESTRUCT
}

template <class U, std::size_t N>
static void destroy(U (*value)[N])
static void _destroy(U (*value)[N])
{
_destroy_array(*value, N);
}
template <class U>
static void _destroy_array(U * array, std::size_t N)
{
for (std::size_t i = 0; i < N; ++i)
destroy(value[i]);
array[i].~U();
}
template <class U>
static void destroy(U * value)
static void _destroy(U * value)
{
value->~U();
}
static void destroy(void * value) { destroy(static_cast<T *>(value)); }
static void destroy(void * value)
{
_destroy(static_cast<T *>(value));
#if CHIP_CONFIG_DYNAMIC_GLOBALS
delete[] static_cast<unsigned char *>(value);
#endif // CHIP_CONFIG_DYNAMIC_GLOBALS
}

#else // CHIP_CONFIG_GLOBALS_LAZY_INIT
public:
Expand Down
6 changes: 6 additions & 0 deletions src/platform/Linux/CHIPPlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@

#define CHIP_CONFIG_ABORT() abort()

extern "C" int __cxa_atexit(void (*func)(void *), void * arg, void * d);
#define CHIP_CXA_ATEXIT(f, p) __cxa_atexit((f), (p), nullptr)

#define CHIP_CONFIG_DYNAMIC_GLOBALS 1
#define CHIP_CONFIG_GLOBALS_LAZY_INIT 1

using CHIP_CONFIG_PERSISTED_STORAGE_KEY_TYPE = const char *;
#define CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH 16

Expand Down

0 comments on commit be87822

Please sign in to comment.