1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#include <allocman/mspace/dual_pool.h>
14#include <allocman/allocman.h>
15#include <allocman/util.h>
16#include <stdlib.h>
17
18void mspace_dual_pool_create(mspace_dual_pool_t *dual_pool, struct mspace_fixed_pool_config config)
19{
20    *dual_pool = (mspace_dual_pool_t) {
21        .fixed_pool_start = (uintptr_t)config.pool,
22        .fixed_pool_end = (size_t)config.pool + config.size,
23        .have_virtual_pool = 0
24    };
25    mspace_fixed_pool_create(&dual_pool->fixed_pool, config);
26}
27
28void mspace_dual_pool_attach_virtual(mspace_dual_pool_t *dual_pool, struct mspace_virtual_pool_config config) {
29    mspace_virtual_pool_create(&dual_pool->virtual_pool, config);
30    dual_pool->have_virtual_pool = 1;
31}
32
33void *_mspace_dual_pool_alloc(allocman_t *alloc, void *_dual_pool, size_t bytes, int *error)
34{
35    mspace_dual_pool_t *dual_pool = (mspace_dual_pool_t*)_dual_pool;
36    /* if we have a virtual pool try and use this instead of wasting time in the fixed pool */
37    if (dual_pool->have_virtual_pool) {
38        int _error;
39        void *ret = _mspace_virtual_pool_alloc(alloc, &dual_pool->virtual_pool, bytes, &_error);
40        if (!_error) {
41            SET_ERROR(error, 0);
42            return ret;
43        }
44    }
45    /* try from the fixed pool */
46    return _mspace_fixed_pool_alloc(alloc, &dual_pool->fixed_pool, bytes, error);
47}
48
49void _mspace_dual_pool_free(struct allocman *alloc, void *_dual_pool, void *ptr, size_t bytes)
50{
51    mspace_dual_pool_t *dual_pool = (mspace_dual_pool_t*)_dual_pool;
52    if ( (uintptr_t)ptr >= dual_pool->fixed_pool_start && (uintptr_t)ptr < dual_pool->fixed_pool_end) {
53        _mspace_fixed_pool_free(alloc, &dual_pool->fixed_pool, ptr, bytes);
54    } else {
55        _mspace_virtual_pool_free(alloc, &dual_pool->virtual_pool, ptr, bytes);
56    }
57}
58