abortion/retry conditions for concurrent linked list
Closed this issue ยท 13 comments
In the lecture, it is explained that if compare&set is failed or if node is already marked as deleted , then insertion/deletion will be retried.
I couldn't find those conditions in the slides, if anyone wrote down or took picture of them, could you please share it?
Also, do those retries work without changing arguments of insertion/deletion?
One more question, given X->Y->Z and trying to delete Y, we need to know predecessor of Y to delete Y, so X and Y should be given as an argument, right?
- Yes, to delete
Y
, it's necessary to knowX
as well. - Insertion is regarded as successful if its CAS succeeds. Deletion is regarded as successful if its first CAS succeeds. If an operation is not successful, the user of the data structure should retry with other arguments.
Deletion is regarded as successful if its first CAS succeeds.
First CAS? I thought there is only 1 CAS. This is what I have on my notes and on the slides. You mean that delete is successful if marking is done correctly, right? But Marking is not done using a CAS operation, right? It is a fetch_or. I think fetch_add would also work too
Thank you!
@HaritzPuerto Thank you for pointing out my mistake. Yes, a node is regarded as deleted when the first RMW that marks the node succeeds.
You mean checking if first RMW and CAS for deletion/insertion is enough??
When given X->Y->Z and trying to delete Y and inserting new node between Y and Z, if Y's next is marked, for insertion, next = Y.next is Z with marked 1.
If we don't check if it is marked, new node will set its next as marked Z, which makes new node already deleted as soon as it is inserted. As I remember, insertion should check if Y is marked as deleted or not, at the beginning of insertion.
For deletion, think about the situation that tries to remove Y and inserting new node next X. Even if deletion successfully marks Y's next as deleted, a node can be inserted between X and Y successfully and X's next can be changed before deletion completes. Then, second CAS of deletion, trying to set X.next = Y to X.next = Z fails, since X.next is changed to new node.
I think their success are not simply checked with only first RMW and CAS, but checking if a node is marked as deleted should be done, too.
@qkrclrl701 I couldn't understand your question... ํน์ ํ๊ตญ์ด๋ก ๋จผ์ ์๊ธฐํ ์ ์์๊น์?
- X->Y->Z, Y๋ฅผ ์ง์ฐ๊ณ , Y์ Z ์ฌ์ด์ ์๋ก์ด node๋ฅผ insertํ๋ ๊ฒ์ด ๋์์ ์ผ์ด๋๋ ์ํฉ
deletion์์ Y์ next๋ฅผ deleted๋ก markํ ์ดํ์ insertion์ด ์์๋๋ ์ํฉ์ ๊ฐ์ ํ๋ฉด, new node W์ next๋ Y์ next๋ก ์ค์ ๋ ํ ๋ฐ, Y์ next๋ mark๊ฐ ๋ ์ํฉ์ด๋ W.next = marked Z๊ฐ ๋ ๊ฒ์ ๋๋ค. ์ด ์ํฉ์์ insertion์ ๋๋ฒ์งธ CAS๋ ์ฑ๊ณตํ๊ณ , Y.next = W๋ก ์ค์ ๋์ด insertion์ด ์ฑ๊ณตํ ํ ๋ฐ, W์ next๋ ์ฒ์์ Y.next, ์ฆ mark ๋ Z๋ก ์ค์ ๋ ํ ๋ X->Y->W-/>Z๊ฐ ๋์ด, ์ง์ฐ์ง๋ ์์ W๋ฅผ ์ง์ ๋ค๊ณ markํ๊ฒ ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฐ๋ผ์, insertion์ ์ฒ์์ Y.next๊ฐ mark ๋์๋์ง ํ์ธํ๊ณ , mark ๋์๋ค๋ฉด abort ํด์ผํ ๊ฒ ๊ฐ์ต๋๋ค.
- X->Y->Z, Y๋ฅผ ์ง์ฐ๊ณ X์ Y ์ฌ์ด์ ์๋ก์ด node๋ฅผ insert ํ๋ ๊ฒ์ด ๋์์ ์ผ์ด๋๋ ์ํฉ
์ฒ์์ deletion์์ Y์ next๋ฅผ mark ํ๋๊ฒ์ด ์ฑ๊ณตํ๋ค๊ณ ํ๋๋ผ๋, insertion์ ์๋ฌด ๋ฌธ์ ์์ด ์ฑ๊ณตํ์ฌ X->W->Y-/>Z๊ฐ ๋ ๊ฒ์ด๊ณ , deletion์ ๋๋ฒ์งธ CAS๋ X.next๋ฅผ Y์์ Z๋ก ๋ฐ๊พธ๋ ค๊ณ ํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฐ๋ฐ, X.next๊ฐ ์ด๋ฏธ W๋ก ๋ฐ๋์์ผ๋ CAS๊ฐ ์คํจํ๊ณ deletion์ด ์คํจํ ๊ฒ์ ๋๋ค.
๋ต๋ณ์ฃผ์ ๋ด์ฉ์์๋ deletion์ ์ฒซ RMW๊ฐ ์ฑ๊ณตํ๋ฉด deletion์ด ์ฑ๊ณตํ ๊ฒ์ด๋ผ๊ณ ํ์ จ๋๋ฐ, ์ฒซ RMW๊ฐ ์ฑ๊ณตํ๋๋ผ๋ deletion์ด ์คํจํ๋ ์ํฉ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
๋จ์ํ RMW, CAS์ ์ฑ๊ณต ์ฌ๋ถ๋ง์ด ์๋๋ผ, next๊ฐ mark ๋์๋์ง ๋ํ ํ์ธํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค.
- Insertion์ CAS๋ฅผ ํ๋ฒ๋ง ์คํํฉ๋๋ค.
- ๋ง์ํ์ ๋๋ก Insertion์ Y.next๊ฐ mark๋์๋ค๋ฉด abortํฉ๋๋ค.
- Deletion์์ markingํ๋ RMW๊ฐ ์ฑ๊ณตํ๋ฉด deletion ์์ฒด๊ฐ ์ฑ๊ณตํ ๊ฒ์ ๋๋ค. ๋ฆฌ์คํธ์ ๋ฌผ๋ฆฌ์ ์ผ๋ก Y๊ฐ ๋จ์์๋๋ผ๋, ๋ ผ๋ฆฌ์ ์ผ๋ก๋ ์๋ ๊ฒ์ผ๋ก ์ทจ๊ธ๋ฉ๋๋ค.
๋ช
์พํ ๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด, iterate ํ ๋ delete๋ node๊ฐ ์ฌ๋ฌ ๊ฐ ์๋ ๊ฒฝ์ฐ๋ ์กด์ฌํ ๊ฒ ๊ฐ์๋ฐ์,
V->W-/>X-/>Y->Z
์ด๋ฌํ ๊ฒฝ์ฐ์๋ V ์ดํ์ ๋ฐ๋ก Y๋ก ์ด๋ํด์ผ ํ ํ ๋ฐ, ์์ ์๊ฐ์ ๋ง์ํ์ ๋๋ก W์ next๊ฐ mark๋์ง ํ์ธํ ๋ค์ mark๋์์ผ๋ฉด W.next๋ก ์ด๋ํ๋ ๊ฒ์ด ์๋๋ผ while loop๋ก next๊ฐ mark ๋์ง ์์ ์ฒซ๋ฒ์งธ node๋ฅผ ์ฐพ์ ๊ทธ node๋ก ์ด๋ํด์ผ ํ ๊ฒ ๊ฐ์๋ฐ ๋ง๋์?
I think two deletion case is not handled in our algorithm. There was a question about it some days ago but it was buried.
See the concurrent deletion section on link below.
https://en.m.wikipedia.org/wiki/Non-blocking_linked_list
@qkrclrl701 Yes, during iteration, a thread should (1) skip the marked-as-deleted node, or (2) try to remove the marked-as-deleted node and proceed.
I think two deletion case is not handled in our algorithm.
May I ask if you can elaborate on it?
I think two deletion case is not handled in our algorithm.
May I ask if you can elaborate on it?
Hello @jeehoonkang ,
here #63 (comment)
Yeah I was referring that issue. And think it is not that simple to handle