1/**
2 * \file
3 * \brief Slot allocator
4 */
5
6/*
7 * Copyright (c) 2010, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef SLOT_ALLOC_H
16#define SLOT_ALLOC_H
17
18#include <sys/cdefs.h>
19
20#include <barrelfish/threads.h>
21#include <barrelfish/slab.h>
22#include <barrelfish/vspace_common.h>
23
24__BEGIN_DECLS
25
26struct slot_allocator {
27    errval_t (*alloc)(struct slot_allocator *ca, struct capref *cap);
28    errval_t (*free)(struct slot_allocator *ca, struct capref cap);
29    struct thread_mutex mutex;     ///< Mutex for thread safety
30    cslot_t nslots;                ///< Slots to grow allocator by
31    cslot_t space;                 ///< Space left in the allocator
32};
33
34/// Meta data for single_slot_allocator
35struct cnode_meta {
36    cslot_t slot;
37    cslot_t space;
38    struct cnode_meta *next;
39};
40
41struct single_slot_allocator {
42    struct slot_allocator a;    ///< Public data
43    struct capref cap;          ///< Cap of the cnode the allocator is tracking
44    struct cnoderef cnode;      ///< Cnode the allocator is tracking
45    struct cnode_meta *head;    ///< Linked list of free slots
46    struct slab_allocator slab;     ///< Slab for backing the list
47};
48
49struct slot_allocator_list {
50    struct single_slot_allocator a;
51    struct slot_allocator_list *next;
52};
53
54struct multi_slot_allocator {
55    struct slot_allocator a;      ///< Public data
56
57    struct slot_allocator_list *head; ///< List of single slot allocators
58    struct slot_allocator_list *reserve; ///< One single allocator in reserve
59
60    struct slab_allocator slab;      ///< Slab backing the slot_allocator_list
61
62    struct vspace_mmu_aware mmu_state;
63};
64
65struct range_slot_allocator {
66    struct capref cnode_cap;     ///< capref for the L1 cnode
67    struct cnoderef cnode;       ///< cnoderef for the cnode to allocate from
68    struct cnode_meta *meta;     ///< Linked list of meta data
69    struct slab_allocator slab;      ///< Slab allocation
70    struct thread_mutex mutex;   ///< Mutex for thread safety (used when is_head == true)
71    struct range_slot_allocator *next; ///< Next slot allocator
72    bool is_head; ///< Is this instance head of a chain
73};
74
75// single_slot_alloc_init_raw() requires a specific buflen
76#define SINGLE_SLOT_ALLOC_BUFLEN(nslots) \
77    (SLAB_STATIC_SIZE(nslots / 2, sizeof(struct cnode_meta)))
78
79errval_t single_slot_alloc_init(struct single_slot_allocator *ret,
80                                cslot_t nslots, cslot_t *retslots);
81errval_t single_slot_alloc_init_raw(struct single_slot_allocator *ret,
82                                    struct capref cap, struct cnoderef cnode,
83                                    cslot_t nslots, void *buf, size_t buflen);
84
85cslot_t single_slot_alloc_freecount(struct single_slot_allocator *s);
86errval_t single_slot_alloc_resize(struct single_slot_allocator *this,
87                                  cslot_t newslotcount);
88
89errval_t two_level_slot_alloc_init(struct multi_slot_allocator *ret);
90errval_t two_level_slot_alloc_init_raw(struct multi_slot_allocator *ret,
91                                       struct capref initial_cap,
92                                       struct cnoderef initial_cnode,
93                                       struct capref reserve_cap,
94                                       struct cnoderef reserve_cnode,
95                                       void *head_buf, void *reserve_buf, size_t bufsize);
96
97errval_t slot_alloc_init(void);
98struct slot_allocator *get_default_slot_allocator(void);
99errval_t slot_alloc(struct capref *ret);
100
101/// Root slot allocator functions
102errval_t slot_alloc_root(struct capref *ret);
103typedef errval_t (*cn_ram_alloc_func_t)(void *st, uint8_t reqbits, struct capref *ret);
104errval_t root_slot_allocator_refill(cn_ram_alloc_func_t myalloc, void *allocst);
105
106errval_t slot_free(struct capref ret);
107
108errval_t range_slot_alloc(struct range_slot_allocator *alloc, cslot_t nslots,
109                          struct capref *ret);
110errval_t range_slot_free(struct range_slot_allocator *alloc, struct capref cap,
111                         cslot_t nslots);
112errval_t range_slot_alloc_init(struct range_slot_allocator *ret,
113                               cslot_t nslots, cslot_t *retslots);
114size_t range_slot_alloc_freecount(struct range_slot_allocator *alloc);
115errval_t range_slot_alloc_refill(struct range_slot_allocator *alloc, cslot_t slots);
116
117__END_DECLS
118
119#endif // SLOT_ALLOC_H
120