From e5eb83db8ddcfe7212f3884f588a899f600e876d Mon Sep 17 00:00:00 2001 From: Morten Brenna Date: Mon, 9 Mar 2026 00:58:17 +0100 Subject: [PATCH 1/6] Changed the alignment of allocations back to 8 bytes. --- arch/m68k-all/include/aros/cpu.h | 2 +- compiler/include/aros/cpu.h | 2 +- compiler/include/exec/memory.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/m68k-all/include/aros/cpu.h b/arch/m68k-all/include/aros/cpu.h index 6d1109dafbc..379087658aa 100644 --- a/arch/m68k-all/include/aros/cpu.h +++ b/arch/m68k-all/include/aros/cpu.h @@ -23,7 +23,7 @@ #define AROS_PTRALIGN 2 /* Alignment for PTR */ #define AROS_IPTRALIGN 2 /* Alignment for IPTR */ #define AROS_DOUBLEALIGN 2 /* Alignment for double */ -#define AROS_WORSTALIGN 32 /* Worst case alignment - ApolloOS = 32 Bytes */ +#define AROS_WORSTALIGN 4 /* Worst case alignment - ApolloOS = 32 Bytes */ #define AROS_SLOWSTACKFORMAT 1 diff --git a/compiler/include/aros/cpu.h b/compiler/include/aros/cpu.h index e556b361f84..d7a53817218 100644 --- a/compiler/include/aros/cpu.h +++ b/compiler/include/aros/cpu.h @@ -50,7 +50,7 @@ #define AROS_PTRALIGN 8 /* Alignment for PTR */ #define AROS_IPTRALIGN 8 /* Alignment for IPTR */ #define AROS_DOUBLEALIGN 8 /* Alignment for double */ -#define AROS_WORSTALIGN 32 /* Worst case alignment */ +#define AROS_WORSTALIGN 4 /* Worst case alignment */ #define AROS_STACKALIGN 16 /* Clean stack alignment */ #elif defined __arm__ # if defined __thumb2__ diff --git a/compiler/include/exec/memory.h b/compiler/include/exec/memory.h index cb97060ffe1..7855fbedfdf 100644 --- a/compiler/include/exec/memory.h +++ b/compiler/include/exec/memory.h @@ -30,7 +30,7 @@ struct MemChunk }; /* Total size of struct MemChunk, including padding */ -#define MEMCHUNK_TOTAL 32 //[WD] ApolloOS is set to 32 Byte Memory Boundary from Core 11350+ | (AROS_WORSTALIGN > sizeof(struct MemChunk) ? AROS_WORSTALIGN : sizeof(struct MemChunk)) +#define MEMCHUNK_TOTAL (AROS_WORSTALIGN > sizeof(struct MemChunk) ? AROS_WORSTALIGN : sizeof(struct MemChunk)) /* Total size of struct MemHeader, including padding */ #define MEMHEADER_TOTAL (AROS_ROUNDUP2(sizeof(struct MemHeader), MEMCHUNK_TOTAL)) From 89f68845d17b9aebb6dd276683931eb2da70c449 Mon Sep 17 00:00:00 2001 From: Morten Brenna Date: Mon, 9 Mar 2026 01:02:22 +0100 Subject: [PATCH 2/6] Removed free list consistency checks, removed handling of MEMF_MANAGED, as it is never set. --- rom/exec/allocate.c | 4 +- rom/exec/allocpooled.c | 4 +- rom/exec/allocvecpooled.c | 5 +- rom/exec/createpool.c | 4 +- rom/exec/deallocate.c | 4 +- rom/exec/deletepool.c | 4 +- rom/exec/freepooled.c | 4 +- rom/exec/freevecpooled.c | 4 +- rom/exec/memory.c | 185 ++++++++++++++++++++++++++++--------- rom/exec/memory.h | 4 + rom/exec/memory_nommu.c | 19 ++-- rom/exec/prepareexecbase.c | 4 +- 12 files changed, 184 insertions(+), 61 deletions(-) diff --git a/rom/exec/allocate.c b/rom/exec/allocate.c index 22ada6d3231..aa3efa30130 100644 --- a/rom/exec/allocate.c +++ b/rom/exec/allocate.c @@ -84,6 +84,7 @@ { AROS_LIBFUNC_INIT +#ifdef HANDLE_MANAGED_MEM if ((freeList->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(freeList)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList; @@ -94,7 +95,8 @@ return NULL; } else - { +#endif + { struct TraceLocation tp = CURRENT_LOCATION("Allocate"); APTR res; diff --git a/rom/exec/allocpooled.c b/rom/exec/allocpooled.c index badde62ab53..f6e4cba1691 100644 --- a/rom/exec/allocpooled.c +++ b/rom/exec/allocpooled.c @@ -75,6 +75,7 @@ if(!memSize) return NULL; +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { ULONG poolrequirements = (ULONG)(IPTR)mhe->mhe_MemHeader.mh_First; @@ -85,7 +86,8 @@ return NULL; } else - { +#endif + { struct TraceLocation tp = CURRENT_LOCATION("AllocPooled"); struct Pool *pool = poolHeader + MEMHEADER_TOTAL; diff --git a/rom/exec/allocvecpooled.c b/rom/exec/allocvecpooled.c index 95f945ee350..c7eb4908f34 100644 --- a/rom/exec/allocvecpooled.c +++ b/rom/exec/allocvecpooled.c @@ -56,7 +56,7 @@ /* 0-sized allocation results in returning NULL (API guarantee) */ if(!memSize) return NULL; - +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { ULONG poolrequirements = (ULONG)(IPTR)mhe->mhe_MemHeader.mh_First; @@ -67,7 +67,8 @@ return NULL; } else - { +#endif + { IPTR *memory; if (poolHeader == NULL) return NULL; diff --git a/rom/exec/createpool.c b/rom/exec/createpool.c index 49d42ccb914..18ed4774fa0 100644 --- a/rom/exec/createpool.c +++ b/rom/exec/createpool.c @@ -139,6 +139,7 @@ * If the pool is in managed memory, don't bother any further setup. The * pool should do the rest self. */ +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(firstPuddle)) { D(bug("Managed pool\n");) @@ -152,7 +153,8 @@ firstPuddle->mh_First = (APTR)(IPTR)requirements; } else - { +#endif + { /* * Add the puddle to the list (yes, contained in itself). * This is the first puddle so it's safe to use AddTail() here. diff --git a/rom/exec/deallocate.c b/rom/exec/deallocate.c index c3ad9eb20f2..ac57d52374a 100644 --- a/rom/exec/deallocate.c +++ b/rom/exec/deallocate.c @@ -58,6 +58,7 @@ { AROS_LIBFUNC_INIT +#ifdef HANDLE_MANAGED_MEM if ((freeList->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(freeList)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList; @@ -66,7 +67,8 @@ mhe->mhe_Free(mhe, memoryBlock, byteSize); } else - { +#endif + { struct TraceLocation tp = CURRENT_LOCATION("Deallocate"); /* If there is no memory free nothing */ diff --git a/rom/exec/deletepool.c b/rom/exec/deletepool.c index 4541ce6f2f7..224602368cd 100644 --- a/rom/exec/deletepool.c +++ b/rom/exec/deletepool.c @@ -61,12 +61,14 @@ { struct TraceLocation tp = CURRENT_LOCATION("DeletePool"); +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(poolHeader)) { /* Do nothing, everything is handled in FreeMemHeader */ } else - { +#endif + { struct Pool *pool = poolHeader + MEMHEADER_TOTAL; struct Node *p, *p2; /* Avoid casts */ diff --git a/rom/exec/freepooled.c b/rom/exec/freepooled.c index c2dd992f133..c77ad43f0e4 100644 --- a/rom/exec/freepooled.c +++ b/rom/exec/freepooled.c @@ -61,13 +61,15 @@ if(!memSize || !memory) return; +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { if (mhe->mhe_Free) mhe->mhe_Free(mhe, memory, memSize); } else - { +#endif + { struct TraceLocation tp = CURRENT_LOCATION("FreePooled"); InternalFreePooled(poolHeader, memory, memSize, &tp, SysBase); diff --git a/rom/exec/freevecpooled.c b/rom/exec/freevecpooled.c index 845692fa857..647d4377646 100644 --- a/rom/exec/freevecpooled.c +++ b/rom/exec/freevecpooled.c @@ -57,13 +57,15 @@ if(!memory) return; +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { if (mhe->mhe_FreeVec) mhe->mhe_FreeVec(mhe, memory); } else - { +#endif + { if (memory != NULL) { IPTR *real = (IPTR *) memory; diff --git a/rom/exec/memory.c b/rom/exec/memory.c index 430c7edf3a9..a0597430dfe 100644 --- a/rom/exec/memory.c +++ b/rom/exec/memory.c @@ -33,6 +33,7 @@ struct MemHeader *FindMem(APTR address, struct ExecBase *SysBase) while (mh->mh_Node.ln_Succ != NULL) { +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -47,7 +48,8 @@ struct MemHeader *FindMem(APTR address, struct ExecBase *SysBase) } } else - { +#endif + { /* Check if this MemHeader fits */ if (address >= mh->mh_Lower && address < mh->mh_Upper) { @@ -99,9 +101,9 @@ char *FormatMMContext(char *buffer, struct MMContext *ctx, struct ExecBase *SysB return buffer; } -/* #define NO_ALLOCATOR_CONTEXT */ +#define NO_ALLOCATOR_CONTEXT -#ifdef NO_ALLOCATOR_CONTEXT +#if defined(NO_ALLOCATOR_CONTEXT) struct MemHeaderAllocatorCtx * mhac_GetSysCtx(struct MemHeader * mh, struct ExecBase * SysBase) { @@ -379,8 +381,8 @@ void mhac_PoolMemHeaderSetup(struct MemHeader * mh, struct ProtectedPool * pool) #ifdef NO_CONSISTENCY_CHECKS -#define validateHeader(mh, op, addr, size, SysBase) TRUE -#define validateChunk(mc, prev, mh, op, addr, size, SysBase) TRUE +#define validateHeader(mh, op, addr, size, tp, SysBase) TRUE +#define validateChunk(mc, prev, mh, op, addr, size, tp, SysBase) TRUE #else @@ -444,10 +446,10 @@ static inline BOOL validateChunk(struct MemChunk *p2, struct MemChunk *p1, struc UBYTE op, APTR addr, IPTR size, struct TraceLocation *tp, struct ExecBase *SysBase) { - if (((IPTR)p2->mc_Next & (MEMCHUNK_TOTAL-1)) || (p2->mc_Bytes == 0) || (p2->mc_Bytes & (MEMCHUNK_TOTAL-1)) || /* 1 */ - ((APTR)p2 + p2->mc_Bytes > mh->mh_Upper) || /* 2 */ - (p2->mc_Next && (((APTR)p2->mc_Next < (APTR)p2 + p2->mc_Bytes + MEMCHUNK_TOTAL) || /* 3 */ - ((APTR)p2->mc_Next > mh->mh_Upper - MEMCHUNK_TOTAL)))) + if (((IPTR)p2->mc_Next & (MEMCHUNK_TOTAL-1)) || (p2->mc_Bytes == 0) || (p2->mc_Bytes & (MEMCHUNK_TOTAL-1)) || /* 1 */ + ((APTR)p2 + p2->mc_Bytes > mh->mh_Upper) || /* 2 */ + (p2->mc_Next && (((APTR)p2->mc_Next < (APTR)p2 + p2->mc_Bytes + MEMCHUNK_TOTAL) || /* 3 */ + ((APTR)p2->mc_Next > mh->mh_Upper - MEMCHUNK_TOTAL)))) { if (tp) { @@ -471,6 +473,105 @@ static inline BOOL validateChunk(struct MemChunk *p2, struct MemChunk *p1, struc #endif + #define MK_UBYTEPTR(a) ((UBYTE *)(a)) + +APTR stdAllocReverse(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR size, + ULONG requirements, struct TraceLocation *tp, struct ExecBase *SysBase) +{ + /* First round byteSize up to a multiple of MEMCHUNK_TOTAL */ + IPTR byteSize = AROS_ROUNDUP2(size, MEMCHUNK_TOTAL); + struct MemChunk *mc=NULL, *p1, *p2; + + /* Validate MemHeader before doing anything. */ + if (!validateHeader(mh, MM_ALLOC, NULL, size, tp, SysBase)) + return NULL; + + /* Validate if there is even enough total free memory */ + if (mh->mh_Free < byteSize) + return NULL; + /* + * The free memory list is only single linked, i.e. to remove + * elements from the list I need the node's predecessor. For the + * first element I can use mh->mh_First instead of a real predecessor. + */ + p1 = mhac_GetBetterPrevMemChunk((struct MemChunk *)&mh->mh_First, size, mhac); + p2 = p1->mc_Next; + + /* + * Follow the memory list. p1 is the previous MemChunk, p2 is the current one. + * On 1st pass p1 points to mh->mh_First, so that changing p1->mc_Next actually + * changes mh->mh_First. + */ + while (p2 != NULL) + { + /* Validate the current chunk */ + if (!validateChunk(p2, p1, mh, MM_ALLOC, NULL, size, tp, SysBase)) + return NULL; + + /* Check if the current block is large enough */ + if (p2->mc_Bytes>=byteSize) + { + /* It is. */ + mc = p1; + } + /* Go to next block */ + p1 = p2; + p2 = p1->mc_Next; + } + + /* Something found? */ + if (mc != NULL) + { + /* Remember: MEMF_REVERSE is set p1 and p2 are now invalid. */ + p1 = mc; + p2 = p1->mc_Next; + + mhac_MemChunkClaimed(p2, mhac); + + /* Remove the block from the list and return it. */ + if (p2->mc_Bytes == byteSize) + { + /* Fits exactly. Just relink the list. */ + p1->mc_Next = p2->mc_Next; + mc = p2; + } + else + { + struct MemChunk * pp = p1; + + /* Return the last bytes. */ + p1->mc_Next=p2; + mc = (struct MemChunk *)(MK_UBYTEPTR(p2)+p2->mc_Bytes-byteSize); + + p1 = p1->mc_Next; + p1->mc_Next = p2->mc_Next; + p1->mc_Bytes = p2->mc_Bytes-byteSize; + + mhac_MemChunkCreated(p1, pp, mhac); + } + + mh->mh_Free -= byteSize; + + /* Clear the block if requested */ + if (requirements & MEMF_CLEAR) + memset(mc, 0, byteSize); + } + + else + { + if (!mhac_IsIndexEmpty(mhac)) + { + /* + * Since chunks created during deallocation are not returned to index, + * retry with cleared index. + */ + mhac_ClearIndex(mhac); + mc = stdAlloc(mh, mhac, size, requirements, tp, SysBase); + } + } + return mc; +} + /* * Allocate block from the given MemHeader in a specific way. * This routine can be called with SysBase = NULL. @@ -479,6 +580,7 @@ static inline BOOL validateChunk(struct MemChunk *p2, struct MemChunk *p1, struc * However if it was passed once for a given MemHeader it needs to be passed * in all consecutive calls. */ + APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR size, ULONG requirements, struct TraceLocation *tp, struct ExecBase *SysBase) { @@ -486,6 +588,7 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz * The check has to be done for the second time. Exec uses stdAlloc on memheader * passed upon startup. This is bad, very bad. So here a temporary hack :) */ +#ifdef HANDLE_MANAGED_MEM if ((mh->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -498,8 +601,13 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz return NULL; } else +#endif { - /* First round byteSize up to a multiple of MEMCHUNK_TOTAL */ + if(requirements & MEMF_REVERSE) + { + return stdAllocReverse(mh, mhac, size, requirements, tp, SysBase); + } + /* First round byteSize up to a multiple of MEMCHUNK_TOTAL */ IPTR byteSize = AROS_ROUNDUP2(size, MEMCHUNK_TOTAL); struct MemChunk *mc=NULL, *p1, *p2; @@ -508,10 +616,9 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz return NULL; /* Validate if there is even enough total free memory */ - if (mh->mh_Free < byteSize) + if (mh->mh_Free < byteSize) return NULL; - /* * The free memory list is only single linked, i.e. to remove * elements from the list I need the node's predecessor. For the @@ -536,11 +643,7 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz { /* It is. */ mc = p1; - - /* Use this one if MEMF_REVERSE is not set.*/ - if (!(requirements & MEMF_REVERSE)) - break; - /* Else continue - there may be more to come. */ + break; } /* Go to next block */ @@ -568,21 +671,12 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz { struct MemChunk * pp = p1; - if (requirements & MEMF_REVERSE) - { - /* Return the last bytes. */ - p1->mc_Next=p2; - mc = (struct MemChunk *)((UBYTE *)p2+p2->mc_Bytes-byteSize); - } - else - { - /* Return the first bytes. */ - p1->mc_Next=(struct MemChunk *)((UBYTE *)p2+byteSize); - mc=p2; - } + /* Return the first bytes. */ + p1->mc_Next=(struct MemChunk *)(MK_UBYTEPTR(p2)+byteSize); + mc=p2; - p1 = p1->mc_Next; - p1->mc_Next = p2->mc_Next; + p1 = p1->mc_Next; + p1->mc_Next = p2->mc_Next; p1->mc_Bytes = p2->mc_Bytes-byteSize; mhac_MemChunkCreated(p1, pp, mhac); @@ -606,7 +700,6 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz mc = stdAlloc(mh, mhac, size, requirements, tp, SysBase); } } - return mc; } } @@ -623,6 +716,7 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, struct MemChunk *p1, *p2, *p3; UBYTE *p4; +#ifdef HANDLE_MANAGED_MEM if ((freeList->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(freeList)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList; @@ -631,7 +725,8 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, mhe->mhe_Free(mhe, addr, size); } else - { +#endif + { /* Make sure the MemHeader is OK */ if (!validateHeader(freeList, MM_FREE, addr, size, tp, SysBase)) return; @@ -684,7 +779,7 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, If the memory to be freed overlaps with the current block something must be wrong. */ - if (p4>(UBYTE *)p2) + if (p4 > MK_UBYTEPTR(p2)) { bug("[MM] Chunk allocator error\n"); bug("[MM] Attempt to free %u bytes at 0x%p from MemHeader 0x%p\n", byteSize, memoryBlock, freeList); @@ -709,18 +804,17 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, { #if !defined(NO_CONSISTENCY_CHECKS) /* Check if they overlap. */ - if ((UBYTE *)p1 + p1->mc_Bytes > (UBYTE *)p3) + if (MK_UBYTEPTR(p1) + p1->mc_Bytes > MK_UBYTEPTR(p3)) { bug("[MM] Chunk allocator error\n"); - bug("[MM] Attempt to free %u bytes at 0x%p from MemHeader 0x%p\n", byteSize, memoryBlock, freeList); - bug("[MM] Block overlaps (2) with chunk 0x%p (%u bytes)\n", p1, p1->mc_Bytes); - + bug("[MM] Attempt to free 0x%08x bytes at 0x%p from MemHeader 0x%p\n", byteSize, memoryBlock, freeList); + bug("[MM] Block overlaps (2) with chunk 0x%p (0x%08x bytes)\n", p1, p1->mc_Bytes); Alert(AN_FreeTwice); return; } #endif /* Merge if possible */ - if ((UBYTE *)p1 + p1->mc_Bytes == (UBYTE *)p3) + if ((MK_UBYTEPTR(p1) + p1->mc_Bytes) == MK_UBYTEPTR(p3)) { mhac_MemChunkClaimed(p1, mhac); p3 = p1; @@ -740,7 +834,7 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, p1->mc_Next = p3; /* Try to merge with next block (if there is one ;-) ). */ - if (p4 == (UBYTE *)p2 && p2 != NULL) + if (p4 == MK_UBYTEPTR(p2) && p2 != NULL) { /* Overlap checking already done. Doing it here after @@ -752,7 +846,7 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, } /* relink the list and return. */ p3->mc_Next = p2; - p3->mc_Bytes = p4 - (UBYTE *)p3; + p3->mc_Bytes = p4 - MK_UBYTEPTR(p3); freeList->mh_Free += byteSize; if (p1->mc_Next==p3) mhac_MemChunkCreated(p3, p1, mhac); } @@ -795,7 +889,8 @@ APTR AllocMemHeader(IPTR size, ULONG flags, struct TraceLocation *loc, struct Ex { struct MemHeader *orig = FindMem(mh, SysBase); - if (IsManagedMem(orig)) +#ifdef HANDLE_MANAGED_MEM + if (IsManagedMem(orig)) { struct MemHeaderExt *mhe_orig = (struct MemHeaderExt *)orig; struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -837,7 +932,8 @@ APTR AllocMemHeader(IPTR size, ULONG flags, struct TraceLocation *loc, struct Ex mhe->mhe_InitPool(mhe, size, size - header_size); } else - { +#endif + { size -= MEMHEADER_TOTAL; /* @@ -868,12 +964,13 @@ void FreeMemHeader(APTR addr, struct TraceLocation *loc, struct ExecBase *SysBas IPTR size = (IPTR)mhe->mhe_MemHeader.mh_Upper - (IPTR)addr; +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { if (mhe->mhe_DestroyPool) mhe->mhe_DestroyPool(mhe); } - +#endif DMH(bug("[FreeMemHeader] Freeing %u bytes at 0x%p\n", size, addr)); nommu_FreeMem(addr, size, loc, SysBase); } diff --git a/rom/exec/memory.h b/rom/exec/memory.h index 69ba623a52b..7eaba5fd2d0 100644 --- a/rom/exec/memory.h +++ b/rom/exec/memory.h @@ -13,6 +13,10 @@ #include #include +#define NO_CONSISTENCY_CHECKS 1 +#define HANDLE_MANAGED_MEM 0 + + #if defined(__AROSEXEC_SMP__) #define MEM_LOCK do { Forbid(); EXEC_SPINLOCK_LOCK(&PrivExecBase(SysBase)->MemListSpinLock, NULL, SPINLOCK_MODE_WRITE); } while(0) #define MEM_LOCK_SHARED do { Forbid(); EXEC_SPINLOCK_LOCK(&PrivExecBase(SysBase)->MemListSpinLock, NULL, SPINLOCK_MODE_READ); } while(0) diff --git a/rom/exec/memory_nommu.c b/rom/exec/memory_nommu.c index 937e2f51ea7..a909651ee9a 100644 --- a/rom/exec/memory_nommu.c +++ b/rom/exec/memory_nommu.c @@ -36,10 +36,10 @@ APTR nommu_AllocMem(IPTR byteSize, ULONG flags, struct TraceLocation *loc, struc * The requirements are OK if there's no bit in the * 'attributes' that isn't set in the 'mh->mh_Attributes'. */ - if ((requirements & ~mh->mh_Attributes) - || mh->mh_Free < byteSize) + if ((requirements & ~mh->mh_Attributes) || mh->mh_Free < byteSize) continue; +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -48,7 +48,8 @@ APTR nommu_AllocMem(IPTR byteSize, ULONG flags, struct TraceLocation *loc, struc res = mhe->mhe_Alloc(mhe, byteSize, &flags); } else - { +#endif + { res = stdAlloc(mh, mhac_GetSysCtx(mh, SysBase), byteSize, flags, loc, SysBase); } if (res) @@ -72,6 +73,7 @@ APTR nommu_AllocAbs(APTR location, IPTR byteSize, struct ExecBase *SysBase) /* Loop over MemHeader structures */ ForeachNode(&SysBase->MemList, mh) { +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -88,7 +90,8 @@ APTR nommu_AllocAbs(APTR location, IPTR byteSize, struct ExecBase *SysBase) } } else - if (mh->mh_Lower <= location && mh->mh_Upper >= endlocation) +#endif + if (mh->mh_Lower <= location && mh->mh_Upper >= endlocation) break; } @@ -211,6 +214,7 @@ void nommu_FreeMem(APTR memoryBlock, IPTR byteSize, struct TraceLocation *loc, s ForeachNode(&SysBase->MemList, mh) { +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -224,7 +228,8 @@ void nommu_FreeMem(APTR memoryBlock, IPTR byteSize, struct TraceLocation *loc, s } else - { +#endif + { /* Test if the memory belongs to this MemHeader. */ if (mh->mh_Lower > memoryBlock || mh->mh_Upper < blockEnd) continue; @@ -275,7 +280,7 @@ IPTR nommu_AvailMem(ULONG attributes, struct ExecBase *SysBase) D(bug("[MM] Skipping (mh_Attributes = 0x%08X\n", mh->mh_Attributes);) continue; } - +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -295,7 +300,7 @@ IPTR nommu_AvailMem(ULONG attributes, struct ExecBase *SysBase) continue; } } - +#endif /* Find largest chunk? */ if (attributes & MEMF_LARGEST) { diff --git a/rom/exec/prepareexecbase.c b/rom/exec/prepareexecbase.c index a009d35bc61..8b0317eeb2f 100644 --- a/rom/exec/prepareexecbase.c +++ b/rom/exec/prepareexecbase.c @@ -120,6 +120,7 @@ static APTR allocmem(struct MemHeader *mh, ULONG size, ULONG attributes) { APTR ret; +#ifdef HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -130,7 +131,8 @@ static APTR allocmem(struct MemHeader *mh, ULONG size, ULONG attributes) ret = 0; } else - { +#endif + { ret = stdAlloc(mh, NULL, size, attributes, NULL, NULL); } From 0813a81d781f1b2046a7da7dd46a9854e0a6a642 Mon Sep 17 00:00:00 2001 From: Morten Brenna Date: Sat, 11 Apr 2026 20:26:39 +0200 Subject: [PATCH 3/6] Changed the MEMF_MANAGED tests so they actually remove the code. --- rom/exec/allocate.c | 2 +- rom/exec/allocpooled.c | 2 +- rom/exec/allocvecpooled.c | 2 +- rom/exec/createpool.c | 2 +- rom/exec/deallocate.c | 2 +- rom/exec/deletepool.c | 2 +- rom/exec/freepooled.c | 2 +- rom/exec/freevecpooled.c | 2 +- rom/exec/memory.c | 31 +++++++++++++++---------------- rom/exec/memory_nommu.c | 12 +++++++----- rom/exec/prepareexecbase.c | 2 +- 11 files changed, 31 insertions(+), 30 deletions(-) diff --git a/rom/exec/allocate.c b/rom/exec/allocate.c index aa3efa30130..3df74ffc1de 100644 --- a/rom/exec/allocate.c +++ b/rom/exec/allocate.c @@ -84,7 +84,7 @@ { AROS_LIBFUNC_INIT -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if ((freeList->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(freeList)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList; diff --git a/rom/exec/allocpooled.c b/rom/exec/allocpooled.c index f6e4cba1691..fafc9f9c31e 100644 --- a/rom/exec/allocpooled.c +++ b/rom/exec/allocpooled.c @@ -75,7 +75,7 @@ if(!memSize) return NULL; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { ULONG poolrequirements = (ULONG)(IPTR)mhe->mhe_MemHeader.mh_First; diff --git a/rom/exec/allocvecpooled.c b/rom/exec/allocvecpooled.c index c7eb4908f34..1cce73762f4 100644 --- a/rom/exec/allocvecpooled.c +++ b/rom/exec/allocvecpooled.c @@ -56,7 +56,7 @@ /* 0-sized allocation results in returning NULL (API guarantee) */ if(!memSize) return NULL; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { ULONG poolrequirements = (ULONG)(IPTR)mhe->mhe_MemHeader.mh_First; diff --git a/rom/exec/createpool.c b/rom/exec/createpool.c index 18ed4774fa0..93c6d272b45 100644 --- a/rom/exec/createpool.c +++ b/rom/exec/createpool.c @@ -139,7 +139,7 @@ * If the pool is in managed memory, don't bother any further setup. The * pool should do the rest self. */ -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(firstPuddle)) { D(bug("Managed pool\n");) diff --git a/rom/exec/deallocate.c b/rom/exec/deallocate.c index ac57d52374a..cab85db9f07 100644 --- a/rom/exec/deallocate.c +++ b/rom/exec/deallocate.c @@ -58,7 +58,7 @@ { AROS_LIBFUNC_INIT -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if ((freeList->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(freeList)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList; diff --git a/rom/exec/deletepool.c b/rom/exec/deletepool.c index 224602368cd..0981ce3f0e4 100644 --- a/rom/exec/deletepool.c +++ b/rom/exec/deletepool.c @@ -61,7 +61,7 @@ { struct TraceLocation tp = CURRENT_LOCATION("DeletePool"); -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(poolHeader)) { /* Do nothing, everything is handled in FreeMemHeader */ diff --git a/rom/exec/freepooled.c b/rom/exec/freepooled.c index c77ad43f0e4..7b1c66f6865 100644 --- a/rom/exec/freepooled.c +++ b/rom/exec/freepooled.c @@ -61,7 +61,7 @@ if(!memSize || !memory) return; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { if (mhe->mhe_Free) diff --git a/rom/exec/freevecpooled.c b/rom/exec/freevecpooled.c index 647d4377646..8f271bb486e 100644 --- a/rom/exec/freevecpooled.c +++ b/rom/exec/freevecpooled.c @@ -57,7 +57,7 @@ if(!memory) return; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { if (mhe->mhe_FreeVec) diff --git a/rom/exec/memory.c b/rom/exec/memory.c index a0597430dfe..8a1fe8e1cdc 100644 --- a/rom/exec/memory.c +++ b/rom/exec/memory.c @@ -33,7 +33,7 @@ struct MemHeader *FindMem(APTR address, struct ExecBase *SysBase) while (mh->mh_Node.ln_Succ != NULL) { -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -376,7 +376,8 @@ void mhac_PoolMemHeaderSetup(struct MemHeader * mh, struct ProtectedPool * pool) #define mhac_PoolMemHeaderGetCtx(a) ((struct MemHeaderAllocatorCtx *)(a->mh_Node.ln_Name)) #define mhac_PoolMemHeaderGetPool(a) (mhac_PoolMemHeaderGetCtx(a)->mhac_Data1) -#endif +#endif // defined(NO_ALLOCATOR_CONTEXT) + #ifdef NO_CONSISTENCY_CHECKS @@ -540,12 +541,8 @@ APTR stdAllocReverse(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, I struct MemChunk * pp = p1; /* Return the last bytes. */ - p1->mc_Next=p2; mc = (struct MemChunk *)(MK_UBYTEPTR(p2)+p2->mc_Bytes-byteSize); - - p1 = p1->mc_Next; - p1->mc_Next = p2->mc_Next; - p1->mc_Bytes = p2->mc_Bytes-byteSize; + p2->mc_Bytes -= byteSize; mhac_MemChunkCreated(p1, pp, mhac); } @@ -556,7 +553,7 @@ APTR stdAllocReverse(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, I if (requirements & MEMF_CLEAR) memset(mc, 0, byteSize); } - +#if !defined(NO_ALLOCATOR_CONTEXT) else { if (!mhac_IsIndexEmpty(mhac)) @@ -569,6 +566,7 @@ APTR stdAllocReverse(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, I mc = stdAlloc(mh, mhac, size, requirements, tp, SysBase); } } +#endif return mc; } @@ -588,7 +586,7 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz * The check has to be done for the second time. Exec uses stdAlloc on memheader * passed upon startup. This is bad, very bad. So here a temporary hack :) */ -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if ((mh->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -654,7 +652,6 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz /* Something found? */ if (mc != NULL) { - /* Remember: if MEMF_REVERSE is set p1 and p2 are now invalid. */ p1 = mc; p2 = p1->mc_Next; @@ -688,6 +685,7 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz if (requirements & MEMF_CLEAR) memset(mc, 0, byteSize); } +#if !defined(NO_ALLOCATOR_CONTEXT) else { if (!mhac_IsIndexEmpty(mhac)) @@ -700,7 +698,8 @@ APTR stdAlloc(struct MemHeader *mh, struct MemHeaderAllocatorCtx *mhac, IPTR siz mc = stdAlloc(mh, mhac, size, requirements, tp, SysBase); } } - return mc; +#endif + return mc; } } @@ -716,7 +715,7 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, struct MemChunk *p1, *p2, *p3; UBYTE *p4; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if ((freeList->mh_Node.ln_Type == NT_MEMORY) && IsManagedMem(freeList)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)freeList; @@ -774,7 +773,7 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, /* Found a block with a higher address? */ if (p2 >= p3) { -#if !defined(NO_CONSISTENCY_CHECKS) +// #if !defined(NO_CONSISTENCY_CHECKS) /* If the memory to be freed overlaps with the current block something must be wrong. @@ -788,7 +787,7 @@ void stdDealloc(struct MemHeader *freeList, struct MemHeaderAllocatorCtx *mhac, Alert(AN_FreeTwice); return; } -#endif +// #endif /* End the loop with p2 non-zero */ break; } @@ -889,7 +888,7 @@ APTR AllocMemHeader(IPTR size, ULONG flags, struct TraceLocation *loc, struct Ex { struct MemHeader *orig = FindMem(mh, SysBase); -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(orig)) { struct MemHeaderExt *mhe_orig = (struct MemHeaderExt *)orig; @@ -964,7 +963,7 @@ void FreeMemHeader(APTR addr, struct TraceLocation *loc, struct ExecBase *SysBas IPTR size = (IPTR)mhe->mhe_MemHeader.mh_Upper - (IPTR)addr; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mhe)) { if (mhe->mhe_DestroyPool) diff --git a/rom/exec/memory_nommu.c b/rom/exec/memory_nommu.c index a909651ee9a..a48cb676aa4 100644 --- a/rom/exec/memory_nommu.c +++ b/rom/exec/memory_nommu.c @@ -25,6 +25,8 @@ APTR nommu_AllocMem(IPTR byteSize, ULONG flags, struct TraceLocation *loc, struc struct MemHeader *mh; ULONG requirements = flags & MEMF_PHYSICAL_MASK; + byteSize = (byteSize + MEMCHUNK_TOTAL-1) & ~(MEMCHUNK_TOTAL-1); + /* Protect memory list against other tasks */ MEM_LOCK; @@ -39,7 +41,7 @@ APTR nommu_AllocMem(IPTR byteSize, ULONG flags, struct TraceLocation *loc, struc if ((requirements & ~mh->mh_Attributes) || mh->mh_Free < byteSize) continue; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -73,7 +75,7 @@ APTR nommu_AllocAbs(APTR location, IPTR byteSize, struct ExecBase *SysBase) /* Loop over MemHeader structures */ ForeachNode(&SysBase->MemList, mh) { -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -214,7 +216,7 @@ void nommu_FreeMem(APTR memoryBlock, IPTR byteSize, struct TraceLocation *loc, s ForeachNode(&SysBase->MemList, mh) { -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -280,7 +282,7 @@ IPTR nommu_AvailMem(ULONG attributes, struct ExecBase *SysBase) D(bug("[MM] Skipping (mh_Attributes = 0x%08X\n", mh->mh_Attributes);) continue; } -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; @@ -327,7 +329,7 @@ IPTR nommu_AvailMem(ULONG attributes, struct ExecBase *SysBase) /* 2. The end (+1) of the current MemChunk must be lower than the start of the next one. */ if (mc->mc_Next && ((UBYTE *)mc + mc->mc_Bytes >= (UBYTE *)mc->mc_Next)) { - bug("[MM] Chunk allocator error in MemHeader 0x%p\n"); + bug("[MM] Chunk allocator error in MemHeader 0x%p\n", mh); bug("[MM] Overlapping chunks 0x%p (%u bytes) and 0x%p (%u bytes)\n", mc, mc->mc_Bytes, mc->mc_Next, mc->mc_Next->mc_Bytes); Alert(AN_MemoryInsane|AT_DeadEnd); diff --git a/rom/exec/prepareexecbase.c b/rom/exec/prepareexecbase.c index 8b0317eeb2f..86f7bf030b5 100644 --- a/rom/exec/prepareexecbase.c +++ b/rom/exec/prepareexecbase.c @@ -120,7 +120,7 @@ static APTR allocmem(struct MemHeader *mh, ULONG size, ULONG attributes) { APTR ret; -#ifdef HANDLE_MANAGED_MEM +#if HANDLE_MANAGED_MEM if (IsManagedMem(mh)) { struct MemHeaderExt *mhe = (struct MemHeaderExt *)mh; From 74a9f3b5b585f8bbaa1bcd0264619bbb25763482 Mon Sep 17 00:00:00 2001 From: Morten Brenna Date: Sat, 11 Apr 2026 20:47:05 +0200 Subject: [PATCH 4/6] Fixed debug message issues --- rom/exec/memory_nommu.c | 2 +- rom/exec/newaddtask.c | 2 +- rom/exec/signal.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rom/exec/memory_nommu.c b/rom/exec/memory_nommu.c index a48cb676aa4..d3b3c0fcb66 100644 --- a/rom/exec/memory_nommu.c +++ b/rom/exec/memory_nommu.c @@ -83,7 +83,7 @@ APTR nommu_AllocAbs(APTR location, IPTR byteSize, struct ExecBase *SysBase) { if (mhe->mhe_AllocAbs) { - APTR ret = mhe->mhe_AllocAbs(mhe, byteSize, location); + ret = mhe->mhe_AllocAbs(mhe, byteSize, location); MEM_UNLOCK; diff --git a/rom/exec/newaddtask.c b/rom/exec/newaddtask.c index 01f983fe12f..cb31ef22e04 100644 --- a/rom/exec/newaddtask.c +++ b/rom/exec/newaddtask.c @@ -126,7 +126,7 @@ if (mlExtra) AddTail(&task->tc_MemEntry, &mlExtra->ml_Node); - DADDTASK("NewAddTask MemEntry head: 0x%p", GetHead(&task->tc_MemEntry.lh_Head)); + DADDTASK("NewAddTask MemEntry head: 0x%p", GetHead(&task->tc_MemEntry)); /* Set node type to NT_TASK if not set to something else. */ if (!task->tc_Node.ln_Type) diff --git a/rom/exec/signal.c b/rom/exec/signal.c index d0d011dd2f1..1fd626b48dd 100644 --- a/rom/exec/signal.c +++ b/rom/exec/signal.c @@ -36,7 +36,7 @@ AROS_UFH3(IPTR, signal_hook, D( struct KernelBase *KernelBase = __kernelBase; int cpunum = KrnGetCPUNumber(); - bug("[Exec] CPU%03d: Using IPI to do Signal(%p, %08x), SysBase=%p\n", cpunum, msg->target, msg->sigset, SysBase); + bug("[Exec] CPU%03d: Using IPI to do Signal(%p, %08x), SysBase=%p\n", cpunum, target, sigset, SysBase); ); Signal(target, sigset); @@ -203,7 +203,7 @@ AROS_UFH3(IPTR, signal_hook, } else { - (bug("[Exec] Signal: Raising Exception for 'running' Task on CPU %03u\n", IntETask(task->tc_UnionETask.tc_ETask)->iet_CpuNumber)); + D(bug("[Exec] Signal: Raising Exception for 'running' Task on CPU %03u\n", IntETask(task->tc_UnionETask.tc_ETask)->iet_CpuNumber)); KrnScheduleCPU(IntETask(task->tc_UnionETask.tc_ETask)->iet_CpuAffinity); } #endif From 2f9505807c4899ff0058ddaf2f3bacaf29f483e6 Mon Sep 17 00:00:00 2001 From: Morten Brenna Date: Sun, 12 Apr 2026 18:22:20 +0200 Subject: [PATCH 5/6] Fixed Enable/Forbid issues with the task list when removing tasks --- rom/exec/memory.c | 3 ++ rom/exec/prepareexecbase.c | 11 +++-- rom/exec/putmsg.c | 82 +++++++++++++++++++++++--------------- rom/exec/remtask.c | 5 +++ rom/exec/signal.c | 2 +- 5 files changed, 66 insertions(+), 37 deletions(-) diff --git a/rom/exec/memory.c b/rom/exec/memory.c index 8a1fe8e1cdc..f445c8e2396 100644 --- a/rom/exec/memory.c +++ b/rom/exec/memory.c @@ -1037,6 +1037,7 @@ APTR InternalAllocPooled(APTR poolHeader, IPTR memSize, ULONG flags, struct Trac if (pool->pool.PoolMagic != POOL_MAGIC) { PoolManagerAlert(PME_ALLOC_INV_POOL, AT_DeadEnd, memSize, NULL, NULL, poolHeader); + return NULL; } if (pool->pool.Requirements & MEMF_SEM_PROTECTED) @@ -1206,11 +1207,13 @@ void InternalFreePooled(APTR poolHeader, APTR memory, IPTR memSize, struct Trace if (pool->pool.PoolMagic != POOL_MAGIC) { PoolManagerAlert(PME_FREE_INV_POOL, AT_DeadEnd, memSize, memory, poolHeaderMH, NULL); + return; } if (poolHeaderMH != poolHeader) { PoolManagerAlert(PME_FREE_MXD_POOL, 0, memSize, memory, poolHeaderMH, poolHeader); + return; } if (pool->pool.Requirements & MEMF_SEM_PROTECTED) diff --git a/rom/exec/prepareexecbase.c b/rom/exec/prepareexecbase.c index 86f7bf030b5..01cf0aacb12 100644 --- a/rom/exec/prepareexecbase.c +++ b/rom/exec/prepareexecbase.c @@ -334,11 +334,16 @@ struct ExecBase *PrepareExecBase(struct MemHeader *mh, struct TagItem *msg) */ opts = strcasestr(args, "mungwall"); if (opts) - PrivExecBase(SysBase)->IntFlags = EXECF_MungWall; + { + if(!strcasestr(args, "nomungwall")) + { + PrivExecBase(SysBase)->IntFlags = EXECF_MungWall; + } + } opts = strcasestr(args, "stacksnoop"); if (opts) - PrivExecBase(SysBase)->IntFlags = EXECF_StackSnoop; + PrivExecBase(SysBase)->IntFlags |= EXECF_StackSnoop; /* * Parse system runtime debug flags. @@ -372,7 +377,7 @@ struct ExecBase *PrepareExecBase(struct MemHeader *mh, struct TagItem *msg) PrivExecBase(SysBase)->ExecLockBase = ExecLock__PrepareBase(mh); #endif - D(bug("[Exec] %s: Preperation complete.\n")); + D(bug("[Exec] %s: Preparation complete.\n", __func__)); return SysBase; } diff --git a/rom/exec/putmsg.c b/rom/exec/putmsg.c index c37eb85f963..5fc0af907da 100644 --- a/rom/exec/putmsg.c +++ b/rom/exec/putmsg.c @@ -82,53 +82,69 @@ void InternalPutMsg(struct MsgPort *port, struct Message *message, struct ExecBa D(bug("[EXEC] PutMsg: Port @ 0x%p, Msg @ 0x%p\n", port, message);) - Disable(); + /* + * Capture port fields while under Disable() so they remain consistent + * even if an interrupt causes the port owner to wake and modify/free + * the port before we get to Signal()/Cause(). + */ + { + APTR sigTask; + UBYTE action; + UBYTE sigBit; + + Disable(); #if defined(__AROSEXEC_SMP__) - EXEC_SPINLOCK_LOCK(&port->mp_SpinLock, NULL, SPINLOCK_MODE_WRITE); + EXEC_SPINLOCK_LOCK(&port->mp_SpinLock, NULL, SPINLOCK_MODE_WRITE); #endif - AddTail(&port->mp_MsgList, &message->mn_Node); - D(bug("[EXEC] PutMsg: Port MsgList->lh_TailPred = 0x%p\n", port->mp_MsgList.lh_TailPred);) + AddTail(&port->mp_MsgList, &message->mn_Node); + D(bug("[EXEC] PutMsg: Port MsgList->lh_TailPred = 0x%p\n", port->mp_MsgList.lh_TailPred);) + + sigTask = port->mp_SigTask; + action = port->mp_Flags & PF_ACTION; + sigBit = port->mp_SigBit; + #if defined(__AROSEXEC_SMP__) - EXEC_SPINLOCK_UNLOCK(&port->mp_SpinLock); + EXEC_SPINLOCK_UNLOCK(&port->mp_SpinLock); #endif - Enable(); - - if (port->mp_SigTask) - { - ASSERT_VALID_PTR(port->mp_SigTask); + Enable(); - /* And trigger the action. */ - switch(port->mp_Flags & PF_ACTION) + if (sigTask) { - case PA_SIGNAL: - D(bug("[EXEC] PutMsg: PA_SIGNAL -> Task 0x%p, Signal %08x\n", port->mp_SigTask, (1 << port->mp_SigBit));) + ASSERT_VALID_PTR(sigTask); + + /* And trigger the action. */ + switch(action) + { + case PA_SIGNAL: + D(bug("[EXEC] PutMsg: PA_SIGNAL -> Task 0x%p, Signal %08x\n", sigTask, (1 << sigBit));) - /* Send the signal */ - Signal((struct Task *)port->mp_SigTask, (1 << port->mp_SigBit)); - break; + /* Send the signal */ + Signal((struct Task *)sigTask, (1 << sigBit)); + break; - case PA_SOFTINT: - D(bug("[EXEC] PutMsg: PA_SOFTINT -> Int %s\n", ((struct Interrupt *)port->mp_SoftInt)->is_Node.ln_Name);) + case PA_SOFTINT: + D(bug("[EXEC] PutMsg: PA_SOFTINT -> Int %s\n", ((struct Interrupt *)sigTask)->is_Node.ln_Name);) - /* Raise a software interrupt */ - Cause((struct Interrupt *)port->mp_SoftInt); - break; + /* Raise a software interrupt */ + Cause((struct Interrupt *)sigTask); + break; - case PA_IGNORE: - /* Do nothing. */ - break; + case PA_IGNORE: + /* Do nothing. */ + break; - case PA_CALL: - D(bug("[EXEC] PutMsg: PA_CALL -> Func @ 0x%p\n", port->mp_SigTask, port);) + case PA_CALL: + D(bug("[EXEC] PutMsg: PA_CALL -> Func @ 0x%p, Port @ 0x%p\n", sigTask, port);) #if defined(__AROSEXEC_SMP__) - //TODO! - the called function must be SMP safe. + //TODO! - the called function must be SMP safe. #endif - /* Call the function in mp_SigTask. */ - AROS_UFC2NR(void, port->mp_SigTask, - AROS_UFCA(struct MsgPort *, port, D0), - AROS_UFCA(struct ExecBase *, SysBase, A6)); - break; + /* Call the function in mp_SigTask. */ + AROS_UFC2NR(void, sigTask, + AROS_UFCA(struct MsgPort *, port, D0), + AROS_UFCA(struct ExecBase *, SysBase, A6)); + break; + } } } } diff --git a/rom/exec/remtask.c b/rom/exec/remtask.c index 720fbae0e76..c78e3ecda00 100644 --- a/rom/exec/remtask.c +++ b/rom/exec/remtask.c @@ -95,10 +95,15 @@ /* * Remove() here, before freeing the MemEntry list. Because * the MemEntry list might contain the task struct itself! + * + * Use Disable() to protect against interrupt-level Signal() + * which can move this task between lists concurrently. */ #if !defined(EXEC_REMTASK_NEEDSSWITCH) + Disable(); task->tc_State = TS_REMOVED; Remove(&task->tc_Node); + Enable(); #else krnSysCallReschedTask(task, TS_REMOVED); #endif diff --git a/rom/exec/signal.c b/rom/exec/signal.c index 1fd626b48dd..a295fcfddee 100644 --- a/rom/exec/signal.c +++ b/rom/exec/signal.c @@ -236,7 +236,7 @@ AROS_UFH3(IPTR, signal_hook, (!(PrivExecBase(SysBase)->IntFlags & EXECF_CPUAffinity) || (KrnCPUInMask(cpunum, IntETask(task->tc_UnionETask.tc_ETask)->iet_CpuAffinity))) && #endif - (task->tc_Node.ln_Pri >= thisTask->tc_Node.ln_Pri)) + (task->tc_Node.ln_Pri > thisTask->tc_Node.ln_Pri)) { /* Yes. A taskswitch is necessary. Prepare one if possible. From 445f2ae428fdcca034dfeaf416a61da336db3767 Mon Sep 17 00:00:00 2001 From: Morten Brenna Date: Sun, 12 Apr 2026 18:23:56 +0200 Subject: [PATCH 6/6] Fixed buffer overruns and resource leaks. --- rom/dos/fgets.c | 5 ++++- rom/dos/getvar.c | 1 + rom/dos/runhandler.c | 1 + rom/dos/splitname.c | 3 +++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/rom/dos/fgets.c b/rom/dos/fgets.c index 3ab87a7644a..2a8c33197f4 100644 --- a/rom/dos/fgets.c +++ b/rom/dos/fgets.c @@ -54,7 +54,10 @@ ULONG len = 0; LONG c; - buflen--; + if(!buflen) + return NULL; + + buflen--; do { diff --git a/rom/dos/getvar.c b/rom/dos/getvar.c index fdee57d61c6..d8d0d5d180f 100644 --- a/rom/dos/getvar.c +++ b/rom/dos/getvar.c @@ -237,6 +237,7 @@ static LONG getvar_from(const char *name, const char *volume, STRPTR buffer, LON { D(bug("GetVar: can't find size\n")); + Close(file); return -1; } diff --git a/rom/dos/runhandler.c b/rom/dos/runhandler.c index 9fc8184bb16..f0cc4733ebc 100644 --- a/rom/dos/runhandler.c +++ b/rom/dos/runhandler.c @@ -73,6 +73,7 @@ struct MsgPort *RunHandler(struct DeviceNode *deviceNode, const char *path, stru D(bug("[RunHandler] LoadSeg(\"L:%s\")\n", cp)); deviceNode->dn_SegList = LoadSeg(cp); CurrentDir(olddir); + UnLock(dir); } } } diff --git a/rom/dos/splitname.c b/rom/dos/splitname.c index 438f6afc531..7839d05883c 100644 --- a/rom/dos/splitname.c +++ b/rom/dos/splitname.c @@ -69,6 +69,9 @@ { AROS_LIBFUNC_INIT + if(!size) + return -1; + size --; name += oldpos;