commit 2c0f7769124bf407101df932e36cfa982de2b663
Author: Louis Burda <quent.burda@gmail.com>
Date: Fri, 15 Mar 2024 23:14:54 +0100
Squashed 'src/lib/libhmap/lib/liballoc/' content from commit 3f388a2
git-subtree-dir: src/lib/libhmap/lib/liballoc
git-subtree-split: 3f388a2659ae2d121322101930d33412815d84e6
Diffstat:
10 files changed, 329 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,7 @@
+compile_commands.json
+build
+build.jst
+.cache
+vgcore*
+.gdb_history
+test
diff --git a/Makefile b/Makefile
@@ -0,0 +1,45 @@
+PREFIX ?= /usr/local
+LIBDIR ?= /lib
+INCLDIR ?= /include
+
+CFLAGS = -I include
+
+ifeq "$(DEBUG)" "1"
+CFLAGS += -Og -g
+else
+CFLAGS += -O2
+endif
+
+all: build/liballoc.so build/liballoc.a build/test
+
+clean:
+ rm -rf build
+
+cleanall: clean
+
+build:
+ mkdir build
+
+build/liballoc.a: src/allocator.c | build
+ $(CC) -o build/tmp.o src/allocator.c $(CFLAGS) -r
+ objcopy --keep-global-symbols=liballoc.api build/tmp.o build/fixed.o
+ ar rcs $@ build/fixed.o
+
+build/liballoc.so: src/allocator.c include/allocator.h | build
+ $(CC) -o $@ src/allocator.c $(CFLAGS) \
+ -shared -Wl,-version-script liballoc.lds
+
+build/test: src/test.c build/liballoc.a | build
+ $(CC) -o $@ $^ -I include
+
+install:
+ install -m755 include/allocator.h -t "$(DESTDIR)$(PREFIX)$(INCLDIR)"
+ install -m755 build/liballoc.a -t "$(DESTDIR)$(PREFIX)$(LIBDIR)"
+ install -m755 build/liballoc.so -t "$(DESTDIR)$(PREFIX)$(LIBDIR)"
+
+uninstall:
+ rm -f "$(DESTDIR)$(PREFIX)$(INCLDIR)/allocator.h"
+ rm -f "$(DESTDIR)$(PREFIX)$(LIBDIR)/liballoc.a"
+ rm -f "$(DESTDIR)$(PREFIX)$(LIBDIR)/liballoc.so"
+
+.PHONY: all clean cleanall install uninstall
diff --git a/build.jst.tmpl b/build.jst.tmpl
@@ -0,0 +1,60 @@
+#default PREFIX /usr/local
+#default INCLDIR /include
+#default LIBDIR /lib
+#default CC gcc
+
+#ifdef DEBUG
+#define OPT_CFLAGS -Og -g
+#else
+#define OPT_CFLAGS -O2
+#endif
+
+cflags = -Wunused-function -Wunused-variable -Wconversion -Wformat
+ -I include #{OPT_CFLAGS} #{EXTRA_CFLAGS}
+
+rule liba
+ gcc -o $out.tmp.o $in $cflags -r
+ objcopy --keep-global-symbols=liballoc.api $out.tmp.o $out.fixed.o
+ ar rcs $out $out.fixed.o
+ rm $out.tmp.o $out.fixed.o
+
+rule libso
+ gcc -o $out $in $cflags -shared -Wl,-version-script liballoc.lds
+
+rule cc
+ gcc -o $out $in $cflags
+
+rule mkdir
+ mkdir $out
+
+target build
+ mkdir
+
+target build/liballoc.a
+ liba src/allocator.c | include/allocator.h build
+
+target build/liballoc.so
+ libso src/allocator.c | include/allocator.h build
+
+target build/test
+ cc src/test.c build/liballoc.a | build
+
+command clean
+ rm -rf build
+
+command cleanall
+ just clean
+
+command install
+ install -m755 build/liballoc.a -t "#{DESTDIR}#{PREFIX}#{LIBDIR}"
+ install -m755 build/liballoc.so -t "#{DESTDIR}#{PREFIX}#{LIBDIR}"
+ install -m644 include/allocator.h -t "#{DESTDIR}#{PREFIX}#{INCLDIR}"
+
+command uninstall
+ rm -f "#{DESTDIR}#{PREFIX}#{LIBDIR}/liballoc.a"
+ rm -f "#{DESTDIR}#{PREFIX}#{LIBDIR}/liballoc.so"
+ rm -f "#{DESTDIR}#{PREFIX}#{INCLDIR}/allocator.h"
+
+command all
+ just build/liballoc.a build/liballoc.so build/test
+
diff --git a/common.mk b/common.mk
@@ -0,0 +1,9 @@
+LIBALLOC_A = build/liballoc.a
+LIBALLOC_A_SRC = src/allocator.c
+LIBALLOC_A_DEP = $(LIBALLOC_A_SRC) include/allocator.h
+LIBALLOC_A_SRCDEP = $(LIBALLOC_A_DEP)
+
+LIBALLOC_SO = build/liballoc.so
+LIBALLOC_SO_SRC = src/allocator.c
+LIBALLOC_SO_DEP = $(LIBALLOC_SO_SRC) include/allocator.h
+LIBALLOC_SO_SRCDEP = $(LIBALLOC_SO_DEP)
diff --git a/configure b/configure
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+tmpl "$@" build.jst.tmpl > build.jst
diff --git a/include/allocator.h b/include/allocator.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <stddef.h>
+
+struct allocator {
+ void *(*alloc)(const struct allocator *allocator,
+ size_t size, int *rc);
+ void *(*realloc)(const struct allocator *allocator,
+ void *p, size_t size, int *rc);
+ int (*free)(const struct allocator *allocator, void *p);
+};
+
+struct strict_allocator {
+ const struct allocator *allocator_ul;
+ struct allocator allocator;
+};
+
+void strict_allocator_init(struct strict_allocator *strict_allocator_init,
+ const struct allocator *allocator_ul);
+
+extern const struct allocator stdlib_heap_allocator;
+extern const struct allocator stdlib_strict_heap_allocator;
diff --git a/liballoc.api b/liballoc.api
@@ -0,0 +1,4 @@
+strict_allocator_init
+
+stdlib_heap_allocator
+stdlib_strict_heap_allocator
diff --git a/liballoc.lds b/liballoc.lds
@@ -0,0 +1,7 @@
+LIBALLOC_2.1 {
+ global:
+ strict_allocator_init;
+ stdlib_heap_allocator;
+ stdlib_strict_heap_allocator;
+ local: *;
+};
diff --git a/src/allocator.c b/src/allocator.c
@@ -0,0 +1,150 @@
+#include "allocator.h"
+
+#include <errno.h>
+#include <stdlib.h>
+
+static void *stdlib_heap_alloc(const struct allocator *allocator,
+ size_t size, int *rc);
+static void *stdlib_heap_realloc(const struct allocator *allocator,
+ void *p, size_t size, int *rc);
+static int stdlib_heap_free(const struct allocator *allocator, void *p);
+
+static void *stdlib_strict_heap_alloc(const struct allocator *allocator,
+ size_t size, int *rc);
+static void *stdlib_strict_heap_realloc(const struct allocator *allocator,
+ void *p, size_t size, int *rc);
+static int stdlib_strict_heap_free(const struct allocator *allocator, void *p);
+
+const struct allocator stdlib_heap_allocator = {
+ .alloc = stdlib_heap_alloc,
+ .realloc = stdlib_heap_realloc,
+ .free = stdlib_heap_free
+};
+
+const struct allocator stdlib_strict_heap_allocator = {
+ .alloc = stdlib_strict_heap_alloc,
+ .realloc = stdlib_strict_heap_realloc,
+ .free = stdlib_strict_heap_free
+};
+
+void *
+stdlib_heap_alloc(const struct allocator *allocator, size_t size, int *rc)
+{
+ void *p;
+
+ p = malloc(size);
+ if (rc && !p) *rc = errno;
+
+ return p;
+}
+
+void *
+stdlib_heap_realloc(const struct allocator *allocator,
+ void *p, size_t size, int *rc)
+{
+ void *np;
+
+ np = realloc(p, size);
+ if (rc && !np) *rc = errno;
+
+ return np;
+}
+
+int
+stdlib_heap_free(const struct allocator *allocator, void *p)
+{
+ free(p);
+
+ return 0;
+}
+
+void *
+stdlib_strict_heap_alloc(const struct allocator *allocator,
+ size_t size, int *rc)
+{
+ void *p;
+
+ p = malloc(size);
+ if (!p) abort();
+
+ return p;
+}
+
+void *
+stdlib_strict_heap_realloc(const struct allocator *allocator,
+ void *p, size_t size, int *rc)
+{
+ void *np;
+
+ np = realloc(p, size);
+ if (!np) abort();
+
+ return np;
+}
+
+int
+stdlib_strict_heap_free(const struct allocator *allocator, void *p)
+{
+ free(p);
+
+ return 0;
+}
+
+void *
+strict_allocator_alloc(const struct allocator *allocator, size_t size, int *rc)
+{
+ const struct strict_allocator *strict_allocator;
+ void *p;
+
+ strict_allocator = ((void *) allocator)
+ - offsetof(struct strict_allocator, allocator);
+
+ p = strict_allocator->allocator_ul->alloc(
+ strict_allocator->allocator_ul, size, rc);
+ if (!p) abort();
+
+ return p;
+}
+
+void *
+strict_allocator_realloc(const struct allocator *allocator,
+ void *p, size_t size, int *rc)
+{
+ const struct strict_allocator *strict_allocator;
+ void *np;
+
+ strict_allocator = ((void *) allocator)
+ - offsetof(struct strict_allocator, allocator);
+
+ np = strict_allocator->allocator_ul->realloc(
+ strict_allocator->allocator_ul, p, size, rc);
+ if (!np) abort();
+
+ return np;
+}
+
+int
+strict_allocator_free(const struct allocator *allocator, void *p)
+{
+ const struct strict_allocator *strict_allocator;
+ int rc;
+
+ strict_allocator = ((void *) allocator)
+ - offsetof(struct strict_allocator, allocator);
+
+ rc = strict_allocator->allocator_ul->free(
+ strict_allocator->allocator_ul, p);
+ if (rc) abort();
+
+ return 0;
+}
+
+void
+strict_allocator_init(struct strict_allocator *strict_allocator,
+ const struct allocator *allocator_ul)
+{
+ strict_allocator->allocator_ul = allocator_ul;
+ strict_allocator->allocator.alloc = strict_allocator_alloc;
+ strict_allocator->allocator.realloc = strict_allocator_realloc;
+ strict_allocator->allocator.free = strict_allocator_free;
+}
diff --git a/src/test.c b/src/test.c
@@ -0,0 +1,22 @@
+#include "allocator.h"
+
+#include <err.h>
+#include <string.h>
+#include <stdlib.h>
+
+const struct allocator *ga = &stdlib_heap_allocator;
+
+int
+main(int argc, const char **argv)
+{
+ struct test *test;
+ int rc;
+
+ if (argc <= 1) exit(1);
+
+ test = ga->alloc(ga, strtoull(argv[1], NULL, 10), &rc);
+ if (!test) errx(1, "alloc: %s", strerror(rc));
+
+ rc = ga->free(ga, test);
+ if (rc) errx(1, "free: %s", strerror(rc));
+}