Download presentation
Presentation is loading. Please wait.
Published bySabrina Hawkins Modified over 9 years ago
1
Verifying Transactional Programs with Programmer-Defined Conflict Detection Omer Subasi, Serdar Tasiran (Koç University) Tim Harris (Microsoft Research) Adrian Cristal, Osman Unsal (Barcelona SC) Ruben Titos-Gil (University of Murcia)
2
Motivation: Linked List from Genome 1 3 6912 1517 Head 5 16 Insert 5 Insert 16
3
1 3 6912 1517 Head READ
4
1 3 6912 1517 Head 5 WRITE READ
5
Write- After- Read conflict! 1 3 6912 1517 Head 5 16 WRITE READ
6
Write- After- Read conflict! 1 3 6912 1517 Head 5 16 WRITE READ Conventional TM conflict detection – Insertions conflict often
7
1 3 6912 1517 Head 5 16 But, both insertions OK even if we ignore WAR conflict ⇒ Relaxed conflict detection
8
User-Defined Conflict Detection Ignore write-after-read conflicts (Titos et al): atomic[!WAR]{ insert method body } 8
9
Linked List: Insert list_insert(list_t *listPtr, node_t *node) { atomic { *curr = listPtr->head; do { prev = curr; curr = curr->next; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; } 9
10
Linked List: Insert list_insert(list_t *listPtr, node_t *node) { atomic { *curr = listPtr->head; do { prev = curr; curr = curr->next; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 10 Strict conflict detection: Can reason about transaction code sequentially.
11
Linked List: Insert list_insert(list_t *listPtr, node_t *node) { atomic [!WAR]{ *curr = listPtr->head; do { prev = curr; curr = curr->next; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 11 Ignore Write-After-Read conflicts: Writes by others can occur between read phase and write phase Lost ability to reason sequentially Ignore Write-After-Read conflicts: Writes by others can occur between read phase and write phase Lost ability to reason sequentially 1 3 6 5 WRITE READ
12
Making !WAR block atomic list_insert(list_t *listPtr, node_t *node) { atomic [!WAR]{ *curr = listPtr->head; do { prev = curr; curr = curr->next; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 12 Would like this action to be “right mover” Can commute to the right of any action by another thread Would like this action to be “right mover” Can commute to the right of any action by another thread
13
Right Mover commutes to the right of if ; goes to state S then ; goes to same state S. 13 If is right-mover: ; ; ;
14
Making !WAR block atomic list_insert(list_t *listPtr, node_t *node) { atomic [!WAR]{ *curr = listPtr->head; do { prev = curr; curr T1 = curr T1 ->next; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 14 node T2 ->next = curr; Ignored WAR conflict: curr T1 = curr T1 ->next; does not move to the right of node T2 ->next = curr; Solution: Abstraction
15
Abstraction intuition 15 1 3 6 5 READ 6; WRITE 5 1 3 6 5 WRITE 5; READ 5 Want to read 6 again! 1 3 6 5 ABSTRACT READ 6; WRITE 5 1 3 6 5 WRITE 5; ABSTRACT READ 6 Need to jump over 5. ABSTRACT READ: Read anything forward but do not pass the key.
16
Abstraction intuition 16 1 3 6 5 READ 6; WRITE 5 1 3 6 5 WRITE 5; READ 5 Want to read 6 again! 1 3 6 5 ABSTRACT READ 6; WRITE 5 1 3 6 5 WRITE 5; ABSTRACT READ 6 Need to jump over 5. curr = curr->next; with curr = curr->next*; but don’t go past key.
17
Abstraction list_insert(list_t *listPtr, node_t *node) { atomic [!WAR]{ *curr = listPtr->head; do { prev = curr; curr T1 = curr T1 ->next*; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 17 Solution: Abstraction Replace curr T1 = curr T1 ->next; with curr T1 = curr T1 ->next*; but don’t go past key. Solution: Abstraction Replace curr T1 = curr T1 ->next; with curr T1 = curr T1 ->next*; but don’t go past key. Now the block is atomic. Can do sequential verification. Use a sequential verification tool such as HAVOC, VCC…
18
1. Sequentially prove the original code list_insert(list_t *listPtr, node_t *node) { *curr = listPtr->head; do { prev = curr; curr = curr->next; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 18
19
2. Apply the program transformation list_insert(list_t *listPtr, node_t *node) { *curr = listPtr->head; do { prev = curr; curr = curr->next*; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 19 Do global read abstractions Abstract transaction becomes atomic.
20
3. Prove sequentially properties on abstract code list_insert(list_t *listPtr, node_t *node) { *curr = listPtr->head; do { prev = curr; curr = curr->next*; } while (curr != NULL && curr->key key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } 20 Finally: Soundness theorem says properties hold on original code, with !WAR ignored.
21
Other proofs Labyrinth from STAMP. StringBuffer pool. Can apply to any program that has the pattern where: a large portion of the shared data is read first local computations is done and then a small portion of shared data is updated 21
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.