~aleteoryx/muditaos

d2bf42d411b21efd7d79614bb544959904d01082 — Adam Wulkiewicz 2 years ago 89cfcb9
[BH-1655] Fix memory leaks in clock faces and shortcuts

Disable libphonenumber initialization since it is not used in Harmony
but takes around 1.4MB of memory

Add heap allocation statistics
M .vscode/launch.json => .vscode/launch.json +2 -0
@@ 115,6 115,8 @@
            "jlinkscript": "${workspaceFolder}/evkbimxrt1050_sdram_init_T6.jlinkscript",
            "rtos": "FreeRTOS",
            "overrideLaunchCommands": [
                "source tools/gdb_crash_extend.py",
                "source tools/misc/puregdb/puregdb.py",
                "monitor reset 0",
                "monitor halt",
                "monitor memU32 0x401BC000 = 128;",

M .vscode/settings.json => .vscode/settings.json +4 -1
@@ 88,7 88,10 @@
        "assert": "cpp",
        "narrow": "cpp",
        "util": "cpp",
        "filesystem": "cpp"
        "filesystem": "cpp",
        "numbers": "cpp",
        "semaphore": "cpp",
        "byte": "cpp"
    },
    "favorites.sortDirection": "ASC",
}

M .vscode/tasks.json => .vscode/tasks.json +1 -0
@@ 55,6 55,7 @@
                "bell",
                "linux",
                "Debug",
                //"-DLINUX_ENABLE_SANITIZER=OFF",
                "-G",
                "Ninja"
            ],

M module-apps/apps-common/widgets/spinners/ItemSpinner.hpp => module-apps/apps-common/widgets/spinners/ItemSpinner.hpp +12 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 21,6 21,7 @@ namespace gui
                             range range,
                             Boundaries boundaries   = Boundaries::Continuous,
                             Orientation orientation = Orientation::Vertical);
        ~ItemSpinner();

        [[nodiscard]] value_type getCurrentValue() const noexcept;
        void setCurrentValue(value_type val);


@@ 71,6 72,16 @@ namespace gui
    }

    template <typename Container>
    ItemSpinner<Container>::~ItemSpinner()
    {
        for (Item *layout : container) {
            if (layout != currentLayout) {
                delete layout;
            }
        }
    }

    template <typename Container>
    void ItemSpinner<Container>::setFocusEdges(RectangleEdge edges)
    {
        focusEdges = edges;

M module-apps/apps-common/widgets/spinners/Model.hpp => module-apps/apps-common/widgets/spinners/Model.hpp +11 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 102,6 102,16 @@ class Model
        return std::next(it) == elements.end();
    }

    auto begin() const
    {
        return elements.begin();
    }

    auto end() const
    {
        return elements.end();
    }

  private:
    range elements;
    typename range::iterator it = elements.end();

M module-bsp/board/rt1051/bsp/rtc/rtc.cpp => module-bsp/board/rt1051/bsp/rtc/rtc.cpp +1 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "rtc_configuration.hpp"

A module-os/memory/UserMemStatsLogger.hpp => module-os/memory/UserMemStatsLogger.hpp +34 -0
@@ 0,0 1,34 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <log/log.hpp>

#include "usermem.h"

struct UserMemStatsLogger
{
#if DEBUG_HEAP_ALLOCATIONS == 1
    UserMemStatsLogger()
    {
        usermemResetStatistics();
        freeHeapSize1 = usermemGetFreeHeapSize();
    }

    ~UserMemStatsLogger()
    {
        size_t freeHeapSize2      = usermemGetFreeHeapSize();
        size_t allocationsCount   = usermemGetAllocationsCount();
        size_t deallocationsCount = usermemGetDeallocationsCount();
        size_t allocatedMin       = usermemGetAllocatedMin();
        size_t allocatedMax       = usermemGetAllocatedMax();
        size_t allocatedSum       = usermemGetAllocatedSum();
        LOG_INFO("\nFree before: %zu\nFree after: %zu\n# allocations: %zu\n# deallocations: %zu\nSmallest block: %zu\nBiggest block: %zu\nAllocated: %zu",
                 freeHeapSize1, freeHeapSize2, allocationsCount, deallocationsCount, allocatedMin, allocatedMax, allocatedSum);
    }

private:
    size_t freeHeapSize1;
#endif
};

M module-os/memory/usermem.c => module-os/memory/usermem.c +50 -0
@@ 107,6 107,12 @@ fragmentation. */
static size_t userxFreeBytesRemaining = 0U;
static size_t userxMinimumEverFreeBytesRemaining = 0U;

/* Allocation statistics */
static size_t xAllocationsCount = 0;
static size_t xDeallocationsCount = 0;
static size_t xAllocatedMin = SIZE_MAX;
static size_t xAllocatedMax = 0;
static size_t xAllocatedSum = 0;

/* Gets set to the top bit of an size_t type.  When this bit in the xBlockSize
member of an BlockLink_t structure is set then the block belongs to the


@@ 222,6 228,14 @@ void *usermalloc(size_t xWantedSize)
							mtCOVERAGE_TEST_MARKER();
						}

						/* Allocation statistics */
#if DEBUG_HEAP_ALLOCATIONS == 1
						++xAllocationsCount;
						if (pxBlock->xBlockSize < xAllocatedMin) xAllocatedMin = pxBlock->xBlockSize;
						if (pxBlock->xBlockSize > xAllocatedMax) xAllocatedMax = pxBlock->xBlockSize;
						xAllocatedSum += pxBlock->xBlockSize;
