Skip to content

Commit

Permalink
obj: slab allocator example
Browse files Browse the repository at this point in the history
This is a simple example demonstrating the usage of the alloc class
CTL API to construct a slab-like allocator mechanism that
eliminates fragmentation for predefined structures.
  • Loading branch information
pbalcer committed Jul 25, 2017
1 parent e8574ee commit 7be1ecf
Show file tree
Hide file tree
Showing 5 changed files with 328 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/examples/libpmemobj/slab_allocator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
main
libslab_allocator.so

48 changes: 48 additions & 0 deletions src/examples/libpmemobj/slab_allocator/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright 2017, Intel Corporation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

#
# examples/libpmemobj/slab_allocator/Makefile -- build the slab_allocator example
#
TOP := $(dir $(lastword $(MAKEFILE_LIST)))../../../../
include $(TOP)/src/common.inc

PROGS = main
LIBRARIES = slab_allocator

LIBS = -lpmemobj

include ../../Makefile.inc

libslab_allocator.o: slab_allocator.o

main: main.o slab_allocator.o
121 changes: 121 additions & 0 deletions src/examples/libpmemobj/slab_allocator/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright 2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* main.c -- example usage of a slab-like mechanism implemented in libpmemobj
*
* This application does nothing besides demonstrating the example slab
* allocator mechanism.
*
* By using the CTL alloc class API we can instrument libpmemobj to optimally
* manage memory for the pool.
*/

#include <ex_common.h>
#include <assert.h>
#include <stdio.h>
#include "slab_allocator.h"

POBJ_LAYOUT_BEGIN(slab_allocator);
POBJ_LAYOUT_ROOT(slab_allocator, struct foo);
POBJ_LAYOUT_TOID(slab_allocator, struct bar);
POBJ_LAYOUT_TOID(slab_allocator, struct root);
POBJ_LAYOUT_END(slab_allocator);

struct foo {
char data[100];
};

struct bar {
char data[500];
};

struct root {
TOID(struct foo) foop;
TOID(struct bar) barp;
};

int
main(int argc, char *argv[])
{
if (argc < 2) {
printf("usage: %s file-name\n", argv[0]);
return 1;
}

const char *path = argv[1];

PMEMobjpool *pop;

if (file_exists(path) != 0) {
if ((pop = pmemobj_create(path, POBJ_LAYOUT_NAME(btree),
PMEMOBJ_MIN_POOL, 0666)) == NULL) {
perror("failed to create pool\n");
return 1;
}
} else {
if ((pop = pmemobj_open(path,
POBJ_LAYOUT_NAME(btree))) == NULL) {
perror("failed to open pool\n");
return 1;
}
}

struct slab_allocator *foo_producer = slab_new(pop, sizeof(struct foo));
assert(foo_producer != NULL);
struct slab_allocator *bar_producer = slab_new(pop, sizeof(struct bar));
assert(bar_producer != NULL);

TOID(struct root) root = POBJ_ROOT(pop, struct root);

if (TOID_IS_NULL(D_RO(root)->foop)) {
TX_BEGIN(pop) {
TX_SET(root, foop.oid, slab_tx_alloc(foo_producer));
} TX_END
}

if (TOID_IS_NULL(D_RO(root)->barp)) {
slab_alloc(bar_producer, &D_RW(root)->barp.oid, NULL, NULL);
}

assert(pmemobj_alloc_usable_size(D_RO(root)->foop.oid) ==
sizeof(struct foo));

assert(pmemobj_alloc_usable_size(D_RO(root)->barp.oid) ==
sizeof(struct bar));

slab_delete(foo_producer);
slab_delete(bar_producer);
pmemobj_close(pop);

return 0;
}
105 changes: 105 additions & 0 deletions src/examples/libpmemobj/slab_allocator/slab_allocator.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* slab_allocator.c -- slab-like mechanism for libpmemobj
*/

#include "slab_allocator.h"
#include <stdlib.h>

struct slab_allocator {
PMEMobjpool *pop;
struct pobj_alloc_class_desc class;
};

/*
* slab_new -- creates a new slab allocator instance
*/
struct slab_allocator *
slab_new(PMEMobjpool *pop, size_t size)
{
struct slab_allocator *slab = malloc(sizeof(struct slab_allocator));
if (slab == NULL)
return NULL;

slab->pop = pop;

slab->class.header_type = POBJ_HEADER_NONE;
slab->class.unit_size = size;

/* should be a reasonably high number, but not too crazy */
slab->class.units_per_block = 1000;

if (pmemobj_ctl_set(pop,
"heap.alloc_class.new.desc", &slab->class) != 0)
goto error;

return slab;

error:
free(slab);
return NULL;
}

/*
* slab_delete -- deletes an existing slab allocator instance
*/
void
slab_delete(struct slab_allocator *slab)
{
free(slab);
}

/*
* slab_alloc -- works just like pmemobj_alloc but uses the predefined
* blocks from the slab
*/
int
slab_alloc(struct slab_allocator *slab, PMEMoid *oid,
pmemobj_constr constructor, void *arg)
{
return pmemobj_xalloc(slab->pop, oid, slab->class.unit_size, 0,
POBJ_CLASS_ID(slab->class.class_id),
constructor, arg);
}

/*
* slab_tx_alloc -- works just like pmemobj_tx_alloc but uses the predefined
* blocks from the slab
*/
PMEMoid
slab_tx_alloc(struct slab_allocator *slab)
{
return pmemobj_tx_xalloc(slab->class.unit_size, 0,
POBJ_CLASS_ID(slab->class.class_id));
}
51 changes: 51 additions & 0 deletions src/examples/libpmemobj/slab_allocator/slab_allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2017, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* slab_allocator.h -- slab-like mechanism for libpmemobj
*/

#ifndef SLAB_ALLOCATOR_H
#define SLAB_ALLOCATOR_H

#include <libpmemobj.h>

struct slab_allocator;

struct slab_allocator *slab_new(PMEMobjpool *pop, size_t size);
void slab_delete(struct slab_allocator *slab);

int slab_alloc(struct slab_allocator *slab, PMEMoid *oid,
pmemobj_constr constructor, void *arg);
PMEMoid slab_tx_alloc(struct slab_allocator *slab);

#endif /* SLAB_ALLOCATOR_H */

0 comments on commit 7be1ecf

Please sign in to comment.