5 #include <exec/types.h>
7 #include <dos/anchorpath.h>
8 #include <dos/dostags.h>
11 #include <dos/dosasl.h>
15 #include <proto/exec.h>
16 #include <proto/ttengine.h>
18 #include <proto/scalos.h>
20 #include <clib/alib_protos.h>
23 #include <scalos/scalos.h>
32 #include "scalos_structures.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__)
53 // DLMALLOC_CLEAR to clear all allocated memory - ATM still required
54 #define DLMALLOC_CLEAR 1
56 //----------------------------------------------------------------------------
59 void* dlmalloc(size_t);
61 void* dlrealloc(void*, size_t);
64 //----------------------------------------------------------------------------
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
78 // ----------------------------------------------------------
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
)
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
)
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
)
107 // ----------------------------------------------------------
109 void MemoryCleanup(void)
113 d1(KPrintF("%s/%s/%ld: MainMemPool=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, MainMemPool
));
116 DeletePool(MainMemPool
);
119 d1(KPrintF("%s/%s/%ld: MsgMemPool=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, MsgMemPool
));
122 DeletePool(MsgMemPool
);
125 d1(KPrintF("%s/%s/%ld: NodeMemPool=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, NodeMemPool
));
128 DeletePool(NodeMemPool
);
134 // ----------------------------------------------------------
139 #undef ObtainSemaphore
140 #undef ReleaseSemaphore
141 #endif /* __GNUC__ */
143 APTR
ScalosAlloc(ULONG Size
)
148 d1(kprintf("%s/%s/%ld: Size=%lu\n", __FILE__
, __FUNC__
, __LINE__
, Size
));
150 ptr
= (APTR
) dlmalloc(Size
);
154 memset(ptr
, 0, Size
);
155 #endif //DLMALLOC_CLEAR
157 d1(kprintf("%s/%s/%ld: END return %08lx\n", __FILE__
, __FUNC__
, __LINE__
, ptr
));
160 struct AllocatedMemFromPool
*ptr
;
162 d1(kprintf("%s/%s/%ld: Size=%lu MemPool=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Size
, MemPool
));
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
));
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__
));
189 void ScalosFree(APTR mem
)
192 d1(KPrintF("%s/%s/%ld: START OldMem=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, mem
));
194 d1(kprintf("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
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
);
210 APTR
ScalosRealloc(APTR OldMem
, ULONG NewSize
)
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
));
223 d1(KPrintF("%s/%s/%ld: OldMem=%08lx NewSize=%lu\n", __FILE__
, __FUNC__
, __LINE__
, OldMem
, NewSize
));
226 struct AllocatedMemFromPool
*ptr
;
235 ptr
= (struct AllocatedMemFromPool
*) (((UBYTE
*) OldMem
) - offsetof(struct AllocatedMemFromPool
, amp_UserData
));
236 OldSize
= ptr
->amp_Size
- sizeof(struct AllocatedMemFromPool
);
238 if (OldSize
>= NewSize
)
241 NewMem
= ScalosAlloc(NewSize
);
243 if (NewMem
&& OldMem
)
245 memcpy(NewMem
, OldMem
, OldSize
);
249 d1(KPrintF("%s/%s/%ld: NewMem=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, NewMem
));
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
)
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
));
275 memset(ptr
, 0x00, Size
);
276 #endif //DLMALLOC_CLEAR
280 struct AllocatedMemFromPoolDebug
*ptr
;
286 AllocSize
= Size
+ sizeof(struct AllocatedMemFromPoolDebug
) + SCALOS_MEM_TRAILER
* sizeof(ULONG
);
288 ScalosObtainSemaphore(&MainMemPoolSemaphore
);
289 ptr
= AllocPooled(MainMemPool
, AllocSize
);
290 ScalosReleaseSemaphore(&MainMemPoolSemaphore
);
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
;
315 void ScalosFree_Debug(APTR mem
, CONST_STRPTR CallingFile
,
316 CONST_STRPTR CallingFunc
, ULONG CallingLine
)
319 d1(KPrintF("%s/%s/%ld: START OldMem=%08lx\n", CallingFile
, CallingFunc
, CallingLine
, mem
));
321 d1(kprintf("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
323 if (MainMemPool
&& mem
)
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
);
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
);
359 #endif /* DEBUG_MEMORY */
361 // ----------------------------------------------------------
363 STRPTR
AllocCopyString(CONST_STRPTR clp
)
367 d1(KPrintF("%s/%s/%ld: START clp=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, clp
));
373 lp
= dlmalloc(1 + strlen(clp
));
375 lp
= AllocVec(1 + strlen(clp
), MEMF_PUBLIC
);
380 d1(KPrintF("%s/%s/%ld: END lp=%08lx <%s>\n", __FILE__
, __FUNC__
, __LINE__
, lp
, clp
));
386 void FreeCopyString(STRPTR lp
)
388 d1(KPrintF("%s/%s/%ld: START lp=%08lx <%s>\n", __FILE__
, __FUNC__
, __LINE__
, lp
, lp
));
395 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
398 // ----------------------------------------------------------
400 void *ScalosAllocNode(size_t Size
)
405 d1(kprintf("%s/%s/%ld: START Size=%lu\n", __FILE__
, __FUNC__
, __LINE__
, Size
));
407 ptr
= (APTR
) dlmalloc(Size
);
411 memset(ptr
, 0, Size
);
412 #endif //DLMALLOC_CLEAR
414 d1(KPrintF("%s/%s/%ld: END ptr=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, ptr
));
417 struct AllocatedMemFromPool
*ptr
;
419 d1(KPrintF("%s/%s/%ld: Size=%lu NodeMemPool=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Size
, NodeMemPool
));
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__
));
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__
));
449 void ScalosFreeNode(void *mem
)
451 d1(kprintf("%s/%s/%ld: START mem=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, mem
));
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
);
466 d1(KPrintF("%s/%s/%ld: END\n", __FILE__
, __FUNC__
, __LINE__
));
469 // ----------------------------------------------------------
471 void *ScalosAllocMessage(size_t Size
)
476 d1(kprintf("%s/%s/%ld: START Size=%lu\n", __FILE__
, __FUNC__
, __LINE__
, Size
));
478 ptr
= (APTR
) dlmalloc(Size
);
482 memset(ptr
, 0, Size
);
485 d1(KPrintF("%s/%s/%ld: END ptr=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, ptr
));
488 struct AllocatedMemFromPool
*ptr
;
490 d1(KPrintF("%s/%s/%ld: Size=%lu MsgMemPool=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, Size
, 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__
));
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__
));
518 void ScalosFreeMessage(void *mem
)
520 d1(kprintf("%s/%s/%ld: START mem=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, mem
));
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
);
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
;
545 ap
= ScalosAlloc(sizeof(struct AnchorPath
) + Max_PathLen
);
546 d1(KPrintF("%s/%s/%ld: ap=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, 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
,
557 ADO_Strlen
, MaxPathLen
,
560 d1(KPrintF("%s/%s/%ld: ap=%08lx\n", __FILE__
, __FUNC__
, __LINE__
, ap
));
561 #endif /* __amigaos4__ */
567 void ScalosFreeAnchorPath(struct AnchorPath
*ap
)
573 #else /* __amigaos4__ */
574 FreeDosObject(DOS_ANCHORPATH
, ap
);
575 #endif /* __amigaos4__ */
579 // ----------------------------------------------------------
581 struct InfoData
*ScalosAllocInfoData(void)
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
)
597 FreeDosObject(DOS_INFODATA
, *pId
);
598 #else // __amigaos4__
600 #endif //__amigaos4__
605 // ----------------------------------------------------------
607 STRPTR
AllocPathBuffer(void)
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__
,
622 // ----------------------------------------------------------
624 void FreePathBuffer(STRPTR Buffer
)
626 d1(kprintf("%s/%s/%ld: Buffer=%08lx\n", __FILE__
, __FUNC__
, __LINE__
,
633 // ----------------------------------------------------------