Detab
[AROS.git] / rom / exec / createpool.c
blob821b69b3075e0adc38c3d4d7ca2950051ddb9f43
1 /*
2 Copyright © 1995-2012, 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(IPTR, puddleSize, D1),
29 AROS_LHA(IPTR, 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 by
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, 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.
55 EXAMPLE
56 \* Get the handle to a private memory pool *\
57 po=CreatePool(MEMF_ANY,16384,8192);
58 if(po!=NULL)
60 \* Use the pool *\
61 UBYTE *mem1,*mem2;
62 mem1=AllocPooled(po,1000);
63 mem2=AllocPooled(po,2000);
64 \* Do something with the memory... *\
66 \* Free everything at once *\
67 DeletePool(po);
70 BUGS
72 SEE ALSO
73 DeletePool(), AllocPooled(), FreePooled()
75 INTERNALS
77 ******************************************************************************/
79 AROS_LIBFUNC_INIT
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));
109 if (firstPuddle)
111 ULONG poolstruct_size = (requirements & MEMF_SEM_PROTECTED) ? sizeof(struct ProtectedPool) :
112 sizeof(struct Pool);
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
137 * our pool.
139 firstPuddle->mh_Node.ln_Name = (STRPTR)pool;
140 AddTail((struct List *)&pool->pool.PuddleList, &firstPuddle->mh_Node);
143 return firstPuddle;
145 AROS_LIBFUNC_EXIT
146 } /* CreatePool */