Add makefile and restructure
This commit is contained in:
27
Makefile
Normal file
27
Makefile
Normal 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
|
||||||
@@ -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
30
src/alloc_backend.c
Normal 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
9
src/alloc_backend.h
Normal 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
60
src/arena.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,12 +1,19 @@
|
|||||||
|
|
||||||
|
#ifndef ARENA_H
|
||||||
|
#define ARENA_H
|
||||||
|
|
||||||
|
|
||||||
#include <stddef.h> // ptrdiff_t
|
#include <stddef.h> // ptrdiff_t
|
||||||
|
|
||||||
struct arena {
|
struct arena {
|
||||||
void *start,
|
unsigned char *begin,
|
||||||
*next;
|
*next;
|
||||||
ptrdiff_t cap;
|
ptrdiff_t cap;
|
||||||
} __attribute__((aligned(64)));
|
};
|
||||||
|
|
||||||
struct arena* arena_new();
|
struct arena* arena_new();
|
||||||
void arena_reset(struct arena *a);
|
void arena_reset(struct arena *a);
|
||||||
void* arena_alloc(struct arena *a, size_t len);
|
void* arena_alloc(struct arena *a, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
44
src/test_arena.c
Normal file
44
src/test_arena.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user