forwarding build fix when MUIA_Scrollgroup_AutoBars is defined (NicJA).
[AROS-Contrib.git] / scalos / main / Memory.c
blobc4fe6eec91c65d617a12f4634a044e2d362af7e9
1 // Memory.c
2 // $Date$
3 // $Revision$
5 #include <exec/types.h>
6 #ifdef __amigaos4__
7 #include <dos/anchorpath.h>
8 #include <dos/dostags.h>
9 #include <proto/dos.h>
10 #endif
11 #include <dos/dosasl.h>
13 #define __USE_SYSBASE
15 #include <proto/exec.h>
16 #include <proto/ttengine.h>
17 #include "debug.h"
18 #include <proto/scalos.h>
20 #include <clib/alib_protos.h>
22 #include <defs.h>
23 #include <scalos/scalos.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <stddef.h>
30 #include <limits.h>
32 #include "scalos_structures.h"
33 #include "locale.h"
34 #include "functions.h"
35 #include "Variables.h"
37 //----------------------------------------------------------------------------
39 // macros and local data structures
41 #define PUDDLESIZE_MAIN 65536
42 #define THRESHOLD_MAIN 2048
43 #define PUDDLESIZE_MSG 8192
44 #define THRESHOLD_MSG 256
45 #define PUDDLESIZE_NODES 8192
46 #define THRESHOLD_NODES 256
48 // define DLMALLOC to use Doug Lea's memory allocator instead of OS's memory pools
49 #if !defined(__AROS__)
50 #define DLMALLOC 1
51 #endif
53 // DLMALLOC_CLEAR to clear all allocated memory - ATM still required
54 #define DLMALLOC_CLEAR 1
56 //----------------------------------------------------------------------------
58 #if DLMALLOC
59 void* dlmalloc(size_t);
60 void dlfree(void*);
61 void* dlrealloc(void*, size_t);
62 #endif //DLMALLOC
64 //----------------------------------------------------------------------------
66 // local Data
68 #if DLMALLOC
69 #else //DLMALLOC
70 static SCALOSSEMAPHORE MainMemPoolSemaphore; // main memory pool semaphore
71 static SCALOSSEMAPHORE MsgMemPoolSemaphore; // main memory pool semaphore
72 static SCALOSSEMAPHORE NodeMemPoolSemaphore; // main memory pool semaphore
73 static void *MainMemPool = NULL; // main memory pool
74 static void *MsgMemPool = NULL; // main memory pool
75 static void *NodeMemPool = NULL; // main memory pool
76 #endif //DLMALLOC
78 // ----------------------------------------------------------
80 BOOL MemoryInit(void)
82 #if DLMALLOC
83 #else //DLMALLOC
84 ScalosInitSemaphore(&MainMemPoolSemaphore);
85 ScalosInitSemaphore(&MsgMemPoolSemaphore);
86 ScalosInitSemaphore(&NodeMemPoolSemaphore);
88 MainMemPool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, PUDDLESIZE_MAIN, THRESHOLD_MAIN);
89 d1(KPrintF("%s/%s/%ld: MainMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, MainMemPool));
90 if (NULL == MainMemPool)
91 return FALSE;
93 MsgMemPool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, PUDDLESIZE_MSG, THRESHOLD_MSG);
94 d1(KPrintF("%s/%s/%ld: MsgMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, MsgMemPool));
95 if (NULL == MsgMemPool)
96 return FALSE;
98 NodeMemPool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR, PUDDLESIZE_NODES, THRESHOLD_NODES);
99 d1(KPrintF("%s/%s/%ld: MainMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, NodeMemPool));
100 if (NULL == NodeMemPool)
101 return FALSE;
102 #endif //DLMALLOC
104 return TRUE;
107 // ----------------------------------------------------------
109 void MemoryCleanup(void)
111 #if DLMALLOC
112 #else //DLMALLOC
113 d1(KPrintF("%s/%s/%ld: MainMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, MainMemPool));
114 if (MainMemPool)
116 DeletePool(MainMemPool);
117 MainMemPool = NULL;
119 d1(KPrintF("%s/%s/%ld: MsgMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, MsgMemPool));
120 if (MsgMemPool)
122 DeletePool(MsgMemPool);
123 MsgMemPool = NULL;
125 d1(KPrintF("%s/%s/%ld: NodeMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, NodeMemPool));
126 if (NodeMemPool)
128 DeletePool(NodeMemPool);
129 NodeMemPool = NULL;
131 #endif //DLMALLOC
134 // ----------------------------------------------------------
136 #ifndef DEBUG_MEMORY
138 #ifndef __GNUC__
139 #undef ObtainSemaphore
140 #undef ReleaseSemaphore
141 #endif /* __GNUC__ */
143 APTR ScalosAlloc(ULONG Size)
145 #if DLMALLOC
146 APTR ptr;
148 d1(kprintf("%s/%s/%ld: Size=%lu\n", __FILE__, __FUNC__, __LINE__, Size));
150 ptr = (APTR) dlmalloc(Size);
152 #if DLMALLOC_CLEAR
153 if (ptr)
154 memset(ptr, 0, Size);
155 #endif //DLMALLOC_CLEAR
157 d1(kprintf("%s/%s/%ld: END return %08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
158 return ptr;
159 #else //DLMALLOC
160 struct AllocatedMemFromPool *ptr;
162 d1(kprintf("%s/%s/%ld: Size=%lu MemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, Size, MemPool));
164 if (MainMemPool)
166 size_t AllocSize = Size + sizeof(struct AllocatedMemFromPool);
168 d1(kprintf("%s/%s/%ld: AllocSize=%lu\n", __FILE__, __FUNC__, __LINE__, AllocSize));
169 ScalosObtainSemaphore(&MainMemPoolSemaphore);
170 ptr = AllocPooled(MainMemPool, AllocSize);
171 ScalosReleaseSemaphore(&MainMemPoolSemaphore);
172 d1(kprintf("%s/%s/%ld: ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
173 if (ptr)
175 ptr->amp_Size = AllocSize;
177 d1(kprintf("%s/%s/%ld: return %08lx\n", __FILE__, __FUNC__, __LINE__, ptr->amp_UserData));
178 return (APTR) &ptr->amp_UserData;
182 d1(kprintf("%s/%s/%ld: return NULL\n", __FILE__, __FUNC__, __LINE__));
184 return NULL;
185 #endif //DLMALLOC
189 void ScalosFree(APTR mem)
191 #if DLMALLOC
192 d1(KPrintF("%s/%s/%ld: START OldMem=%08lx\n", __FILE__, __FUNC__, __LINE__, mem));
193 dlfree(mem);
194 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
195 #else //DLMALLOC
196 if (MainMemPool && mem)
198 struct AllocatedMemFromPool *ptr;
200 ptr = (struct AllocatedMemFromPool *) (((UBYTE *) mem) - offsetof(struct AllocatedMemFromPool, amp_UserData));
202 ScalosObtainSemaphore(&MainMemPoolSemaphore);
203 FreePooled(MainMemPool, ptr, ptr->amp_Size);
204 ScalosReleaseSemaphore(&MainMemPoolSemaphore);
206 #endif //DLMALLOC
210 APTR ScalosRealloc(APTR OldMem, ULONG NewSize)
212 #if DLMALLOC
213 APTR ptr;
215 d1(KPrintF("%s/%s/%ld: START OldMem=%08lx NewSize=%lu\n", __FILE__, __FUNC__, __LINE__, OldMem, NewSize));
216 ptr = dlrealloc(OldMem, NewSize);
217 d1(kprintf("%s/%s/%ld: END return %08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
219 return ptr;
220 #else //DLMALLOC
221 APTR NewMem = NULL;
223 d1(KPrintF("%s/%s/%ld: OldMem=%08lx NewSize=%lu\n", __FILE__, __FUNC__, __LINE__, OldMem, NewSize));
224 if (OldMem)
226 struct AllocatedMemFromPool *ptr;
227 ULONG OldSize;
229 if (0 == NewSize)
231 ScalosFree(OldMem);
232 return NULL;
235 ptr = (struct AllocatedMemFromPool *) (((UBYTE *) OldMem) - offsetof(struct AllocatedMemFromPool, amp_UserData));
236 OldSize = ptr->amp_Size - sizeof(struct AllocatedMemFromPool);
238 if (OldSize >= NewSize)
239 return OldMem;
241 NewMem = ScalosAlloc(NewSize);
243 if (NewMem && OldMem)
245 memcpy(NewMem, OldMem, OldSize);
246 ScalosFree(OldMem);
249 d1(KPrintF("%s/%s/%ld: NewMem=%08lx\n", __FILE__, __FUNC__, __LINE__, NewMem));
252 return NewMem;
253 #endif //DLMALLOC
256 #endif /* DEBUG_MEMORY */
258 // ----------------------------------------------------------
260 //#if defined(DEBUG_MEMORY) && !defined(__GNUC__)
261 #if defined(DEBUG_MEMORY)
263 APTR ScalosAlloc_Debug(ULONG Size, CONST_STRPTR CallingFile,
264 CONST_STRPTR CallingFunc, ULONG CallingLine)
266 #if DLMALLOC
267 void *ptr;
269 d1(KPrintF("%s/%s/%ld: START Size=%lu\n", CallingFile, CallingFunc, CallingLine, Size));
270 ptr = dlmalloc(Size);
271 d1(kprintf("%s/%s/%ld: END return %08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
273 #if DLMALLOC_CLEAR
274 if (ptr)
275 memset(ptr, 0x00, Size);
276 #endif //DLMALLOC_CLEAR
278 return ptr;
279 #else //DLMALLOC
280 struct AllocatedMemFromPoolDebug *ptr;
282 if (MainMemPool)
284 size_t AllocSize;
286 AllocSize = Size + sizeof(struct AllocatedMemFromPoolDebug) + SCALOS_MEM_TRAILER * sizeof(ULONG);
288 ScalosObtainSemaphore(&MainMemPoolSemaphore);
289 ptr = AllocPooled(MainMemPool, AllocSize);
290 ScalosReleaseSemaphore(&MainMemPoolSemaphore);
291 if (ptr)
293 ULONG n;
295 ptr->amp_Size = AllocSize;
297 ptr->amp_Line = CallingLine;
298 ptr->amp_File = CallingFile;
299 ptr->amp_Function = CallingFunc;
301 ptr->amp_Magic = SCALOS_MEM_START_MAGIC;
303 for (n = 0; n < SCALOS_MEM_TRAILER; n++)
304 *((ULONG *) &ptr->amp_UserData[Size + n * sizeof(ULONG)]) = SCALOS_MEM_END_MAGIC;
306 return (APTR) &ptr->amp_UserData;
310 return NULL;
311 #endif //DLMALLOC
315 void ScalosFree_Debug(APTR mem, CONST_STRPTR CallingFile,
316 CONST_STRPTR CallingFunc, ULONG CallingLine)
318 #if DLMALLOC
319 d1(KPrintF("%s/%s/%ld: START OldMem=%08lx\n", CallingFile, CallingFunc, CallingLine, mem));
320 dlfree(mem);
321 d1(kprintf("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
322 #else //DLMALLOC
323 if (MainMemPool && mem)
325 ULONG n;
326 size_t OrigSize;
327 struct AllocatedMemFromPoolDebug *ptr;
329 ptr = (struct AllocatedMemFromPoolDebug *) (((UBYTE *) mem) - offsetof(struct AllocatedMemFromPoolDebug, amp_UserData));
331 if (ptr->amp_Magic != SCALOS_MEM_START_MAGIC)
333 kprintf("ScalosFree: %08lx START_MAGIC not found, called from %s/%s/%ld\n",
334 mem, CallingFile, CallingFunc, CallingLine);
335 return;
338 OrigSize = ptr->amp_Size - sizeof(struct AllocatedMemFromPoolDebug) - SCALOS_MEM_TRAILER * sizeof(ULONG);
340 // Check if block trailer is OK
341 for (n = 0; n < SCALOS_MEM_TRAILER; n++)
343 if (*((ULONG *) &ptr->amp_UserData[OrigSize + n * sizeof(ULONG)]) != SCALOS_MEM_END_MAGIC)
345 kprintf("ScalosFree: %08lx trailer damaged, called from %s/%s/%ld\n",
346 mem, CallingFile, CallingFunc, CallingLine);
347 kprintf(" original Length=%lu, allocated from %s/%s/%ld\n",
348 OrigSize, ptr->amp_File, ptr->amp_Function, ptr->amp_Line);
352 ScalosObtainSemaphore(&MainMemPoolSemaphore);
353 FreePooled(MainMemPool, ptr, ptr->amp_Size);
354 ScalosReleaseSemaphore(&MainMemPoolSemaphore);
356 #endif //DLMALLOC
359 #endif /* DEBUG_MEMORY */
361 // ----------------------------------------------------------
363 STRPTR AllocCopyString(CONST_STRPTR clp)
365 STRPTR lp;
367 d1(KPrintF("%s/%s/%ld: START clp=%08lx\n", __FILE__, __FUNC__, __LINE__, clp));
369 if (NULL == clp)
370 clp = "";
372 #if DLMALLOC
373 lp = dlmalloc(1 + strlen(clp));
374 #else //DLMALLOC
375 lp = AllocVec(1 + strlen(clp), MEMF_PUBLIC);
376 #endif //DLMALLOC
377 if (lp)
378 strcpy(lp, clp);
380 d1(KPrintF("%s/%s/%ld: END lp=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, lp, clp));
382 return lp;
386 void FreeCopyString(STRPTR lp)
388 d1(KPrintF("%s/%s/%ld: START lp=%08lx <%s>\n", __FILE__, __FUNC__, __LINE__, lp, lp));
389 #if DLMALLOC
390 dlfree(lp);
391 #else //DLMALLOC
392 if (lp)
393 FreeVec(lp);
394 #endif //DLMALLOC
395 d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
398 // ----------------------------------------------------------
400 void *ScalosAllocNode(size_t Size)
402 #if DLMALLOC
403 APTR ptr;
405 d1(kprintf("%s/%s/%ld: START Size=%lu\n", __FILE__, __FUNC__, __LINE__, Size));
407 ptr = (APTR) dlmalloc(Size);
409 #if DLMALLOC_CLEAR
410 if (ptr)
411 memset(ptr, 0, Size);
412 #endif //DLMALLOC_CLEAR
414 d1(KPrintF("%s/%s/%ld: END ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
415 return ptr;
416 #else //DLMALLOC
417 struct AllocatedMemFromPool *ptr;
419 d1(KPrintF("%s/%s/%ld: Size=%lu NodeMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, Size, NodeMemPool));
421 if (NodeMemPool)
423 size_t AllocSize;
425 AllocSize = Size + sizeof(struct AllocatedMemFromPool);
427 d1(kprintf("%s/%s/%ld: AllocSize=%lu\n", __FILE__, __FUNC__, __LINE__, AllocSize));
428 ScalosObtainSemaphore(&NodeMemPoolSemaphore);
429 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
430 ptr = AllocPooled(NodeMemPool, AllocSize);
431 d1(kprintf("%s/%s/%ld: ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
432 ScalosReleaseSemaphore(&NodeMemPoolSemaphore);
433 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
434 if (ptr)
436 ptr->amp_Size = AllocSize;
438 d1(kprintf("%s/%s/%ld: return %08lx\n", __FILE__, __FUNC__, __LINE__, ptr->amp_UserData));
439 return (APTR) &ptr->amp_UserData;
443 d1(kprintf("%s/%s/%ld: return NULL\n", __FILE__, __FUNC__, __LINE__));
445 return NULL;
446 #endif //DLMALLOC
449 void ScalosFreeNode(void *mem)
451 d1(kprintf("%s/%s/%ld: START mem=%08lx\n", __FILE__, __FUNC__, __LINE__, mem));
452 #if DLMALLOC
453 dlfree(mem);
454 #else //DLMALLOC
455 if (NodeMemPool && mem)
457 struct AllocatedMemFromPool *ptr;
459 ptr = (struct AllocatedMemFromPool *) (((UBYTE *) mem) - offsetof(struct AllocatedMemFromPool, amp_UserData));
461 ScalosObtainSemaphore(&NodeMemPoolSemaphore);
462 FreePooled(NodeMemPool, ptr, ptr->amp_Size);
463 ScalosReleaseSemaphore(&NodeMemPoolSemaphore);
465 #endif //DLMALLOC
466 d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
469 // ----------------------------------------------------------
471 void *ScalosAllocMessage(size_t Size)
473 #if DLMALLOC
474 APTR ptr;
476 d1(kprintf("%s/%s/%ld: START Size=%lu\n", __FILE__, __FUNC__, __LINE__, Size));
478 ptr = (APTR) dlmalloc(Size);
480 #if DLMALLOC_CLEAR
481 if (ptr)
482 memset(ptr, 0, Size);
483 #endif
485 d1(KPrintF("%s/%s/%ld: END ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
486 return ptr;
487 #else //DLMALLOC
488 struct AllocatedMemFromPool *ptr;
490 d1(KPrintF("%s/%s/%ld: Size=%lu MsgMemPool=%08lx\n", __FILE__, __FUNC__, __LINE__, Size, MsgMemPool));
492 if (MsgMemPool)
494 size_t AllocSize = Size + sizeof(struct AllocatedMemFromPool);
496 d1(kprintf("%s/%s/%ld: AllocSize=%lu\n", __FILE__, __FUNC__, __LINE__, AllocSize));
497 ScalosObtainSemaphore(&MsgMemPoolSemaphore);
498 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
499 ptr = AllocPooled(MsgMemPool, AllocSize);
500 d1(kprintf("%s/%s/%ld: ptr=%08lx\n", __FILE__, __FUNC__, __LINE__, ptr));
501 ScalosReleaseSemaphore(&MsgMemPoolSemaphore);
502 d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
503 if (ptr)
505 ptr->amp_Size = AllocSize;
507 d1(kprintf("%s/%s/%ld: return %08lx\n", __FILE__, __FUNC__, __LINE__, ptr->amp_UserData));
508 return (APTR) &ptr->amp_UserData;
512 d1(kprintf("%s/%s/%ld: return NULL\n", __FILE__, __FUNC__, __LINE__));
514 return NULL;
515 #endif //DLMALLOC
518 void ScalosFreeMessage(void *mem)
520 d1(kprintf("%s/%s/%ld: START mem=%08lx\n", __FILE__, __FUNC__, __LINE__, mem));
521 #if DLMALLOC
522 dlfree(mem);
523 #else //DLMALLOC
524 if (MsgMemPool && mem)
526 struct AllocatedMemFromPool *ptr;
528 ptr = (struct AllocatedMemFromPool *) (((UBYTE *) mem) - offsetof(struct AllocatedMemFromPool, amp_UserData));
530 ScalosObtainSemaphore(&MsgMemPoolSemaphore);
531 FreePooled(MsgMemPool, ptr, ptr->amp_Size);
532 ScalosReleaseSemaphore(&MsgMemPoolSemaphore);
534 #endif //DLMALLOC
535 d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
538 // ----------------------------------------------------------
540 struct AnchorPath *ScalosAllocAnchorPath(ULONG Flags, size_t MaxPathLen)
542 struct AnchorPath *ap;
544 #ifndef __amigaos4__
545 ap = ScalosAlloc(sizeof(struct AnchorPath) + Max_PathLen);
546 d1(KPrintF("%s/%s/%ld: ap=%08lx\n", __FILE__, __FUNC__, __LINE__, ap));
547 if (ap)
549 memset(ap, 0, sizeof(struct AnchorPath));
551 ap->ap_Flags = Flags;
552 ap->ap_Strlen = MaxPathLen;
554 #else /* __amigaos4__ */
555 ap = AllocDosObjectTags(DOS_ANCHORPATH,
556 ADO_Flags, Flags,
557 ADO_Strlen, MaxPathLen,
558 TAG_DONE
560 d1(KPrintF("%s/%s/%ld: ap=%08lx\n", __FILE__, __FUNC__, __LINE__, ap));
561 #endif /* __amigaos4__ */
563 return ap;
567 void ScalosFreeAnchorPath(struct AnchorPath *ap)
569 if (ap)
571 #ifndef __amigaos4__
572 ScalosFree(ap);
573 #else /* __amigaos4__ */
574 FreeDosObject(DOS_ANCHORPATH, ap);
575 #endif /* __amigaos4__ */
579 // ----------------------------------------------------------
581 struct InfoData *ScalosAllocInfoData(void)
583 #ifdef __amigaos4__
584 return (struct InfoData *) AllocDosObject(DOS_INFODATA, NULL);
585 #else // __amigaos4__
586 return (struct InfoData *) ScalosAlloc(sizeof(struct InfoData));
587 #endif //__amigaos4__
590 // ----------------------------------------------------------
592 void ScalosFreeInfoData(struct InfoData **pId)
594 if (*pId)
596 #ifdef __amigaos4__
597 FreeDosObject(DOS_INFODATA, *pId);
598 #else // __amigaos4__
599 ScalosFree(*pId);
600 #endif //__amigaos4__
601 *pId = NULL;
605 // ----------------------------------------------------------
607 STRPTR AllocPathBuffer(void)
609 STRPTR Buffer;
611 d1(kprintf("%s/%s/%ld: Max_PathLen=%ld Task=%08lx\n", __FILE__, __FUNC__, __LINE__,
612 Max_PathLen, FindTask(NULL)));
614 Buffer = (STRPTR) ScalosAlloc(Max_PathLen);
616 d1(kprintf("%s/%s/%ld: String=%08lx\n", __FILE__, __FUNC__, __LINE__,
617 Buffer));
619 return Buffer;
622 // ----------------------------------------------------------
624 void FreePathBuffer(STRPTR Buffer)
626 d1(kprintf("%s/%s/%ld: Buffer=%08lx\n", __FILE__, __FUNC__, __LINE__,
627 Buffer));
629 if (Buffer)
630 ScalosFree(Buffer);
633 // ----------------------------------------------------------