revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / newallocentry.c
blobe1e80d70e91ba3bca81fc2e5f953fecb8776f790
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Allocate memory.
6 Lang: english
7 */
8 #include <aros/config.h>
9 #include "exec_intern.h"
10 #include <aros/libcall.h>
11 #include <exec/memory.h>
12 #include <proto/exec.h>
14 #include "exec_debug.h"
15 #ifndef DEBUG_NewAllocEntry
16 # define DEBUG_NewAllocEntry 0
17 #endif
18 #undef DEBUG
19 #if DEBUG_NewAllocEntry
20 # define DEBUG 1
21 #endif
22 #include <aros/debug.h>
23 #undef kprintf
25 /*****************************************************************************
27 NAME */
29 AROS_LH2(struct MemList *, NewAllocEntry,
31 /* SYNOPSIS */
32 AROS_LHA(struct MemList *, entry, A0),
33 AROS_LHA(ULONG *, return_flags, A1),
35 /* LOCATION */
36 struct ExecBase *, SysBase, 174, Exec)
38 /* FUNCTION
39 Allocate a number of memory blocks through a MemList structure.
41 INPUTS
42 entry - The MemList with one MemEntry for each block you want to get
43 return_entry - Pointer to struct MemList *variable where the address
44 of the MemList allocated by this function will be stored.
45 return_flags - Pointer to ULONG variable where upon failure the type of
46 memory that could not be allocated is stored. You may pass
47 NULL here.
49 RESULT
50 Address of the allocated MemList if the allocation was successful. In this
51 case *return_flags will be set to 0.
53 NULL if the allocation failed. In this case *return_flags will contain the
54 type of memory that couldn't be allocated.
56 NOTES
57 This function is AROS-specific.
59 EXAMPLE
61 BUGS
63 SEE ALSO
64 AllocEntry(), FreeEntry()
66 INTERNALS
68 ******************************************************************************/
70 AROS_LIBFUNC_INIT
72 struct MemList *ret;
73 ULONG mlsize, i;
75 D(bug("NewAllocEntry $%lx num=%d\ttask=\"%s\"\n", entry, entry->ml_NumEntries, GET_THIS_TASK->tc_Node.ln_Name));
78 for(i = 0; i < entry->ml_NumEntries; i++)
80 kprintf("\treq $%lx\tsize $%lx\n", entry->ml_ME[i].me_Reqs, entry->ml_ME[i].me_Length);
84 /* Calculate size of a MemList with ml_NumEntries MemEntries. */
85 mlsize = sizeof(struct MemList) - sizeof(struct MemEntry) +
86 sizeof(struct MemEntry) * entry->ml_NumEntries;
88 /* Get the MemList structure */
89 ret = (struct MemList *)AllocMem(mlsize, MEMF_PUBLIC);
91 /* The allocation failed? Return "no public memory" */
92 if(ret == NULL)
94 if (return_flags) *return_flags = MEMF_PUBLIC;
95 return NULL;
98 /* Init new struct */
99 ret->ml_NumEntries = entry->ml_NumEntries;
100 ret->ml_Node.ln_Type = 0;
101 ret->ml_Node.ln_Pri = 0;
102 ret->ml_Node.ln_Name = NULL;
104 /* Fill all entries */
105 for(i = 0; i < entry->ml_NumEntries; i++)
108 A compatibility kludge: some programs rely that
109 AllocEntry() doesn't fail if the length field is 0.
111 E.g. CrossDos' PCx wants to allocate 7 memory regions, but the
112 last two fields are empty.
114 Don't depend on this feature.
116 if(entry->ml_ME[i].me_Length)
118 /* Get one */
119 ret->ml_ME[i].me_Addr = AllocMem(entry->ml_ME[i].me_Length,
120 entry->ml_ME[i].me_Reqs);
121 /* Got it? */
122 if(ret->ml_ME[i].me_Addr == NULL)
124 /* No. Set return flags to "none of the 'ml_ME[i].me_Reqs' memory". */
125 if (return_flags) *return_flags = entry->ml_ME[i].me_Reqs;
127 /* Free everything allocated until now... */
128 for( ; i-->0; )
130 FreeMem(ret->ml_ME[i].me_Addr, ret->ml_ME[i].me_Length);
133 /* ...including the MemList */
134 FreeMem(ret, mlsize);
136 /* All done */
137 return NULL;
140 else /* if length = 0 */
142 ret->ml_ME[i].me_Addr = NULL;
145 /* Copy the Length field */
146 ret->ml_ME[i].me_Length = entry->ml_ME[i].me_Length;
148 D(bug("[NewAllocEntry] Allocated size %d at 0x%p\n",
149 ret->ml_ME[i].me_Length, ret->ml_ME[i].me_Addr
153 /* Everything filled. Return OK. */
154 if (return_flags) *return_flags = 0;
156 return ret;
158 AROS_LIBFUNC_EXIT
159 } /* AllocEntry */