From febd43c9870a0305f0d38b4c3ff87b54f5f18fb1 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Mon, 27 Jun 2022 14:08:32 +0300 Subject: [PATCH] Add macro `KERNAUX_CONTAINER_OF` (#100) * Add macro KERNAUX_CONTAINER_OF * Add includes * Add "examples/macro_container_of" --- .gitignore | 1 + examples/Makefile.am | 8 ++++++++ examples/generic_file.c | 3 +++ examples/macro_container_of.c | 33 +++++++++++++++++++++++++++++++++ include/kernaux/macro.h | 6 ++++++ src/free_list.c | 7 +++---- 6 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 examples/macro_container_of.c diff --git a/.gitignore b/.gitignore index 2eb78b1..a98493d 100644 --- a/.gitignore +++ b/.gitignore @@ -111,6 +111,7 @@ /examples/generic_file /examples/generic_malloc /examples/generic_mutex +/examples/macro_container_of /examples/memmap /examples/ntoa /examples/panic diff --git a/examples/Makefile.am b/examples/Makefile.am index 3d4ce95..a9ce770 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -45,6 +45,14 @@ TESTS += generic_mutex generic_mutex_LDADD = $(top_builddir)/libkernaux.la generic_mutex_SOURCES = main.c generic_mutex.c +###################### +# macro_container_of # +###################### + +TESTS += macro_container_of +macro_container_of_LDADD = $(top_builddir)/libkernaux.la +macro_container_of_SOURCES = main.c macro_container_of.c + ########## # memmap # ########## diff --git a/examples/generic_file.c b/examples/generic_file.c index ee47802..510639e 100644 --- a/examples/generic_file.c +++ b/examples/generic_file.c @@ -28,6 +28,9 @@ struct MyFile MyFile_create(char *ptr, size_t size); // my_file.c //=========== +#include +#include + static int MyFile_putc(void *file, unsigned char c); struct MyFile MyFile_create(char *const ptr, const size_t size) diff --git a/examples/macro_container_of.c b/examples/macro_container_of.c new file mode 100644 index 0000000..3c92f3e --- /dev/null +++ b/examples/macro_container_of.c @@ -0,0 +1,33 @@ +#include + +#include + +struct Foo { + const char *hello; +}; + +struct Bar { + unsigned char a; + unsigned int b; + struct Foo foo; + unsigned short c; +}; + +static const struct Bar bar = { + .a = 143, + .b = 820794098, + .foo = { + .hello = "Hello, World!", + }, + .c = 10981, +}; + +void example_main() +{ + const struct Bar *const bar_ptr = + KERNAUX_CONTAINER_OF(&bar.foo, struct Bar, foo); + + assert(bar_ptr->a == 143); + assert(bar_ptr->b == 820794098); + assert(bar_ptr->c == 10981); +} diff --git a/include/kernaux/macro.h b/include/kernaux/macro.h index 244748b..be4c3d0 100644 --- a/include/kernaux/macro.h +++ b/include/kernaux/macro.h @@ -5,6 +5,12 @@ extern "C" { #endif +#include +#include + +#define KERNAUX_CONTAINER_OF(ptr, type, member) \ + ((type*)((uintptr_t)(ptr) - offsetof(type, member))) + #ifdef KERNAUX_ACCESS_PRIVATE # define KERNAUX_PRIVATE_FIELD(id) id # define KERNAUX_PROTECTED_FIELD(id) id diff --git a/src/free_list.c b/src/free_list.c index 9a9024e..c6963ab 100644 --- a/src/free_list.c +++ b/src/free_list.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -22,8 +23,6 @@ #define MIN_ZONE_SIZE (2 * NODE_HEADER_SIZE) #define MIN_SPLIT_SIZE (NODE_HEADER_SIZE + 16) -#define CONTAINER_OF(ptr, type, member) ((type*)((uintptr_t)(ptr) - offsetof(type, member))) - //#define ALIGN_MASK(align) ((align) - 1) // align should be a power of 2 //#define ALIGN_UP(val, align) (((val) + ALIGN_MASK(align)) & ~ALIGN_MASK(align)) @@ -131,7 +130,7 @@ void KernAux_FreeList_free(void *const malloc, void *const ptr) LOCK(free_list); KernAux_FreeList_Node node = - CONTAINER_OF(ptr, struct KernAux_FreeList_Node, block); + KERNAUX_CONTAINER_OF(ptr, struct KernAux_FreeList_Node, block); KernAux_FreeList_Node last_node = NULL; for ( @@ -216,7 +215,7 @@ void *KernAux_FreeList_realloc( LOCK(free_list); KernAux_FreeList_Node node = - CONTAINER_OF(old_ptr, struct KernAux_FreeList_Node, block); + KERNAUX_CONTAINER_OF(old_ptr, struct KernAux_FreeList_Node, block); const size_t old_size = node->size - NODE_HEADER_SIZE; void *new_ptr = KernAux_FreeList_malloc(free_list, new_size);