Преглед изворни кода

core: mem - fm memory manager updated to align to 16

- same as malloc() on linux 64b
- https://www.gnu.org/software/libc/manual/html_node/Aligned-Memory-Blocks.html
- some libraries (e.g., libwolfssl) expect such alignement for specific optimizations
- done even for 32b, expected rather low overhead in average, not expected many
  chunks under 16 bytes versus those over
- malloc optimization factor increased to 15
Daniel-Constantin Mierla пре 1 година
родитељ
комит
7cc22301b3
2 измењених фајлова са 46 додато и 33 уклоњено
  1. 27 12
      src/core/mem/f_malloc.c
  2. 19 21
      src/core/mem/f_malloc.h

+ 27 - 12
src/core/mem/f_malloc.c

@@ -43,20 +43,19 @@
 
 
 /* useful macros */
 /* useful macros */
 
 
+/** ROUNDTO= 2^k so the following works */
+#define ROUNDTO_MASK (~((unsigned long)ROUNDTO - 1))
+#define ROUNDUP(s) (((s) + (ROUNDTO - 1)) & ROUNDTO_MASK)
+#define ROUNDDOWN(s) ((s)&ROUNDTO_MASK)
+
 #define FRAG_NEXT(f) \
 #define FRAG_NEXT(f) \
 	((struct fm_frag *)((char *)(f) + sizeof(struct fm_frag) + (f)->size))
 	((struct fm_frag *)((char *)(f) + sizeof(struct fm_frag) + (f)->size))
 
 
 #define FRAG_OVERHEAD (sizeof(struct fm_frag))
 #define FRAG_OVERHEAD (sizeof(struct fm_frag))
+
 #define INIT_OVERHEAD \
 #define INIT_OVERHEAD \
 	(ROUNDUP(sizeof(struct fm_block)) + 2 * sizeof(struct fm_frag))
 	(ROUNDUP(sizeof(struct fm_block)) + 2 * sizeof(struct fm_frag))
 
 
