Merge branch 'develop'

This commit is contained in:
Tilen M 2024-10-12 15:15:25 +02:00
commit 0f79742628
55 changed files with 1100 additions and 648 deletions

View File

@ -16,14 +16,14 @@ AlignConsecutiveBitFields:
AlignConsecutiveDeclarations: None AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right AlignEscapedNewlines: Right
AlignOperands: Align AlignOperands: Align
SortIncludes: false SortIncludes: true
InsertBraces: true # Control statements must have curly brackets InsertBraces: true # Control statements must have curly brackets
AlignTrailingComments: true AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Empty AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never AllowShortIfStatementsOnASingleLine: Never

19
.clang-tidy Normal file
View File

@ -0,0 +1,19 @@
---
Checks: "*,
-abseil-*,
-altera-*,
-android-*,
-fuchsia-*,
-google-*,
-llvm*,
-modernize-use-trailing-return-type,
-zircon-*,
-readability-else-after-return,
-readability-static-accessed-through-instance,
-readability-avoid-const-params-in-decls,
-cppcoreguidelines-non-private-member-variables-in-classes,
-misc-non-private-member-variables-in-classes,
"
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none

18
.readthedocs.yaml Normal file
View File

@ -0,0 +1,18 @@
version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# Python configuration
python:
install:
- requirements: docs/requirements.txt
formats:
- pdf
- epub

View File

@ -4,7 +4,14 @@
"lwevt_type.h": "c", "lwevt_type.h": "c",
"lwevt.h": "c", "lwevt.h": "c",
"string.h": "c", "string.h": "c",
"lwevt_opt.h": "c" "lwevt_opt.h": "c",
"streambuf": "c",
"lwmem.h": "c",
"lwmem_opt.h": "c",
"array": "c",
"string_view": "c",
"initializer_list": "c",
"limits.h": "c"
}, },
"esbonio.sphinx.confDir": "" "esbonio.sphinx.confDir": ""
} }

2
.vscode/tasks.json vendored
View File

