add necessary tasklist spinlocks
[AROS.git] / rom / exec / allocate.c
blob22ada6d323153ea9415b00408955837815b1ee9c
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Allocate memory from a specific MemHeader.
6 */
8 #define MDEBUG 1
10 #include <aros/debug.h>
11 #include <exec/alerts.h>
12 #include <aros/libcall.h>
13 #include <aros/macros.h>
14 #include <exec/memory.h>
15 #include <exec/memheaderext.h>
16 #include <proto/exec.h>
18 #include "exec_intern.h"
19 #include "exec_util.h"
20 #include "memory.h"
22 /*****************************************************************************
24 NAME */
26 AROS_LH2(APTR, Allocate,
28 /* SYNOPSIS */
29 AROS_LHA(struct MemHeader *, freeList, A0),
30 AROS_LHA(IPTR, byteSize, D0),
32 /* LOCATION */
33 struct ExecBase *, SysBase, 31, Exec)
35 /* FUNCTION
36 Allocate memory out of a private region handled by the MemHeader
37 structure.
39 INPUTS
40 freeList - Pointer to the MemHeader structure which holds the memory
41 byteSize - Number of bytes you want to get
43 RESULT
44 A pointer to the number of bytes you wanted or NULL if the memory
45 couldn't be allocated
47 NOTES
48 The memory is aligned to sizeof(struct MemChunk). All requests
49 are rounded up to a multiple of that size.
51 EXAMPLE
52 #define POOLSIZE 4096
53 \* Get a MemHeader structure and some private memory *\
54 mh=(struct MemHeader *)
55 AllocMem(sizeof(struct MemHeader)+POOLSIZE,MEMF_ANY);
56 if(mh!=NULL)
58 \* Build a private pool *\
59 mh->mh_First=(struct MemChunk *)(mh+1);
60 mh->mh_First->mc_Next=NULL;
61 mh->mh_First->mc_Bytes=POOLSIZE;
62 mh->mh_Free=POOLSIZE;
64 \* Use the pool *\
65 UBYTE *mem1,*mem2;
66 mem1=Allocate(mh,1000);
67 mem2=Allocate(mh,2000);
68 \* Do something with memory... *\
70 \* Free everything at once *\
71 FreeMem(mh,sizeof(struct MemHeader)+POOLSIZE);
74 BUGS
75 Does not work with managed memory blocks because of backwards
76 compatibility issues
78 SEE ALSO
79 Deallocate()
81 INTERNALS
83 ******************************************************************************/
85 AROS_LIBFUNC_INIT
87 if ((freeList->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(freeList))
89 struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList;
91 if (mhe->mhe_Alloc)
92 return mhe->mhe_Alloc(mhe, byteSize, NULL);
93 else
94 return NULL;
96 else
98 struct TraceLocation tp = CURRENT_LOCATION("Allocate");
99 APTR res;
101 D(bug("[exec] Allocate(0x%p, %u)\n", freeList, byteSize));
102 ASSERT(freeList != NULL);
103 #ifdef __mc68000
104 /* There are some programs (ie users of an older libSDL.a)
105 * that use Allocate() on their own managed pool, and did
106 * NOT set freeList->mh_Node.ln_Type. We fix it up for them
107 * here...
109 if (freeList->mh_Node.ln_Type == 0)
110 freeList->mh_Node.ln_Type = NT_MEMORY;
111 /* Fix also possibly uninitialized mh_Attributes */
112 freeList->mh_Attributes &= ~MEMF_MANAGED;
113 #endif
114 ASSERT(freeList->mh_Node.ln_Type == NT_MEMORY);
115 ASSERT(freeList->mh_Lower <= freeList->mh_Upper);
117 /* Zero bytes requested? May return everything ;-). */
118 if(!byteSize)
119 return NULL;
121 /* Is there enough free memory in the list? */
122 if(freeList->mh_Free<byteSize)
123 return NULL;
125 res = stdAlloc(freeList, NULL /* by design */, byteSize, 0, &tp, SysBase);
127 if ((PrivExecBase(SysBase)->IntFlags & EXECF_MungWall) && res) {
128 MUNGE_BLOCK(res, MEMFILL_ALLOC, byteSize);
131 return res;
134 AROS_LIBFUNC_EXIT
135 } /* Allocate() */