2 Copyright © 1995-2011, 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(ULONG
, puddleSize
, D1
),
29 AROS_LHA(ULONG
, 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
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 implementation of pools has been rewritten
51 to make use of memory protection capabilities. threshSize parameter
52 is effectively ignored and is present only for backwards compatibility.
55 \* Get the handle to a private memory pool *\
56 po=CreatePool(MEMF_ANY,16384,8192);
61 mem1=AllocPooled(po,1000);
62 mem2=AllocPooled(po,2000);
63 \* Do something with the memory... *\
65 \* Free everything at once *\
72 DeletePool(), AllocPooled(), FreePooled()
76 ******************************************************************************/
80 struct TraceLocation tp
= CURRENT_LOCATION("CreatePool");
81 struct MemHeader
*firstPuddle
= NULL
;
82 ULONG align
= PrivExecBase(SysBase
)->PageSize
- 1;
84 D(bug("[exec] CreatePool(0x%08X, %u, %u)\n", requirements
, puddleSize
, threshSize
));
87 * puddleSize needs to include MEMHEADER_TOTAL and one pointer.
88 * This is because our puddles must be able to accomodate an allocation
89 * of own size. Allocations of larger size will always use enlarged puddles.
90 * Pointer is used for pointing back to the MemHeader from which the block
91 * was allocated, in AllocVec()-alike manner. This way we get rid of slow lookup
94 puddleSize
+= MEMHEADER_TOTAL
+ sizeof(struct MemHeader
*);
96 /* If mungwall is enabled, count also size of walls, at least for one allocation */
97 if (PrivExecBase(SysBase
)->IntFlags
& EXECF_MungWall
)
98 puddleSize
+= MUNGWALL_TOTAL_SIZE
;
100 /* Then round puddleSize up to be a multiple of page size. */
101 puddleSize
= (puddleSize
+ align
) & ~align
;
102 D(bug("[CreatePool] Aligned puddle size: %u (0x%08X)\n", puddleSize
, puddleSize
));
104 /* Allocate the first puddle. It will contain pool header. */
105 firstPuddle
= AllocMemHeader(puddleSize
, requirements
, &tp
, SysBase
);
106 D(bug("[CreatePool] Initial puddle 0x%p\n", firstPuddle
));
110 ULONG poolstruct_size
= (requirements
& MEMF_SEM_PROTECTED
) ? sizeof(struct ProtectedPool
) :
112 struct ProtectedPool
*pool
;
115 * Allocate pool header inside the puddle.
116 * It is the first allocation in this puddle, so in future we can always find
117 * header's address as poolbase + MEMHEADER_TOTAL.
119 pool
= Allocate(firstPuddle
, poolstruct_size
);
120 D(bug("[CreatePool] Pool header 0x%p (size %u)\n", pool
, poolstruct_size
));
122 /* Initialize pool header */
123 NEWLIST((struct List
*)&pool
->pool
.PuddleList
);
124 pool
->pool
.Requirements
= requirements
;
125 pool
->pool
.PuddleSize
= puddleSize
;
127 if (requirements
& MEMF_SEM_PROTECTED
)
129 InitSemaphore(&pool
->sem
);
133 * Add the puddle to the list (yes, contained in itself).
134 * This is the first puddle so it's safe to use AddTail() here.
135 * Note that we use ln_Name of our MemHeader to point back to
138 firstPuddle
->mh_Node
.ln_Name
= (STRPTR
)pool
;
139 AddTail((struct List
*)&pool
->pool
.PuddleList
, &firstPuddle
->mh_Node
);