add malloc_usable_size function and non-stub malloc.h
authorRich Felker <dalias@aerifal.cx>
Tue, 26 Aug 2014 02:47:27 +0000 (22:47 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 26 Aug 2014 02:47:27 +0000 (22:47 -0400)
this function is needed for some important practical applications of
ABI compatibility, and may be useful for supporting some non-portable
software at the source level too.

I was hesitant to add a function which imposes any constraints on
malloc internals; however, it turns out that any malloc implementation
which has realloc must already have an efficient way to determine the
size of existing allocations, so no additional constraint is imposed.

for now, some internal malloc definitions are duplicated in the new
source file. if/when malloc is refactored to put them in a shared
internal header file, these could be removed.

since malloc_usable_size is conventionally declared in malloc.h, the
empty stub version of this file was no longer suitable. it's updated
to provide the standard allocator functions, nonstandard ones (even if
stdlib.h would not expose them based on the feature test macros in
effect), and any malloc-extension functions provided (currently, only
malloc_usable_size).

include/malloc.h
src/malloc/malloc_usable_size.c [new file with mode: 0644]

index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..35f8b19c2c340d510c7aeaf4a5401b54acbc1d0b 100644 (file)
@@ -0,0 +1,25 @@
+#ifndef _MALLOC_H
+#define _MALLOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *valloc (size_t);
+void *memalign(size_t, size_t);
+
+size_t malloc_usable_size(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/malloc/malloc_usable_size.c b/src/malloc/malloc_usable_size.c
new file mode 100644 (file)
index 0000000..8cccd9d
--- /dev/null
@@ -0,0 +1,17 @@
+#include <malloc.h>
+
+void *(*const __realloc_dep)(void *, size_t) = realloc;
+
+struct chunk {
+       size_t psize, csize;
+       struct chunk *next, *prev;
+};
+
+#define OVERHEAD (2*sizeof(size_t))
+#define CHUNK_SIZE(c) ((c)->csize & -2)
+#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)
+
+size_t malloc_usable_size(void *p)
+{
+       return CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD;
+}