Hello (i lost the old mails but want answer to this)
>If you have lots smallish objects with a wide range of lifetimes you >can massively reduce fragmentation by using a pool allocator of some >sort to collect objects of a similar lifetimes into larger chunks of >memory. I've seen techniques such has this solve address space have you some links how to enhance that ? amiga os 68k can use several mem allocator easy. I have test netsurf with diffrent memallocators too tlsfmem (very slow due to lots cache misses) buddyallocator (fast speed and no slowdown see) first fit poolalloctar (little faster as buddy alloc at beginning, but after longer netsurf use slowdown extreme.) here a page that slowdown by 3 after 5-7 reload (test with versions without cache) and poolallocator. http://www.fotocommunity.com/members On other pages this is not notice Here is the code of pool allocator.there can a value set so that below a value mem is alloc from the pool. if higher then its alloc from global memory.there is another value that show how large each pool should alloc. this work very system friendly and can work on any OS, when replace the allocate command with the command your OS have. maybe i can tweak with netsurf more when i find some time, currently i use treshold and puddle size of 64 kb in the netsurf tests. thats the pool alloc, if intresting i can post other funcs too.its also possible that netsurf use for diffrent types of mem diffrent pools.I need this for the amiblitz compiler(vars labels functions have own pool) and it compile lots faster as any other compiler, because of less cache misses during search with hash AROS_LH2(APTR, AllocPooled, /* SYNOPSIS */ AROS_LHA(APTR, poolHeader, A0), AROS_LHA(ULONG, memSize, D0), /* LOCATION */ struct ExecBase *, SysBase, 118, Exec) /* FUNCTION Allocate memory out of a private memory pool. INPUTS poolHeader - Handle of the memory pool memSize - Number of bytes you want to get RESULT A pointer to the number of bytes you wanted or NULL if the memory couldn't be allocated NOTES EXAMPLE BUGS SEE ALSO CreatePool(), DeletePool(), FreePooled() INTERNALS ******************************************************************************/ { AROS_LIBFUNC_INIT //STORED0_D1_A0_A1 struct ProtectedPool *pool = (struct ProtectedPool *)poolHeader; APTR ret = NULL; extern char tlsfmem; //memSize+=8; D(bug("AllocPooled $%lx memsize $%lx by \"%s\"\n", poolHeader, memSize, SysBase->ThisTask->tc_Node.ln_Name)); memSize = AROS_ROUNDUP2(memSize, 8); if (pool->pool.Requirements & MEMF_SEM_PROTECTED) { ObtainSemaphore(&pool->sem); } /* If the memSize is bigger than the ThreshSize allocate seperately. */ if(memSize > pool->pool.ThreshSize) { struct Block *bl; ULONG size; /* Get enough memory for the memory block including the header. */ size = memSize + BLOCK_TOTAL; bl = (struct Block *)AllocMem(size, pool->pool.Requirements & ~MEMF_SEM_PROTECTED); /* No memory left */ if(bl == NULL) goto done; /* Initialize the header */ bl->Size = size; /* Add the block to the BlockList */ AddHead((struct List *)&pool->pool.BlockList,(struct Node *)&bl->Node); /* Set pointer to allocated memory */ ret = (UBYTE *)bl + BLOCK_TOTAL; } else { struct MemHeader *mh; /* Follow the list of MemHeaders */ mh = (struct MemHeader *)pool->pool.PuddleList.mlh_Head; for(;;) { /* Are there no more MemHeaders? */ if(mh->mh_Node.ln_Succ==NULL) { /* Get a new one */ mh = (struct MemHeader *) AllocMem(pool->pool.PuddleSize + MEMHEADER_TOTAL, pool->pool.Requirements & ~MEMF_SEM_PROTECTED); /* No memory left? */ if(mh == NULL) goto done; /* Initialize new MemHeader */ mh->mh_First = (struct MemChunk *)((UBYTE *)mh + MEMHEADER_TOTAL); mh->mh_First->mc_Next = NULL; mh->mh_First->mc_Bytes = pool->pool.PuddleSize; mh->mh_Lower = mh->mh_First; mh->mh_Upper = (UBYTE *)mh->mh_First+pool->pool.PuddleSize; mh->mh_Free = pool->pool.PuddleSize; /* And add it to the list */ AddHead((struct List *)&pool->pool.PuddleList, (struct Node *)&mh->mh_Node); /* Fall through to get the memory */ } /* Try to get the memory */ ret = Allocate(mh, memSize); /* Got it? */ if(ret != NULL) break; // /* Got it? */ if(ret != NULL) { /* If this is not the first list and it has some free space, move it to the head */ if (mh->mh_Node.ln_Pred != NULL && mh->mh_Free > 32) { Remove(mh); AddHead((struct List *)&pool->pool.PuddleList, (struct Node *)&mh->mh_Node); } break; } /* No. Try next MemHeader */ mh = (struct MemHeader *)mh->mh_Node.ln_Succ; } /* Allocate does not clear the memory! */ if(pool->pool.Requirements & MEMF_CLEAR) { ULONG *p= (ULONG *)ret; /* Round up (clearing longs is faster than just bytes) */ memSize = (memSize + sizeof(ULONG) - 1) / sizeof(ULONG); /* NUL the memory out */ while(memSize--) *p++=0; } } done: if (pool->pool.Requirements & MEMF_SEM_PROTECTED) { ReleaseSemaphore(&pool->sem); } //LOADD0_D1_A0_A1 /* Everything fine */ return ret; AROS_LIBFUNC_EXIT } /* AllocPooled */ ragmentation issues we had with a project on 32 bit linux. In the case of RISC OS, the C runtime won't give the memory back, but at Regards
