15
15
16
16
static volatile uint8_t * tree = 0 ;
17
17
static volatile uint32_t * index = 0 ;
18
+ static volatile uint64_t base_address = 0 ;
18
19
19
20
static volatile uint32_t depth = 0 ;
20
21
static volatile uint64_t tree_size = 0 ; /* bytes */
21
22
static volatile uint64_t index_size = 0 ; /* bytes */
22
23
23
24
static volatile uint64_t total_memory = 0 ;
24
- static volatile uint64_t max_level = 0 ; /* [0, depth] */
25
+ static volatile uint64_t max_level = 0 ;
25
26
static volatile uint64_t min_size = 0 ;
26
27
static volatile uint64_t max_size = 0 ;
27
28
28
- int nb_init (uint64_t base_addr , uint64_t size )
29
+ int nb_init (uint64_t base , uint64_t size )
29
30
{
30
- if (size < min_size ) {
31
+ if (base == 0 | size == 0 ) {
31
32
return 1 ;
32
33
}
33
34
34
- if (base_addr == 0 | size == 0 ) {
35
+ if (size < min_size ) {
35
36
return 1 ;
36
37
}
37
38
38
39
/* Setup */
40
+ base_address = base ;
39
41
total_memory = size ;
40
42
min_size = PAGE_SIZE ;
41
- depth = LOG2 (total_memory / min_size ) - 1 ;
43
+ depth = LOG2_LOWER (total_memory / min_size );
42
44
max_level = 0 ;
43
- max_size = ( EXP2 (depth - max_level ) * min_size ) ;
45
+ max_size = EXP2 (depth - max_level ) * min_size ;
44
46
45
47
/* Calculate required tree size */
46
- uint32_t total_nodes = 1 ; // we start at idx 1
47
- for (uint32_t i = 0 ; i < depth ; i ++ ) {
48
- total_nodes += (size / (EXP2 (i ) * min_size ));
48
+ uint32_t total_nodes = 1 ; // we have garbage node at idx 0
49
+ for (uint32_t i = 0 ; i <= depth ; i ++ ) {
50
+ total_nodes += (total_memory / (EXP2 (i ) * min_size ));
49
51
}
50
52
51
53
/* Calculate required index size */
52
- uint32_t total_elems = (size / min_size );
54
+ uint32_t total_pages = (total_memory / min_size );
53
55
54
- tree_size = total_nodes * 1 ; // each node is 1 byte
55
- index_size = total_elems * 4 ; // each elem is 4 byte
56
+ tree_size = total_nodes * 1 ; // each node is 1 byte
57
+ index_size = total_pages * 4 ; // each page id is 4 byte
56
58
57
59
/* Allocate */
58
60
uint32_t req_pages = (tree_size + PAGE_SIZE - 1 ) / PAGE_SIZE ;
@@ -76,9 +78,54 @@ int nb_init(uint64_t base_addr, uint64_t size)
76
78
return 0 ;
77
79
}
78
80
81
+ uint32_t try_alloc (uint32_t node )
82
+ {
83
+ return 1 ;
84
+ }
85
+
79
86
void * nb_alloc (uint64_t size )
80
87
{
88
+ if (max_size < size ) {
89
+ return 0 ;
90
+ }
81
91
92
+ if (size < min_size ) {
93
+ size = min_size ;
94
+ }
95
+
96
+ uint32_t level = LOG2_LOWER (total_memory / size );
97
+
98
+ if (depth < level ) {
99
+ level = depth ;
100
+ }
101
+
102
+ /* Range of nodes at target level */
103
+ uint32_t start_node = EXP2 (level );
104
+ uint32_t end_node = EXP2 (level + 1 );
105
+
106
+ for (uint32_t i = start_node ; i < end_node ; i ++ ) {
107
+ if (is_free (tree [i ])) {
108
+ uint32_t failed_at = try_alloc (i );
109
+
110
+ if (!failed_at ) {
111
+ /* TODO: Explain what's going on here */
112
+ uint32_t leaf = leftmost (i , depth ) - EXP2 (depth );
113
+ index [leaf ] = i ;
114
+
115
+ return (void * ) (base_address + leaf * min_size );
116
+ } else {
117
+ /* Skip the entire subtree [of failed] */
118
+ uint32_t curr_level = LOG2_LOWER (i );
119
+ uint32_t fail_level = LOG2_LOWER (failed_at );
120
+
121
+ uint32_t d = EXP2 (curr_level - fail_level );
122
+ i = (failed_at + 1 ) * d ;
123
+ }
124
+ }
125
+ }
126
+
127
+ return (void * ) 0 ;
128
+
82
129
}
83
130
84
131
void * nb_free (void * addr )
0 commit comments