2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
5 Desc: Create a memory pool.
9 #include <aros/kernel.h>
10 #include <aros/libcall.h>
11 #include <clib/alib_protos.h>
13 #include "exec_intern.h"
14 #include "exec_util.h"
18 /*****************************************************************************
21 #include <exec/memory.h>
22 #include <proto/exec.h>
24 AROS_LH3(APTR
, CreatePool
,
27 AROS_LHA(ULONG
, requirements
, D0
),
28 AROS_LHA(IPTR
, puddleSize
, D1
),
29 AROS_LHA(IPTR
, threshSize
, D2
),
32 struct ExecBase
*, SysBase
, 116, Exec
)
35 Create a private pool for memory allocations.
38 requirements - The type of the memory
39 puddleSize - The number of bytes that the pool expands by
41 threshSize - Allocations beyond the threshSize are given
42 directly to the system. threshSize must be
43 smaller than or equal to the puddleSize.
46 A handle for the memory pool or NULL if the pool couldn't
50 Since exec.library v41.12, the implementation of pools has been
51 rewritten to make use of memory protection capabilities. The
52 threshSize parameter is effectively ignored and is present only
53 for backwards compatibility.
56 \* Get the handle to a private memory pool *\
57 po=CreatePool(MEMF_ANY,16384,8192);
62 mem1=AllocPooled(po,1000);
63 mem2=AllocPooled(po,2000);
64 \* Do something with the memory... *\
66 \* Free everything at once *\
73 DeletePool(), AllocPooled(), FreePooled()
77 ******************************************************************************/
81 struct TraceLocation tp
= CURRENT_LOCATION("CreatePool");
82 struct MemHeader
*firstPuddle
= NULL
;
83 IPTR align
= PrivExecBase(SysBase
)->PageSize
- 1;
85 D(bug("[exec] CreatePool(0x%08X, %u, %u)\n", requirements
, puddleSize
, threshSize
));
88 * puddleSize needs to include MEMHEADER_TOTAL and one pointer.
89 * This is because our puddles must be able to accommodate an allocation
90 * of own size. Allocations of larger size will always use enlarged puddles.
91 * Pointer is used for pointing back to the MemHeader from which the block
92 * was allocated, in AllocVec()-alike manner. This way we get rid of slow
93 * lookup in FreePooled().
95 puddleSize
+= MEMHEADER_TOTAL
+ sizeof(struct MemHeader
*);
97 /* If mungwall is enabled, count also size of walls, at least for one allocation */
98 if (PrivExecBase(SysBase
)->IntFlags
& EXECF_MungWall
)
99 puddleSize
+= MUNGWALL_TOTAL_SIZE
;
101 /* Then round puddleSize up to be a multiple of page size. */
102 puddleSize
= (puddleSize
+ align
) & ~align
;
103 D(bug("[CreatePool] Aligned puddle size: %u (0x%08X)\n", puddleSize
, puddleSize
));
105 /* Allocate the first puddle. It will contain pool header. */
106 firstPuddle
= AllocMemHeader(puddleSize
, requirements
, &tp
, SysBase
);
107 D(bug("[CreatePool] Initial puddle 0x%p\n", firstPuddle
));
111 ULONG poolstruct_size
= (requirements
& MEMF_SEM_PROTECTED
) ? sizeof(struct ProtectedPool
) :
113 struct ProtectedPool
*pool
;
116 * Allocate pool header inside the puddle.
117 * It is the first allocation in this puddle, so in future we can always find
118 * header's address as poolbase + MEMHEADER_TOTAL.
120 pool
= Allocate(firstPuddle
, poolstruct_size
);
121 D(bug("[CreatePool] Pool header 0x%p (size %u)\n", pool
, poolstruct_size
));
123 /* Initialize pool header */
124 NEWLIST((struct List
*)&pool
->pool
.PuddleList
);
125 pool
->pool
.Requirements
= requirements
;
126 pool
->pool
.PuddleSize
= puddleSize
;
128 if (requirements
& MEMF_SEM_PROTECTED
)
130 InitSemaphore(&pool
->sem
);
134 * Add the puddle to the list (yes, contained in itself).
135 * This is the first puddle so it's safe to use AddTail() here.
136 * Note that we use ln_Name of our MemHeader to point back to
139 firstPuddle
->mh_Node
.ln_Name
= (STRPTR
)pool
;
140 AddTail((struct List
*)&pool
->pool
.PuddleList
, &firstPuddle
->mh_Node
);