Presentation is loading. Please wait.

Presentation is loading. Please wait.

Verifying Transactional Programs with Programmer-Defined Conflict Detection Omer Subasi, Serdar Tasiran (Koç University) Tim Harris (Microsoft Research)

Similar presentations


Presentation on theme: "Verifying Transactional Programs with Programmer-Defined Conflict Detection Omer Subasi, Serdar Tasiran (Koç University) Tim Harris (Microsoft Research)"— Presentation transcript:

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


Download ppt "Verifying Transactional Programs with Programmer-Defined Conflict Detection Omer Subasi, Serdar Tasiran (Koç University) Tim Harris (Microsoft Research)"

Similar presentations


Ads by Google