1
1
/*
2
- * Copyright (c) 2014-2018 ARM Limited. All rights reserved.
2
+ * Copyright (c) 2014-2019 ARM Limited. All rights reserved.
3
3
* SPDX-License-Identifier: Apache-2.0
4
4
* Licensed under the Apache License, Version 2.0 (the License); you may
5
5
* not use this file except in compliance with the License.
@@ -33,10 +33,13 @@ typedef struct {
33
33
34
34
typedef int ns_mem_word_size_t ; // internal signed heap block size type
35
35
36
+ // Amount of memory regions
37
+ #define REGION_COUNT 3
38
+
36
39
/* struct for book keeping variables */
37
40
struct ns_mem_book {
38
- ns_mem_word_size_t * heap_main ;
39
- ns_mem_word_size_t * heap_main_end ;
41
+ ns_mem_word_size_t * heap_main [ REGION_COUNT ] ;
42
+ ns_mem_word_size_t * heap_main_end [ REGION_COUNT ] ;
40
43
mem_stat_t * mem_stat_info_ptr ;
41
44
void (* heap_failure_callback )(heap_fail_t );
42
45
NS_LIST_HEAD (hole_t , link ) holes_list ;
@@ -68,14 +71,49 @@ static void heap_failure(ns_mem_book_t *book, heap_fail_t reason)
68
71
}
69
72
}
70
73
71
- #endif
74
+ static int ns_dyn_mem_region_find (ns_mem_book_t * book , ns_mem_word_size_t * block_ptr , ns_mem_word_size_t size )
75
+ {
76
+ int index ;
77
+ for (index = 0 ; index < REGION_COUNT ; index ++ ) {
78
+ if (book -> heap_main [index ] != 0 ) {
79
+ if ((block_ptr >= book -> heap_main [index ]) &&
80
+ (block_ptr < book -> heap_main_end [index ]) &&
81
+ ((block_ptr + size ) < book -> heap_main_end [index ])) {
82
+ return index ;
83
+ }
84
+ }
85
+ }
86
+
87
+ return -1 ;
88
+ }
89
+
90
+ static int ns_dyn_mem_region_save (ns_mem_book_t * book , ns_mem_word_size_t * region_start_ptr , ns_mem_word_size_t region_size )
91
+ {
92
+ for (int i = 1 ; i < REGION_COUNT ; i ++ ) {
93
+ if (book -> heap_main [i ] == 0 ) {
94
+ book -> heap_main [i ] = region_start_ptr ;
95
+ book -> heap_main_end [i ] = book -> heap_main [i ] + region_size ;
96
+ return 0 ;
97
+ }
98
+ }
99
+
100
+ return -1 ;
101
+ }
102
+
103
+
104
+ #endif //STANDARD_MALLOC
72
105
73
106
void ns_dyn_mem_init (void * heap , ns_mem_heap_size_t h_size ,
74
107
void (* passed_fptr )(heap_fail_t ), mem_stat_t * info_ptr )
75
108
{
76
109
default_book = ns_mem_init (heap , h_size , passed_fptr , info_ptr );
77
110
}
78
111
112
+ int ns_dyn_mem_region_add (void * region_ptr , ns_mem_heap_size_t region_size )
113
+ {
114
+ return ns_mem_region_add (default_book , region_ptr , region_size );
115
+ }
116
+
79
117
const mem_stat_t * ns_dyn_mem_get_mem_stat (void )
80
118
{
81
119
#ifndef STANDARD_MALLOC
@@ -85,7 +123,6 @@ const mem_stat_t *ns_dyn_mem_get_mem_stat(void)
85
123
#endif
86
124
}
87
125
88
-
89
126
ns_mem_book_t * ns_mem_init (void * heap , ns_mem_heap_size_t h_size ,
90
127
void (* passed_fptr )(heap_fail_t ),
91
128
mem_stat_t * info_ptr )
@@ -107,19 +144,23 @@ ns_mem_book_t *ns_mem_init(void *heap, ns_mem_heap_size_t h_size,
107
144
if (temp_int ) {
108
145
h_size -= (sizeof (ns_mem_word_size_t ) - temp_int );
109
146
}
147
+
110
148
book = heap ;
111
- book -> heap_main = (ns_mem_word_size_t * ) & (book [1 ]); // SET Heap Pointer
149
+ memset (book -> heap_main , 0 , REGION_COUNT * sizeof (ns_mem_word_size_t * ));
150
+ memset (book -> heap_main_end , 0 , REGION_COUNT * sizeof (ns_mem_word_size_t * ));
151
+
152
+ book -> heap_main [0 ] = (ns_mem_word_size_t * ) & (book [1 ]); // SET Heap Pointer
112
153
book -> heap_size = h_size - sizeof (ns_mem_book_t ); //Set Heap Size
113
154
temp_int = (book -> heap_size / sizeof (ns_mem_word_size_t ));
114
155
temp_int -= 2 ;
115
- ptr = book -> heap_main ;
156
+ ptr = book -> heap_main [ 0 ] ;
116
157
* ptr = - (temp_int );
117
158
ptr += (temp_int + 1 );
118
159
* ptr = - (temp_int );
119
- book -> heap_main_end = ptr ;
160
+ book -> heap_main_end [ 0 ] = ptr ;
120
161
121
162
ns_list_init (& book -> holes_list );
122
- ns_list_add_to_start (& book -> holes_list , hole_from_block_start (book -> heap_main ));
163
+ ns_list_add_to_start (& book -> holes_list , hole_from_block_start (book -> heap_main [ 0 ] ));
123
164
124
165
book -> mem_stat_info_ptr = info_ptr ;
125
166
//RESET Memory by Hea Len
@@ -135,6 +176,81 @@ ns_mem_book_t *ns_mem_init(void *heap, ns_mem_heap_size_t h_size,
135
176
return book ;
136
177
}
137
178
179
+ int ns_mem_region_add (ns_mem_book_t * book , void * region_ptr , ns_mem_heap_size_t region_size )
180
+ {
181
+ #ifndef STANDARD_MALLOC
182
+ if (!book || !region_ptr || region_size < 3 * sizeof (ns_mem_word_size_t )) {
183
+ return -1 ;
184
+ }
185
+
186
+ ns_mem_word_size_t * block_ptr ;
187
+ ns_mem_word_size_t temp_int ;
188
+
189
+ /* Do memory alignment */
190
+ temp_int = ((uintptr_t )region_ptr % sizeof (ns_mem_word_size_t ));
191
+ if (temp_int ) {
192
+ region_ptr = (uint8_t * ) region_ptr + (sizeof (ns_mem_word_size_t ) - temp_int );
193
+ region_size -= (sizeof (ns_mem_word_size_t ) - temp_int );
194
+ }
195
+
196
+ /* Make correction for total length */
197
+ temp_int = (region_size % sizeof (ns_mem_word_size_t ));
198
+ if (temp_int ) {
199
+ region_size -= (sizeof (ns_mem_word_size_t ) - temp_int );
200
+ }
201
+
202
+ // Create hole from new heap memory
203
+ temp_int = (region_size / sizeof (ns_mem_word_size_t ));
204
+ temp_int -= 2 ;
205
+ block_ptr = region_ptr ;
206
+ * block_ptr = - (temp_int );
207
+ block_ptr += (temp_int + 1 ); // now block_ptr points to end of block
208
+ * block_ptr = - (temp_int );
209
+
210
+ // find place for the new hole from the holes list
211
+ hole_t * hole_to_add = hole_from_block_start (region_ptr );
212
+ hole_t * previous_hole = NULL ;
213
+ ns_list_foreach (hole_t , hole_in_list_ptr , & book -> holes_list ) {
214
+ if (hole_in_list_ptr < hole_to_add ) {
215
+ previous_hole = hole_in_list_ptr ;
216
+ } else if (hole_in_list_ptr == hole_to_add ) {
217
+ // trying to add memory block that is already in the list!
218
+ return -2 ;
219
+ }
220
+ }
221
+
222
+ // save region
223
+ if (ns_dyn_mem_region_save (book , region_ptr , (region_size / (sizeof (ns_mem_word_size_t ))) - 1 ) != 0 ) {
224
+ return -3 ;
225
+ }
226
+
227
+ // Add new hole to the list
228
+ if (previous_hole ) {
229
+ ns_list_add_after (& book -> holes_list , previous_hole , hole_to_add );
230
+ } else {
231
+ ns_list_add_to_start (& book -> holes_list , hole_to_add );
232
+ }
233
+
234
+ // adjust total heap size with new hole
235
+ book -> heap_size += region_size ;
236
+
237
+ if (book -> mem_stat_info_ptr ) {
238
+ book -> mem_stat_info_ptr -> heap_sector_size = book -> heap_size ;
239
+ }
240
+
241
+ // adjust temporary allocation limits to match new heap
242
+ book -> temporary_alloc_heap_limit = book -> heap_size / 100 * (100 - TEMPORARY_ALLOC_FREE_HEAP_THRESHOLD );
243
+
244
+ return 0 ;
245
+ #else
246
+ (void ) book ;
247
+ (void ) region_ptr ;
248
+ (void ) region_size ;
249
+
250
+ return -1 ;
251
+ #endif
252
+ }
253
+
138
254
const mem_stat_t * ns_mem_get_mem_stat (ns_mem_book_t * heap )
139
255
{
140
256
#ifndef STANDARD_MALLOC
@@ -211,7 +327,7 @@ static void dev_stat_update(mem_stat_t *mem_stat_info_ptr, mem_stat_update_t typ
211
327
212
328
static ns_mem_word_size_t convert_allocation_size (ns_mem_book_t * book , ns_mem_block_size_t requested_bytes )
213
329
{
214
- if (book -> heap_main == 0 ) {
330
+ if (book -> heap_main [ 0 ] == 0 ) {
215
331
heap_failure (book , NS_DYN_MEM_HEAP_SECTOR_UNITIALIZED );
216
332
} else if (requested_bytes < 1 ) {
217
333
heap_failure (book , NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID );
@@ -329,7 +445,6 @@ static void *ns_mem_internal_alloc(ns_mem_book_t *book, const ns_mem_block_size_
329
445
if (block_ptr ) {
330
446
//Update Allocate OK
331
447
dev_stat_update (book -> mem_stat_info_ptr , DEV_HEAP_ALLOC_OK , (data_size + 2 ) * sizeof (ns_mem_word_size_t ));
332
-
333
448
} else {
334
449
//Update Allocate Fail, second parameter is used for stats
335
450
dev_stat_update (book -> mem_stat_info_ptr , DEV_HEAP_ALLOC_FAIL , 0 );
@@ -381,12 +496,25 @@ static void ns_mem_free_and_merge_with_adjacent_blocks(ns_mem_book_t *book, ns_m
381
496
hole_t * existing_end = NULL ;
382
497
ns_mem_word_size_t * start = cur_block ;
383
498
ns_mem_word_size_t * end = cur_block + data_size + 1 ;
499
+ ns_mem_word_size_t * region_start ;
500
+ ns_mem_word_size_t * region_end ;
501
+
502
+ int region_index = ns_dyn_mem_region_find (book , cur_block , data_size );
503
+ if (region_index >= 0 ) {
504
+ region_start = book -> heap_main [region_index ];
505
+ region_end = book -> heap_main_end [region_index ];
506
+ } else {
507
+ heap_failure (book , NS_DYN_MEM_HEAP_SECTOR_CORRUPTED );
508
+ // can't find region for the block, return
509
+ return ;
510
+ }
511
+
384
512
//invalidate current block
385
513
* start = - data_size ;
386
514
* end = - data_size ;
387
515
ns_mem_word_size_t merged_data_size = data_size ;
388
516
389
- if (start != book -> heap_main ) {
517
+ if (start != region_start ) {
390
518
if (* (start - 1 ) < 0 ) {
391
519
ns_mem_word_size_t * block_end = start - 1 ;
392
520
ns_mem_word_size_t block_size = 1 + (- * block_end ) + 1 ;
@@ -401,7 +529,7 @@ static void ns_mem_free_and_merge_with_adjacent_blocks(ns_mem_book_t *book, ns_m
401
529
}
402
530
}
403
531
404
- if (end != book -> heap_main_end ) {
532
+ if (end != region_end ) {
405
533
if (* (end + 1 ) < 0 ) {
406
534
ns_mem_word_size_t * block_start = end + 1 ;
407
535
ns_mem_word_size_t block_size = 1 + (- * block_start ) + 1 ;
@@ -457,6 +585,16 @@ static void ns_mem_free_and_merge_with_adjacent_blocks(ns_mem_book_t *book, ns_m
457
585
}
458
586
#endif
459
587
588
+ static bool pointer_address_validate (ns_mem_book_t * book , ns_mem_word_size_t * ptr , ns_mem_word_size_t size )
589
+ {
590
+
591
+ if (ns_dyn_mem_region_find (book , ptr , size ) >= 0 ) {
592
+ return true;
593
+ }
594
+
595
+ return false;
596
+ }
597
+
460
598
void ns_mem_free (ns_mem_book_t * book , void * block )
461
599
{
462
600
#ifndef STANDARD_MALLOC
@@ -472,9 +610,7 @@ void ns_mem_free(ns_mem_book_t *book, void *block)
472
610
ptr -- ;
473
611
//Read Current Size
474
612
size = * ptr ;
475
- if (ptr < book -> heap_main || ptr >= book -> heap_main_end ) {
476
- heap_failure (book , NS_DYN_MEM_POINTER_NOT_VALID );
477
- } else if ((ptr + size ) >= book -> heap_main_end ) {
613
+ if (!pointer_address_validate (book , ptr , size )) {
478
614
heap_failure (book , NS_DYN_MEM_POINTER_NOT_VALID );
479
615
} else if (size < 0 ) {
480
616
heap_failure (book , NS_DYN_MEM_DOUBLE_FREE );
@@ -489,6 +625,7 @@ void ns_mem_free(ns_mem_book_t *book, void *block)
489
625
}
490
626
}
491
627
}
628
+
492
629
platform_exit_critical ();
493
630
#else
494
631
platform_enter_critical ();
0 commit comments