#endif

						userxFreeBytesRemaining -= pxBlock->xBlockSize;

						if( userxFreeBytesRemaining < userxMinimumEverFreeBytesRemaining )


@@ 329,6 343,12 @@ void userfree(void *pv)

					vTaskSuspendAll();
					{
						/* Allocation statistics */
#if DEBUG_HEAP_ALLOCATIONS == 1
						++xDeallocationsCount;
						xAllocatedSum -= pxLink->xBlockSize;
#endif

						/* Add this block to the list of free blocks. */
						userxFreeBytesRemaining += pxLink->xBlockSize;
						traceFREE( pv, pxLink->xBlockSize );


@@ 407,6 427,36 @@ size_t usermemGetMinimumEverFreeHeapSize( void )
}
/*-----------------------------------------------------------*/

void usermemResetStatistics(void)
{
	xAllocationsCount = 0;
	xDeallocationsCount = 0;
	xAllocatedMin = SIZE_MAX;
	xAllocatedMax = 0;
	xAllocatedSum = 0;
}
size_t usermemGetAllocationsCount(void)
{
	return xAllocationsCount;
}
size_t usermemGetDeallocationsCount(void)
{
	return xDeallocationsCount;
}
size_t usermemGetAllocatedMin(void)
{
	return xAllocatedMin;
}
size_t usermemGetAllocatedMax(void)
{
	return xAllocatedMax;
}
size_t usermemGetAllocatedSum(void)
{
	return xAllocatedSum;
}

/*-----------------------------------------------------------*/

static void prvHeapInit( void )
{

M module-os/memory/usermem.h => module-os/memory/usermem.h +7 -0
@@ 24,6 24,13 @@ size_t usermemGetFreeHeapSize(void);

size_t usermemGetMinimumEverFreeHeapSize(void);

void usermemResetStatistics(void);
size_t usermemGetAllocationsCount(void);
size_t usermemGetDeallocationsCount(void);
size_t usermemGetAllocatedMin(void);
size_t usermemGetAllocatedMax(void);
size_t usermemGetAllocatedSum(void);

void *userrealloc(void *pv, size_t xWantedSize);

#ifdef __cplusplus

M module-services/service-evtmgr/WorkerEventCommon.cpp => module-services/service-evtmgr/WorkerEventCommon.cpp +5 -0
@@ 25,6 25,7 @@
#include <optional>

#include <log/log.hpp>
#include <memory/usermem.h>

WorkerEventCommon::WorkerEventCommon(sys::Service *service)
    : sys::Worker(service, stackDepthBytes),


@@ 33,6 34,10 @@ WorkerEventCommon::WorkerEventCommon(sys::Service *service)

bool WorkerEventCommon::handleMessage(uint32_t queueID)
{
#if DEBUG_HEAP_ALLOCATIONS == 1
    LOG_INFO("Free space: %zu", usermemGetFreeHeapSize());
#endif

    auto &queue = queues[queueID];

    // service queue

M module-utils/log/api/log/debug.hpp => module-utils/log/api/log/debug.hpp +2 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 13,6 13,7 @@
#define DEBUG_GUI_TEXT               0 /// show basic debug messages for gui::Text - warning this can be hard on cpu
#define DEBUG_GUI_TEXT_LINES         0 /// show extended debug messages for gui::Text - lines building
#define DEBUG_GUI_TEXT_CURSOR        0 /// show extended debug messages for gui::Text - cursor handling
#define DEBUG_HEAP_ALLOCATIONS       0 /// gather heap allocations statictics
#define DEBUG_INPUT_EVENTS           0 /// show input events prints in system
#define DEBUG_MISSING_ASSETS         0 /// show debug concerning missing assets
#define DEBUG_SCOPED_TIMINGS         0 /// show timings in measured functions

M products/BellHybrid/BellHybridMain.cpp => products/BellHybrid/BellHybridMain.cpp +1 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "PlatformFactory.hpp"


@@ 104,10 104,6 @@ int main()
            }

            Log::Logger::get().init(Log::Application{ApplicationName, GIT_REV, VERSION, GIT_BRANCH});
            /// force initialization of PhonenumberUtil because of its stack usage
            /// otherwise we would end up with an init race and PhonenumberUtil could
            /// be initiated in a task with stack not big enough to handle it
            i18n::phonenumbers::PhoneNumberUtil::GetInstance();
            return true;
        },
        [sysmgr]() {

M products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp => products/BellHybrid/apps/application-bell-main/windows/BellHomeScreenWindow.cpp +3 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "BellHomeScreenWindow.hpp"


@@ 52,6 52,8 @@ namespace gui
    {
        if (currentLayout) {
            removeWidget(currentLayout->getLayout());
            delete currentLayout;
            currentLayout = nullptr;
        }
        currentLayout = layoutGenerator();
        addWidget(static_cast<BellBaseLayout *>(currentLayout->getLayout()));

M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalSimple.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutVerticalSimple.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "layouts/HomeScreenLayoutVerticalSimple.hpp"


@@ 35,4 35,4 @@ namespace gui
        leftBox->resizeItems();
        rightBox->resizeItems();
    }
}; // namespace gui
} // namespace gui