@ -1,5 +1,5 @@
{ {
"version": "2.1.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"type": "cppbuild", "type": "cppbuild",

4
AUTHORS Normal file
View File

@ -0,0 +1,4 @@
Tilen Majerle <tilen.majerle@gmail.com>
upbeat27 <upbeat27@gmail.com>
Tilen Majerle <tilen@majerle.eu>
Y <469960757@qq.com>

View File

@ -2,6 +2,12 @@
## Develop ## Develop
## v2.2.0
- Rework library CMake with removed INTERFACE type
- Add `LWMEM_CFG_FULL` to allow control build configuration of the library
- Implement support for simple (no realloc, no free, grow-only malloc) allocation mechanism
## v2.1.0 ## v2.1.0
- Split CMakeLists.txt files between library and executable - Split CMakeLists.txt files between library and executable

View File

@ -6,41 +6,26 @@ project(LwLibPROJECT)
if(NOT PROJECT_IS_TOP_LEVEL) if(NOT PROJECT_IS_TOP_LEVEL)
add_subdirectory(lwmem) add_subdirectory(lwmem)
else() else()
# Set as executable
add_executable(${PROJECT_NAME}) add_executable(${PROJECT_NAME})
# Add key executable block
target_sources(${PROJECT_NAME} PUBLIC target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}/dev/main.cpp ${CMAKE_CURRENT_LIST_DIR}/dev/main.cpp
${CMAKE_CURRENT_LIST_DIR}/tests/lwmem_test.c ${CMAKE_CURRENT_LIST_DIR}/tests/lwmem_test.c
${CMAKE_CURRENT_LIST_DIR}/tests/lwmem_test_simple.c
# win32 port # win32 port
${CMAKE_CURRENT_LIST_DIR}/lwmem/src/system/lwmem_sys_win32.c ${CMAKE_CURRENT_LIST_DIR}/lwmem/src/system/lwmem_sys_win32.c
) )
# Add key include paths
target_include_directories(${PROJECT_NAME} PUBLIC target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/dev ${CMAKE_CURRENT_LIST_DIR}/dev
) )
# Compilation definition information
target_compile_definitions(${PROJECT_NAME} PUBLIC
WIN32
_DEBUG
CONSOLE
LWMEM_DEV
)
# Compiler options
target_compile_options(${PROJECT_NAME} PRIVATE
-Wall
-Wextra
-Wpedantic
)
# Add subdir with lwmem and link to the project # Add subdir with lwmem and link to the project
set(LWMEM_OPTS_FILE ${CMAKE_CURRENT_LIST_DIR}/dev/lwmem_opts.h)
add_subdirectory(lwmem) add_subdirectory(lwmem)
target_link_libraries(${PROJECT_NAME} lwmem) target_link_libraries(${PROJECT_NAME} PUBLIC lwmem_cpp)
target_link_libraries(${PROJECT_NAME} lwmem_cpp)
# Add compile options to the library, which will propagate options to executable through public link
target_compile_definitions(lwmem PUBLIC WIN32 _DEBUG CONSOLE LWMEM_DEV)
target_compile_options(lwmem PUBLIC -Wall -Wextra -Wpedantic)
endif() endif()

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023 Tilen MAJERLE Copyright (c) 2024 Tilen MAJERLE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -4,7 +4,7 @@
## Features ## Features
* Written in ANSI C99, compatible with ``size_t`` for size data types * Written in C (C11), compatible with ``size_t`` for size data types
* Implements standard C library functions for memory allocation, malloc, calloc, realloc and free * Implements standard C library functions for memory allocation, malloc, calloc, realloc and free
* Uses *first-fit* algorithm to search for free block * Uses *first-fit* algorithm to search for free block
* Supports multiple allocation instances to split between memories and/or CPU cores * Supports multiple allocation instances to split between memories and/or CPU cores
@ -13,16 +13,17 @@
* Supports embedded applications with fragmented memories * Supports embedded applications with fragmented memories
* Supports automotive applications * Supports automotive applications
* Supports advanced free/realloc algorithms to optimize memory usage * Supports advanced free/realloc algorithms to optimize memory usage
* **Since v2.2.0** Supports light implementation with allocation only
* Operating system ready, thread-safe API * Operating system ready, thread-safe API
* C++ wrapper functions * C++ wrapper functions
* User friendly MIT license * User friendly MIT license
## Contribute ## Contribute
Fresh contributions are always welcome. Simple instructions to proceed:: Fresh contributions are always welcome. Simple instructions to proceed:
1. Fork Github repository 1. Fork Github repository
2. Respect [C style & coding rules](https://github.com/MaJerle/c-code-style) used by the library 2. Follow [C style & coding rules](https://github.com/MaJerle/c-code-style) already used in the project
3. Create a pull request to develop branch with new features or bug fixes 3. Create a pull request to develop branch with new features or bug fixes
Alternatively you may: Alternatively you may:

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -41,9 +41,10 @@
* Open "include/lwmem/lwmem_opt.h" and * Open "include/lwmem/lwmem_opt.h" and
* copy & replace here settings you want to change values * copy & replace here settings you want to change values
*/ */
#define LWMEM_CFG_OS 1 #define LWMEM_CFG_OS 1
#define LWMEM_CFG_OS_MUTEX_HANDLE HANDLE #define LWMEM_CFG_OS_MUTEX_HANDLE HANDLE
#define LWMEM_CFG_ENABLE_STATS 0 #define LWMEM_CFG_ENABLE_STATS 0
#define LWMEM_CFG_CLEAN_MEMORY 1 #define LWMEM_CFG_CLEAN_MEMORY 1
#define LWMEM_CFG_FULL 0
#endif /* LWMEM_HDR_OPTS_H */ #endif /* LWMEM_HDR_OPTS_H */

View File

@ -1,24 +1,33 @@
#include "lwmem/lwmem.h"
#include "lwmem/lwmem.hpp"
#include <iostream> #include <iostream>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "lwmem/lwmem.h"
#include "lwmem/lwmem.hpp"
extern "C" void lwmem_test_run(void); extern "C" void lwmem_test_run(void);
extern "C" void lwmem_test_simple_run(void);
extern "C" void lwmem_test_memory_structure(void); extern "C" void lwmem_test_memory_structure(void);
/* Setup manager */ /* Setup manager */
Lwmem::LwmemLight<1024> manager; static Lwmem::LwmemLight<1024> manager;
int int
main(void) { main(void) {
#if LWMEM_CFG_FULL
lwmem_test_memory_structure(); lwmem_test_memory_structure();
//lwmem_test_run(); //lwmem_test_run();
#else
lwmem_test_simple_run();
#endif
#if 1
/* Test C++ code */ /* Test C++ code */
void* ret = manager.malloc(123); void* ret = manager.malloc(123);
std::cout << ret << std::endl; std::cout << ret << std::endl;
#if LWMEM_CFG_FULL
manager.free(ret); manager.free(ret);
#endif /* LWMEM_CFG_FULL */
#endif
return 0; return 0;
} }

8
docs/authors/index.rst Normal file
View File

@ -0,0 +1,8 @@
.. _authors:
Authors
=======
List of authors and contributors to the library
.. literalinclude:: ../../AUTHORS

View File

@ -23,7 +23,7 @@ subprocess.call('doxygen doxyfile.doxy', shell=True)
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = 'LwMEM' project = 'LwMEM'
copyright = '2022, Tilen MAJERLE' copyright = '2023, Tilen MAJERLE'
author = 'Tilen MAJERLE' author = 'Tilen MAJERLE'
# Try to get branch at which this is running # Try to get branch at which this is running

View File

@ -1,19 +1,20 @@
#define ASSERT(x) do { \ #define ASSERT(x) \
if (!(x)) { \ do { \
printf("Assert failed with condition (" # x ")\r\n"); \ if (!(x)) { \
} else {\ printf("Assert failed with condition (" #x ")\r\n"); \
printf("Assert passed with condition (" # x ")\r\n"); \ } else { \
}\ printf("Assert passed with condition (" #x ")\r\n"); \
} while (0) } \
} while (0)
/* For debug purposes */ /* For debug purposes */
lwmem_region_t* regions_used; lwmem_region_t* regions_used;
size_t regions_count = 1; /* Use only 1 region for debug purposes of non-free areas */ size_t regions_count = 1; /* Use only 1 region for debug purposes of non-free areas */
int int
main(void) { main(void) {
uint8_t* ptr1, *ptr2, *ptr3, *ptr4; uint8_t *ptr1, *ptr2, *ptr3, *ptr4;
uint8_t* rptr1, *rptr2, *rptr3, *rptr4; uint8_t *rptr1, *rptr2, *rptr3, *rptr4;
/* Create regions for debug purpose */ /* Create regions for debug purpose */
if (!lwmem_debug_create_regions(&regions_used, regions_count, 128)) { if (!lwmem_debug_create_regions(&regions_used, regions_count, 128)) {
@ -31,11 +32,11 @@ main(void) {
ptr2 = lwmem_malloc(4); ptr2 = lwmem_malloc(4);
ptr3 = lwmem_malloc(4); ptr3 = lwmem_malloc(4);
ptr4 = lwmem_malloc(16); ptr4 = lwmem_malloc(16);
lwmem_free(ptr1); /* Free but keep value for future comparison */ lwmem_free(ptr1); /* Free but keep value for future comparison */
lwmem_free(ptr3); /* Free but keep value for future comparison */ lwmem_free(ptr3); /* Free but keep value for future comparison */
lwmem_debug_print(1, 1); lwmem_debug_print(1, 1);
printf("Debug above is effectively state 3\r\n"); printf("Debug above is effectively state 3\r\n");
lwmem_debug_save_state(); /* Every restore operations rewinds here */ lwmem_debug_save_state(); /* Every restore operations rewinds here */
/* We always try to reallocate pointer ptr2 */ /* We always try to reallocate pointer ptr2 */
@ -53,7 +54,7 @@ main(void) {
printf("State 3b\r\n"); printf("State 3b\r\n");
rptr2 = lwmem_realloc(ptr2, 20); rptr2 = lwmem_realloc(ptr2, 20);
lwmem_debug_print(1, 1); lwmem_debug_print(1, 1);
ASSERT(rptr2 == ptr2); ASSERT(rptr2 == ptr1);
/* Create 3c case */ /* Create 3c case */
printf("\r\n------------------------------------------------------------------------\r\n"); printf("\r\n------------------------------------------------------------------------\r\n");

View File

@ -52,7 +52,7 @@ State 3b
| 4 | 0034A548 | 1 | 56 | 48 |Free block | | 4 | 0034A548 | 1 | 56 | 48 |Free block |
| 5 | 0034A580 | 0 | 0 | 0 |End of region | | 5 | 0034A580 | 0 | 0 | 0 |End of region |
|-------|----------|--------|------|------------------|----------------| |-------|----------|--------|------|------------------|----------------|
Assert failed with condition (rptr2 == ptr2) Assert passed with condition (rptr2 == ptr1)
------------------------------------------------------------------------ ------------------------------------------------------------------------
-- > State restored to last saved! -- > State restored to last saved!

View File

@ -57,8 +57,18 @@ Update cloned to latest version
Add library to project Add library to project
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
At this point it is assumed that you have successfully download library, either cloned it or from releases page. At this point it is assumed that you have successfully download library, either with ``git clone`` command or with manual download from the library releases page.
Next step is to add the library to the project, by means of source files to compiler inputs and header files in search path Next step is to add the library to the project, by means of source files to compiler inputs and header files in search path.
*CMake* is the main supported build system. Package comes with the ``CMakeLists.txt`` and ``library.cmake`` files, both located in the ``lwmem`` directory:
* ``library.cmake``: It is a fully configured set of variables and with library definition. User can include this file to the project file with ``include(path/to/library.cmake)`` and then manually use the variables provided by the file, such as list of source files, include paths or necessary compiler definitions. It is up to the user to properly use the this file on its own.
* ``CMakeLists.txt``: It is a wrapper-only file and includes ``library.cmake`` file. It is used for when user wants to include the library to the main project by simply calling *CMake* ``add_subdirectory`` command, followed by ``target_link_libraries`` to link external library to the final project.
.. tip::
Open ``library.cmake`` and analyze the provided information. Among variables, you can also find list of all possible exposed libraries for the user.
If you do not use the *CMake*, you can do the following:
* Copy ``lwmem`` folder to your project, it contains library files * Copy ``lwmem`` folder to your project, it contains library files
* Add ``lwmem/src/include`` folder to `include path` of your toolchain. This is where `C/C++` compiler can find the files during compilation process. Usually using ``-I`` flag * Add ``lwmem/src/include`` folder to `include path` of your toolchain. This is where `C/C++` compiler can find the files during compilation process. Usually using ``-I`` flag
@ -70,7 +80,7 @@ Configuration file
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
Configuration file is used to overwrite default settings defined for the essential use case. Configuration file is used to overwrite default settings defined for the essential use case.
Library comes with template config file, which can be modified according to needs. Library comes with template config file, which can be modified according to the application needs.
and it should be copied (or simply renamed in-place) and named ``lwmem_opts.h`` and it should be copied (or simply renamed in-place) and named ``lwmem_opts.h``
.. note:: .. note::
@ -78,7 +88,11 @@ and it should be copied (or simply renamed in-place) and named ``lwmem_opts.h``
File must be renamed to ``lwmem_opts.h`` first and then copied to the project directory where compiler File must be renamed to ``lwmem_opts.h`` first and then copied to the project directory where compiler
include paths have access to it by using ``#include "lwmem_opts.h"``. include paths have access to it by using ``#include "lwmem_opts.h"``.
List of configuration options are available in the :ref:`api_lwmem_opt` section. .. tip::
If you are using *CMake* build system, define the variable ``LWMEM_OPTS_FILE`` before adding library's directory to the *CMake* project.
Variable must contain the path to the user options file. If not provided and to avoid build error, one will be generated in the build directory.
Configuration options list is available available in the :ref:`api_lwmem_opt` section.
If any option is about to be modified, it should be done in configuration file If any option is about to be modified, it should be done in configuration file
.. literalinclude:: ../../lwmem/src/include/lwmem/lwmem_opts_template.h .. literalinclude:: ../../lwmem/src/include/lwmem/lwmem_opts_template.h

View File

@ -16,7 +16,7 @@ LwMEM is lightweight dynamic memory manager optimized for embedded systems.
Features Features
^^^^^^^^ ^^^^^^^^
* Written in ANSI C99, compatible with ``size_t`` for size data types * Written in C (C11), compatible with ``size_t`` for size data types
* Implements standard C library functions for memory allocation, malloc, calloc, realloc and free * Implements standard C library functions for memory allocation, malloc, calloc, realloc and free
* Uses *first-fit* algorithm to search for free block * Uses *first-fit* algorithm to search for free block
* Supports multiple allocation instances to split between memories and/or CPU cores * Supports multiple allocation instances to split between memories and/or CPU cores
@ -25,6 +25,7 @@ Features
* Supports embedded applications with fragmented memories * Supports embedded applications with fragmented memories
* Supports automotive applications * Supports automotive applications
* Supports advanced free/realloc algorithms to optimize memory usage * Supports advanced free/realloc algorithms to optimize memory usage
* **Since v2.2.0** Supports light implementation with allocation only
* Operating system ready, thread-safe API * Operating system ready, thread-safe API
* C++ wrapper functions * C++ wrapper functions
* User friendly MIT license * User friendly MIT license
@ -67,6 +68,7 @@ Table of contents
api-reference/index api-reference/index
examples/index examples/index
changelog/index changelog/index
authors/index
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
@ -78,7 +80,7 @@ Table of contents
LwESP - ESP-AT library <https://github.com/MaJerle/lwesp> LwESP - ESP-AT library <https://github.com/MaJerle/lwesp>
LwEVT - Event manager <https://github.com/MaJerle/lwevt> LwEVT - Event manager <https://github.com/MaJerle/lwevt>
LwGPS - GPS NMEA parser <https://github.com/MaJerle/lwgps> LwGPS - GPS NMEA parser <https://github.com/MaJerle/lwgps>
LwGSM - GSM-AT library <https://github.com/MaJerle/lwgsm> LwCELL - Cellular modem host AT library <https://github.com/MaJerle/lwcell>
LwJSON - JSON parser <https://github.com/MaJerle/lwjson> LwJSON - JSON parser <https://github.com/MaJerle/lwjson>
LwMEM - Memory manager <https://github.com/MaJerle/lwmem> LwMEM - Memory manager <https://github.com/MaJerle/lwmem>
LwOW - OneWire with UART <https://github.com/MaJerle/lwow> LwOW - OneWire with UART <https://github.com/MaJerle/lwow>
@ -87,3 +89,4 @@ Table of contents
LwRB - Ring buffer <https://github.com/MaJerle/lwrb> LwRB - Ring buffer <https://github.com/MaJerle/lwrb>
LwSHELL - Shell <https://github.com/MaJerle/lwshell> LwSHELL - Shell <https://github.com/MaJerle/lwshell>
LwUTIL - Utility functions <https://github.com/MaJerle/lwutil> LwUTIL - Utility functions <https://github.com/MaJerle/lwutil>
LwWDG - RTOS task watchdog <https://github.com/MaJerle/lwwdg>

View File

@ -1,7 +1,8 @@
breathe>=4.9.1
colorama
docutils==0.16
sphinx>=3.5.1 sphinx>=3.5.1
breathe>=4.9.1
urllib3==1.26.18
docutils==0.16
colorama
sphinx_rtd_theme>=1.0.0 sphinx_rtd_theme>=1.0.0
sphinx-tabs sphinx-tabs
sphinxcontrib-svg2pdfconverter sphinxcontrib-svg2pdfconverter

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -9,4 +9,5 @@ User manual
how-it-works how-it-works
instances instances
realloc-algorithm realloc-algorithm
light-version
thread-safety thread-safety

View File

@ -0,0 +1,19 @@
.. _light_version:
LwMEM light implementation
==========================
When system is super memory constrained or when system only requires memory allocation at initialization stage,
it is possible to put the library into *light* mode by controlling the :c:macro:`LWMEM_CFG_FULL` user configuration option
When *full* mode is disabled, user must be aware of some contraints:
* It is only possible to allocate memory (no free, no realloc)
* It is only possible to use one (``1``) memory region. When assigning the memory with more than one region, function will return an error.
.. tip::
Light mode is useful for opaque types that are returned to user and must be allocated on the heap.
These are typically allocated at initialization stage and never freed during program execution.
.. toctree::
:maxdepth: 2

View File

@ -1,5 +1,5 @@
{ {
"version": "2.1.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"type": "cppbuild", "type": "cppbuild",

View File

@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
message("Entering ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt")
# #
# Core project settings # Core project settings
# #
@ -223,5 +221,3 @@ add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}> ${EXECUTABLE}.bin COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}> ${EXECUTABLE}.bin
) )
message("Exiting ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt")

View File

@ -4,12 +4,15 @@ set(CMAKE_SYSTEM_PROCESSOR arm)
# Some default GCC settings # Some default GCC settings
# arm-none-eabi- must be part of path environment # arm-none-eabi- must be part of path environment
set(TOOLCHAIN_PREFIX arm-none-eabi-) set(TOOLCHAIN_PREFIX arm-none-eabi-)
set(FLAGS "-fdata-sections -ffunction-sections --specs=nano.specs -Wl,--gc-sections") set(FLAGS "-fdata-sections -ffunction-sections -Wl,--gc-sections")
set(CPP_FLAGS "-fno-rtti -fno-exceptions -fno-threadsafe-statics") set(CPP_FLAGS "${FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc ${FLAGS}) set(CMAKE_C_FLAGS ${FLAGS})
set(CMAKE_CXX_FLAGS ${CPP_FLAGS})
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++ ${FLAGS} ${CPP_FLAGS}) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size) set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size)

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -1,5 +1,5 @@
{ {
"version": "2.1.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"type": "cppbuild", "type": "cppbuild",

View File

@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
message("Entering ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt")
# #
# Core project settings # Core project settings
# #
@ -207,5 +205,3 @@ add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}> ${EXECUTABLE}.bin COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${EXECUTABLE}> ${EXECUTABLE}.bin
) )
message("Exiting ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt")

View File

@ -4,12 +4,15 @@ set(CMAKE_SYSTEM_PROCESSOR arm)
# Some default GCC settings # Some default GCC settings
# arm-none-eabi- must be part of path environment # arm-none-eabi- must be part of path environment
set(TOOLCHAIN_PREFIX arm-none-eabi-) set(TOOLCHAIN_PREFIX arm-none-eabi-)
set(FLAGS "-fdata-sections -ffunction-sections --specs=nano.specs -Wl,--gc-sections") set(FLAGS "-fdata-sections -ffunction-sections -Wl,--gc-sections")
set(CPP_FLAGS "-fno-rtti -fno-exceptions -fno-threadsafe-statics") set(CPP_FLAGS "${FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics")
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc ${FLAGS}) set(CMAKE_C_FLAGS ${FLAGS})
set(CMAKE_CXX_FLAGS ${CPP_FLAGS})
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++ ${FLAGS} ${CPP_FLAGS}) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size) set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size)

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -1,5 +1,5 @@
{ {
"version": "2.1.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"type": "cppbuild", "type": "cppbuild",

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation

View File

@ -1,6 +1,6 @@
{ {
"name": "LwMEM", "name": "LwMEM",
"version": "2.1.0", "version": "2.2.0",
"description": "Lightweight dynamic memory manager optimized for embedded systems", "description": "Lightweight dynamic memory manager optimized for embedded systems",
"keywords": "lwmem, memory, dynamic, heap, malloc, calloc, realloc, free, lightweight, manager, embedded, stm32, win32", "keywords": "lwmem, memory, dynamic, heap, malloc, calloc, realloc, free, lightweight, manager, embedded, stm32, win32",
"repository": { "repository": {
@ -29,5 +29,8 @@
"build", "build",
"**/build" "**/build"
] ]
},
"build": {
"includeDir": "lwmem/src/include"
} }
} }

