some fixes to accented characters
[tangerine.git] / rom / exec / deallocate.c
blob42709bf5359e80aa0dcc48b600da58d87de508e8
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Free memory allocated by Allocate().
6 Lang: english
7 */
8 #include <exec/execbase.h>
9 #include <exec/alerts.h>
10 #include <aros/libcall.h>
11 #include "memory.h"
12 #include <exec/memory.h>
13 #include <proto/exec.h>
15 /*****************************************************************************
17 NAME */
19 AROS_LH3(void, Deallocate,
21 /* SYNOPSIS */
22 AROS_LHA(struct MemHeader *, freeList, A0),
23 AROS_LHA(APTR, memoryBlock, A1),
24 AROS_LHA(ULONG, byteSize, D0),
26 /* LOCATION */
27 struct ExecBase *, SysBase, 32, Exec)
29 /* FUNCTION
30 Free block of memory associated with a given MemHandler structure.
32 INPUTS
33 freeList - Pointer to the MemHeader structure
34 memoryBlock - Pointer to the memory to be freed
35 byteSize - Size of the block
37 RESULT
39 NOTES
40 The start and end borders of the block are aligned to
41 a multiple of sizeof(struct MemChunk) and to include the block.
43 EXAMPLE
45 BUGS
47 SEE ALSO
48 Allocate()
50 INTERNALS
52 ******************************************************************************/
54 AROS_LIBFUNC_INIT
56 struct MemChunk *p1, *p2, *p3;
57 UBYTE *p4;
59 /* If there is no memory free nothing */
60 if(!byteSize)
61 return;
63 /* Align size to the requirements */
64 byteSize+=(IPTR)memoryBlock&(MEMCHUNK_TOTAL-1);
65 byteSize=(byteSize+MEMCHUNK_TOTAL-1)&~(MEMCHUNK_TOTAL-1);
67 /* Align the block as well */
68 memoryBlock=(APTR)((IPTR)memoryBlock&~(MEMCHUNK_TOTAL-1));
71 The free memory list is only single linked, i.e. to insert
72 elements into the list I need the node as well as it's
73 predessor. For the first element I can use freeList->mh_First
74 instead of a real predessor.
76 p1=(struct MemChunk *)&freeList->mh_First;
77 p2=freeList->mh_First;
79 /* Start and end(+1) of the block */
80 p3=(struct MemChunk *)memoryBlock;
81 p4=(UBYTE *)p3+byteSize;
83 /* No chunk in list? Just insert the current one and return. */
84 if(p2==NULL)
86 p3->mc_Bytes=byteSize;
87 p3->mc_Next=NULL;
88 p1->mc_Next=p3;
89 freeList->mh_Free+=byteSize;
90 return;
93 /* Follow the list to find a place where to insert our memory. */
96 #if !defined(NO_CONSISTENCY_CHECKS)
98 Do some constistency checks:
99 1. All MemChunks must be aligned to MEMCHUNK_TOTAL.
100 2. The end (+1) of the current MemChunk
101 must be lower than the start of the next one.
103 if( ((IPTR)p2|p2->mc_Bytes)&(MEMCHUNK_TOTAL-1)
104 ||( (UBYTE *)p2+p2->mc_Bytes>=(UBYTE *)p2->mc_Next
105 &&p2->mc_Next!=NULL))
106 Alert(AN_MemCorrupt|AT_DeadEnd);
107 #endif
108 /* Found a block with a higher address? */
109 if(p2>=p3)
111 #if !defined(NO_CONSISTENCY_CHECKS)
113 If the memory to be freed overlaps with the current
114 block something must be wrong.
116 if(p4>(UBYTE *)p2)
118 Alert(AN_FreeTwice);
119 return;
121 #endif
122 /* End the loop with p2 non-zero */
123 break;
125 /* goto next block */
126 p1=p2;
127 p2=p2->mc_Next;
129 /* If the loop ends with p2 zero add it at the end. */
130 }while(p2!=NULL);
132 /* If there was a previous block merge with it. */
133 if(p1!=(struct MemChunk *)&freeList->mh_First)
135 #if !defined(NO_CONSISTENCY_CHECKS)
136 /* Check if they overlap. */
137 if((UBYTE *)p1+p1->mc_Bytes>(UBYTE *)p3)
139 Alert(AN_FreeTwice);
140 return;
142 #endif
143 /* Merge if possible */
144 if((UBYTE *)p1+p1->mc_Bytes==(UBYTE *)p3)
145 p3=p1;
146 else
147 /* Not possible to merge */
148 p1->mc_Next=p3;
149 }else
151 There was no previous block. Just insert the memory at
152 the start of the list.
154 p1->mc_Next=p3;
156 /* Try to merge with next block (if there is one ;-) ). */
157 if(p4==(UBYTE *)p2&&p2!=NULL)
160 Overlap checking already done. Doing it here after
161 the list potentially changed would be a bad idea.
163 p4+=p2->mc_Bytes;
164 p2=p2->mc_Next;
166 /* relink the list and return. */
167 p3->mc_Next=p2;
168 p3->mc_Bytes=p4-(UBYTE *)p3;
169 freeList->mh_Free+=byteSize;
170 return;
171 AROS_LIBFUNC_EXIT
172 } /* Deallocate */