From 0d78eab2e190c29a1ca5f18506212083bd9694e2 Mon Sep 17 00:00:00 2001 From: Olaf Bergmann Date: Wed, 18 Jun 2014 16:30:07 +0200 Subject: [PATCH] Some small additions for combined memory management. Two new functions coap_malloc_type() and coap_free_type() have been added to centralize the typed memory allocation for Contiki and LWIP. Currently, calls to memb_alloc(), memp_malloc() and coap_malloc() are distributed across several modules. The idea of the new functions is to centralize memory management in one place (mem.c). coap_malloc() and coap_free() are still available as wrappers for the new functions. --- mem.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mem.h | 55 ++++++++++++++++++++++++++++++---- 2 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 mem.c diff --git a/mem.c b/mem.c new file mode 100644 index 00000000..63e37869 --- /dev/null +++ b/mem.c @@ -0,0 +1,95 @@ +/* mem.c -- CoAP memory handling + * + * Copyright (C) 2014 Olaf Bergmann + * + * This file is part of the CoAP library libcoap. Please see + * README for terms of use. + */ + + +#include "config.h" +#include "mem.h" + +#ifdef HAVE_MALLOC +#include + +void +coap_memory_init() { +} + +void * +coap_malloc_type(coap_memory_tag_t type, size_t size) { + return malloc(size); +} + +void +coap_free_type(void *p) { + free(p); +} + +#else /* HAVE_MALLOC */ + +#ifdef WITH_CONTIKI +#define COAP_MAX_STRING_SIZE 12 +#define COAP_MAX_STRINGS 8 + +typedef struct { + coap_memory_tag_t type; + char data[]; +} coap_memory_item_t; + +struct coap_string_t { + coap_memory_tag_t type; + char data[COAP_MAX_STRING_SIZE]; +}; + +MEMB(string_storage, struct coap_string_t, COAP_MAX_STRINGS); + +static struct memb * +get_container(coap_memory_tag_t type) { + switch(type) { + default: + return &string_storage; + } +} + +void +coap_memory_init() { + memb_init(&string_storage); +} + +void * +coap_malloc_type(coap_memory_tag_t type, size_t size) { + struct memb *container = get_container(type); + coap_memory_item_t *item; + + assert(container); + + if (size + sizeof(coap_memory_item_t) > container->size) { + debug("coap_malloc_type: Requested memory exceeds maximum object size\n"); + return NULL; + } + + item = (coap_memory_item_t *)memb_alloc(container); + if (item != NULL) { + item->type = type; + return item->data; + } else { + debug("coap_malloc_type: insufficient memory\n"); + return NULL; + } +} + +void +coap_free_type(void *object) { + coap_memory_item_t *item; + + if (object) { + item = (char *)object - sizeof(coap_memory_item_t); + + memb_free(get_container(item->type), item); + } +} +#endif /* WITH_CONTIKI */ + +#endif /* HAVE_MALLOC */ diff --git a/mem.h b/mem.h index a84405ee..e84b36ca 100644 --- a/mem.h +++ b/mem.h @@ -1,7 +1,6 @@ /* mem.h -- CoAP memory handling - * Currently, this is just a dummy for malloc/free * - * Copyright (C) 2010,2011 Olaf Bergmann + * Copyright (C) 2010,2011,2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see * README for terms of use. @@ -10,9 +9,55 @@ #ifndef _COAP_MEM_H_ #define _COAP_MEM_H_ -#include +/** + * Initializes libcoap's memory management. This function must be + * called once before coap_malloc() can be used on constrained + * devices. + */ +void coap_memory_init(); -#define coap_malloc(size) malloc(size) -#define coap_free(size) free(size) +/** + * Type specifiers for coap_malloc_type(). Memory objects can be typed + * to facilitate arrays of type objects to be used instead of dynamic + * memory management on constrained devices. + */ +typedef enum { + COAP_STRING, COAP_ATTRIBUTE_NAME, COAP_ATTRIBUTE_VALUE +} coap_memory_tag_t; + +/** + * Allocates a chunk of @p size bytes and returns a pointer to the + * newly allocated memory. The @p type is used to select the + * appropriate storage container on constrained devices. The storage + * allocated by coap_malloc_type() must be released with + * coap_free_type(). + * + * @param type The type of object to be stored. + * @param size The number of bytes requested. + * @return A pointer to the allocated storage or @c NULL on error. + */ +void *coap_malloc_type(coap_memory_tag_t type, size_t size); + +/** + * Releases the memory that was allocated by coap_malloc_type(). + * + * @param p A pointer to memory that was allocated by + * coap_malloc_type(). + */ +void coap_free_type(void *p); + +/** + * Wrapper function to coap_malloc_type() for backwards compatibility. + */ +static inline void *coap_malloc(size_t size) { + return coap_malloc_type(COAP_STRING, size); +} + +/** + * Wrapper function to coap_free_type() for backwards compatibility. + */ +static inline void coap_free(void *object) { + coap_free_type(object); +} #endif /* _COAP_MEM_H_ */