2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
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
19 #if DEBUG_NewAllocEntry
22 #include <aros/debug.h>
25 /*****************************************************************************
29 AROS_LH3(BOOL
, NewAllocEntry
,
32 AROS_LHA(struct MemList
*, entry
, A0
),
33 AROS_LHA(struct MemList
**, return_entry
, A1
),
34 AROS_LHA(ULONG
*, return_flags
, D0
),
37 struct ExecBase
*, SysBase
, 151, Exec
)
40 Allocate a number of memory blocks through a MemList structure.
43 entry - The MemList with one MemEntry for each block you want to get
44 return_entry - Pointer to struct MemList *variable where the address
45 of the MemList allocated by this function will be stored.
46 return_flags - Pointer to ULONG variable where upon failure the type of
47 memory that could not be allocated is stored. You may pass
51 TRUE if the allocation was successful. In this case *return_entry will
52 be set to the address of the allocated MemList. *return_flags will be set
55 FALSE if the allocation failed. In this case *return_entry will be set
56 to NULL and *return_flags will be set to contain the type of memory that
57 couldn't be allocated.
66 AllocEntry(), FreeEntry()
70 ******************************************************************************/
77 D(bug("NewAllocEntry $%lx num=%d\ttask=\"%s\"\n", entry
, entry
->ml_NumEntries
, SysBase
->ThisTask
->tc_Node
.ln_Name
));
80 for(i
= 0; i
< entry
->ml_NumEntries
; i
++)
82 kprintf("\treq $%lx\tsize $%lx\n", entry
->ml_ME
[i
].me_Reqs
, entry
->ml_ME
[i
].me_Length
);
86 /* Calculate size of a MemList with ml_NumEntries MemEntries. */
87 mlsize
= sizeof(struct MemList
) - sizeof(struct MemEntry
) +
88 sizeof(struct MemEntry
) * entry
->ml_NumEntries
;
90 /* Get the MemList structure */
91 ret
= (struct MemList
*)AllocMem(mlsize
, MEMF_PUBLIC
);
93 /* The allocation failed? Return "no public memory" */
97 if (return_flags
) *return_flags
= MEMF_PUBLIC
;
101 /* Init new struct */
102 ret
->ml_NumEntries
= entry
->ml_NumEntries
;
103 ret
->ml_Node
.ln_Type
= 0;
104 ret
->ml_Node
.ln_Pri
= 0;
105 ret
->ml_Node
.ln_Name
= NULL
;
107 /* Fill all entries */
108 for(i
= 0; i
< entry
->ml_NumEntries
; i
++)
111 A compatibility kludge: some programs rely that
112 AllocEntry() doesn't fail if the length field is 0.
114 E.g. CrossDos' PCx wants to allocate 7 memory regions, but the
115 last two fields are empty.
117 Don't depend on this feature.
119 if(entry
->ml_ME
[i
].me_Length
)
122 ret
->ml_ME
[i
].me_Addr
= AllocMem(entry
->ml_ME
[i
].me_Length
,
123 entry
->ml_ME
[i
].me_Reqs
);
125 if(ret
->ml_ME
[i
].me_Addr
== NULL
)
127 /* No. Set return flags to "none of the 'ml_ME[i].me_Reqs' memory". */
128 if (return_flags
) *return_flags
= entry
->ml_ME
[i
].me_Reqs
;
130 /* Free everything allocated until now... */
133 FreeMem(ret
->ml_ME
[i
].me_Addr
, ret
->ml_ME
[i
].me_Length
);
136 /* ...including the MemList */
137 FreeMem(ret
, mlsize
);
140 *return_entry
= NULL
;
145 else /* if length = 0 */
147 ret
->ml_ME
[i
].me_Addr
= NULL
;
150 /* Copy the Length field */
151 ret
->ml_ME
[i
].me_Length
= entry
->ml_ME
[i
].me_Length
;
154 /* Everything filled. Return OK. */
156 if (return_flags
) *return_flags
= 0;