verifying transactional programs with programmer-defined conflict detection

Post on 24-Feb-2016

25 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Verifying Transactional Programs with Programmer-Defined Conflict Detection. O mer Subasi (Koç University ) , T ayfun Elmas ( University of California, Berkeley) , S erdar Tasiran (Koç University ). Motivation: Linked List from Genome. Insert 5. 5. Head. 3. 1. 9. 12. 6. 17. - PowerPoint PPT Presentation

TRANSCRIPT

1

Verifying Transactional Programs with

Programmer-Defined Conflict Detection

Omer Subasi (Koç University), Tayfun Elmas (University of California, Berkeley),

Serdar Tasiran (Koç University)

Motivation: Linked List from Genome

1 3 6 9 12 15 17Head

5

16

Insert 5

Insert 16

1 3 6 9 12 15 17HeadREAD

1 3 6 9 12 15 17Head

5

WRITE

READ

Write-After-Read

conflict!

1 3 6 9 12 15 17Head

5

16

WRITE

WRITE

READ

Write-After-Read

conflict!

1 3 6 9 12 15 17Head

5

16

WRITE

WRITE

READ

• Conventional TM conflict detection– Insertions conflict often

1 3 6 9 12 15 17Head

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

}

9

Linked List: Insertlist_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: Insertlist_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: Insertlist_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

1 3 6

5

WRITE

READ

12

Making !WAR block atomiclist_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

commutates to the right of if ; goes to state S then ; goes to same state S.

If is right-mover:

; ;

14

Making !WAR block atomiclist_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;

Ignored WAR conflict:

currT1 = currT1->next;

does not move to the right of

nodeT2->next = curr;

Solution: Abstraction

15

Abstraction intuition

1 3 6

5READ 6; WRITE 5

1 3 6

5WRITE 5; READ 5

Want to read 6 again!

1 3 6

5ABSTRACT READ 6; WRITE 5

1 3 6

5WRITE 5; ABSTRACT READ 6

Need to jump over

5.

ABSTRACT READ: Read anything forward but do

not pass the key.

16

Abstraction intuition

1 3 6

5READ 6; WRITE 5

1 3 6

5WRITE 5; READ 5

Want to read 6 again!

1 3 6

5ABSTRACT READ 6; WRITE 5

1 3 6

5WRITE 5; ABSTRACT READ 6

Need to jump over

5.

curr = curr->next; with curr = curr->next*; but don’t go past key.

17

Abstractionlist_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); }

}

Solution: Abstraction

Replace

currT1 = currT1->next; with currT1 = currT1->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 < 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 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 < 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

22

Conclusion

• We provided a modeling and static verification method for programs using transactions with relaxed conflict detection which is:

• tool-supported– HAVOC, VCC, any sequential verification tool supporting non-

determinism• based on program abstraction• enables programmers to reason sequentially

• Applied our method to Labyrinth and Genome benchmarks from STAMP suite.

top related