summaryrefslogtreecommitdiffstats
path: root/cpukit/sapi/include/rtems/rbheap.h
blob: be1eec6b66b02785beb843818830ed98cac21143 (plain) (blame)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
 * @file
 *
 * @ingroup RBHeap
 *
 * @brief Red-Black Tree Heap API.
 */

/*
 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
 *
 *  embedded brains GmbH
 *  Obere Lagerstr. 30
 *  82178 Puchheim
 *  Germany
 *  <rtems@embedded-brains.de>
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.com/license/LICENSE.
 */

#ifndef _RTEMS_RBHEAP_H
#define _RTEMS_RBHEAP_H

#include <rtems.h>
#include <rtems/chain.h>
#include <rtems/rbtree.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @defgroup RBHeap Red-Black Tree Heap
 *
 * @brief Red-Black Tree Heap API.
 *
 * In the Red-Black Tree Heap the administration data structures are not
 * contained in the managed memory area.  This can be used for example in a
 * task stack allocator which protects the task stacks from access by other
 * tasks.
 *
 * @{
 */

typedef struct {
  rtems_chain_node chain_node;
  rtems_rbtree_node tree_node;
  uintptr_t begin;
  uintptr_t size;
} rtems_rbheap_page;

typedef struct rtems_rbheap_control rtems_rbheap_control;

typedef void (*rtems_rbheap_extend_page_pool)(rtems_rbheap_control *control);

struct rtems_rbheap_control {
  rtems_chain_control free_chain;
  rtems_chain_control pool_chain;
  rtems_rbtree_control page_tree;
  uintptr_t page_alignment;
  rtems_rbheap_extend_page_pool extend_page_pool;
  void *handler_arg;
};

rtems_status_code rtems_rbheap_initialize(
  rtems_rbheap_control *control,
  void *area_begin,
  uintptr_t area_size,
  uintptr_t page_alignment,
  rtems_rbheap_extend_page_pool extend_page_pool,
  void *handler_arg
);

void *rtems_rbheap_allocate(rtems_rbheap_control *control, size_t size);

rtems_status_code rtems_rbheap_free(rtems_rbheap_control *control, void *ptr);

static inline rtems_chain_control *rtems_rbheap_get_pool_chain(
  rtems_rbheap_control *control
)
{
  return &control->pool_chain;
}

static inline void rtems_rbheap_set_extend_page_pool(
  rtems_rbheap_control *control,
  rtems_rbheap_extend_page_pool extend_page_pool
)
{
  control->extend_page_pool = extend_page_pool;
}

static inline void *rtems_rbheap_get_handler_arg(
  const rtems_rbheap_control *control
)
{
  return control->handler_arg;
}

static inline void rtems_rbheap_set_handler_arg(
  rtems_rbheap_control *control,
  void *handler_arg
)
{
  control->handler_arg = handler_arg;
}

void rtems_rbheap_extend_page_pool_never(rtems_rbheap_control *control);

void rtems_rbheap_extend_page_pool_with_malloc(rtems_rbheap_control *control);

/** @} */

/* Private API */

#define rtems_rbheap_page_of_node(node) \
  rtems_rbtree_container_of(node, rtems_rbheap_page, tree_node)

static inline bool rtems_rbheap_is_page_free(const rtems_rbheap_page *page)
{
  return !rtems_chain_is_node_off_chain(&page->chain_node);
}

#ifdef __cplusplus
}
#endif

#endif /* _RTEMS_RBHEAP_H */