From b47209e2549dbf90663a2860c8beefbddbde14c7 Mon Sep 17 00:00:00 2001
From: chrysn <chrysn@fsfe.org>
Date: Wed, 6 Jul 2016 12:38:16 +0200
Subject: [PATCH 2/3] Introduce LWIP_ALIGN_SUFFIX macro

This allows compilers that can align buffers to place them right in the
first place without wasting memory to do alignment at runtime.
---
 doc/sys_arch.txt        |  5 +++++
 src/core/ipv4/ip_frag.c |  2 +-
 src/core/mem.c          |  2 +-
 src/include/lwip/mem.h  | 19 +++++++++++++++++++
 src/include/lwip/memp.h |  2 +-
 5 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/doc/sys_arch.txt b/doc/sys_arch.txt
index 847cd77..1f08fd7 100644
--- a/doc/sys_arch.txt
+++ b/doc/sys_arch.txt
@@ -231,6 +231,11 @@ cc.h       - Architecture environment, some compiler specific, some
     PACK_STRUCT_BEGIN
     PACK_STRUCT_END
 
+  Compiler hints for alignment -
+    LWIP_ALIGN_SUFFIX        - must, when added to a variable definition,
+                               ensure that its address is at least aligned to
+                               the MEM_ALIGNMENT defined in the lwIP options
+
   Platform specific diagnostic output -
     LWIP_PLATFORM_DIAG(x)    - non-fatal, print a message.
     LWIP_PLATFORM_ASSERT(x)  - fatal, print message and abandon execution.
diff --git a/src/core/ipv4/ip_frag.c b/src/core/ipv4/ip_frag.c
index 028e4d9..8822a0e 100644
--- a/src/core/ipv4/ip_frag.c
+++ b/src/core/ipv4/ip_frag.c
@@ -640,7 +640,7 @@ nullreturn:
 
 #if IP_FRAG
 #if IP_FRAG_USES_STATIC_BUF
-static u8_t buf[LWIP_MEM_ALIGN_BUFFER(IP_FRAG_MAX_MTU)];
+static u8_t buf[LWIP_MEM_ALIGN_BUFFER(IP_FRAG_MAX_MTU)] LWIP_ALIGN_SUFFIX;
 #else /* IP_FRAG_USES_STATIC_BUF */
 
 #if !LWIP_NETIF_TX_SINGLE_PBUF
diff --git a/src/core/mem.c b/src/core/mem.c
index d431f3b..da67e24 100644
--- a/src/core/mem.c
+++ b/src/core/mem.c
@@ -202,7 +202,7 @@ struct mem {
  * how that space is calculated). */
 #ifndef LWIP_RAM_HEAP_POINTER
 /** the heap. we need one struct mem at the end and some room for alignment */
-u8_t ram_heap[LWIP_MEM_ALIGN_BUFFER(MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM))];
+u8_t ram_heap[LWIP_MEM_ALIGN_BUFFER(MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM))] LWIP_ALIGN_SUFFIX;
 #define LWIP_RAM_HEAP_POINTER ram_heap
 #endif /* LWIP_RAM_HEAP_POINTER */
 
diff --git a/src/include/lwip/mem.h b/src/include/lwip/mem.h
index 66537a9..2bb3c5f 100644
--- a/src/include/lwip/mem.h
+++ b/src/include/lwip/mem.h
@@ -38,6 +38,7 @@
 #define LWIP_HDR_MEM_H
 
 #include "lwip/opt.h"
+#include "lwip/arch.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -106,13 +107,31 @@ void  mem_free(void *mem);
 #define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1U) & ~(MEM_ALIGNMENT-1U))
 #endif
 
+/** @see LWIP_MEM_ALIGN_BUFFER */
+#ifdef LWIP_ALIGN_SUFFIX
+#define LWIP_ALIGN_SUFFIX_AVAILABLE
+#else
+#define LWIP_ALIGN_SUFFIX
+#endif
+
 /** Calculate safe memory size for an aligned buffer when using an unaligned
  * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the
  * start (e.g. if buffer is u8_t[] and actual data will be u32_t*)
+ *
+ * This must only be used paired with the LWIP_MEM_ALIGN_SUFFIX macro described in
+ * sys_arch.txt, for example like this:
+ * u8_t my_buffer[LWIP_MEM_ALIGN_BUFFER(my_custom_size)] LWIP_ALIGN_SUFFIX;
+ * u8_t *my_buf = LWIP_MEM_ALIGN(my_buffer);
+ *
+ * On architectures that provide LWIP_MEM_ALIGN macro, no bloat will be added.
  */
 #ifndef LWIP_MEM_ALIGN_BUFFER
+#ifdef LWIP_ALIGN_SUFFIX_AVAILABLE
+#define LWIP_MEM_ALIGN_BUFFER(size) (size)
+#else
 #define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1U))
 #endif
+#endif
 
 /** Align a memory pointer to the alignment defined by MEM_ALIGNMENT
  * so that ADDR % MEM_ALIGNMENT == 0
diff --git a/src/include/lwip/memp.h b/src/include/lwip/memp.h
index 11a8481..a0f1407 100644
--- a/src/include/lwip/memp.h
+++ b/src/include/lwip/memp.h
@@ -91,7 +91,7 @@ extern const struct memp_desc* const memp_pools[MEMP_MAX];
 #else /* MEMP_MEM_MALLOC */
 
 #define LWIP_MEMPOOL_DECLARE(name,num,size,desc) u8_t memp_memory_ ## name ## _base \
-    [LWIP_MEM_ALIGN_BUFFER((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))]; \
+    [LWIP_MEM_ALIGN_BUFFER((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))] LWIP_ALIGN_SUFFIX; \
     \
   static struct memp *memp_tab_ ## name; \
     \
-- 
2.8.1

