source: mainline/src/mm/heap.c@ 623ba26c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 623ba26c was 9c0a9b3, checked in by Jakub Vana <jakub.vana@…>, 20 years ago

1) memcopy and _memcopy functions rewriten to ANSI C norm.
2) Repaired ia32,ia64 and mips version of SPARTAN to work with this memcopy functions
3) Warning for non declared funcions added and repaired ia32,ia64 and mips versions to pass build process with this warning and Werror option

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 * Copyright (C) 2001-2004 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <mm/heap.h>
30#include <synch/spinlock.h>
31#include <func.h>
32#include <memstr.h>
33#include <panic.h>
34#include <arch/types.h>
35#include <arch/asm.h>
36#include <arch.h>
37
38/*
39 * First-fit algorithm.
40 * Simple, but hopefully correct.
41 * Chunks being freed are tested for mergability with their neighbours.
42 */
43
44static chunk_t *chunk0;
45static spinlock_t heaplock;
46
47void heap_init(__address heap, size_t size)
48{
49 spinlock_initialize(&heaplock);
50 memsetb(heap, size, 0);
51 chunk0 = (chunk_t *) heap;
52 chunk0->used = 0;
53 chunk0->size = size - sizeof(chunk_t);
54 chunk0->next = NULL;
55 chunk0->prev = NULL;
56}
57
58/*
59 * Uses first-fit algorithm.
60 */
61void *malloc(size_t size)
62{
63 pri_t pri;
64 chunk_t *x, *y, *z;
65
66 if (size == 0)
67 panic("zero-size allocation request");
68
69 x = chunk0;
70 pri = cpu_priority_high();
71 spinlock_lock(&heaplock);
72 while (x) {
73 if (x->used || x->size < size) {
74 x = x->next;
75 continue;
76 }
77
78 x->used = 1;
79
80 /*
81 * If the chunk exactly matches required size or if truncating
82 * it would not provide enough space for storing a new chunk
83 * header plus at least one byte of data, we are finished.
84 */
85 if (x->size < size + sizeof(chunk_t) + 1) {
86 spinlock_unlock(&heaplock);
87 cpu_priority_restore(pri);
88 return &x->data[0];
89 }
90
91 /*
92 * Truncate x and create a new chunk.
93 */
94 y = (chunk_t *) (((__address) x) + size + sizeof(chunk_t));
95 y->used = 0;
96 y->size = x->size - size - sizeof(chunk_t);
97 y->prev = x;
98 y->next = NULL;
99
100 if (z = x->next) {
101 z->prev = y;
102 y->next = z;
103 }
104
105 x->size = size;
106 x->next = y;
107 spinlock_unlock(&heaplock);
108 cpu_priority_restore(pri);
109
110 return &x->data[0];
111 }
112 spinlock_unlock(&heaplock);
113 cpu_priority_restore(pri);
114 return NULL;
115}
116
117void free(void *ptr)
118{
119 pri_t pri;
120 chunk_t *x, *y, *z;
121
122 if (!ptr)
123 panic("free on NULL");
124
125
126 y = (chunk_t *) (((__u8 *) ptr) - sizeof(chunk_t));
127 if (y->used != 1)
128 panic("freeing unused/damaged chunk");
129
130 pri = cpu_priority_high();
131 spinlock_lock(&heaplock);
132 x = y->prev;
133 z = y->next;
134 /* merge x and y */
135 if (x && !x->used) {
136 x->size += y->size + sizeof(chunk_t);
137 x->next = z;
138 if (z)
139 z->prev = x;
140 y = x;
141 }
142 /* merge y and z or merge (x merged with y) and z */
143 if (z && !z->used) {
144 y->size += z->size + sizeof(chunk_t);
145 y->next = z->next;
146 if (z->next) {
147 /* y is either y or x */
148 z->next->prev = y;
149 }
150 }
151 y->used = 0;
152 spinlock_unlock(&heaplock);
153 cpu_priority_restore(pri);
154}
Note: See TracBrowser for help on using the repository browser.