1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#pragma once
#include <types.h>
/* Define SLAB_REDZONE to add top and bottom redzones to every object. */
#define SLAB_REDZONE 0xdeadbeefdeadbeef
/* Define SLAB_CHECK_FREE to add extra book keeping to make sure there
* are no double frees. */
#define SLAB_CHECK_FREE
/*
* The slab allocator. A "cache" is a store of objects; you create one by
* specifying a constructor, destructor, and the size of an object. The
* "alloc" function allocates one object, and the "free" function returns
* it to the free list *without calling the destructor*. This lets you save
* on destruction/construction calls; the idea is that every free object in
* the cache is in a known state.
*/
typedef struct slab_allocator slab_allocator_t;
/* Initializes the slab allocator subsystem. This should be done
* only after the page subsystem has been initialized. Slab allocators
* and kmalloc will not work until this function has been called. */
void slab_init();
/*
* Example Usage
* See the below example for how to use a slab allocator to allocate objects
* of a given size. Note that you usually don't need to destroy most allocators,
* as they should last as long as the system is running (e.g. the process allocator).
*
* ```
* typedef struct {
* int x;
* int y;
* } point_t;
*
* // Create a new allocator for objects of type point_t. This only needs to
* // happen once, usually in an initialization routine.
* slab_allocator_t *point_allocator = slab_allocator_create("point", sizeof(point_t));
*
* // Allocate a new point_t from the slab allocator
* point_t *p = (point_t *)slab_obj_alloc(point_allocator);
*
* // ... Use p here ...
*
* // Deallocate the point_t
* slab_obj_free(point_allocator, p);
* ```
*/
/**
* Creates a slab allocator for allocating objects of a given size.
*
* @param name The name of the allocator (for debugging)
* @param size The size (bytes) of objects that will be allocated from this allocator
* @return slab_allocator_t* An allocator, or NULL on failure
*/
slab_allocator_t *slab_allocator_create(const char *name, size_t size);
/**
* Destroys a slab allocator.
*
* @param allocator The allocator to destroy
*/
void slab_allocator_destroy(struct slab_allocator *allocator);
/**
* Allocates an object from the given slab allocator. The object is a chunk of
* memory as big as the size that slab allocator was created with.
*
* @param allocator The allocator to allocate from
* @return void* A chunk of memory of the appropriate object size, or NULL
* on failure
*/
void *slab_obj_alloc(slab_allocator_t *allocator);
/**
* Frees a given object that was allocated by a given slab allocator.
*
* @param allocator The allocator that allocated this object
* @param obj The object to be freed
*/
void slab_obj_free(slab_allocator_t *allocator, void *obj);
/**
* Reclaims memory from unused slabs.
*
* NOTE: This is not currently implemented.
*
* @param target Target number of pages to reclaim. If negative, reclaim as many
* as possible
* @return long Number of pages freed
*/
long slab_allocators_reclaim(long target);
|