fix off-by-1 screen title fill
[AROS.git] / rom / exec / allocate.c
blob5656a4bba392450353ea6bcc0e1212627cd11602
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) &&
88 (freeList->mh_Attributes & MEMF_MANAGED) &&
89 (((struct MemHeaderExt *)freeList)->mhe_Magic == MEMHEADER_EXT_MAGIC)
92 struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList;
94 if (mhe->mhe_Alloc)
95 return mhe->mhe_Alloc(mhe, byteSize, NULL);
96 else
97 return NULL;
99 else
101 struct TraceLocation tp = CURRENT_LOCATION("Allocate");
102 APTR res;
104 D(bug("[exec] Allocate(0x%p, %u)\n", freeList, byteSize));
105 ASSERT(freeList != NULL);
106 #ifdef __mc68000
107 /* There are some programs (ie users of an older libSDL.a)
108 * that use Allocate() on their own managed pool, and did
109 * NOT set freeList->mh_Node.ln_Type. We fix it up for them
110 * here...
112 if (freeList->mh_Node.ln_Type == 0)
113 freeList->mh_Node.ln_Type = NT_MEMORY;
114 /* Fix also possibly uninitialized mh_Attributes */
115 freeList->mh_Attributes &= ~MEMF_MANAGED;
116 #endif
117 ASSERT(freeList->mh_Node.ln_Type == NT_MEMORY);
118 ASSERT(freeList->mh_Lower <= freeList->mh_Upper);
120 /* Zero bytes requested? May return everything ;-). */
121 if(!byteSize)
122 return NULL;
124 /* Is there enough free memory in the list? */
125 if(freeList->mh_Free<byteSize)
126 return NULL;
128 res = stdAlloc(freeList, NULL /* by design */, byteSize, 0, &tp, SysBase);
130 if ((PrivExecBase(SysBase)->IntFlags & EXECF_MungWall) && res) {
131 MUNGE_BLOCK(res, MEMFILL_ALLOC, byteSize);
134 return res;
137 AROS_LIBFUNC_EXIT
138 } /* Allocate() */