View File

@ -1,23 +1,3 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
# Debug message include(${CMAKE_CURRENT_LIST_DIR}/library.cmake)
message("Entering ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt")
# Register core library
add_library(lwmem INTERFACE)
target_sources(lwmem PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lwmem/lwmem.c)
target_include_directories(lwmem INTERFACE ${CMAKE_CURRENT_LIST_DIR}/src/include)
if (DEFINED LWMEM_SYS_PORT)
target_sources(lwmem PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/system/lwmem_sys_${LWMEM_SYS_PORT}.c)
endif()
# Register core library with C++ extensions
add_library(lwmem_cpp INTERFACE)
target_sources(lwmem_cpp PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lwmem/lwmem.cpp)
target_include_directories(lwmem_cpp INTERFACE ${CMAKE_CURRENT_LIST_DIR}/src/include)
# Register other modules
# Debug message
message("Exiting ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt")

64
lwmem/library.cmake Normal file
View File

@ -0,0 +1,64 @@
#
# LIB_PREFIX: LWMEM
#
# This file provides set of variables for end user
# and also generates one (or more) libraries, that can be added to the project using target_link_libraries(...)
#
# Before this file is included to the root CMakeLists file (using include() function), user can set some variables:
#
# LWMEM_SYS_PORT: If defined, it will include port source file from the library.
# LWMEM_OPTS_FILE: If defined, it is the path to the user options file. If not defined, one will be generated for you automatically
# LWMEM_COMPILE_OPTIONS: If defined, it provide compiler options for generated library.
# LWMEM_COMPILE_DEFINITIONS: If defined, it provides "-D" definitions to the library build
#
# Custom include directory
set(LWMEM_CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib_inc)
# Library core sources
set(lwmem_core_SRCS
${CMAKE_CURRENT_LIST_DIR}/src/lwmem/lwmem.c
)
# C++ extension
set(lwmem_core_cpp_SRCS
${CMAKE_CURRENT_LIST_DIR}/src/lwmem/lwmem.cpp
)
# Setup include directories
set(lwmem_include_DIRS
${CMAKE_CURRENT_LIST_DIR}/src/include
${LWMEM_CUSTOM_INC_DIR}
)
# Add system port
if(DEFINED LWMEM_SYS_PORT)
set(lwmem_core_SRCS ${lwmem_core_SRCS}
${CMAKE_CURRENT_LIST_DIR}/src/system/lwmem_sys_${LWMEM_SYS_PORT}.c
)
endif()
# Register core library
add_library(lwmem)
target_sources(lwmem PRIVATE ${lwmem_core_SRCS})
target_include_directories(lwmem PUBLIC ${lwmem_include_DIRS})
target_compile_options(lwmem PRIVATE ${LWMEM_COMPILE_OPTIONS})
target_compile_definitions(lwmem PRIVATE ${LWMEM_COMPILE_DEFINITIONS})
# Register core library with C++ extensions
add_library(lwmem_cpp)
target_sources(lwmem_cpp PRIVATE ${lwmem_core_SRCS})
target_include_directories(lwmem_cpp PUBLIC ${lwmem_include_DIRS})
target_compile_options(lwmem_cpp PRIVATE ${LWMEM_COMPILE_OPTIONS})
target_compile_definitions(lwmem_cpp PRIVATE ${LWMEM_COMPILE_DEFINITIONS})
target_link_libraries(lwmem_cpp PUBLIC lwmem)
# Create config file if user didn't provide one info himself
if(NOT LWMEM_OPTS_FILE)
message(STATUS "Using default lwmem_opts.h file")
set(LWMEM_OPTS_FILE ${CMAKE_CURRENT_LIST_DIR}/src/include/lwmem/lwmem_opts_template.h)
else()
message(STATUS "Using custom lwmem_opts.h file from ${LWMEM_OPTS_FILE}")
endif()
configure_file(${LWMEM_OPTS_FILE} ${LWMEM_CUSTOM_INC_DIR}/lwmem_opts.h COPYONLY)

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -29,12 +29,13 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#ifndef LWMEM_HDR_H #ifndef LWMEM_HDR_H
#define LWMEM_HDR_H #define LWMEM_HDR_H
#include <limits.h> #include <limits.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "lwmem/lwmem_opt.h" #include "lwmem/lwmem_opt.h"
@ -59,33 +60,39 @@ extern "C" {
* \brief Memory block structure * \brief Memory block structure
*/ */
typedef struct lwmem_block { typedef struct lwmem_block {
struct lwmem_block* struct lwmem_block* next; /*!< Next free memory block on linked list.
next; /*!< Next free memory block on linked list. Set to \ref LWMEM_BLOCK_ALLOC_MARK when block is allocated and in use */ Set to \ref LWMEM_BLOCK_ALLOC_MARK when block is allocated and in use */
size_t size; /*!< Size of block, including metadata part. size_t size; /*!< Size of block, including metadata part.
MSB bit is set to `1` when block is allocated and in use, MSB bit is set to `1` when block is allocated and in use,
or `0` when block is considered free */ or `0` when block is considered free */
} lwmem_block_t; } lwmem_block_t;
/** /**
* \brief Statistics structure * \brief Statistics structure
*/ */
typedef struct { typedef struct {
uint32_t mem_size_bytes; /*!< Total memory size of all regions combined */ uint32_t mem_size_bytes; /*!< Total memory size of all regions combined */
uint32_t mem_available_bytes; /*!< Free memory available for allocation */ uint32_t mem_available_bytes; /*!< Free memory available for allocation */
uint32_t uint32_t minimum_ever_mem_available_bytes; /*!< Minimum amount of total free memory there has been
minimum_ever_mem_available_bytes; /*!< Minimum amount of total free memory there has been in the heap since the system booted. */ in the heap since the system booted. */
uint32_t nr_alloc; /*!< Number of all allocated blocks in single instance */ uint32_t nr_alloc; /*!< Number of all allocated blocks in single instance */
uint32_t nr_free; /*!< Number of frees in the LwMEM instance */ uint32_t nr_free; /*!< Number of frees in the LwMEM instance */
} lwmem_stats_t; } lwmem_stats_t;
/** /**
* \brief LwMEM main structure * \brief LwMEM main structure
*/ */
typedef struct lwmem { typedef struct lwmem {
lwmem_block_t start_block; /*!< Holds beginning of memory allocation regions */
lwmem_block_t* end_block; /*!< Pointer to the last memory location in regions linked list */
size_t mem_available_bytes; /*!< Memory size available for allocation */ size_t mem_available_bytes; /*!< Memory size available for allocation */
size_t mem_regions_count; /*!< Number of regions used for allocation */ #if LWMEM_CFG_FULL
lwmem_block_t start_block; /*!< Holds beginning of memory allocation regions */
lwmem_block_t* end_block; /*!< Pointer to the last memory location in regions linked list */
size_t mem_regions_count; /*!< Number of regions used for allocation */
#else
uint8_t* mem_next_available_ptr; /*!< Pointer for next allocation */
uint8_t is_initialized; /*!< Set to `1` when initialized */
#endif
#if LWMEM_CFG_OS || __DOXYGEN__ #if LWMEM_CFG_OS || __DOXYGEN__
LWMEM_CFG_OS_MUTEX_HANDLE mutex; /*!< System mutex for OS */ LWMEM_CFG_OS_MUTEX_HANDLE mutex; /*!< System mutex for OS */
#endif /* LWMEM_CFG_OS || __DOXYGEN__ */ #endif /* LWMEM_CFG_OS || __DOXYGEN__ */
@ -94,7 +101,7 @@ typedef struct lwmem {
#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */ #endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
#if defined(LWMEM_DEV) && !__DOXYGEN__ #if defined(LWMEM_DEV) && !__DOXYGEN__
lwmem_block_t start_block_first_use; /*!< Value of start block for very first time. lwmem_block_t start_block_first_use; /*!< Value of start block for very first time.
This is used only during validation process and is removed in final use */ This is used only during validation process and is removed in final use */
#endif /* defined(LWMEM_DEV) && !__DOXYGEN__ */ #endif /* defined(LWMEM_DEV) && !__DOXYGEN__ */
} lwmem_t; } lwmem_t;
@ -109,107 +116,29 @@ typedef struct {
size_t lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions); size_t lwmem_assignmem_ex(lwmem_t* lwobj, const lwmem_region_t* regions);
void* lwmem_malloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t size); void* lwmem_malloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t size);
void* lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitems, const size_t size); void* lwmem_calloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, const size_t nitems, const size_t size);
#if LWMEM_CFG_FULL || __DOXYGEN__
void* lwmem_realloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, void* const ptr, const size_t size); void* lwmem_realloc_ex(lwmem_t* lwobj, const lwmem_region_t* region, void* const ptr, const size_t size);
uint8_t lwmem_realloc_s_ex(lwmem_t* lwobj, const lwmem_region_t* region, void** const ptr, const size_t size); int lwmem_realloc_s_ex(lwmem_t* lwobj, const lwmem_region_t* region, void** const ptr, const size_t size);
void lwmem_free_ex(lwmem_t* lwobj, void* const ptr); void lwmem_free_ex(lwmem_t* lwobj, void* const ptr);
void lwmem_free_s_ex(lwmem_t* lwobj, void** const ptr); void lwmem_free_s_ex(lwmem_t* lwobj, void** const ptr);
size_t lwmem_get_size_ex(lwmem_t* lwobj, void* ptr); size_t lwmem_get_size_ex(lwmem_t* lwobj, void* ptr);
#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
#if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ #if LWMEM_CFG_ENABLE_STATS || __DOXYGEN__
void lwmem_get_stats_ex(lwmem_t* lwobj, lwmem_stats_t* stats); void lwmem_get_stats_ex(lwmem_t* lwobj, lwmem_stats_t* stats);
void lwmem_get_size(lwmem_stats_t* stats);
#endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */ #endif /* LWMEM_CFG_ENABLE_STATS || __DOXYGEN__ */
/** size_t lwmem_assignmem(const lwmem_region_t* regions);
* \note This is a wrapper for \ref lwmem_assignmem_ex function. void* lwmem_malloc(size_t size);
* It operates in default LwMEM instance and uses first available region for memory operations void* lwmem_calloc(size_t nitems, size_t size);
* \param[in] regions: Pointer to array of regions with address and respective size.
* Regions must be in increasing order (start address) and must not overlap in-between.
* Last region entry must have address `NULL` and size set to `0`
* \code{.c}
//Example definition
lwmem_region_t regions[] = {
{ (void *)0x10000000, 0x1000 }, //Region starts at address 0x10000000 and is 0x1000 bytes long
{ (void *)0x20000000, 0x2000 }, //Region starts at address 0x20000000 and is 0x2000 bytes long
{ (void *)0x30000000, 0x3000 }, //Region starts at address 0x30000000 and is 0x3000 bytes long
{ NULL, 0 } //Array termination indicator
}
\endcode
* \return `0` on failure, number of final regions used for memory manager on success
*/
#define lwmem_assignmem(regions) lwmem_assignmem_ex(NULL, (regions))
/** #if LWMEM_CFG_FULL || __DOXYGEN__
* \note This is a wrapper for \ref lwmem_malloc_ex function. void* lwmem_realloc(void* ptr, size_t size);
* It operates in default LwMEM instance and uses first available region for memory operations int lwmem_realloc_s(void** ptr2ptr, size_t size);
* \param[in] size: Size to allocate in units of bytes void lwmem_free(void* ptr);
* \return Pointer to allocated memory on success, `NULL` otherwise void lwmem_free_s(void** ptr2ptr);
* \note This function is thread safe when \ref LWMEM_CFG_OS is enabled size_t lwmem_get_size(void* ptr);
*/ #endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
#define lwmem_malloc(size) lwmem_malloc_ex(NULL, NULL, (size))
/**
* \note This is a wrapper for \ref lwmem_calloc_ex function.
* It operates in default LwMEM instance and uses first available region for memory operations
* \param[in] nitems: Number of elements to be allocated
* \param[in] size: Size of each element, in units of bytes
* \return Pointer to allocated memory on success, `NULL` otherwise
* \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
*/
#define lwmem_calloc(nitems, size) lwmem_calloc_ex(NULL, NULL, (nitems), (size))
/**
* \note This is a wrapper for \ref lwmem_realloc_ex function.
* It operates in default LwMEM instance and uses first available region for memory operations
* \param[in] ptr: Memory block previously allocated with one of allocation functions.
* It may be set to `NULL` to create new clean allocation
* \param[in] size: Size of new memory to reallocate
* \return Pointer to allocated memory on success, `NULL` otherwise
* \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
*/
#define lwmem_realloc(ptr, size) lwmem_realloc_ex(NULL, NULL, (ptr), (size))
/**
* \note This is a wrapper for \ref lwmem_realloc_s_ex function.
* It operates in default LwMEM instance and uses first available region for memory operations
* \param[in] ptrptr: Pointer to pointer to allocated memory. Must not be set to `NULL`.
* If reallocation is successful, it modifies pointer's pointing address,
* or sets it to `NULL` in case of `free` operation
* \param[in] size: New requested size in bytes
* \return `1` if successfully reallocated, `0` otherwise
* \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
*/
#define lwmem_realloc_s(ptrptr, size) lwmem_realloc_s_ex(NULL, NULL, (ptrptr), (size))
/**
* \note This is a wrapper for \ref lwmem_free_ex function.
* It operates in default LwMEM instance and uses first available region for memory operations
* \param[in] ptr: Memory to free. `NULL` pointer is valid input
* \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
*/
#define lwmem_free(ptr) lwmem_free_ex(NULL, (ptr))
/**
* \note This is a wrapper for \ref lwmem_free_s_ex function.
* It operates in default LwMEM instance and uses first available region for memory operations
* \param[in] ptrptr: Pointer to pointer to allocated memory.
* When set to non `NULL`, pointer is freed and set to `NULL`
* \note This function is thread safe when \ref LWMEM_CFG_OS is enabled
*/
#define lwmem_free_s(ptrptr) lwmem_free_s_ex(NULL, (ptrptr))
/**
* \note This is a wrapper for \ref lwmem_get_size_ex function.
* It operates in default LwMEM instance and uses first available region for memory operations
* \param[in] ptr: Pointer to allocated memory
* \return Block size for user in units of bytes
*/
#define lwmem_get_size(ptr) lwmem_get_size_ex(NULL, (ptr))
/**
* \note This is a wrapper for \ref lwmem_get_stats_ex function.
* It operates in default LwMEM instance
* \param[in] ptr: Pointer to lwmem_stats_t to store result
*/
#define lwmem_get_stats(stats) lwmem_get_stats_ex(NULL, (stats))
#if defined(LWMEM_DEV) && !__DOXYGEN__ #if defined(LWMEM_DEV) && !__DOXYGEN__
unsigned char lwmem_debug_create_regions(lwmem_region_t** regs_out, size_t count, size_t size); unsigned char lwmem_debug_create_regions(lwmem_region_t** regs_out, size_t count, size_t size);