-
-/** ROUNDTO= 2^k so the following works */
-#define ROUNDTO_MASK (~((unsigned long)ROUNDTO - 1))
-#define ROUNDUP(s) (((s) + (ROUNDTO - 1)) & ROUNDTO_MASK)
-#define ROUNDDOWN(s) ((s)&ROUNDTO_MASK)
-
-
 /** finds the hash value for s, s=ROUNDTO multiple */
 /** finds the hash value for s, s=ROUNDTO multiple */
 #define GET_HASH(s)                                                   \
 #define GET_HASH(s)                                                   \
 	(((unsigned long)(s) <= F_MALLOC_OPTIMIZE)                        \
 	(((unsigned long)(s) <= F_MALLOC_OPTIMIZE)                        \
@@ -321,12 +320,28 @@ struct fm_block *fm_malloc_init(char *address, unsigned long size, int type)
 	struct fm_block *qm;
 	struct fm_block *qm;
 	unsigned long init_overhead;
 	unsigned long init_overhead;
 
 
-	/* make address and size multiple of 8*/
+	if(sizeof(struct fm_frag) % ROUNDTO != 0) {
+		LM_ERR("memory fragment align constraints failure (%lu %% %lu = %lu)\n",
+				sizeof(struct fm_frag), ROUNDTO,
+				sizeof(struct fm_frag) % ROUNDTO);
+		return 0;
+	}
+	if(sizeof(struct fm_block) % ROUNDTO != 0) {
+		LM_ERR("memory block align constraints failure (%lu %% %lu = %lu)\n",
+				sizeof(struct fm_block), ROUNDTO,
+				sizeof(struct fm_block) % ROUNDTO);
+		return 0;
+	}
+
+	/* make address and size multiple of ROUNDTO */
 	start = (char *)ROUNDUP((unsigned long)address);
 	start = (char *)ROUNDUP((unsigned long)address);
-	LM_DBG("F_OPTIMIZE=%lu, /ROUNDTO=%lu\n", F_MALLOC_OPTIMIZE,
-			F_MALLOC_OPTIMIZE / ROUNDTO);
-	LM_DBG("F_HASH_SIZE=%lu, fm_block size=%lu\n", F_HASH_SIZE,
-			(unsigned long)sizeof(struct fm_block));
+	LM_DBG("F_OPTIMIZE=%lu, F_OPTIMIZE/ROUNDTO=%lu, ROUNDTO=%lu\n",
+			F_MALLOC_OPTIMIZE, F_MALLOC_OPTIMIZE / ROUNDTO, ROUNDTO);
+	LM_DBG("F_HASH_SIZE=%lu, FM_HASH_BMP_SIZE=%lu, fm_block_size=%lu, "
+		   "fm_block_size %% ROUNDTO=%lu\n",
+			F_HASH_SIZE, FM_HASH_BMP_SIZE,
+			(unsigned long)sizeof(struct fm_block),
+			(unsigned long)sizeof(struct fm_block) % ROUNDTO);
 	LM_DBG("fm_malloc_init(%p, %lu), start=%p\n", address, (unsigned long)size,
 	LM_DBG("fm_malloc_init(%p, %lu), start=%p\n", address, (unsigned long)size,
 			start);
 			start);
 
 

+ 19 - 21
src/core/mem/f_malloc.h

@@ -40,24 +40,21 @@
  */
  */
 #define F_MALLOC_HASH_BITMAP
 #define F_MALLOC_HASH_BITMAP
 
 
-#ifdef DBG_F_MALLOC
-#if defined(__CPU_sparc64) || defined(__CPU_sparc)
-/* tricky, on sun in 32 bits mode long long must be 64 bits aligned
- * but long can be 32 bits aligned => malloc should return long long
- * aligned memory */
-#define ROUNDTO sizeof(long long)
-#else
-#define ROUNDTO \
-	sizeof(void *) /* size we round to, must be = 2^n, and
-							* sizeof(fm_frag) must be multiple of ROUNDTO !*/
-#endif
-#else /* DBG_F_MALLOC */
-#define ROUNDTO 8UL
-#endif
+/**
+ * ROUNDTO: size to round to, must be = 2^n
+ * - on sun in 32 bits mode long long must be 64 bits aligned but long
+ * can be 32 bits aligned => malloc should return multiple of long long
+ * aligned memory
+ * - malloc() on gnu/linux: multiple of 8 or 16 on 64-bit systems
+ * - for simplicity settle for 16 always
+ * - sizeof(fm_frag) must be multiple of ROUNDTO!
+ */
+#define ROUNDTO 16UL
+
 #define MIN_FRAG_SIZE ROUNDTO
 #define MIN_FRAG_SIZE ROUNDTO
 
 
 
 
-#define F_MALLOC_OPTIMIZE_FACTOR 14UL /* used below */
+#define F_MALLOC_OPTIMIZE_FACTOR 15UL /* used below */
 /** Size to optimize for, (most allocs <= this size), must be 2^k */
 /** Size to optimize for, (most allocs <= this size), must be 2^k */
 #define F_MALLOC_OPTIMIZE (1UL << F_MALLOC_OPTIMIZE_FACTOR)
 #define F_MALLOC_OPTIMIZE (1UL << F_MALLOC_OPTIMIZE_FACTOR)
 
 
@@ -81,18 +78,18 @@ typedef unsigned long fm_hash_bitmap_t;
  */
  */
 struct fm_frag
 struct fm_frag
 {
 {
-	unsigned long size;		   /* size of fragment */
+	unsigned long size;	   /* size of fragment */
+	unsigned long is_free; /* used to detect if fragment is free (when not 0) */
 	struct fm_frag *next_free; /* next free frag in slot */
 	struct fm_frag *next_free; /* next free frag in slot */
-	struct fm_frag
-			*prev_free;	  /* prev free frag in slot - for faster join/defrag */
-	unsigned int is_free; /* used to detect if fragment is free (when not 0) */
+	struct fm_frag *prev_free; /* prev free frag in slot - faster join/defrag */
 #ifdef DBG_F_MALLOC
 #ifdef DBG_F_MALLOC
 	const char *file;
 	const char *file;
 	const char *func;
 	const char *func;
 	const char *mname;
 	const char *mname;
 	unsigned long line;
 	unsigned long line;
 #endif
 #endif
-	unsigned int check;
+	unsigned long reserved1;
+	unsigned long check;
 };
 };
 
 
 struct fm_frag_lnk
 struct fm_frag_lnk
@@ -107,12 +104,13 @@ struct fm_frag_lnk
  */
  */
 struct fm_block
 struct fm_block
 {
 {
-	int type;
+	long type;
 	unsigned long size;		 /** total size */
 	unsigned long size;		 /** total size */
 	unsigned long used;		 /** allocated size*/
 	unsigned long used;		 /** allocated size*/
 	unsigned long real_used; /** used + malloc overhead */
 	unsigned long real_used; /** used + malloc overhead */
 	unsigned long max_real_used;
 	unsigned long max_real_used;
 	unsigned long ffrags;
 	unsigned long ffrags;
+	unsigned long reserved1;
 
 
 	struct fm_frag *first_frag;
 	struct fm_frag *first_frag;
 	struct fm_frag *last_frag;
 	struct fm_frag *last_frag;