Ik probeer een non-blocking linked list te maken, maar dat lukt niet erg. Veel online bronnen refereren aan het artikel van Timothy L. Harris A Pragmatic Implementation of Non-blocking Linked-Lists Alle pseudo code is geschreven rond C++, maar het lukt me niet om de boel te vertalen naar C voor mijn unordered list.
Invoegen gaat nog, ook aan de hand van de wikipedia uitleg:
Dat werkt prima.
Voor het verwijderen beschrijft Harris een tweetrapsraket. Eerst verwijder je een node logisch, daarna fysiek.
Voor de logische verwijderingen is het nodig eerst de tail te ontkoppelen van de huidige node en er een nieuwe node tussen te plaatsen.
Waar ik echter al vast loop is hoe je een dubbele linked list maakt om de tail ontkoppeling te faciliteren bij verwijdering.
Het probleem hier is dat het vullen van de tail van de node volgens mij niet thread-safe is. Op hetzelfde moment als dat de tail gevuld wordt, kan ergens via een logische verwijdering al een ontkoppeling hebben plaatsgevonden, waardoor de head van de tail al niet meer naar node verwijst.
En dan ben ik nog niet eens toegekomen aan de daadwerkelijke verwijderingslogica, maar zit ik nog vast in het begrijpen van dit deel van het concept zoals beschreven door Harris
Invoegen gaat nog, ook aan de hand van de wikipedia uitleg:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| typedef struct ll { int i; struct ll *head; } ll; struct ll *list = NULL; void list_add(int x) { struct ll *node = malloc(sizeof(struct ll)); node->i = x; struct ll *cpy = list; do { cpy = list; node->head = cpy; } while(!__sync_bool_compare_and_swap(&list, cpy, node)); } |
Dat werkt prima.
Voor het verwijderen beschrijft Harris een tweetrapsraket. Eerst verwijder je een node logisch, daarna fysiek.
Voor de logische verwijderingen is het nodig eerst de tail te ontkoppelen van de huidige node en er een nieuwe node tussen te plaatsen.
Waar ik echter al vast loop is hoe je een dubbele linked list maakt om de tail ontkoppeling te faciliteren bij verwijdering.
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| typedef struct ll { int i; struct ll *head; struct ll *tail; } ll; struct ll *list = NULL; void list_add(int x) { struct ll *node = malloc(sizeof(struct ll)); node->i = x; node->tail = NULL; struct ll *cpy = list; do { cpy = list; node->head = cpy; } while(!__sync_bool_compare_and_swap(&list, cpy, node)); if(node->head != NULL) { node->head->tail = node; } } |
Het probleem hier is dat het vullen van de tail van de node volgens mij niet thread-safe is. Op hetzelfde moment als dat de tail gevuld wordt, kan ergens via een logische verwijdering al een ontkoppeling hebben plaatsgevonden, waardoor de head van de tail al niet meer naar node verwijst.
En dan ben ik nog niet eens toegekomen aan de daadwerkelijke verwijderingslogica, maar zit ik nog vast in het begrijpen van dit deel van het concept zoals beschreven door Harris
Sinds de 2 dagen regel reageer ik hier niet meer