2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
5 Allocate memory from a specific MemHeader.
8 #include "exec_intern.h"
10 #include <exec/alerts.h>
11 #include <aros/libcall.h>
12 #include <aros/macros.h>
13 #include <exec/memory.h>
14 #include <proto/exec.h>
16 /*****************************************************************************
20 AROS_LH2(APTR
, Allocate
,
23 AROS_LHA(struct MemHeader
*, freeList
, A0
),
24 AROS_LHA(ULONG
, byteSize
, D0
),
27 struct ExecBase
*, SysBase
, 31, Exec
)
30 Allocate memory out of a private region handled by the MemHeader
34 freeList - Pointer to the MemHeader structure which holds the memory
35 byteSize - Number of bytes you want to get
38 A pointer to the number of bytes you wanted or NULL if the memory
42 The memory is aligned to sizeof(struct MemChunk). All requests
43 are rounded up to a multiple of that size.
47 \* Get a MemHeader structure and some private memory *\
48 mh=(struct MemHeader *)
49 AllocMem(sizeof(struct MemHeader)+POOLSIZE,MEMF_ANY);
52 \* Build a private pool *\
53 mh->mh_First=(struct MemChunk *)(mh+1);
54 mh->mh_First->mc_Next=NULL;
55 mh->mh_First->mc_Bytes=POOLSIZE;
60 mem1=Allocate(mh,1000);
61 mem2=Allocate(mh,2000);
62 \* Do something with memory... *\
64 \* Free everything at once *\
65 FreeMem(mh,sizeof(struct MemHeader)+POOLSIZE);
75 ******************************************************************************/
79 struct MemChunk
*p1
, *p2
;
81 ASSERT_VALID_PTR(freeList
);
84 /* Zero bytes requested? May return everything ;-). */
88 /* First round byteSize to a multiple of MEMCHUNK_TOTAL. */
89 byteSize
=AROS_ROUNDUP2(byteSize
,MEMCHUNK_TOTAL
);
91 /* Is there enough free memory in the list? */
92 if(freeList
->mh_Free
<byteSize
)
96 The free memory list is only single linked, i.e. to remove
97 elements from the list I need the node as well as it's
98 predessor. For the first element I can use freeList->mh_First
99 instead of a real predecessor.
101 p1
=(struct MemChunk
*)&freeList
->mh_First
;
104 /* Is the list enpty? */
108 /* Follow the list */
111 #if !defined(NO_CONSISTENCY_CHECKS)
112 /* Consistency check: Check alignment restrictions */
113 if( ((IPTR
)p2
|(ULONG
)p2
->mc_Bytes
) & (MEMCHUNK_TOTAL
-1) )
115 if (SysBase
!= NULL
) Alert(AN_MemCorrupt
);
119 /* Check if current block is large enough */
120 if(p2
->mc_Bytes
>=byteSize
)
122 /* It is. Remove it from the list and return it. */
123 if(p2
->mc_Bytes
==byteSize
)
124 /* Fits exactly. Just relink the list. */
125 p1
->mc_Next
=p2
->mc_Next
;
128 /* Split the current chunk and return the first bytes. */
129 p1
->mc_Next
=(struct MemChunk
*)((UBYTE
*)p2
+byteSize
);
131 p1
->mc_Next
=p2
->mc_Next
;
132 p1
->mc_Bytes
=p2
->mc_Bytes
-byteSize
;
134 /* Adjust free memory count and return */
135 freeList
->mh_Free
-=byteSize
;
137 /* Fill the block with weird stuff to exploit bugs in applications */
138 MUNGE_BLOCK(p2
,MEMFILL_ALLOC
,byteSize
);
140 /* Return allocated block to caller */
144 /* Go to next block */
148 /* Check if this was the end */
151 #if !defined(NO_CONSISTENCY_CHECKS)
154 If the end of the last block+1 is bigger or equal to
155 the start of the current block something must be wrong.
157 if((UBYTE
*)p2
<=(UBYTE
*)p1
+p1
->mc_Bytes
)
159 if (SysBase
!= NULL
) Alert(AN_MemCorrupt
);