IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31568


Ignore:
Timestamp:
May 25, 2011, 2:16:18 PM (15 years ago)
Author:
eugene
Message:

adding element to psMemBlock to allow more fine-grained locking

Location:
branches/eam_branches/ipp-20110505/psLib/src/sys
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110505/psLib/src/sys/psMemory.c

    r31152 r31568  
    328328// This is the root of the entire memory list
    329329static psMemBlock *lastMemBlockAllocated = NULL;
     330static bool lastMemBlockInFlight = false;
    330331
    331332/* Actually allocate memory
     
    536537    // Reallocate the memory
    537538
    538     // we need to lock this whole section because we need to be able to adjust
    539     // lastMemBlockAllocated if needed (ie, this IS lastMemBlockAllocated)
    540     // this lock is frequently called in a given program
     539    /* psRealloc and locks:
     540
     541       psRealloc calls 'realloc' to change the size of the memory block.  This call is likely
     542       to change the address of the memory block itself.  This is a problem because the address
     543       of the memory block is referred to by the neighbor blocks via their memBlock->nextBlock
     544       and memBlock->previousBlock elements.  If the current memBlock is the first one, then
     545       this issue also applies to 'lastMemBlockAllocated'.  The elements may also be modified
     546       by psFree and psAlloc.  Thus, we need to prevent multiple threads from calling psFree,
     547       psAlloc, or psRealloc on neighbor memory blocks at the same time.
     548
     549       Unfortunately, unlike psAlloc and psFree, psRealloc cannot perform the (expensive)
     550       system call operation (realloc) first and adjust the pointers in separate step (since
     551       the value modified by realloc *is* one of those points.  It is thus necessary to include
     552       the realloc call within the locked segement, making psRealloc likely to serialize the
     553       thread operations.
     554
     555       Alternatively, we can recognize that the lock only need be applied to operations which
     556       are performed on neighboring memBlocks.  We can thus reduce the contention by having a
     557       per-memBlock boolean (inFlight) which says the memBlock or a neighbor is being
     558       modified.  If psFree and psAlloc respect that boolean, they will not modify a memBlock
     559       which is already being realloced (or its neighbor).  In this way, the 'realloc' call can
     560       be performed outside of the locked region.
     561
     562    */
     563
     564    // set a lock, then lock this memblock and its neighbors
    541565    MUTEX_LOCK(&memBlockListMutex);
    542566
     
    548572    // lastMemBlockAllocated will be left with a bogus value
    549573    bool isBlockLast = (memBlock == lastMemBlockAllocated);
     574
     575    memBlock->inFlight = true;
     576    nextBlock->inFlight = true;
     577    previousBlock->inFlight = true;
     578    if (isBlockLast) lastMemBlockInFlight = true;
     579
     580    MUTEX_UNLOCK(&memBlockListMutex);
     581
     582    // now that the per-memBlock locks are set, we can unlock the threads and realloc the data
    550583
    551584    memBlock = (psMemBlock *)realloc(memBlock, sizeof(psMemBlock) + size + sizeof(void *));
     
    581614        memAllocID += memAllocCallback(memBlock);
    582615    }
     616
     617    // all of the list modifications are done; set the lock and clear the per-memBlock locks
     618    MUTEX_LOCK(&memBlockListMutex);
     619    memBlock->inFlight = false;
     620    nextBlock->inFlight = false;
     621    previousBlock->inFlight = false;
     622    if (isBlockLast) lastMemBlockInFlight = false;
    583623
    584624    MUTEX_UNLOCK(&memBlockListMutex);
  • branches/eam_branches/ipp-20110505/psLib/src/sys/psMemory.h

    r31152 r31568  
    7373
    7474    psReferenceCount refCounter;        ///< how many times pointer is referenced
    75     bool persistent;                    ///< marks if this non-user persistent data like error stack, etc.
     75    bool persistent;                    ///< true if this is non-user persistent data like error stack, etc.
     76    bool inFlight;                      ///< true if a nearby block is being free'ed / realloc'ed (local lock)
    7677    const uint32_t endblock;            ///< initialised to p_psMEMMAGIC
    7778}
Note: See TracChangeset for help on using the changeset viewer.