2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
5 Desc: Allocate memory in a pool.
8 #include "exec_intern.h"
9 #include <aros/libcall.h>
12 #include "exec_debug.h"
13 #ifndef DEBUG_AllocPooled
14 # define DEBUG_AllocPooled 0
20 #include <aros/debug.h>
23 /*****************************************************************************
26 #include <exec/memory.h>
27 #include <proto/exec.h>
29 AROS_LH2(APTR
, AllocPooled
,
32 AROS_LHA(APTR
, poolHeader
, A0
),
33 AROS_LHA(ULONG
, memSize
, D0
),
36 struct ExecBase
*, SysBase
, 118, Exec
)
39 Allocate memory out of a private memory pool.
42 poolHeader - Handle of the memory pool
43 memSize - Number of bytes you want to get
46 A pointer to the number of bytes you wanted or NULL if the memory
56 CreatePool(), DeletePool(), FreePooled()
60 ******************************************************************************/
64 struct ProtectedPool
*pool
= (struct ProtectedPool
*)poolHeader
;
67 D(bug("AllocPooled $%lx memsize $%lx by \"%s\"\n", poolHeader
, memSize
, SysBase
->ThisTask
->tc_Node
.ln_Name
));
69 if (pool
->pool
.Requirements
& MEMF_SEM_PROTECTED
)
71 ObtainSemaphore(&pool
->sem
);
74 /* If the memSize is bigger than the ThreshSize allocate seperately. */
75 if(memSize
> pool
->pool
.ThreshSize
)
80 /* Get enough memory for the memory block including the header. */
81 size
= memSize
+ BLOCK_TOTAL
;
82 bl
= (struct Block
*)AllocMem(size
, pool
->pool
.Requirements
& ~MEMF_SEM_PROTECTED
);
88 /* Initialize the header */
91 /* Add the block to the BlockList */
92 AddHead((struct List
*)&pool
->pool
.BlockList
,(struct Node
*)&bl
->Node
);
94 /* Set pointer to allocated memory */
95 ret
= (UBYTE
*)bl
+ BLOCK_TOTAL
;
101 /* Follow the list of MemHeaders */
102 mh
= (struct MemHeader
*)pool
->pool
.PuddleList
.mlh_Head
;
105 /* Are there no more MemHeaders? */
106 if(mh
->mh_Node
.ln_Succ
==NULL
)
109 mh
= (struct MemHeader
*)
110 AllocMem(pool
->pool
.PuddleSize
+ MEMHEADER_TOTAL
,
111 pool
->pool
.Requirements
& ~MEMF_SEM_PROTECTED
);
113 /* No memory left? */
117 /* Initialize new MemHeader */
118 mh
->mh_First
= (struct MemChunk
*)((UBYTE
*)mh
+ MEMHEADER_TOTAL
);
119 mh
->mh_First
->mc_Next
= NULL
;
120 mh
->mh_First
->mc_Bytes
= pool
->pool
.PuddleSize
;
121 mh
->mh_Lower
= mh
->mh_First
;
122 mh
->mh_Upper
= (UBYTE
*)mh
->mh_First
+pool
->pool
.PuddleSize
;
123 mh
->mh_Free
= pool
->pool
.PuddleSize
;
125 /* And add it to the list */
126 AddHead((struct List
*)&pool
->pool
.PuddleList
, (struct Node
*)&mh
->mh_Node
);
127 /* Fall through to get the memory */
129 /* Try to get the memory */
130 ret
= Allocate(mh
, memSize
);
135 /* If this is not the first MemHeader and it has some free space, move it to the head */
136 if (mh
->mh_Node
.ln_Pred
!= NULL
&& mh
->mh_Free
> 32)
139 AddHead((struct List
*)&pool
->pool
.PuddleList
, (struct Node
*)&mh
->mh_Node
);
145 /* No. Try next MemHeader */
146 mh
= (struct MemHeader
*)mh
->mh_Node
.ln_Succ
;
148 /* Allocate does not clear the memory! */
149 if(pool
->pool
.Requirements
& MEMF_CLEAR
)
151 ULONG
*p
= (ULONG
*)ret
;
153 /* Round up (clearing longs is faster than just bytes) */
154 memSize
= (memSize
+ sizeof(ULONG
) - 1) / sizeof(ULONG
);
156 /* NUL the memory out */
163 if (pool
->pool
.Requirements
& MEMF_SEM_PROTECTED
)
165 ReleaseSemaphore(&pool
->sem
);
168 /* Everything fine */