Minor fixes to comments.
[AROS.git] / rom / exec / createpool.c
blob744883d4d959d5478d535c1b5f460b61701647f4
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Create a memory pool.
6 Lang: english
7 */
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"
15 #include "memory.h"
16 #include "mungwall.h"
18 /*****************************************************************************
20 NAME */
21 #include <exec/memory.h>
22 #include <proto/exec.h>
24 AROS_LH3(APTR, CreatePool,
26 /* SYNOPSIS */
27 AROS_LHA(ULONG, requirements, D0),
28 AROS_LHA(ULONG, puddleSize, D1),
29 AROS_LHA(ULONG, threshSize, D2),
31 /* LOCATION */
32 struct ExecBase *, SysBase, 116, Exec)
34 /* FUNCTION
35 Create a private pool for memory allocations.
37 INPUTS
38 requirements - The type of the memory
39 puddleSize - The number of bytes that the pool expands
40 if it is too small.
41 threshSize - Allocations beyond the threshSize are given
42 directly to the system. threshSize must be
43 smaller than or equal to the puddleSize.
45 RESULT
46 A handle for the memory pool or NULL if the pool couldn't
47 be created
49 NOTES
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.
54 EXAMPLE
55 \* Get the handle to a private memory pool *\
56 po=CreatePool(MEMF_ANY,16384,8192);
57 if(po!=NULL)
59 \* Use the pool *\
60 UBYTE *mem1,*mem2;
61 mem1=AllocPooled(po,1000);
62 mem2=AllocPooled(po,2000);
63 \* Do something with the memory... *\
65 \* Free everything at once *\
66 DeletePool(po);
69 BUGS
71 SEE ALSO
72 DeletePool(), AllocPooled(), FreePooled()
74 INTERNALS
76 ******************************************************************************/
78 AROS_LIBFUNC_INIT
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
92 * in FreePooled().
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));
108 if (firstPuddle)
110 ULONG poolstruct_size = (requirements & MEMF_SEM_PROTECTED) ? sizeof(struct ProtectedPool) :
111 sizeof(struct Pool);
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
136 * our pool.
138 firstPuddle->mh_Node.ln_Name = (STRPTR)pool;
139 AddTail((struct List *)&pool->pool.PuddleList, &firstPuddle->mh_Node);
142 return firstPuddle;
144 AROS_LIBFUNC_EXIT
145 } /* CreatePool */