Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / rom / exec / createpool.c
blob8a13bf8ebfe157a289a2f5d7fec3cc1c79f2a7e3
1 /*
2 Copyright © 1995-2010, 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 "memory.h"
15 #include "mungwall.h"
17 /*****************************************************************************
19 NAME */
20 #include <exec/memory.h>
21 #include <proto/exec.h>
23 AROS_LH3(APTR, CreatePool,
25 /* SYNOPSIS */
26 AROS_LHA(ULONG, requirements, D0),
27 AROS_LHA(ULONG, puddleSize, D1),
28 AROS_LHA(ULONG, threshSize, D2),
30 /* LOCATION */
31 struct ExecBase *, SysBase, 116, Exec)
33 /* FUNCTION
34 Create a private pool for memory allocations.
36 INPUTS
37 requirements - The type of the memory
38 puddleSize - The number of bytes that the pool expands
39 if it is too small.
40 threshSize - Allocations beyond the threshSize are given
41 directly to the system. threshSize must be
42 smaller than or equal to the puddleSize.
44 RESULT
45 A handle for the memory pool or NULL if the pool couldn't
46 be created
48 NOTES
49 Since exec.library v41.12 implementation of pools has been rewritten
50 to make use of memory protection capabilities. threshSize parameter
51 is effectively ignored and is present only for backwards compatibility.
53 EXAMPLE
54 \* Get the handle to a private memory pool *\
55 po=CreatePool(MEMF_ANY,16384,8192);
56 if(po!=NULL)
58 \* Use the pool *\
59 UBYTE *mem1,*mem2;
60 mem1=AllocPooled(po,1000);
61 mem2=AllocPooled(po,2000);
62 \* Do something with the memory... *\
64 \* Free everything at once *\
65 DeletePool(po);
68 BUGS
70 SEE ALSO
71 DeletePool(), AllocPooled(), FreePooled()
73 INTERNALS
75 ******************************************************************************/
77 AROS_LIBFUNC_INIT
79 struct MemHeader *firstPuddle = NULL;
80 ULONG align = PrivExecBase(SysBase)->PageSize - 1;
82 D(bug("[exec] CreatePool(0x%08X, %u, %u)\n", requirements, puddleSize, threshSize));
85 * puddleSize needs to include MEMHEADER_TOTAL and one pointer.
86 * This is because our puddles must be able to accomodate an allocation
87 * of own size. Allocations of larger size will always use enlarged puddles.
88 * Pointer is used for pointing back to the MemHeader from which the block
89 * was allocated, in AllocVec()-alike manner. This way we get rid of slow lookup
90 * in FreePooled().
92 puddleSize += MEMHEADER_TOTAL + sizeof(struct MemHeader *);
94 /* If mungwall is enabled, count also size of walls, at least for one allocation */
95 if (PrivExecBase(SysBase)->IntFlags & EXECF_MungWall)
96 puddleSize += MUNGWALL_TOTAL_SIZE;
98 /* Then round puddleSize up to be a multiple of page size. */
99 puddleSize = (puddleSize + align) & ~align;
100 D(bug("[CreatePool] Aligned puddle size: %u (0x%08X)\n", puddleSize, puddleSize));
102 /* Allocate the first puddle. It will contain pool header. */
103 firstPuddle = AllocMemHeader(puddleSize, requirements, SysBase);
104 D(bug("[CreatePool] Initial puddle 0x%p\n", firstPuddle));
106 if (firstPuddle)
108 ULONG poolstruct_size = (requirements & MEMF_SEM_PROTECTED) ? sizeof(struct ProtectedPool) :
109 sizeof(struct Pool);
110 struct ProtectedPool *pool;
113 * Allocate pool header inside the puddle.
114 * It is the first allocation in this puddle, so in future we can always find
115 * header's address as poolbase + MEMHEADER_TOTAL.
117 pool = Allocate(firstPuddle, poolstruct_size);
118 D(bug("[CreatePool] Pool header 0x%p (size %u)\n", pool, poolstruct_size));
120 /* Initialize pool header */
121 NEWLIST((struct List *)&pool->pool.PuddleList);
122 pool->pool.Requirements = requirements;
123 pool->pool.PuddleSize = puddleSize;
125 if (requirements & MEMF_SEM_PROTECTED)
127 InitSemaphore(&pool->sem);
131 * Add the puddle to the list (yes, contained in itself).
132 * This is the first puddle so it's safe to use AddTail() here.
133 * Note that we use ln_Name of our MemHeader to point back to
134 * our pool.
136 firstPuddle->mh_Node.ln_Name = (STRPTR)pool;
137 AddTail((struct List *)&pool->pool.PuddleList, &firstPuddle->mh_Node);
140 return firstPuddle;
142 AROS_LIBFUNC_EXIT
143 } /* CreatePool */