IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31576


Ignore:
Timestamp:
May 26, 2011, 6:47:53 PM (15 years ago)
Author:
eugene
Message:

add spinlock option and lock before testing, use only 100us delays

Location:
branches/eam_branches/ipp-20110505
Files:
3 edited

Legend:

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

    r31575 r31576  
    4040#define P_PS_MEMMAGIC (uint32_t)0xdeadbeef
    4141
     42# define USE_SPINLOCK 1
     43
     44# if (USE_SPINLOCK)
     45#define MUTEX_LOCK(mutexPtr) \
     46if (safeThreads) { \
     47    pthread_spin_lock(mutexPtr); \
     48}
     49#define MUTEX_UNLOCK(mutexPtr) \
     50if (safeThreads) { \
     51    pthread_spin_unlock(mutexPtr); \
     52}
     53# else // !USE_SPINLOCK
    4254#define MUTEX_LOCK(mutexPtr) \
    4355if (safeThreads) { \
    4456    pthread_mutex_lock(mutexPtr); \
    4557}
    46 
    4758#define MUTEX_UNLOCK(mutexPtr) \
    4859if (safeThreads) { \
    4960    pthread_mutex_unlock(mutexPtr); \
    5061}
     62# endif // USE_SPINLOCK
    5163
    5264// psAbort() calls functions that call psAlloc() so it is *UNSAFE* to use it
     
    94106//
    95107//
    96 static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     108
     109# if (USE_SPINLOCK)
     110static pthread_spinlock_t memBlockListMutex;
     111# else
     112// static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     113static pthread_mutex_t memBlockListMutex;
     114# endif
     115
     116void psMemInit() {
     117
     118# if (USE_SPINLOCK)
     119    pthread_spin_init(&memBlockListMutex, 0);
     120# else
     121    pthread_mutex_init(&memBlockListMutex, NULL);
     122# endif
     123
     124}
    97125
    98126/******** thread safety options management ********/
     
    335363
    336364# if (!HARDLOCKS)
    337 static int setLock1 = 0;
    338 static int clearLock1 = 0;
    339 
    340 static int setLock2 = 0;
    341 static int clearLock2 = 0;
    342 
    343 static int setLockNext = 0;
    344 static int clearLockNext = 0;
    345 
    346 static int setLockPrev = 0;
    347 static int clearLockPrev = 0;
     365static int setLock = 0;
     366static int clearLock = 0;
     367static int retryLock = 0;
    348368# endif
    349369
    350370# define BLOCK_SLEEP 100
    351 
    352 static int callL1 = 0;
    353 static int callL2 = 0;
    354371
    355372# define MEM_ASSERT(COND,MSG) { if (!(COND)) { fprintf (stderr, MSG); abort(); } }
     
    373390       
    374391    while (true) {
    375         // we cannot set the lock on the marker while the lock is held
    376         while (lastMemBlockAllocated->inFlight) { usleep (BLOCK_SLEEP); }
    377 
    378392        // set a lock, then lock this memblock and its neighbors
    379393        MUTEX_LOCK(&memBlockListMutex);
     
    383397            // nope, we need to try again
    384398            MUTEX_UNLOCK(&memBlockListMutex);
     399            retryLock ++;
     400            usleep (BLOCK_SLEEP);
    385401            continue;
    386402        }
     
    388404        // the marker is ours!
    389405        lastMemBlockAllocated->inFlight = true;
    390         setLock1 ++;
     406        setLock ++;
    391407        return;
    392408    }
     
    410426       
    411427    while (true) {
    412         // we cannot set the lock on the marker while the lock is held
    413         while (memBlock->inFlight) { usleep (BLOCK_SLEEP); }
    414 
    415428        // set a lock, then lock this memblock and its neighbors
    416429        MUTEX_LOCK(&memBlockListMutex);
     
    420433            // nope, we need to try again
    421434            MUTEX_UNLOCK(&memBlockListMutex);
     435            usleep (BLOCK_SLEEP);
     436            retryLock ++;
    422437            continue;
    423438        }
     
    425440        // the marker is ours!
    426441        memBlock->inFlight = true;
    427         setLock1 ++;
     442        setLock ++;
    428443        if (keepMutex) return;
    429444
     
    455470    }
    456471    memBlock->inFlight = false;
    457     clearLock1 ++;
     472    clearLock ++;
    458473    MUTEX_UNLOCK(&memBlockListMutex);
    459474    return;
     
    475490        // we cannot set the lock on the marker while the lock is held
    476491        // wait until all three markers are clear:
    477         while (memBlock->inFlight) { usleep (BLOCK_SLEEP); }
    478         while (memBlock->nextBlock && memBlock->nextBlock->inFlight) { usleep (BLOCK_SLEEP); }
    479         while (memBlock->previousBlock && memBlock->previousBlock->inFlight) { usleep (BLOCK_SLEEP); }
     492        // while (memBlock->inFlight) { usleep (BLOCK_SLEEP); }
     493        // while (memBlock->nextBlock && memBlock->nextBlock->inFlight) { usleep (BLOCK_SLEEP); }
     494        // while (memBlock->previousBlock && memBlock->previousBlock->inFlight) { usleep (BLOCK_SLEEP); }
    480495
    481496        // set a lock, then lock this memblock and its neighbors
     
    486501            // nope, we need to try again
    487502            MUTEX_UNLOCK(&memBlockListMutex);
     503            usleep (BLOCK_SLEEP);
     504            retryLock ++;
    488505            continue;
    489506        }
     
    491508            // nope, we need to try again
    492509            MUTEX_UNLOCK(&memBlockListMutex);
     510            usleep (BLOCK_SLEEP);
     511            retryLock ++;
    493512            continue;
    494513        }
     
    496515            // nope, we need to try again
    497516            MUTEX_UNLOCK(&memBlockListMutex);
     517            usleep (BLOCK_SLEEP);
     518            retryLock ++;
    498519            continue;
    499520        }
     
    501522        // the markers are ours!
    502523        memBlock->inFlight = true;
    503         setLock2 ++;
     524        setLock ++;
    504525        if (memBlock->nextBlock) {
    505526            memBlock->nextBlock->inFlight = true;
    506             setLockNext ++;
    507527        }
    508528        if (memBlock->previousBlock) {
    509529            memBlock->previousBlock->inFlight = true;
    510             setLockPrev ++;
    511530        }
    512531        if (keepMutex) return;
     
    530549    MEM_ASSERT (memBlock->inFlight, "trying to clear an unlocked memBlock\n");
    531550    memBlock->inFlight = false;
    532     clearLock2 ++;
     551    clearLock ++;
    533552    if (memBlock->nextBlock) {
    534553        MEM_ASSERT (memBlock->nextBlock->inFlight, "trying to clear an unlocked memBlock\n");
    535554        memBlock->nextBlock->inFlight = false;
    536         clearLockNext ++;
    537555    }
    538556    if (memBlock->previousBlock) {
    539557        MEM_ASSERT (memBlock->previousBlock->inFlight, "trying to clear an unlocked memBlock\n");
    540558        memBlock->previousBlock->inFlight = false;
    541         clearLockPrev ++;
    542559    }
    543560    MUTEX_UNLOCK(&memBlockListMutex);
     
    621638    // lastMemBlockAllocated is always true except the first allocation
    622639    BLOCKLAST_LOCK ();
    623     callL1++;
    624640
    625641    psMemBlock *last1 = lastMemBlockAllocated;
     
    649665
    650666    BLOCK_UNLOCK (memBlock->nextBlock, true);
    651     callL1--;
    652 
    653     // if (callL1 > +7) abort();
    654     // if (callL1 < -7) abort();
    655667
    656668    // And return the user the memory that they allocated
     
    800812    // set a lock, then lock this memblock and its neighbors.  at the end of this call,
    801813    // the global mutex is released, but the memBlock and its neighbors are protected
    802     // BLOCKSET_LOCK (memBlock, false);
    803     MUTEX_LOCK(&memBlockListMutex);
     814    BLOCKSET_LOCK (memBlock, false);
     815    // MUTEX_LOCK(&memBlockListMutex);
    804816
    805817    psMemBlock *nextBlock = memBlock->nextBlock;
     
    847859
    848860    // all of the list modifications are done; set the lock and clear the per-memBlock locks
    849     // BLOCKSET_UNLOCK(memBlock, false);
    850     MUTEX_UNLOCK(&memBlockListMutex);
     861    BLOCKSET_UNLOCK(memBlock, false);
     862    // MUTEX_UNLOCK(&memBlockListMutex);
    851863
    852864    // XXX these are not actually guaranteed : another thread may already grab them before we get here
     
    872884    psS32 j = 0;
    873885    psMemBlock *topBlock = lastMemBlockAllocated;
     886
     887    // XXX move this elsewhere?
     888    fprintf (stderr, "set %d locks, cleared %d locks, retry on %d locks (memID %ld)\n", setLock, clearLock, retryLock, memid);
    874889
    875890    // make sure that the memblock list is free of corruption before we crawl
     
    10801095    // we need a MUTEX_LOCK here: otherwise, two functions can race on refCounter--;
    10811096    BLOCK_LOCK (memBlock, true);
    1082     callL2++;
    10831097    if (memBlock->refCounter > 1) {
    10841098        memBlock->refCounter--;
     
    10891103        }
    10901104        BLOCK_UNLOCK(memBlock, true);
    1091         callL2--;
    10921105        return ptr;
    10931106    }
    10941107    BLOCK_UNLOCK(memBlock, true);
    1095     callL2--;
    1096     // if (callL2 > +7) abort();
    1097     // if (callL2 < -7) abort();
    10981108
    10991109    // we can't invoke freeFunc() while we're holding memBlockListMutex as it
  • branches/eam_branches/ipp-20110505/psLib/src/sys/psMemory.h

    r31568 r31576  
    146146#endif // ifdef DOXYGEN
    147147
     148void psMemInit(void);
    148149
    149150/** Set the deallocator routine
  • branches/eam_branches/ipp-20110505/psphot/src/psphot.c

    r31154 r31576  
    44int main (int argc, char **argv) {
    55
     6    psMemInit();
    67    psTimerStart ("complete");
    78    pmErrorRegister();                  // register psModule's error codes/messages
Note: See TracChangeset for help on using the changeset viewer.