Example #1
0
C99INLINE
#endif
static void
plasma_spin_pause_yield_adaptive (const uint32_t distance, const int callcount)
{
    /* simplistic backoff employing call count and distance to acquire fair lock
     * (might be adjusted to pause multiple times for slightly larger input
     *  distances, especially on machines with larger numbers of CPUs/cores/SMT,
     *  but be sure to always yield quickly/immediately if distance >= nprocs)
     *
     * callers must initialize nshift and nprocs prior to calling this routine
     * (initialization avoided here since code might be inlined in tight loop)
     * (ok if a few threads run the initialization; results will be same)
     *    if (__builtin_expect( (!nprocs), 0))
     *        plasma_spin_nprocs_init();
     *
     * (nshift == 0 for one core; always yield CPU
     *  nshift == 1 for two cores; test distance <= nshift)
     */
    if (callcount < 128 && distance <= nshift) {
        plasma_spin_pause();  /* brief pause if almost our turn */
    }
    else {
        plasma_spin_yield();  /* yield CPU if highly contended */
    }
}
Example #2
0
bool
plasma_spin_lock_acquire_spinloop (plasma_spin_lock_t * const spin)
{
    uint32_t * const lck = &spin->lck;
    do {
        while (plasma_atomic_load_explicit(lck, memory_order_relaxed)) {
            plasma_spin_pause();
        }
    } while (!plasma_atomic_lock_acquire(lck)); /*(includes barrier)*/
    return true;
}
Example #3
0
bool
plasma_spin_lock_acquire_spinloop (plasma_spin_lock_t * const spin)
{
    uint32_t * const lck = &spin->lck;
    do {
        while (plasma_atomic_ld_nopt_T(uint32_t *, lck)) {
            plasma_spin_pause();
        }
    } while (!plasma_atomic_lock_acquire(lck)); /*(includes barrier)*/
    return true;
}
Example #4
0
bool
plasma_spin_lock_acquire_spindecay (plasma_spin_lock_t * const spin,
                                    int pause1, int pause32, int yield)
{
    /* ((uint32_t *) cast also works for Apple OSSpinLock, which is int32_t) */
    uint32_t * const lck = (uint32_t *)&spin->lck;
    do {
        while (plasma_atomic_load_explicit(lck, memory_order_relaxed)) {
            if (pause1) {
                --pause1;
                plasma_spin_pause();
            }
            else if (pause32) {
                int i = 4;
                --pause32;
                do {
                    plasma_spin_pause();
                    plasma_spin_pause();
                    plasma_spin_pause();
                    plasma_spin_pause();
                    plasma_spin_pause();
                    plasma_spin_pause();
                    plasma_spin_pause();
                    plasma_spin_pause();
                } while (--i);
            }
            else if (yield) {
                --yield;
                plasma_spin_yield();
            }
            else
                return false;
        }
    } while (!plasma_atomic_lock_acquire(lck)); /*(includes barrier)*/
    return true;
}