1 / 21

Verifying Transactional Programs with Programmer-Defined Conflict Detection

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). Motivation: Linked List from Genome.

thalia
Download Presentation

Verifying Transactional Programs with Programmer-Defined Conflict Detection

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Verifying Transactional Programs withProgrammer-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 Insert 5 5 Head 3 1 9 12 6 17 15 16 Insert 16

  3. Head 3 1 9 12 6 17 15 READ

  4. 5 WRITE Head 3 1 9 12 6 17 15 READ

  5. Write-After-Readconflict! 5 WRITE Head 3 1 9 12 6 17 15 WRITE READ 16

  6. Write-After-Readconflict! • Conventional TM conflict detection • Insertions conflict often 5 WRITE Head 3 1 9 12 6 17 15 WRITE READ 16

  7. But, both insertions OK even if we ignore WAR conflict • Relaxed conflict detection 5 Head 3 1 9 12 6 17 15 16

  8. User-Defined Conflict Detection • Ignore write-after-read conflicts (Titos et al): atomic[!WAR]{ insert method body }

  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 < node->key); node->next = curr; prev->next = node; } }

  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 < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } } 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 < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } } • Ignore Write-After-Readconflicts: • Writes by others can occur between read phase and write phase • Lost ability to reasonsequentially 5 3 1 6 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 < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } } • Would like this action to be “right mover” • Can commute to the right of any actionby another thread

  13. Right Mover  commutes to the right of  if  ;  goes to state S then  ;  goes to same state S. If  is right-mover:  ;  ;

  14. Making !WAR block atomic Ignored WAR conflict:currT1 = currT1->next; does not move to the right of nodeT2->next = curr; list_insert(list_t *listPtr, node_t *node) { atomic [!WAR]{ *curr = listPtr->head; do { prev = curr; currT1 = currT1->next; } while (curr != NULL && curr->key < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } } nodeT2->next = curr; Solution: Abstraction

  15. Want to read 6 again! Abstraction​ intuition 5 5 5 5 ABSTRACT READ 6; WRITE 5 WRITE 5; ABSTRACT READ 6 WRITE 5; READ 5 Need to jump over 5. READ 6; WRITE 5 ABSTRACT READ: Read anything forward but do not pass the key. 3 3 3 3 1 1 1 1 6 6 6 6

  16. Want to read 6 again! Abstraction​ intuition 5 5 5 5 curr= curr->next; with curr= curr->next*; but don’t go past key. ABSTRACT READ 6; WRITE 5 WRITE 5; ABSTRACT READ 6 WRITE 5; READ 5 Need to jump over 5. READ 6; WRITE 5 3 3 3 3 1 1 1 1 6 6 6 6

  17. Abstraction Solution: Abstraction Replace currT1= currT1->next; with currT1 = currT1->next*; but don’t go past key. list_insert(list_t *listPtr, node_t *node) { atomic [!WAR]{ *curr = listPtr->head; do { prev = curr; currT1 = currT1->next*; } while (curr != NULL && curr->key < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } } • 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 < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } }

  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 < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } } • Do global readabstractions  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 < node->key); node->next = curr; prev->next = node; assert(node is in the list && list is sorted); } } 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

More Related