View File

@ -29,7 +29,7 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#ifndef LWMEM_HDR_HPP #ifndef LWMEM_HDR_HPP
#define LWMEM_HDR_HPP #define LWMEM_HDR_HPP
@ -93,6 +93,7 @@ class LwmemLight {
return lwmem_calloc_ex(&m_lw, nullptr, nitems, size); return lwmem_calloc_ex(&m_lw, nullptr, nitems, size);
} }
#if LWMEM_CFG_FULL || __DOXYGEN__
/** /**
* \brief Reallocate block of memory * \brief Reallocate block of memory
* \param ptr: Pointer to previously allocated memory block * \param ptr: Pointer to previously allocated memory block
@ -114,6 +115,7 @@ class LwmemLight {
free(void* ptr) { free(void* ptr) {
lwmem_free_ex(&m_lw, ptr); lwmem_free_ex(&m_lw, ptr);
} }
#endif /* LWMEM_CFG_FULL || __DOXYGEN__ */
private: private:
/* Delete unused constructors */ /* Delete unused constructors */

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -29,7 +29,7 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#ifndef LWMEM_OPT_HDR_H #ifndef LWMEM_OPT_HDR_H
#define LWMEM_OPT_HDR_H #define LWMEM_OPT_HDR_H
@ -82,7 +82,27 @@ extern "C" {
* Usually alignment of `4` bytes fits to all processors. * Usually alignment of `4` bytes fits to all processors.
*/ */
#ifndef LWMEM_CFG_ALIGN_NUM #ifndef LWMEM_CFG_ALIGN_NUM
#define LWMEM_CFG_ALIGN_NUM ((size_t)4) #define LWMEM_CFG_ALIGN_NUM 4
#endif
/**
* \brief Enables `1` or disables `0` full memory management support.
*
* When enabled (default config), library supports allocation, reallocation and freeing of the memory.
* - Memory [c]allocation
* - Memory reallocation
* - Memory allocation in user defined memory regions
* - Memory freeing
*
* When disabled, library only supports allocation and does not provide any other service.
* - Its purpose is for memory allocation at the start of firmware initialization only
*
* \note When disabled, statistics functionaltiy is not available
* and only one region is supported (for now, may be updated later).
* API to allocate memory remains the same as for full configuration.
*/
#ifndef LWMEM_CFG_FULL
#define LWMEM_CFG_FULL 1
#endif #endif
/** /**
@ -103,6 +123,33 @@ extern "C" {
#define LWMEM_CFG_ENABLE_STATS 0 #define LWMEM_CFG_ENABLE_STATS 0
#endif #endif
/**
* \brief Memory set function
*
* \note Function footprint is the same as \ref memset
*/
#ifndef LWMEM_MEMSET
#define LWMEM_MEMSET(dst, val, len) memset((dst), (val), (len))
#endif
/**
* \brief Memory copy function
*
* \note Function footprint is the same as \ref memcpy
*/
#ifndef LWMEM_MEMCPY
#define LWMEM_MEMCPY(dst, src, len) memcpy((dst), (src), (len))
#endif
/**
* \brief Memory move function
*
* \note Function footprint is the same as \ref memmove
*/
#ifndef LWMEM_MEMMOVE
#define LWMEM_MEMMOVE(dst, src, len) memmove((dst), (src), (len))
#endif
/** /**
* \} * \}
*/ */

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -29,7 +29,7 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#ifndef LWMEM_OPTS_HDR_H #ifndef LWMEM_OPTS_HDR_H
#define LWMEM_OPTS_HDR_H #define LWMEM_OPTS_HDR_H

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -29,7 +29,7 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#ifndef LWMEM_SYS_HDR_H #ifndef LWMEM_SYS_HDR_H
#define LWMEM_SYS_HDR_H #define LWMEM_SYS_HDR_H

File diff suppressed because it is too large Load Diff

View File

@ -29,5 +29,5 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -29,7 +29,7 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#include "system/lwmem_sys.h" #include "system/lwmem_sys.h"

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -29,7 +29,7 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#include "system/lwmem_sys.h" #include "system/lwmem_sys.h"

View File

@ -4,7 +4,7 @@
*/ */
/* /*
* Copyright (c) 2023 Tilen MAJERLE * Copyright (c) 2024 Tilen MAJERLE
* *
* Permission is hereby granted, free of charge, to any person * Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation * obtaining a copy of this software and associated documentation
@ -29,13 +29,13 @@
* This file is part of LwMEM - Lightweight dynamic memory manager library. * This file is part of LwMEM - Lightweight dynamic memory manager library.
* *
* Author: Tilen MAJERLE <tilen@majerle.eu> * Author: Tilen MAJERLE <tilen@majerle.eu>
* Version: v2.1.0 * Version: v2.2.0
*/ */
#include "system/lwmem_sys.h" #include "system/lwmem_sys.h"
#if LWMEM_CFG_OS && !__DOXYGEN__ #if LWMEM_CFG_OS && !__DOXYGEN__
#include "Windows.h" #include "windows.h"
uint8_t uint8_t
lwmem_sys_mutex_create(LWMEM_CFG_OS_MUTEX_HANDLE* m) { lwmem_sys_mutex_create(LWMEM_CFG_OS_MUTEX_HANDLE* m) {
@ -50,12 +50,7 @@ lwmem_sys_mutex_isvalid(LWMEM_CFG_OS_MUTEX_HANDLE* m) {
uint8_t uint8_t
lwmem_sys_mutex_wait(LWMEM_CFG_OS_MUTEX_HANDLE* m) { lwmem_sys_mutex_wait(LWMEM_CFG_OS_MUTEX_HANDLE* m) {
DWORD ret; return WaitForSingleObject(*m, INFINITE) == WAIT_OBJECT_0;
ret = WaitForSingleObject(*m, INFINITE);
if (ret != WAIT_OBJECT_0) {
return 0;
}
return 1;
} }
uint8_t uint8_t

View File

@ -1,70 +1,75 @@
#include "lwmem/lwmem.h"
#include <stdio.h> #include <stdio.h>
#include "lwmem/lwmem.h"
#if LWMEM_CFG_FULL
/* Assert check */ /* Assert check */
#define ASSERT(x) do { \ #define ASSERT(x) \
if (!(x)) { \ do { \
printf("Assert on line %d failed with condition (" # x ")\r\n", (int)__LINE__); \ if (!(x)) { \
} else {\ printf("Assert on line %d failed with condition (" #x ")\r\n", (int)__LINE__); \
printf("Assert on line %d passed with condition (" # x ")\r\n", (int)__LINE__); \ } else { \
}\ printf("Assert on line %d passed with condition (" #x ")\r\n", (int)__LINE__); \
} while (0) } \
} while (0)
/********************************************/ /********************************************/
/* Test case helpers */ /* Test case helpers */
#define UINT_PTR_CAST(x) ((uintptr_t)(x)) #define UINT_PTR_CAST(x) ((uintptr_t)(x))
#define IS_ALLOC_IN_REGION(ptr, region) ASSERT( \ #define IS_ALLOC_IN_REGION(ptr, region) \
UINT_PTR_CAST(ptr) >= UINT_PTR_CAST((region)->start_addr) \ ASSERT(UINT_PTR_CAST(ptr) >= UINT_PTR_CAST((region)->start_addr) \
&& UINT_PTR_CAST(ptr) < (UINT_PTR_CAST((region)->start_addr) + (region)->size) \ && UINT_PTR_CAST(ptr) < (UINT_PTR_CAST((region)->start_addr) + (region)->size))
)
/********************************************/ /********************************************/
/* Configuration for default lwmem instance */ /* Configuration for default lwmem instance */
/* Region memory declaration */ /* Region memory declaration */
uint8_t lw_mem1[1024], lw_mem2[256], lw_mem3[128]; static struct {
uint8_t m1[128];
uint8_t m2[256];
uint8_t m3[1024];
} lw_mem;
/* Regions descriptor */ /* Regions descriptor */
lwmem_region_t static lwmem_region_t lw_regions[] = {
lw_regions[] = { {lw_mem.m1, sizeof(lw_mem.m1)},
{ lw_mem3, sizeof(lw_mem3) }, {lw_mem.m2, sizeof(lw_mem.m2)},
{ lw_mem2, sizeof(lw_mem2) }, {lw_mem.m3, sizeof(lw_mem.m3)},
{ lw_mem1, sizeof(lw_mem1) }, {NULL, 0},
{ NULL, 0 }
}; };
/********************************************/ /********************************************/
/********************************************/ /********************************************/
/* Configuration for custom lwmem instance */ /* Configuration for custom lwmem instance */
/* LwMEM instance */ /* LwMEM instance */
lwmem_t lw_c; static lwmem_t lw_c;
/* Region memory declaration */ static struct {
uint8_t lw_c_mem1[1024], lw_c_mem2[256], lw_c_mem3[128]; uint8_t m1[128];
uint8_t m2[256];
uint8_t m3[1024];
} lw_mem_c;
/* Regions descriptor */ /* Regions descriptor */
lwmem_region_t static lwmem_region_t lw_c_regions[] = {
lw_c_regions[] = { {lw_mem_c.m1, sizeof(lw_mem_c.m1)},
{ lw_c_mem3, sizeof(lw_c_mem3) }, {lw_mem_c.m2, sizeof(lw_mem_c.m2)},
{ lw_c_mem2, sizeof(lw_c_mem2) }, {lw_mem_c.m3, sizeof(lw_mem_c.m3)},
{ lw_c_mem1, sizeof(lw_c_mem1) }, {NULL, 0},
{ NULL, 0 }
}; };
/********************************************/ /********************************************/
void void
lwmem_test_run(void) { lwmem_test_run(void) {
void* ptr_1, * ptr_2, * ptr_3; void *ptr_1 = NULL, *ptr_2 = NULL, *ptr_3 = NULL;
void* ptr_c_1, * ptr_c_2, * ptr_c_3; void *ptr_c_1 = NULL, *ptr_c_2 = NULL, *ptr_c_3 = NULL;
/* Initialize default lwmem instance */ /* Initialize default lwmem instance */
/* Use one of 2 possible function calls: */ /* Use one of 2 possible function calls: */
lwmem_assignmem(lw_regions); lwmem_assignmem(lw_regions);
//lwmem_assignmem_ex(NULL, lw_regions); //lwmem_assignmem_ex(NULL, lw_regions);
/* Initialize another, custom instance */
lwmem_assignmem_ex(&lw_c, lw_c_regions);
/* Regions initialized... */ /* Regions initialized... */
/********************************************/ /********************************************/
@ -73,15 +78,18 @@ lwmem_test_run(void) {
/* Allocation of 64 bytes must in in first region */ /* Allocation of 64 bytes must in in first region */
ptr_1 = lwmem_malloc(64); ptr_1 = lwmem_malloc(64);
ASSERT(ptr_1 != NULL);
IS_ALLOC_IN_REGION(ptr_1, &lw_regions[0]); IS_ALLOC_IN_REGION(ptr_1, &lw_regions[0]);
/* Allocation of 256 bytes can only be in 3rd region */ /* Allocation of 256 bytes can only be in 3rd region */
ptr_2 = lwmem_malloc(256); ptr_2 = lwmem_malloc(256);
ASSERT(ptr_2 != NULL);
IS_ALLOC_IN_REGION(ptr_2, &lw_regions[2]); IS_ALLOC_IN_REGION(ptr_2, &lw_regions[2]);
/* Allocation of 128 bytes can be in second or third region (depends on memory availability), /* Allocation of 128 bytes can be in second or third region (depends on memory availability),
but in case of these tests it can be (and should be) in second region */ but in case of these tests it can be (and should be) in second region */
ptr_3 = lwmem_malloc(128); ptr_3 = lwmem_malloc(128);
ASSERT(ptr_3 != NULL);
IS_ALLOC_IN_REGION(ptr_3, &lw_regions[1]); IS_ALLOC_IN_REGION(ptr_3, &lw_regions[1]);
/* Free all pointers to default state */ /* Free all pointers to default state */
@ -92,10 +100,12 @@ lwmem_test_run(void) {
/* Force allocation region to be used */ /* Force allocation region to be used */
/* Allocation of 16-bytes forced to 2nd region */ /* Allocation of 16-bytes forced to 2nd region */
ptr_1 = lwmem_malloc_ex(NULL, &lw_regions[1], 16); ptr_1 = lwmem_malloc_ex(NULL, &lw_regions[1], 16);
ASSERT(ptr_1 != NULL);
IS_ALLOC_IN_REGION(ptr_1, &lw_regions[1]); IS_ALLOC_IN_REGION(ptr_1, &lw_regions[1]);
/* Allocate ptr 2 in any region of default lwmem, the first available must be 1st region */ /* Allocate ptr 2 in any region of default lwmem, the first available must be 1st region */
ptr_2 = lwmem_malloc_ex(NULL, NULL, 16); ptr_2 = lwmem_malloc_ex(NULL, NULL, 16);
ASSERT(ptr_2 != NULL);
IS_ALLOC_IN_REGION(ptr_2, &lw_regions[0]); IS_ALLOC_IN_REGION(ptr_2, &lw_regions[0]);
/* Free pointers */ /* Free pointers */
@ -106,33 +116,41 @@ lwmem_test_run(void) {
/* Run tests on custom region */ /* Run tests on custom region */
/********************************************/ /********************************************/
/* Initialize another, custom instance */
lwmem_assignmem_ex(&lw_c, lw_c_regions);
/* Allocation of 64 bytes must in in first region */ /* Allocation of 64 bytes must in in first region */
ptr_c_1 = lwmem_malloc_ex(&lw_c, NULL, 64); ptr_c_1 = lwmem_malloc_ex(&lw_c, NULL, 64);
ASSERT(ptr_c_1 != NULL);
IS_ALLOC_IN_REGION(ptr_c_1, &lw_c_regions[0]); IS_ALLOC_IN_REGION(ptr_c_1, &lw_c_regions[0]);
/* Allocation of 256 bytes can only be in 3rd region */ /* Allocation of 256 bytes can only be in 3rd region */
ptr_c_2 = lwmem_malloc_ex(&lw_c, NULL, 256); ptr_c_2 = lwmem_malloc_ex(&lw_c, NULL, 256);
ASSERT(ptr_c_2 != NULL);
IS_ALLOC_IN_REGION(ptr_c_2, &lw_c_regions[2]); IS_ALLOC_IN_REGION(ptr_c_2, &lw_c_regions[2]);
/* Allocation of 128 bytes can be in second or third region (depends on memory availability), /* Allocation of 128 bytes can be in second or third region (depends on memory availability),
but in case of these tests it can be (and should be) in second region */ but in case of these tests it can be (and should be) in second region */
ptr_c_3 = lwmem_malloc_ex(&lw_c, NULL, 128); ptr_c_3 = lwmem_malloc_ex(&lw_c, NULL, 128);
ASSERT(ptr_c_3 != NULL);
IS_ALLOC_IN_REGION(ptr_c_3, &lw_c_regions[1]); IS_ALLOC_IN_REGION(ptr_c_3, &lw_c_regions[1]);
/* Free all pointers to default state */ /* Free all pointers to default state */
lwmem_free(ptr_c_1); lwmem_free(ptr_c_1);
lwmem_free(ptr_c_2); lwmem_free(ptr_c_2);
lwmem_free(ptr_c_3); lwmem_free(ptr_c_3);
printf("Done\r\n");
} }
/* For debug purposes */ /* For debug purposes */
lwmem_region_t* regions_used; static lwmem_region_t* regions_used;
size_t regions_count = 4; /* Use only 1 region for debug purposes of non-free areas */ static size_t regions_count = 4; /* Use only 1 region for debug purposes of non-free areas */
void void
lwmem_test_memory_structure(void) { lwmem_test_memory_structure(void) {
uint8_t* ptr1, *ptr2, *ptr3, *ptr4; uint8_t *ptr1, *ptr2, *ptr3, *ptr4;
uint8_t* rptr1, *rptr2, *rptr3, *rptr4; uint8_t *rptr1, *rptr2, *rptr3, *rptr4;
size_t used_regions; size_t used_regions;
/* /*
@ -156,16 +174,20 @@ lwmem_test_memory_structure(void) {
/* Test case 1, allocate 3 blocks, each of different size */ /* Test case 1, allocate 3 blocks, each of different size */
/* We know that sizeof internal metadata block is 8 bytes on win32 */ /* We know that sizeof internal metadata block is 8 bytes on win32 */
printf("\r\n\r\nAllocating 4 pointers and freeing first and third..\r\n"); printf("\r\n------------------------------------------------------------------------\r\n");
printf("Allocating 4 pointers\r\n\r\n");
ptr1 = lwmem_malloc(8); ptr1 = lwmem_malloc(8);
ptr2 = lwmem_malloc(4); ptr2 = lwmem_malloc(4);
ptr3 = lwmem_malloc(4); ptr3 = lwmem_malloc(4);
ptr4 = lwmem_malloc(16); ptr4 = lwmem_malloc(16);
lwmem_free(ptr1); /* Free but keep value for future comparison */ lwmem_debug_print(1, 1);
lwmem_free(ptr3); /* Free but keep value for future comparison */ printf("\r\n------------------------------------------------------------------------\r\n");
printf("Freeing first and third pointers\r\n\r\n");
lwmem_free(ptr1); /* Free but keep value for future comparison */
lwmem_free(ptr3); /* Free but keep value for future comparison */
lwmem_debug_print(1, 1); lwmem_debug_print(1, 1);
printf("Debug above is effectively state 3\r\n"); printf("Debug above is effectively state 3\r\n");
lwmem_debug_save_state(); /* Every restore operations rewinds here */ lwmem_debug_save_state(); /* Every restore operations rewinds here */
/* We always try to reallocate pointer ptr2 */ /* We always try to reallocate pointer ptr2 */
@ -183,7 +205,7 @@ lwmem_test_memory_structure(void) {
printf("State 3b\r\n"); printf("State 3b\r\n");
rptr2 = lwmem_realloc(ptr2, 20); rptr2 = lwmem_realloc(ptr2, 20);
lwmem_debug_print(1, 1); lwmem_debug_print(1, 1);
ASSERT(rptr2 == ptr2); ASSERT(rptr2 == ptr1);
/* Create 3c case */ /* Create 3c case */
printf("\r\n------------------------------------------------------------------------\r\n"); printf("\r\n------------------------------------------------------------------------\r\n");
@ -200,4 +222,11 @@ lwmem_test_memory_structure(void) {
rptr4 = lwmem_realloc(ptr2, 36); rptr4 = lwmem_realloc(ptr2, 36);
lwmem_debug_print(1, 1); lwmem_debug_print(1, 1);
ASSERT(rptr4 != ptr1 && rptr4 != ptr2 && rptr4 != ptr3 && rptr4 != ptr4); ASSERT(rptr4 != ptr1 && rptr4 != ptr2 && rptr4 != ptr3 && rptr4 != ptr4);
}
printf("ptr1: %08X\r\nptr2: %08X\r\nptr3: %08X\r\nptr4: %08X\r\n", (unsigned)ptr1, (unsigned)ptr2, (unsigned)ptr3,
(unsigned)ptr4);
printf("r_ptr1: %08X\r\nr_ptr2: %08X\r\nr_ptr3: %08X\r\nr_ptr4: %08X\r\n", (unsigned)rptr1, (unsigned)rptr2,
(unsigned)rptr3, (unsigned)rptr4);
}
#endif /* LWMEM_CFG_FULL */

68
tests/lwmem_test_simple.c Normal file
View File

@ -0,0 +1,68 @@
#include <stdio.h>
#include "lwmem/lwmem.h"
#if !LWMEM_CFG_FULL
/* Assert check */
#define ASSERT(x) \
do { \
if (!(x)) { \
printf("Assert on line %d failed with condition (" #x ")\r\n", (int)__LINE__); \
} else { \
printf("Assert on line %d passed with condition (" #x ")\r\n", (int)__LINE__); \
} \
} while (0)
/********************************************/
/* Configuration for default lwmem instance */
/* Region memory declaration */
static uint8_t lw_mem1[1024], lw_mem2[256], lw_mem3[128];
/* Regions descriptor */
static lwmem_region_t lw_regions_too_many[] = {
{lw_mem3, sizeof(lw_mem3)},
{lw_mem2, sizeof(lw_mem2)},
{lw_mem1, sizeof(lw_mem1)},
{NULL, 0},
};
/********************************************/
/********************************************/
/* Region memory declaration */
/* Use uint32 for alignment reasons */
static uint32_t lw_c_mem1[64 / 4];
/* Regions descriptor */
static lwmem_region_t lw_c_regions[] = {
{lw_c_mem1, sizeof(lw_c_mem1)},
{NULL, 0},
};
/********************************************/
void
lwmem_test_simple_run(void) {
size_t retval;
void* ptr;
/* Should fail -> too many regions */
retval = lwmem_assignmem(lw_regions_too_many);
ASSERT(retval == 0);
/* Should fly now */
retval = lwmem_assignmem(lw_c_regions);
ASSERT(retval != 0);
/* We have 64 bytes from now on */
/* Try to allocate memory */
ptr = lwmem_malloc(32);
ASSERT(ptr != NULL);
ptr = lwmem_malloc(32);
ASSERT(ptr != NULL);
ptr = lwmem_malloc(4);
ASSERT(ptr == NULL);
}
#endif /* !LWMEM_CFG_FULL */