Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helpers can't recognize different enq-request in one cell #14

Open
Pslydhh opened this issue Mar 13, 2020 · 0 comments
Open

Helpers can't recognize different enq-request in one cell #14

Pslydhh opened this issue Mar 13, 2020 · 0 comments

Comments

@Pslydhh
Copy link
Contributor

Pslydhh commented Mar 13, 2020

Hi Chaoran.
As I appreciate and study from the wonderful technology and extraordinary ideas of this wait-free queue impl, a tricky question produced in my heart, this question looks like violate Invariant 1(enqueue result cannot be changed in future) in [1], maybe you can have a look when you have time.

It ocurred when someone(enq-thread itself or deq-helper-thread) put a enqueue request in one cell(index) through enq_slow or help_enq, The question is, when we put request in the cell, we know enq.id, the unique request responsible by this cell. But when others help this request to improve parallelism, they may read another enqueue request there:

    long ei = ACQUIRE(&e->id);
    void *ev = ACQUIRE(&e->val);

    if (ei > i) {
        if (c->val == TOP && q->Ei <= i) return BOT;
    } else {
        if ((ei > 0 && CAS(&e->id, &ei, -i)) || (ei == -i && c->val == TOP)) {
            long Ei = q->Ei;
            while (Ei <= i && !CAS(&q->Ei, &Ei, i + 1))
                ;
            c->val = ev;
        }
    }

Actually, the enq of one enqueue thread will evolution like a sequence(val1,id1) (va2,id2) and so on.
We could recognized value belongs to a later request, but we can't distinguish id1 and id2, so image two deq-thread to help the same Cell, maybe thread1 help_enq one Cell with id1(val1) and produce result TOP(because other cell do real-help), then, enqueue thread of id1(val1) produce new request(va2, id2), and thread2 in help_enq process the same Cell with id2(val2) but may produce result val2 if id2 is appropriate. This behavior maybe lost data in help_deq, caused by higher-cell defeats lower-cell then:

        if (new != 0) {
            if (CASra(&deq->idx, &idx, new)) idx = new;
            if (idx >= new) new = 0;
        }

Because the valid value in lower-cell will be lost, and there seems to be no simple solution for me.

  1. Yang and Mellor-Crummey. A Wait-free Queue as Fast as Fetch-and-Add. PPoPP 2016.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant