diff --git a/README.md b/README.md index 9db9bce..e926732 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ which makes it suitable for use in high-integrity embedded systems. The codebase is implemented in C99/C11 following MISRA C:2012, with several intended deviations which are unavoidable due to the fact that a memory allocator has to rely on inherently unsafe operations to fulfill its purpose. -The codebase is extremely compact (<500 SLoC) and is therefore trivial to validate. +The codebase is extremely compact (<500 LoC) and is therefore trivial to validate. The allocator is designed to be portable across all conventional architectures, from 8-bit to 64-bit systems. Multi-threaded environments are supported with the help of external synchronization hooks provided by the application. @@ -173,15 +173,18 @@ and its internal data structures are not damaged. ### Build configuration options -The preprocessor options given below can be overridden (e.g., using the `-D` compiler flag, depending on the compiler) -to fine-tune the implementation. +The preprocessor options given below can be overridden to fine-tune the implementation. None of them are mandatory to use. +#### O1HEAP_CONFIG_HEADER + +Define this optional macro like `O1HEAP_CONFIG_HEADER="path/to/my_o1heap_config.h"` to pass build configuration macros. +This is useful because some build systems do not allow passing function-like macros via command line flags. + #### O1HEAP_ASSERT(x) The macro `O1HEAP_ASSERT(x)` can be defined to customize the assertion handling or to disable it. To disable assertion checks, the macro should expand into `(void)(x)`. - If not specified, the macro expands into the standard assertion check macro `assert(x)` as defined in ``. #### O1HEAP_LIKELY(x) @@ -195,7 +198,7 @@ or into the original expression `(x)` if no such hinting is desired. If not specified, the macro expands as follows: - For some well-known compilers the macro automatically expands into appropriate branch weighting intrinsics. -For example, for GCC, Clang, and ARM Compiler, it expands into `__builtin_expect((x), 1)`. + For example, for GCC, Clang, and ARM Compiler, it expands into `__builtin_expect((x), 1)`. - For other (unknown) compilers it expands into the original expression with no modifications: `(x)`. ## Development @@ -256,6 +259,17 @@ An exception applies for the case of false-positive (invalid) warnings -- those - [Dynamic Memory Allocation In SQLite](https://sqlite.org/malloc.html) -- on Robson proof and deterministic fragmentation. - *[Russian]* [Динамическая память в системах жёсткого реального времени](https://habr.com/ru/post/486650/) -- issues with dynamic memory allocation in modern embedded RTOS and related popular misconceptions. +## Changelog + +### v2.0 + +- Remove critical section hooks to enhance MISRA conformance [#4](https://github.com/pavel-kirienko/o1heap/issues/4) +- Add support for config header via `O1HEAP_CONFIG_HEADER` [#5](https://github.com/pavel-kirienko/o1heap/issues/5) + +### v1.0 + +The first release. + ## License The library is available under the terms of the MIT License. diff --git a/o1heap/o1heap.c b/o1heap/o1heap.c index 53801b1..37b5f7e 100644 --- a/o1heap/o1heap.c +++ b/o1heap/o1heap.c @@ -19,6 +19,12 @@ // ---------------------------------------- BUILD CONFIGURATION OPTIONS ---------------------------------------- +/// Define this macro to include build configuration header. This is an alternative to the -D compiler flag. +/// Usage example with CMake: "-DO1HEAP_CONFIG_HEADER=\"${CMAKE_CURRENT_SOURCE_DIR}/my_o1heap_config.h\"" +#ifdef O1HEAP_CONFIG_HEADER +# include O1HEAP_CONFIG_HEADER +#endif + /// The assertion macro defaults to the standard assert(). /// It can be overridden to manually suppress assertion checks or use a different error handling policy. #ifndef O1HEAP_ASSERT @@ -27,8 +33,6 @@ #endif /// Branch probability annotations are used to improve the worst case execution time (WCET). They are entirely optional. -/// A stock implementation is provided for some well-known compilers; for other compilers it defaults to nothing. -/// If you are using a different compiler, consider overriding this value. #ifndef O1HEAP_LIKELY # if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) // Intentional violation of MISRA: branch hinting macro cannot be replaced with a function definition. @@ -39,9 +43,7 @@ #endif /// This option is used for testing only. Do not use in production. -#if defined(O1HEAP_EXPOSE_INTERNALS) && O1HEAP_EXPOSE_INTERNALS -# define O1HEAP_PRIVATE -#else +#ifndef O1HEAP_PRIVATE # define O1HEAP_PRIVATE static inline #endif diff --git a/tests/.idea/dictionaries/pavel.xml b/tests/.idea/dictionaries/pavel.xml index db13b8e..f32082d 100644 --- a/tests/.idea/dictionaries/pavel.xml +++ b/tests/.idea/dictionaries/pavel.xml @@ -12,6 +12,7 @@ unbin wcet wcmc + wmissing \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e4de496..0827fe5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -78,21 +78,24 @@ function(gen_test name files compile_definitions compile_features compile_flags add_test("run_${name}" "${name}" --rng-seed time) endfunction() -function(gen_test_matrix name files compile_definitions compile_flags) - gen_test("${name}_c99_x64" "${files}" "${compile_definitions}" c_std_99 "${compile_flags} -m64" "-m64") - gen_test("${name}_c99_x32" "${files}" "${compile_definitions}" c_std_99 "${compile_flags} -m32" "-m32") - gen_test("${name}_c11_x64" "${files}" "${compile_definitions}" c_std_11 "${compile_flags} -m64" "-m64") - gen_test("${name}_c11_x32" "${files}" "${compile_definitions}" c_std_11 "${compile_flags} -m32" "-m32") +function(gen_test_matrix name files compile_definitions) + gen_test("${name}_c99_x64" "${files}" "${compile_definitions}" c_std_99 "-m64" "-m64") + gen_test("${name}_c99_x32" "${files}" "${compile_definitions}" c_std_99 "-m32" "-m32") + gen_test("${name}_c11_x64" "${files}" "${compile_definitions}" c_std_11 "-m64" "-m64") + gen_test("${name}_c11_x32" "${files}" "${compile_definitions}" c_std_11 "-m32" "-m32") # Coverage is only available for GCC builds. if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_BUILD_TYPE STREQUAL "Debug")) - gen_test("${name}_cov" - "${files}" - "${compile_definitions}" - c_std_11 - "${compile_flags} -g -O0 --coverage" - "--coverage") + gen_test("${name}_cov" "${files}" "${compile_definitions}" c_std_11 "-g -O0 --coverage" "--coverage") endif () endfunction() -gen_test_matrix(test_private test_private.cpp O1HEAP_EXPOSE_INTERNALS=1 "-Wno-missing-declarations") -gen_test_matrix(test_general test_general.cpp "" "") +gen_test_matrix( + test_private + test_private.cpp + "O1HEAP_CONFIG_HEADER=\"${CMAKE_CURRENT_SOURCE_DIR}/cfg_test_internal.h\"" +) +gen_test_matrix( + test_general + test_general.cpp + "" +) diff --git a/tests/cfg_test_internal.h b/tests/cfg_test_internal.h new file mode 100644 index 0000000..f383dfe --- /dev/null +++ b/tests/cfg_test_internal.h @@ -0,0 +1,7 @@ +// This is a config header for O1Heap. It is included from o1heap.c. + +#define O1HEAP_PRIVATE + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wmissing-declarations" // NOLINT +#endif