Commit 085b9762 authored by Swann Perarnau's avatar Swann Perarnau

[feature] add init functions to area_linux

Still the same schema, although it looks a bit messier on linux because
of all the options needed.
parent 8d2cc6ae
......@@ -231,8 +231,30 @@ struct aml_area_linux {
struct aml_area_linux_ops ops;
};
int aml_area_linux_init(struct aml_area_linux *);
int aml_area_linux_destroy(struct aml_area_linux *);
#define AML_AREA_LINUX_DECL(name) \
struct aml_area_linux __ ##name## _inner_data; \
struct aml_area name = { \
&aml_area_linux_ops, \
(struct aml_area_data *)&__ ## name ## _inner_data, \
};
#define AML_AREA_LINUX_ALLOCSIZE \
(sizeof(struct aml_area_linux) + \
sizeof(struct aml_area))
#define AML_AREA_LINUX_MANAGER_TYPE_SINGLE 0
#define AML_AREA_LINUX_MBIND_TYPE_REGULAR 0
#define AML_AREA_LINUX_MBIND_TYPE_MEMPOLICY 1
#define AML_AREA_LINUX_MMAP_TYPE_ANONYMOUS 0
#define AML_AREA_LINUX_MMAP_TYPE_FD 1
#define AML_AREA_LINUX_MMAP_TYPE_TMPFILE 2
int aml_area_linux_create(struct aml_area **, int, int, int, ...);
int aml_area_linux_init(struct aml_area *, int, int, int, ...);
int aml_area_linux_vinit(struct aml_area *, int, int, int, va_list);
int aml_area_linux_destroy(struct aml_area *);
/*******************************************************************************
* Generic Area API:
......
......@@ -117,14 +117,91 @@ struct aml_area_ops aml_area_linux_ops = {
* Collections of init/destroy functions for popular types of linux-based areas
******************************************************************************/
int aml_area_linux_init(struct aml_area_linux *area)
int aml_area_linux_create(struct aml_area **a, int manager_type,
int mbind_type, int mmap_type, ...)
{
assert(area != NULL);
va_list ap;
struct aml_area *ret = NULL;
intptr_t baseptr, dataptr;
va_start(ap, mmap_type);
/* alloc */
baseptr = (intptr_t) calloc(1, AML_AREA_LINUX_ALLOCSIZE);
dataptr = baseptr + sizeof(struct aml_area);
ret = (struct aml_area *)baseptr;
ret->data = (struct aml_area_data *)dataptr;
aml_area_linux_vinit(ret, manager_type, mbind_type, mmap_type, ap);
va_end(ap);
*a = ret;
return 0;
}
int aml_area_linux_vinit(struct aml_area *a, int manager_type,
int mbind_type, int mmap_type, va_list ap)
{
a->ops = &aml_area_linux_ops;
struct aml_area_linux *area = (struct aml_area_linux *)a->data;
/* manager init */
assert(manager_type == AML_AREA_LINUX_MANAGER_TYPE_SINGLE);
struct aml_arena *arena = va_arg(ap, struct aml_arena *);
aml_area_linux_manager_single_init(&area->data.manager, arena);
area->ops.manager = aml_area_linux_manager_single_ops;
/* mbind init */
int policy = va_arg(ap, int);
unsigned long *nodemask = va_arg(ap, unsigned long *);
aml_area_linux_mbind_init(&area->data.mbind, policy, nodemask);
if(mbind_type == AML_AREA_LINUX_MBIND_TYPE_REGULAR)
area->ops.mbind = aml_area_linux_mbind_regular_ops;
else if(mbind_type == AML_AREA_LINUX_MBIND_TYPE_MEMPOLICY)
area->ops.mbind = aml_area_linux_mbind_mempolicy_ops;
/* mmap init */
area->ops.mmap = aml_area_linux_mmap_generic_ops;
if(mmap_type == AML_AREA_LINUX_MMAP_TYPE_ANONYMOUS)
aml_area_linux_mmap_anonymous_init(&area->data.mmap);
else if(mmap_type == AML_AREA_LINUX_MMAP_TYPE_FD)
{
int fd = va_arg(ap, int);
size_t max = va_arg(ap, size_t);
aml_area_linux_mmap_fd_init(&area->data.mmap, fd, max);
}
else if(mmap_type == AML_AREA_LINUX_MMAP_TYPE_TMPFILE)
{
char *template = va_arg(ap, char*);
size_t max = va_arg(ap, size_t);
aml_area_linux_mmap_tmpfile_init(&area->data.mmap, template,
max);
}
aml_arena_register(arena, a);
return 0;
}
int aml_area_linux_destroy(struct aml_area_linux *area)
int aml_area_linux_init(struct aml_area *a, int manager_type,
int mbind_type, int mmap_type, ...)
{
int err;
va_list ap;
va_start(ap, mmap_type);
err = aml_area_linux_vinit(a, manager_type, mbind_type, mmap_type, ap);
va_end(ap);
return err;
}
int aml_area_linux_destroy(struct aml_area *a)
{
assert(area != NULL);
struct aml_area_linux *area = (struct aml_area_linux *)a->data;
struct aml_arena *arena = area->data.manager.pool;
aml_arena_deregister(arena);
aml_area_linux_mmap_anonymous_destroy(&area->data.mmap);
aml_area_linux_mbind_destroy(&area->data.mbind);
aml_area_linux_manager_single_destroy(&area->data.manager);
aml_arena_jemalloc_destroy(arena);
return 0;
}
#include <aml.h>
#include <assert.h>
int main(int argc, char *argv[])
{
struct aml_area area;
void *ptr;
unsigned long *a, *b, *c;
unsigned long i;
/* library initialization */
aml_init(&argc, &argv);
/* initialize the area itself */
aml_area_init(&area, &aml_area_regular);
/* try to allocate something */
ptr = aml_area_malloc(&area, sizeof(unsigned long) * 10);
assert(ptr != NULL);
a = (unsigned long *)ptr;
assert(a[0] == 0);
assert(a[0] == a[9]);
aml_area_free(&area, ptr);
/* libc API compatibility: malloc(0) */
ptr = aml_area_malloc(&area, 0);
assert(ptr == NULL);
aml_area_free(&area, ptr);
/* calloc */
ptr = aml_area_calloc(&area, 10, sizeof(unsigned long));
assert(ptr != NULL);
a = (unsigned long *)ptr;
assert(a[0] == 0);
assert(a[0] == a[9]);
aml_area_free(&area, ptr);
/* libc API compatibility: calloc(0) */
ptr = aml_area_calloc(&area, 0, sizeof(unsigned long));
assert(ptr == NULL);
ptr = aml_area_calloc(&area, 10, 0);
assert(ptr == NULL);
/* realloc */
ptr = aml_area_realloc(&area, NULL, sizeof(unsigned long) * 10);
assert(ptr != NULL);
ptr = aml_area_realloc(&area, ptr, sizeof(unsigned long) * 2);
assert(ptr != NULL);
ptr = aml_area_realloc(&area, ptr, sizeof(unsigned long) * 20);
assert(ptr != NULL);
ptr = aml_area_realloc(&area, ptr, 0);
aml_area_destroy(&area);
aml_finalize();
return 0;
}
......@@ -50,46 +50,29 @@ void doit(struct aml_area *area)
int main(int argc, char *argv[])
{
struct aml_area area;
AML_ARENA_JEMALLOC_DECL(arena);
struct aml_area_linux area_data;
AML_AREA_LINUX_DECL(area);
unsigned long nodemask[AML_NODEMASK_SZ];
struct bitmask *allowed;
/* library initialization */
aml_init(&argc, &argv);
/* initialize the area itself */
assert(!aml_area_linux_init(&area_data));
area.ops = &aml_area_linux_ops;
area.data = (struct aml_area_data*)&area_data;
/* ops init */
area_data.ops.manager = aml_area_linux_manager_single_ops;
area_data.ops.mbind = aml_area_linux_mbind_regular_ops;
area_data.ops.mmap = aml_area_linux_mmap_generic_ops;
/* init all the inner objects:
* WARNING: there an order to this madness. */
assert(!aml_arena_jemalloc_init(&arena, AML_ARENA_JEMALLOC_TYPE_REGULAR));
assert(!aml_area_linux_manager_single_init(&area_data.data.manager,
&arena));
/* init arguments */
allowed = numa_get_mems_allowed();
memcpy(nodemask, allowed->maskp, AML_NODEMASK_BYTES);
assert(!aml_area_linux_mbind_init(&area_data.data.mbind, MPOL_BIND,
nodemask));
assert(!aml_area_linux_mmap_anonymous_init(&area_data.data.mmap));
assert(!aml_arena_register(&arena, &area));
assert(!aml_arena_jemalloc_init(&arena, AML_ARENA_JEMALLOC_TYPE_REGULAR));
assert(!aml_area_linux_init(&area,
AML_AREA_LINUX_MANAGER_TYPE_SINGLE,
AML_AREA_LINUX_MBIND_TYPE_REGULAR,
AML_AREA_LINUX_MMAP_TYPE_ANONYMOUS,
&arena, MPOL_BIND, nodemask));
doit(&area);
/* same here, order matters. */
assert(!aml_arena_deregister(&arena));
assert(!aml_area_linux_mmap_anonymous_destroy(&area_data.data.mmap));
assert(!aml_area_linux_mbind_destroy(&area_data.data.mbind));
assert(!aml_area_linux_manager_single_destroy(&area_data.data.manager));
assert(!aml_arena_jemalloc_destroy(&arena));
assert(!aml_area_linux_destroy(&area_data));
assert(!aml_area_linux_destroy(&area));
aml_finalize();
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment