Support rastport clipping rectangle for layerless rastports
[tangerine.git] / rom / exec / availmem.c
blobb30fbe646062295544844313d733e86e631b594e
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Tell how much memory is available.
6 Lang: english
7 */
8 #include <exec/alerts.h>
9 #include <exec/execbase.h>
10 #include <aros/libcall.h>
11 #include <aros/macros.h>
12 #include <exec/memory.h>
13 #include <exec/memheaderext.h>
14 #include <proto/exec.h>
16 #include "memory.h"
18 #define MDEBUG 1
19 #include <aros/debug.h>
21 /*****************************************************************************
23 NAME */
25 AROS_LH1(ULONG, AvailMem,
27 /* SYNOPSIS */
28 AROS_LHA(ULONG, attributes, D1),
30 /* LOCATION */
31 struct ExecBase *, SysBase, 36, Exec)
33 /* FUNCTION
34 Return either the total available memory or the largest available
35 chunk of a given type of memory.
37 INPUTS
38 attributes - The same attributes you would give to AllocMem().
40 RESULT
41 Either the total of the available memory or the largest chunk if
42 MEMF_LARGEST ist set in the attributes.
44 NOTES
45 Due to the nature of multitasking the returned value may already
46 be obsolete if this function returns.
48 EXAMPLE
49 Print the total available memory.
51 printf("Free memory: %lu bytes\n",AvailMem(0));
53 Print the size of the largest chunk of chip memory.
55 printf("Largest chipmem chunk: %lu bytes\n",
56 AvailMem(MEMF_CHIP|MEMF_LARGEST));
58 BUGS
60 SEE ALSO
62 INTERNALS
64 ******************************************************************************/
66 AROS_LIBFUNC_INIT
68 ULONG ret = 0;
69 struct MemHeader *mh;
71 /* Nobody else should access the memory lists now. */
72 Forbid();
74 ForeachNode(&SysBase->MemList, mh)
77 The current memheader is OK if there's no bit in the
78 'attributes' that isn't set in the 'mh->mh_Attributes'.
79 MEMF_CLEAR, MEMF_REVERSE, MEMF_NO_EXPUNGE, MEMF_TOTAL and
80 MEMF_LARGEST are treated as if they were always set in
81 the memheader.
83 if((attributes &~ (MEMF_CLEAR|MEMF_REVERSE|MEMF_NO_EXPUNGE|
84 MEMF_TOTAL|MEMF_LARGEST|mh->mh_Attributes)))
85 continue;
87 if (mh->mh_Attributes & MEMF_MANAGED)
89 struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh;
91 if (mhe->mhe_Avail)
93 ret += mhe->mhe_Avail(mhe, attributes);
94 continue;
96 /* fall through */
99 /* Find largest chunk? */
100 if(attributes & MEMF_LARGEST)
103 Yes. Follow the list of MemChunks and set 'ret' to
104 each value that is bigger than all previous ones.
106 struct MemChunk *mc=mh->mh_First;
107 while(mc!=NULL)
109 #if !defined(NO_CONSISTENCY_CHECKS)
111 Do some constistency checks:
112 1. All MemChunks must be aligned to
113 sizeof(struct MemChunk).
114 2. The end (+1) of the current MemChunk
115 must be lower than the start of the next one.
117 if( ((IPTR)mc|mc->mc_Bytes)&(sizeof(struct MemChunk)-1)
118 ||( (UBYTE *)mc+mc->mc_Bytes>=(UBYTE *)mc->mc_Next
119 &&mc->mc_Next!=NULL))
120 Alert(AT_DeadEnd|AN_MemoryInsane);
121 #endif
122 if(mc->mc_Bytes>ret)
123 ret=mc->mc_Bytes;
124 mc=mc->mc_Next;
127 else if(attributes & MEMF_TOTAL)
128 /* Determine total size. */
129 ret += (IPTR)mh->mh_Upper - (IPTR)mh->mh_Lower;
130 else
131 /* Sum up free memory. */
132 ret += mh->mh_Free;
134 /* All done. Permit dispatches and return. */
136 #if AROS_MUNGWALL_DEBUG
137 if (attributes & MEMF_CLEAR)
139 struct List *allocmemlist;
140 struct MungwallHeader *allocnode;
141 ULONG alloccount = 0;
142 ULONG allocsize = 0;
144 allocmemlist = (struct List *)&((struct AROSSupportBase *)SysBase->DebugAROSBase)->AllocMemList;
146 kprintf("\n=== MUNGWALL MEMORY CHECK ============\n");
147 ForeachNode(allocmemlist, allocnode)
149 if (allocnode->mwh_magicid != MUNGWALL_HEADER_ID)
151 kprintf(" #%05x BAD MUNGWALL_HEADER_ID\n", alloccount);
154 CHECK_WALL((UBYTE *)allocnode + MUNGWALLHEADER_SIZE, 0xDB, MUNGWALL_SIZE);
155 CHECK_WALL((UBYTE *)allocnode + MUNGWALLHEADER_SIZE + MUNGWALL_SIZE + allocnode->mwh_allocsize, 0xDB,
156 MUNGWALL_SIZE + AROS_ROUNDUP2(allocnode->mwh_allocsize, MEMCHUNK_TOTAL) - allocnode->mwh_allocsize);
158 allocsize += allocnode->mwh_allocsize;
159 alloccount++;
161 kprintf("\n Num allocations: %d Memory allocated %d\n", alloccount, allocsize);
163 #endif
164 Permit();
165 return ret;
166 AROS_LIBFUNC_EXIT
167 } /* AvailMem */