blob: d67f46495f3157f566779b461bdb697a169daad2 (
plain)
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
|
/*
* libc/stdlib/malloc/heap_append_free.c -- append memory to a heap free area
*
* Copyright (C) 2002 NEC Corporation
* Copyright (C) 2002 Miles Bader <miles@gnu.org>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License. See the file COPYING.LIB in the main
* directory of this archive for more details.
*
* Written by Miles Bader <miles@gnu.org>
*/
#include <stdlib.h>
#include "heap.h"
/* If the block MEM, of size SIZE, immediately follows an existing free-area
in HEAP, use it to extend that free-area, and return true; otherwise return
false. */
int
__heap_append_free (struct heap *heap, void *mem, size_t size)
{
int success = 0;
struct heap_free_area *fa;
__heap_lock (heap);
HEAP_DEBUG (heap, "before __heap_append_free");
/* Find an adjacent free-list entry. */
for (fa = heap->free_areas; fa; fa = fa->next)
if (HEAP_FREE_AREA_END (fa) == mem)
/* MEM follows FA, extend FA to include it. Since the descriptor for FA
is located at the end, we must actually write a new descriptor. Note
that we _don't_ handle the case where the extended FA can be merged
with a following free area; this is because this function is
generally only used in cases were we believe that usually won't
happen (it doesn't cause any incorrectness, and the two blocks can be
merged by __heap_free later). */
{
struct heap_free_area *next_fa = fa->next;
struct heap_free_area *prev_fa = fa->prev;
size_t fa_size = fa->size;
struct heap_free_area *new_fa =
(struct heap_free_area *)((char *)fa + size);
/* Update surrounding free-areas to point to FA's new address. */
if (prev_fa)
prev_fa->next = new_fa;
else
heap->free_areas = new_fa;
if (next_fa)
next_fa->prev = new_fa;
/* Fill in the moved descriptor. */
new_fa->prev = prev_fa;
new_fa->next = next_fa;
new_fa->size = fa_size + size;
success = 1;
break;
}
HEAP_DEBUG (heap, "after __heap_append_free");
__heap_unlock (heap);
return success;
}
|