verifying transactional programs with programmer-defined conflict detection
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 PresentationTRANSCRIPT
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.