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


Reply via email to