revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / createpool.c
blob49d42ccb914ce1bcfcd50dd17315be0da6227290
1 /*
2 Copyright (C) 1995-2014, 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 <exec/memheaderext.h>
23 #include <proto/exec.h>
25 AROS_LH3(APTR, CreatePool,
27 /* SYNOPSIS */
28 AROS_LHA(ULONG, requirements, D0),
29 AROS_LHA(IPTR, puddleSize, D1),
30 AROS_LHA(IPTR, threshSize, D2),
32 /* LOCATION */
33 struct ExecBase *, SysBase, 116, Exec)
35 /* FUNCTION
36 Create a private pool for memory allocations.
38 INPUTS
39 requirements - The type of the memory
40 puddleSize - The number of bytes that the pool expands by
41 if it is too small.
42 threshSize - Allocations beyond the threshSize are given
43 directly to the system. threshSize must be
44 smaller than or equal to the puddleSize.
46 RESULT
47 A handle for the memory pool or NULL if the pool couldn't
48 be created
50 NOTES
51 Since exec.library v41.12, the implementation of pools has been
52 rewritten to make use of memory protection capabilities. The
53 threshSize parameter is effectively ignored and is present only
54 for backwards compatibility.
56 EXAMPLE
57 \* Get the handle to a private memory pool *\
58 po=CreatePool(MEMF_ANY,16384,8192);
59 if(po!=NULL)
61 \* Use the pool *\
62 UBYTE *mem1,*mem2;
63 mem1=AllocPooled(po,1000);
64 mem2=AllocPooled(po,2000);
65 \* Do something with the memory... *\
67 \* Free everything at once *\
68 DeletePool(po);
71 BUGS
73 SEE ALSO
74 DeletePool(), AllocPooled(), FreePooled()
76 INTERNALS
78 ******************************************************************************/
80 AROS_LIBFUNC_INIT
82 struct TraceLocation tp = CURRENT_LOCATION("CreatePool");
83 struct MemHeader *firstPuddle = NULL;
84 IPTR align = PrivExecBase(SysBase)->PageSize - 1;
86 if (align < 4095)
87 align = 4095;
89 D(bug("[exec] CreatePool(0x%08X, %u, %u)\n", requirements, puddleSize, threshSize);)
92 * puddleSize needs to include MEMHEADER_TOTAL, allocator context size and one pointer.
93 * This is because our puddles must be able to accommodate an allocation
94 * of own size. Allocations of larger size will always use enlarged puddles.
95 * Pointer is used for pointing back to the MemHeader from which the block
96 * was allocated, in AllocVec()-alike manner. This way we get rid of slow
97 * lookup in FreePooled().
99 puddleSize += MEMHEADER_TOTAL + mhac_GetCtxSize() + sizeof(struct MemHeader *);
101 /* If mungwall is enabled, count also size of walls, at least for one allocation */
102 if (PrivExecBase(SysBase)->IntFlags & EXECF_MungWall)
103 puddleSize += MUNGWALL_TOTAL_SIZE;
105 /* Then round puddleSize up to be a multiple of page size. */
106 puddleSize = (puddleSize + align) & ~align;
107 D(bug("[CreatePool] Aligned puddle size: %u (0x%08X)\n", puddleSize, puddleSize);)
109 /* Allocate the first puddle. It will contain pool header. */
110 firstPuddle = AllocMemHeader(puddleSize, requirements, &tp, SysBase);
111 D(bug("[CreatePool] Initial puddle 0x%p\n", firstPuddle);)
113 if (firstPuddle)
115 ULONG poolstruct_size = (requirements & MEMF_SEM_PROTECTED) ? sizeof(struct ProtectedPool) :
116 sizeof(struct Pool);
117 struct ProtectedPool *pool;
120 * Allocate pool header inside the puddle.
121 * It is the first allocation in this puddle, so in future we can always find
122 * header's address as poolbase + MEMHEADER_TOTAL.
124 pool = Allocate(firstPuddle, poolstruct_size);
125 D(bug("[CreatePool] Pool header 0x%p (size %u)\n", pool, poolstruct_size);)
127 /* Initialize pool header */
128 NEWLIST((struct List *)&pool->pool.PuddleList);
129 pool->pool.Requirements = requirements;
130 pool->pool.PuddleSize = puddleSize;
131 pool->pool.PoolMagic = POOL_MAGIC;
133 if (requirements & MEMF_SEM_PROTECTED)
135 InitSemaphore(&pool->sem);
139 * If the pool is in managed memory, don't bother any further setup. The
140 * pool should do the rest self.
142 if (IsManagedMem(firstPuddle))
144 D(bug("Managed pool\n");)
146 * Just link the pool structure at the ln_Name - we will need that
147 * for the semaphore
149 firstPuddle->mh_Node.ln_Name = (STRPTR)&pool->sem;
151 /* Use mh_First to store the pool requirements */
152 firstPuddle->mh_First = (APTR)(IPTR)requirements;
154 else
157 * Add the puddle to the list (yes, contained in itself).
158 * This is the first puddle so it's safe to use AddTail() here.
159 * Note that we use ln_Name of our MemHeader to point back to
160 * our pool (directly or indirectly).
162 mhac_PoolMemHeaderSetup(firstPuddle, pool);
163 AddTail((struct List *)&pool->pool.PuddleList, &firstPuddle->mh_Node);
166 return firstPuddle;
168 AROS_LIBFUNC_EXIT
169 } /* CreatePool */