Add makefile and restructure

This commit is contained in:
olemorud
2023-05-14 23:57:05 +02:00
parent 9c93b37557
commit 5e92c4eaea
8 changed files with 180 additions and 97 deletions

27
Makefile Normal file
View File

@@ -0,0 +1,27 @@
CC := gcc
CFLAGS := -ggdb -O0 -std=c99 -Wall -Wextra -Wpedantic
OBJS := obj/arena.o obj/alloc_backend.o
all : test/test_arena
test/test_arena : src/test_arena.c $(OBJS) | test
$(CC) -o $@ $(CFLAGS) $^
obj/%.o : src/%.c | obj
$(CC) -o $@ -c $(CFLAGS) $<
obj:
mkdir -p $@
bin:
mkdir -p $@
test:
mkdir -p $@
clean:
rm -rf obj bin test
.PHONY: clean obj test bin all

View File

@@ -1,63 +0,0 @@
#include "arena.h"
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stddef.h> // ptrdiff_t
#include <sys/mman.h>
#define ARENA_PAGES ((size_t)(128))
#define ALIGN 1
struct arena* arena_new()
{
size_t page_size = sysconf(_SC_PAGE_SIZE);
size_t size = page_size * ARENA_PAGES;
void *p = mmap(
NULL,
size,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
-1, /* man mmap(2): "[...], some implementations require fd to be
-1 if MAP_ANONYMOUS is specified [...]" */
0
);
if (p == MAP_FAILED) {
return NULL;
}
struct arena a = {
.start = p + sizeof(struct arena),
.next = p + sizeof(struct arena),
.cap = size
};
memcpy(p, &a, sizeof a);
return p;
}
void arena_reset(struct arena *a)
{
a->next = a->start;
}
void* arena_alloc(struct arena *a, size_t len)
{
void *p = a->next;
a->next += len;
if (a->next - a->start >= a->cap) {
errno = ENOMEM;
return NULL;
}
return p;
}

30
src/alloc_backend.c Normal file
View File

@@ -0,0 +1,30 @@
#include "alloc_backend.h"
#define _GNU_SOURCE
#include <sys/mman.h>
/*
* Separate function to make switching
* allocation backend easier
*
* must take size_t size as an argument
* must return NULL on failure
*/
void* call_alloc_backend(size_t size)
{
void *p = mmap(
NULL,
size,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
-1, /* man mmap(2): "[...], some implementations require fd to be
-1 if MAP_ANONYMOUS is specified [...]" */
0
);
if (p == MAP_FAILED)
return NULL;
return p;
}

9
src/alloc_backend.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef ALLOC_BACKEND_H
#define ALLOC_BACKEND_H
#include <stddef.h>
void* call_alloc_backend(size_t size);
#endif

60
src/arena.c Normal file
View File

@@ -0,0 +1,60 @@
#include "arena.h"
#include "alloc_backend.h"
#include <errno.h>
#include <unistd.h>
#include <string.h>
#define ARENA_SIZE ((size_t)(128*sysconf(_SC_PAGE_SIZE)))
/*
* Allocates and returns new arena
*/
struct arena* arena_new()
{
size_t size = ARENA_SIZE;
unsigned char *p = call_alloc_backend(size);
if (p == NULL)
return NULL;
struct arena a = {
.begin = p + sizeof(struct arena),
.next = p + sizeof(struct arena),
.cap = size
};
memcpy(p, &a, sizeof a);
return (struct arena*)p;
}
/*
* Frees all memory in arena
*/
void arena_reset(struct arena *a)
{
a->next = a->begin;
}
/*
* Allocate new memory using arena
*/
void* arena_alloc(struct arena *a, size_t len)
{
void *p = a->next;
a->next += len;
if (a->next - a->begin >= a->cap) {
errno = ENOMEM;
return NULL;
}
return p;
}

View File

@@ -1,12 +1,19 @@
#ifndef ARENA_H
#define ARENA_H
#include <stddef.h> // ptrdiff_t
struct arena {
void *start,
*next;
unsigned char *begin,
*next;
ptrdiff_t cap;
} __attribute__((aligned(64)));
};
struct arena* arena_new();
void arena_reset(struct arena *a);
void* arena_alloc(struct arena *a, size_t len);
#endif

44
src/test_arena.c Normal file
View File

@@ -0,0 +1,44 @@
// _start test_arena_alloc.c
#include "arena.h"
#include <err.h>
#include <stdio.h>
#include <errno.h>
static struct arena *default_arena = NULL;
int main()
{
default_arena = arena_new();
if (default_arena == NULL) {
err(errno, "failed to allocate arena");
}
printf("\n%p\n", default_arena->next);
char *ten_A = arena_alloc(default_arena, 11 * sizeof *ten_A);
char *ten_B = arena_alloc(default_arena, 11 * sizeof *ten_B);
char *ten_C = arena_alloc(default_arena, 11 * sizeof *ten_C);
for (size_t i=0; i<10; ++i) {
ten_A[i] = 'A';
ten_B[i] = 'B';
ten_C[i] = 'C';
}
ten_A[10] = '\0';
ten_B[10] = '\0';
ten_C[10] = '\0';
printf("\n%s %s %s", ten_A, ten_B, ten_C);
printf("\n%p\n", default_arena->next);
arena_reset(default_arena);
printf("\n%p\n", default_arena->next);
return 0;
}

View File

@@ -1,31 +0,0 @@
// _start test_arena_alloc.c
#include "arena.h"
#include <err.h>
#include <stdio.h>
#include <errno.h>
static struct arena *default_arena = NULL;
int main()
{
default_arena = arena_new();
if (default_arena == NULL) {
err(errno, "failed to allocate arena");
}
char *p = arena_alloc(default_arena, sizeof p * 11);
for (size_t i=0; i<10; ++i) {
p[i] = 'A';
}
p[10] = '\0';
printf("%s", p);
return 0;
}