Exemple #1
0
bool NBBST<T, Threads>::HelpDelete(Info* op){
    infos.publish(op->p->update, 0);
    infos.publish(op->pupdate, 1);
    infos.publish(op, 2);

    Update result = op->p->update;

    //If we succeed
    if(CASPTR(&op->p->update, op->pupdate, Mark(op, MARK))){
        if(op->pupdate){
            infos.releaseNode(Unmark(op->pupdate));
        }

        nodes.releaseNode(op->l);
        HelpMarked(Unmark(op));
        infos.releaseAll();
        
        return true;
    } 
    //if another has succeeded for us
    else if(getState(op->p->update) == MARK && Unmark(op->p->update) == Unmark(op)){
        HelpMarked(Unmark(op));
        infos.releaseAll();
        return true;
    } else {
        Help(result);

        infos.publish(op->gp->update, 0);
        infos.publish(op, 1);
        CASPTR(&op->gp->update, Mark(op, DFLAG), Mark(op, CLEAN));
        infos.releaseAll();

        return false;
    }
}
inline static void connectQueue(void) {
    EnqState lsp_data;
    pointer_t tmp_sp;

    LoadFence();
    tmp_sp = enq_sp;
    lsp_data = enq_pool[tmp_sp.struct_data.index];
    CASPTR(&lsp_data.link_a->next, null, lsp_data.link_b);
}
Exemple #3
0
void NBBST<T, Threads>::HelpInsert(Info* op){
    infos.publish(op, 0);
    infos.publish(op->p->update, 1);

    CASChild(op->p, op->l, op->newInternal);
    CASPTR(&op->p->update, Mark(op, IFLAG), Mark(op, CLEAN));

    infos.releaseAll();
}
inline RetVal LFStackPop(LFStack *l, LFStackThreadState *th_state) {
    reset_backoff(&th_state->backoff);
    do {
        Node *old_top = (Node *) l->top;
        if (old_top == null)
            return (RetVal)INT_MIN;
        if(CASPTR(&l->top, old_top, old_top->next))
            return old_top->val;
        else backoff_delay(&th_state->backoff);
    } while (true) ;
}
Exemple #5
0
void NBBST<T, Threads>::CASChild(Node* parent, Node* old, Node* newNode){
    nodes.publish(old, 0);
    nodes.publish(newNode, 1);

    if(newNode->key < parent->key){
        nodes.publish(parent->left, 2);
        if(CASPTR(&parent->left, old, newNode)){
            if(old){
                nodes.releaseNode(old);
            }
        }
    } else {
        nodes.publish(parent->right, 2);
        if(CASPTR(&parent->right, old, newNode)){
            if(old){
                nodes.releaseNode(old);
            }
        }
    }

    nodes.releaseAll();
}
inline void LFStackPush(LFStack *l, LFStackThreadState *th_state, ArgVal arg) {
    Node *n;

    n = alloc_obj(&th_state->pool);
    reset_backoff(&th_state->backoff);
    n->val = arg;
    do {
        Node *old_top = (Node *) l->top;   // top is volatile
        n->next = old_top;
        if (CASPTR(&l->top, old_top, n) == true)
            break;
        else backoff_delay(&th_state->backoff);
    } while(true);
}
Exemple #7
0
bool NBBST<T, Threads>::remove(T value){
    int key = hash(value);

    SearchResult search;

    while(true){
        Search(key, &search);
        nodes.publish(search.l, 0);
        
        if(search.l->key != key){
            return false;
        }

        if(getState(search.gpupdate) != CLEAN){
            Help(search.gpupdate);
        } else if(getState(search.pupdate) != CLEAN){
            Help(search.pupdate);
        } else {
            infos.publish(search.gp->update, 0);
            infos.publish(search.gpupdate, 1);

            Info* op = newDInfo(search.gp, search.p, search.l, search.pupdate);
            infos.publish(op, 2);

            Update result = search.gp->update;
            if(CASPTR(&search.gp->update, search.gpupdate, Mark(op, DFLAG))){
                if(search.gpupdate){
                    infos.releaseNode(Unmark(search.gpupdate));
                }
                
                infos.releaseAll();

                if(HelpDelete(op)){
                    nodes.releaseAll();
                    
                    return true;
                }
            } else {
                infos.releaseNode(op);
                infos.releaseAll();

                Help(result);
            }
        }
        
        nodes.releaseAll();
    }
}
Exemple #8
0
void NBBST<T, Threads>::HelpMarked(Info* op){
    Node* other;

    if(op->p->right == op->l){
        other = op->p->left;
    } else {
        other = op->p->right;
    }

    CASChild(op->gp, op->p, other);

    infos.publish(op->gp->update, 0);
    infos.publish(op, 1);
    CASPTR(&op->gp->update, Mark(op, DFLAG), Mark(op, CLEAN));
    infos.releaseAll();
}
Exemple #9
0
bool NBBST<T, Threads>::add(T value){
    int key = hash(value);

    Node* newNode = newLeaf(key);

    SearchResult search;

    while(true){
        Search(key, &search);

        nodes.publish(search.l, 0);
            
        infos.publish(search.p->update, 0);
        infos.publish(search.pupdate, 1);

        if(search.l->key == key){
            nodes.releaseNode(newNode);
            nodes.releaseAll();
            
            infos.releaseAll();

            return false; //Key already in the set
        }

        if(getState(search.pupdate) != CLEAN){
            Help(search.pupdate);
        } else {
            Node* newSibling = newLeaf(search.l->key);
            Node* newInt = newInternal(std::max(key, search.l->key));
            newInt->update = Mark(nullptr, CLEAN);
            
            //Put the smaller child on the left
            if(newNode->key <= newSibling->key){
                newInt->left = newNode;
                newInt->right = newSibling;
            } else {
                newInt->left = newSibling;
                newInt->right = newNode;
            }

            Info* op = newIInfo(search.p, newInt, search.l);
            infos.publish(op, 2);

            Update result = search.p->update;
            if(CASPTR(&search.p->update, search.pupdate, Mark(op, IFLAG))){
                HelpInsert(op);

                if(search.pupdate){
                    infos.releaseNode(Unmark(search.pupdate));
                }
                
                nodes.releaseAll();
                infos.releaseAll();

                return true;
            } else {
                nodes.releaseNode(newInt);
                nodes.releaseNode(newSibling);
                nodes.releaseAll();
                
                infos.releaseNode(op);
                infos.releaseAll();

                Help(result);
            }
        }
    }
}