Ejemplo n.º 1
0
volatile qnode * hclh_acquire(local_queue *lq, global_queue *gq, qnode *my_qnode) {
    volatile qnode* my_pred;
    do 
    {
#if defined(OPTERON_OPTIMIZE)
        PREFETCHW(lq);
#endif	/* OPTERON_OPTIMIZE */
        my_pred = *lq;
    }  while (CAS_PTR(lq, my_pred, my_qnode)!=my_pred);

    if (my_pred != NULL) 
    {
        uint16_t i_own_lock = wait_for_grant_or_cluster_master(my_pred, my_qnode->fields.cluster_id);
        if (i_own_lock) 
        {
            return my_pred;
        }
    }
    PAUSE;  PAUSE;

    volatile qnode * local_tail;
    do 
    {
#if defined(OPTERON_OPTIMIZE)
        PREFETCHW(gq);
        PREFETCHW(lq);
#endif	/* OPTERON_OPTIMIZE */
        my_pred = *gq;
        local_tail = *lq;
        PAUSE;
    } while(CAS_PTR(gq, my_pred, local_tail)!=my_pred);

    local_tail->fields.tail_when_spliced = 1;
#if defined(OPTERON_OPTIMIZE)
    PREFETCHW(my_pred);
#endif	/* OPTERON_OPTIMIZE */
    while (my_pred->fields.successor_must_wait) {
        PAUSE;
#if defined(OPTERON_OPTIMIZE)
        pause_rep(23);
        PREFETCHW(my_pred);
#endif	/* OPTERON_OPTIMIZE */
    }
    return my_pred;
}
Ejemplo n.º 2
0
volatile qnode * hclh_acquire(local_queue *lq, global_queue *gq, qnode *my_qnode) {
    //splice my_qnode into local queue
    volatile qnode* my_pred;
    do
    {
        my_pred = *lq;
    }  while (CAS_PTR(lq, my_pred, my_qnode)!=my_pred);

    if (my_pred != NULL)
    {
        uint16_t i_own_lock = wait_for_grant_or_cluster_master(my_pred, my_qnode->fields.cluster_id);
        if (i_own_lock)
        {
            //I have the lock; return qnode just released by previous owner
            return my_pred;
        }
    }
    //at this point, I'm cluster master. Wait to allow time for other acquireres to show up.
    PAUSE;  PAUSE;

    volatile qnode * local_tail;
    //splice local queue into global queue
    do
    {
        my_pred = *gq;
        local_tail = *lq;
        PAUSE;
    } while(CAS_PTR(gq, my_pred, local_tail)!=my_pred);

    //inform successor that it is the new master
    local_tail->fields.tail_when_spliced = 1;
    //wait for predecessor to release lock
    while (my_pred->fields.successor_must_wait) {
        PAUSE;
    }
    //I have the lock. return qnode just released by previous owner for next lock access
    return my_pred;
}