Professional Documents
Culture Documents
of Pthread / C programs
Dynamic Detection
Scalable but may fail to expose all concurrency bugs
Dynamic Verification
Concretely execute the program
Guarantee concurrency bug exposure
No false alarms
APIcallsmadefromreal
programminglanguages
(C,Fortran,C++)
RunFmesemanFcsdeterminedby
realisFccompilersandrunFmes
DynamicVerica-on
Methodsaregoingto
beveryimportantfor
realengineers!
(sta-canalysisandmodel
basedverica-oncan
playimportant
suppor-veroles)
3
P0P1P2P3P4
P0P1P2P3P4
DependentacFons(e.g.,x++andx,
oraccessestothesamelock)
AllotheracFons
arepairwiseindependent
Onlythese2are
RELEVANT!!!
6
lock(y)
lock(x)
lock(x)
..
..
..
unlock(y)
unlock(x)
unlock(x)
L0
L0
U0
U0
L1
L2
U1
U2
L2
L1
U2
U1
SchoolofCompuFng
UniversityofUtah
Features of Inspect
Inspect is a tool for finding (with guarantee, for
a test harness)
Deadlocks
Data races
Assertion violations
in C/Pthread programs
Only DPOR-based tool of its kind
Available for free download
Has an elaborate static analysis front-end that
we have developed using Berkeley CIL
9
void*thread_B(void*arg)
{
pthread_mutex_lock(&mutex);
B_count++;
if(B_count==1)
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex);
A_count;
if(A_count==0)
pthread_mutex_unlock(&lock);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_lock(&mutex);
B_count;
if(B_count==0)
pthread_mutex_unlock(&lock);
pthread_mutex_unlock(&mutex);
}
10
bin/instrument simple-pthread-deadlock.c
Bin/compile simple-pthread-deadlock.instr.c
./inspect ./target
Follow user manual to debug
11
ProgramInstrumentor
Instrumented
Program
ThreadLibrary
Wrapper
compile
ProgramAnalyzer
Analysisresult
Executable
thread1
request/permit
Scheduler
threadn
12
MulFthreadedCProgram
PointerAliasAnalysis
ThreadEscapeAnalysis
IntraproceduralDataowAnalysis
LocksetAnalysis
AnalysisResults
13
pthread_mutex_lock
inspect_thread_create
inspect_mutex_lock
14
lhs=x;
write_shared_xxx(&x,rhs);
..
voidwrite_shared_xxx(type*addr,typeval){
inspect_obj_write(addr);
*addr=val;
}
read_shared_xxx(&lhs,&x);
..
voidread_shared_xxx(type*lhs,type*addr){
inspect_obj_read(addr);
*lhs=*addr;
}
15
thread_rouDne(){
inspect_thread_begin();
inspect_thread_end();
}
16
inspect_local_changes(.)
visibleoperaDon2
visibleoperaDon2
17
Result of instrumentation
void*Philosopher(void*arg){
inti;
i=(int)arg;
...
pthread_mutex_lock(&mutexes[i%3]);
...
while(permits[i%3]==0){
prinn("P%d:trygetF%d\n",i,i%3);
pthread_cond_wait(...);
}
...
permits[i%3]=0;
...
pthread_cond_signal(&condiFonVars[i%3]);
pthread_mutex_unlock(&mutexes[i%3]);
returnNULL;
}
void*Philosopher(void*arg)
{inti;
pthread_mutex_t*tmp;
{
inspect_thread_start("Philosopher");
i=(int)arg;
tmp=&mutexes[i%3];
inspect_mutex_lock(tmp);
while(1){
__cil_tmp43=read_shared_0(&permits[i%3]);
if(!__cil_tmp32){
break;
}
__cil_tmp33=i%3;
tmp___0=__cil_tmp33;
inspect_cond_wait(...);
}
...
write_shared_1(&permits[i%3],0);
...
inspect_cond_signal(tmp___25);
...
inspect_mutex_unlock(tmp___26);
...
inspect_thread_end();
return(__retres31);
}
18
Inspect animation
thread
acDonrequest
Scheduler
permission
DPOR
Programundertest
Statestack
VisibleoperaDoninterceptor
MessageBuer
Unixdomainsockets
Unixdomainsockets
19
permits[i%NUM_THREADS]=0;
prinn("P%d:getF%d\n",i,i%NUM_THREADS);
pthread_mutex_unlock(&mutexes[i%NUM_THREADS]);
//pickuprightfork
pthread_mutex_lock(&mutexes[(i+1)%NUM_THREADS]);
while(permits[(i+1)%NUM_THREADS]==0){
prinn("P%d:trygetF%d\n",i,(i+1)%NUM_THREADS);
pthread_cond_wait(&condiFonVars[(i+1)%NUM_THREADS],&mutexes[(i
+1)%NUM_THREADS]);
}
permits[(i+1)%NUM_THREADS]=0;
prinn("P%d:getF%d\n",i,(i+1)%NUM_THREADS);
pthread_mutex_unlock(&mutexes[(i+1)%NUM_THREADS]);
//prinn("philosopher%dthinks\n",i);
prinn("%d\n",i);
//data=10*data+i;
ush(stdout);
//putdownrightfork
pthread_mutex_lock(&mutexes[(i+1)%NUM_THREADS]);
permits[(i+1)%NUM_THREADS]=1;
prinn("P%d:putF%d\n",i,(i+1)%NUM_THREADS);
pthread_cond_signal(&condiFonVars[(i+1)%NUM_THREADS]);
pthread_mutex_unlock(&mutexes[(i+1)%NUM_THREADS]);
pthread_create(&Fds[NUM_THREADS1],NULL,
OddPhilosopher,(void*)(NUM_THREADS1));
for(i=0;i<NUM_THREADS;i++){
pthread_join(Fds[i],NULL);
}
for(i=0;i<NUM_THREADS;i++){
pthread_mutex_destroy(&mutexes[i]);
}
for(i=0;i<NUM_THREADS;i++){
pthread_cond_destroy(&condiFonVars[i]);
}
//prinn("data=%d\n",data);
//assert(data!=201);
return0;
}
intmain(){
inti;
for(i=0;i<NUM_THREADS;i++)
pthread_mutex_init(&mutexes[i],NULL);
for(i=0;i<NUM_THREADS;i++)
pthread_cond_init(&condiFonVars[i],NULL);
for(i=0;i<NUM_THREADS;i++)
permits[i]=1;
for(i=0;i<NUM_THREADS1;i++){
pthread_create(&Fds[i],NULL,Philosopher,(void*)(i));
}
21
0m0.075s
0m0.001s
0m0.008s
22
//putdownletfork
pthread_mutex_lock(&mutexes[i%NUM_THREADS]);
permits[i%NUM_THREADS]=1;
prinn("P%d:putF%d\n",i,i%NUM_THREADS);
pthread_cond_signal(&condiFonVars[i%NUM_THREADS]);
pthread_mutex_unlock(&mutexes[i%NUM_THREADS]);
//putdownrightfork
pthread_mutex_lock(&mutexes[(i+1)%NUM_THREADS]);
permits[(i+1)%NUM_THREADS]=1;
prinn("P%d:putF%d\n",i,(i+1)%NUM_THREADS);
pthread_cond_signal(&condiFonVars[(i+1)%NUM_THREADS]);
pthread_mutex_unlock(&mutexes[(i+1)%NUM_THREADS]);
returnNULL;
}
pthread_create(&Fds[NUM_THREADS1],NULL,
Philosopher,(void*)(NUM_THREADS1));
for(i=0;i<NUM_THREADS;i++){
pthread_join(Fds[i],NULL);
}
for(i=0;i<NUM_THREADS;i++){
pthread_mutex_destroy(&mutexes[i]);
}
for(i=0;i<NUM_THREADS;i++){
pthread_cond_destroy(&condiFonVars[i]);
}
//prinn("data=%d\n",data);
//assert(data!=201);
return0;
}
intmain(){
inti;
for(i=0;i<NUM_THREADS;i++)
pthread_mutex_init(&mutexes[i],NULL);
for(i=0;i<NUM_THREADS;i++)
pthread_cond_init(&condiFonVars[i],NULL);
for(i=0;i<NUM_THREADS;i++)
permits[i]=1;
for(i=0;i<NUM_THREADS1;i++){
pthread_create(&Fds[i],NULL,Philosopher,(void*)(i));
}
23
0m0.084s
0m0.002s
0m0.011s
24
#include<stdlib.h>//DiningPhilosopherswithnodeadlock
#include<pthread.h>//allphilsbut"odd"onepickuptheir
#include<stdio.h>//letforkrst;oddphilpicks
#include<string.h>//uprightforkrst
#include<malloc.h>
#include<errno.h>
#include<sys/types.h>
#include<assert.h>
#deneNUM_THREADS3
pthread_mutex_tmutexes[NUM_THREADS];
pthread_cond_tcondiFonVars[NUM_THREADS];
intpermits[NUM_THREADS];
pthread_tFds[NUM_THREADS];
intdata=0;
void*Philosopher(void*arg){
inti;
i=(int)arg;
//pickupletfork
pthread_mutex_lock(&mutexes[i%NUM_THREADS]);
while(permits[i%NUM_THREADS]==0){
prinn("P%d:trygetF%d\n",i,i%NUM_THREADS);
pthread_cond_wait(&condiFonVars[i%NUM_THREADS],&mutexes[i
%NUM_THREADS]);
}
permits[i%NUM_THREADS]=0;
prinn("P%d:getF%d\n",i,i%NUM_THREADS);
pthread_mutex_unlock(&mutexes[i%NUM_THREADS]);
nanosleep(0)addedhere
//pickuprightfork
pthread_mutex_lock(&mutexes[(i+1)%NUM_THREADS]);
while(permits[(i+1)%NUM_THREADS]==0){
prinn("P%d:trygetF%d\n",i,(i+1)%NUM_THREADS);
pthread_cond_wait(&condiFonVars[(i+1)%NUM_THREADS],&mutexes[(i
+1)%NUM_THREADS]);
}
permits[(i+1)%NUM_THREADS]=0;
prinn("P%d:getF%d\n",i,(i+1)%NUM_THREADS);
pthread_mutex_unlock(&mutexes[(i+1)%NUM_THREADS]);
//prinn("philosopher%dthinks\n",i);
prinn("%d\n",i);
//data=10*data+i;
ush(stdout);
//putdownrightfork
pthread_mutex_lock(&mutexes[(i+1)%NUM_THREADS]);
permits[(i+1)%NUM_THREADS]=1;
prinn("P%d:putF%d\n",i,(i+1)%NUM_THREADS);
pthread_cond_signal(&condiFonVars[(i+1)%NUM_THREADS]);
pthread_mutex_unlock(&mutexes[(i+1)%NUM_THREADS]);
25
buggysleep
P0:getF0
P0:sleeping0ns
P0:getF1
0
P0:putF1
P0:putF0
P1:getF1
P1:sleeping0ns
P2:getF2
P2:sleeping0ns
P1:trygetF2
P2:getF0
2
P2:putF0
P2:putF2
P1:getF2
1
P1:putF2
P1:putF1
Firstrundeadlockedseconddidnot..
26
P1:putF1
===run48===
P2:getF0
P2:getF2
2
P2:putF2
P2:putF0
P0:getF0
P0:getF1
0
P1:trygetF1
<<
Totalnumber
ofruns:
48,
TransiFons
explored:1814
UsedFme
(seconds):7.999327
===run1===
P0:getF0
P0:getF1
0
P0:putF1
P0:putF0
P1:getF1
P1:getF2
1
P1:putF2
P1:putF1
P2:getF2
P2:getF0
2
P2:putF0
P2:putF2
===run2===
P0:getF0
P0:getF1
0
P0:putF1
P0:putF0
P1:getF1
P1:getF2
1
P2:trygetF2
P1:putF2
P1:putF1
===run28===
P0:getF0
P1:getF1
P0:trygetF1
P2:getF2
P1:trygetF2
P2:trygetF0
Foundadeadlock!!
(0,thread_start)
(0,mutex_init,5)
(0,mutex_init,6)
(0,mutex_init,7)
(0,cond_init,8)
(0,cond_init,9)
(0,cond_init,10)
(0,obj_write,2)
(0,obj_write,3)
(0,obj_write,4)
(0,thread_create,1)
(0,thread_create,2)
(0,thread_create,3)
(1,mutex_lock,5)
(1,obj_read,2)
(1,obj_write,2)
(1,mutex_unlock,5)
(2,mutex_lock,6)
(2,obj_read,3)
(2,obj_write,3)
(2,mutex_unlock,6)
(1,mutex_lock,6)
(1,obj_read,3)
(1,mutex_unlock,6)
(3,mutex_lock,7)
(3,obj_read,4)
(3,obj_write,4)
(3,mutex_unlock,7)
(2,mutex_lock,7)
(2,obj_read,4)
(2,mutex_unlock,7)
(3,mutex_lock,5)
(3,obj_read,2)
(3,mutex_unlock,5)
(1,unknown)
Totalnumberofruns:
29,
killedinthemiddleruns:
4
TransiFonsexplored:
1193
UsedFme(seconds):
5.990523
27
28
BEFOREINSTRUMENTATION
void*thread_A(void*arg)
{
pthread_mutex_lock(&mutex);
A_count++;
pthread_mutex_unlock(&mutex);
}
void*thread_B(void*arg)
{
pthread_mutex_lock(&lock);
B_count++;
pthread_mutex_unlock(&lock);
}
AFTERINSTRUMENTATION
(transiFonsareshownasbands)
void*thread_A(void*arg)//thread_Bissimilar
{void*__retres2;
int__cil_tmp3;
int__cil_tmp4;
{
inspect_thread_start("thread_A");
inspect_mutex_lock(&mutex);
__cil_tmp4=read_shared_0(&A_count);
__cil_tmp3=__cil_tmp4+1;
write_shared_1(&A_count,__cil_tmp3);
inspect_mutex_unlock(&mutex);
__retres2=(void*)0;
inspect_thread_end();
return(__retres2);
}
}
29
Look,ma,nodependencies!
void*thread_A(void*arg)//thread_Bissimilar
{void*__retres2;
int__cil_tmp3;
AFTERINSTRUMENTATION
int__cil_tmp4;
(transiFonsareshownasbands)
{
inspect_thread_start("thread_A");
inspect_mutex_lock(&mutex);
__cil_tmp4=read_shared_0(&A_count);
__cil_tmp3=__cil_tmp4+1;
write_shared_1(&A_count,__cil_tmp3);
inspect_mutex_unlock(&mutex);
__retres2=(void*)0;
inspect_thread_end();
return(__retres2);
}
}
ONEinterleavingwithDPOR
252=(10!)/(5!)2withoutDPOR
30
31
TwotransiDonst1andt2ofaconcurrentprogramare
dependent,if
t1andt2belongtothesameprocess,OR
t1andt2areconcurrentlyenabled,and
t1,t2are:
lockacquireoperaFonsonthesamelock
operaFonsonthesameglobalobjectandat
leastoneofthemisawrite
aWAITandaSIGNALonthesamecondiFon
variable
IntroduceanHBedgebetweeneverypairof
dependentoperaDonsinanexecuDon
32
FirstHAPPENSBEFORE:
AnotherHAPPENSBEFORE
pthread_mutex_lock(&mutex);
A_count++;
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex);
A_count;
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&lock);
B_count++;
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
B_count++;
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&mutex);
A_count;
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex);
A_count++;
pthread_mutex_unlock(&mutex);
33
DATA RACE
Two concurrent transitions enabled out of a state
Both access the same variable and one is a write
34
CLASSICALPOR:
AMPLEdetermined
whenSisreached
S
35
CLASSICALPOR:
AMPLEdetermined
whenSisreached
S
DPOR:
Thisdependency
36
CLASSICALPOR:
AMPLEdetermined
whenSisreached
S
DPOR:
ThisdependencyhelpsEXTEND
THISAMPLESET!!
37
AddRedProcessto
BacktrackSet
ThisbuildstheAmple
setincrementally
basedonobserved
dependencies
Nearest
Dependent
TransiFon
Looking
Back
BlueisinDoneset
CurrentState
Nextmoveof
Redprocess
38
Pu#ngitalltogether
9/6/09
SchoolofCompuFng
UniversityofUtah
40
t0:x++
{Backtrack},{Done}
t1:y++
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
SchoolofCompuFng
UniversityofUtah
41
t0:x++
t0:(!x>2)
{Backtrack},{Done}
t1:y++
{},{}
t1:y++
t1:
y++;
x++;
9/6/09
SchoolofCompuFng
UniversityofUtah
42
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t0:x++
t0:(!x>1)
t1:y++
{},{}
t1:y++
t1:
y++;
x++;
9/6/09
SchoolofCompuFng
UniversityofUtah
43
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t0:x++
t0:(!x>1)
t1:y++
{},{}
t1:y++
{},{}
t1:y++
t1:
y++;
x++;
9/6/09
SchoolofCompuFng
UniversityofUtah
44
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t0:x++
t0:(!x>1)
t1:y++
{},{t0}
t1:y++
{},{}
t1:y++
t1:
y++;
x++;
9/6/09
SchoolofCompuFng
UniversityofUtah
45
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{},{t0}
t1:y++
{},{}
t1:y++
{},{}
t1:x++
SchoolofCompuFng
UniversityofUtah
46
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{},{t0}
t1:y++
{},{t1}
t1:y++
{},{}
t1:x++
SchoolofCompuFng
UniversityofUtah
47
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{},{t0}
t1:y++
{},{t1}
t1:y++
{},{}
t1:x++
SchoolofCompuFng
UniversityofUtah
48
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{t1},{t0}
t1:y++
{},{t1}
t1:y++
{},{}
t1:x++
SchoolofCompuFng
UniversityofUtah
49
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{t1},{t0}
t1:y++
{},{t1}
t1:y++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
50
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{t1},{t0}
t1:y++
{},{t1}
t1:y++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
51
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{t1},{t0}
t1:y++
{},{t1}
t1:y++
{},{t1}
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
52
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{t1},{t0}
t1:y++
{},{t1}
t1:y++
{},{t1}
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
53
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t0:(!x>1)
t1:y++
{},{t0,t1}
t1:y++
{},{t1}
t1:y++
{},{t1}
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
54
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t1:y++
{},{t0,t1}
t0:(!x>1)
t1:y++
{},{}
{},{t1}
t1:y++
t1:x++
{},{t1}
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
55
{Backtrack},{Done}
A Simple DPOR Example
{},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t1:y++
{},{t0,t1}
t0:(!x>1)
t1:y++
{},{}
{},{t1}
t1:y++
t1:x++
{},{t1}
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
56
{Backtrack},{Done}
A Simple DPOR Example
{t1},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t1:y++
{},{t0,t1}
t0:(!x>1)
t1:y++
{},{}
{},{t1}
t1:y++
t1:x++
{},{t1}
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
57
{Backtrack},{Done}
A Simple DPOR Example
{t1},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t1:y++
{},{t0,t1}
t0:(!x>1)
t1:y++
{},{t1}
{},{t1}
t1:y++
t1:x++
{},{t1}
t1:x++
{},{}
t0:(x>1)
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
58
{Backtrack},{Done}
A Simple DPOR Example
{t1},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t1:y++
{},{t0,t1}
t0:(!x>1)
t1:y++
{},{t1}
{},{t1}
t1:y++
t1:x++
{},{t1}
{},{}
t0:(!x>1)
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
59
{Backtrack},{Done}
A Simple DPOR Example
{t1},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t1:y++
{},{t0,t1}
t0:(!x>1)
t1:y++
{t0},{t1}
{},{t1}
t1:y++
t1:x++
{},{}
{},{t1}
t0:(!x>1)
t1:x++
{},{t1}
t1:x++
{},{}
SchoolofCompuFng
UniversityofUtah
60
{Backtrack},{Done}
A Simple DPOR Example
{t1},{t0}
init:x=0;y=0;
t0:
x++;
if(x>1)
assert(false);
t1:
y++;
x++;
9/6/09
t0:x++
t1:y++
{},{t0,t1}
t0:(!x>2)
t1:y++
{t0},{t1}
{},{t1}
t1:y++
t1:x++
{},{}
{},{t1}
t0:(!x>1)
t1:x++
{},{t1}
t1:x++
false
{},{}
SchoolofCompuFng
UniversityofUtah
61
Evaluation
DPOR
benchmark
LOC thrds
SDPOR
runs
trans
time(s)
runs
trans
time(s)
example1
40
35
2k
sharedArray
51
98
18k
bbuf
321
47K
1,058k
938
16k
350k
345
bzip2smp
6k
5k
26k
1311
bzip2smp
6k
18k
92k
9546
bzip2smp
6k
51k
236k
25659
pfscan
1k
84
1k
0.53
71
967
0.48
pfscan
1k
14k
189k
241
3k
40k
58
pfscan
1k
273k
3,402k
5329
9/6/09
SchoolofCompuFng
UniversityofUtah
62
Evaluation
DPOR
benchmark
LOC thrds
SDPOR
runs
trans
time(s)
runs
trans
time(s)
example1
40
35
2k
sharedArray
51
98
18k
bbuf
321
47K
1,058k
938
16k
350k
345
bzip2smp
6k
5k
26k
1311
bzip2smp
6k
18k
92k
9546
bzip2smp
6k
51k
236k
25659
pfscan
1k
84
1k
0.53
71
967
0.48
pfscan
1k
14k
189k
241
3k
40k
58
pfscan
1k
273k
3,402k
5329
9/6/09
SchoolofCompuFng
UniversityofUtah
63
Evaluation
DPOR
benchmark
LOC thrds
SDPOR
runs
trans
time(s)
runs
trans
time(s)
example1
40
35
2k
sharedArray
51
98
18k
bbuf
321
47K
1,058k
938
16k
350k
345
bzip2smp
6k
5k
26k
1311
bzip2smp
6k
18k
92k
9546
bzip2smp
6k
51k
236k
25659
pfscan
1k
84
1k
0.53
71
967
0.48
pfscan
1k
14k
189k
241
3k
40k
58
pfscan
1k
273k
3,402k
5329
9/6/09
SchoolofCompuFng
UniversityofUtah
64
{BT},{Done}
{},{}
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
65
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{},{}
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
66
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{},{}
t0:unlock
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
67
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{},{}
t0:unlock
t1:
lock(t)
unlock(t)
t1:lock
t2:
lock(t)
unlock(t)
68
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
t1:lock
t2:
lock(t)
unlock(t)
69
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
t1:lock
{},{}
t1:unlock
t2:lock
70
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
t1:lock
{t2},{t1}
t1:unlock
t2:lock
71
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
t1:lock
{t2},{t1}
t1:unlock
t2:lock
t2:unlock
72
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
t1:lock
{t2},{t1}
t1:unlock
t2:lock
73
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
{t2},{t1}
t2:
lock(t)
unlock(t)
74
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1,t2},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
t2:lock
{},{t1,t2}
t2:
lock(t)
unlock(t)
75
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1,t2},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
t2:lock
{},{t1,t2}
t2:unlock
76
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t0:lock
{t1,t2},{t0}
t0:unlock
t1:
lock(t)
unlock(t)
{},{t1,t2}
t2:
lock(t)
unlock(t)
77
ASimpleDPORExample
t0:
lock(t)
unlock(t)
{BT},{Done}
{t2},{t0,t1}
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
78
{BT},{Done}
ASimpleDPORExample
t0:
lock(t)
unlock(t)
t1:lock
{t2},{t0,t1}
t1:unlock
t1:
lock(t)
unlock(t)
t2:
lock(t)
unlock(t)
79
Observations
Stateless model checking is
ideal for embarrassingly
parallelism
Different branches of an acyclic
space can be explored
concurrently
9/6/09
SchoolofCompuFng
UniversityofUtah
80
AWorkDistribuDonScheme
load balancer
Request unloading
report result
idle node id
work description
81
9/6/09
82
9/6/09
t0: lock
{t1}, {t0}
t0: unlock
t1: lock
{t2}, {t1}
t1: unlock
t2: lock
t2: unlock
Twonodes:
{}, {t0,t1}
t0: lock
{t1}, {t0}
t0: unlock
{t2}, {t1}
Heuristic : Handoff DEEPEST backtrack point
for another node to explore
Reason : Largest number of paths emanate
from there
83
9/6/09
t0: lock
{}, {t0,t1}
{t1}, {t0}
t0: unlock
{t2}, {}
84
9/6/09
t0: lock
{t2}, {t0,t1}
{t1}, {t0}
t0: unlock
{}, {t2}
t2: lock
t2: unlock
85
9/6/09
t0: lock
{t2}, {t0,t1}
t0: unlock
{}, {t2}
t2: lock
t1: lock
t1: unlock
{}, {}
t2: unlock
86
9/6/09
t0: lock
{t2}, {t0,t1}
t0: unlock
t1: lock
t1: unlock
{}, {t2}
{}, {t2}
t2: lock
t2: lock
t2: unlock
t2: unlock
87
9/6/09
t0: lock
{t2}, {t0,t1}
t0: unlock
t1: lock
t1: unlock
{t2}, {}
{}, {t2}
t2: lock
t2: lock
t2: unlock
t2: unlock
88
9/6/09
t0: lock
{t2}, {t0,t1}
t0: unlock
t1: lock
t1: unlock
{t2}, {}
{}, {t2}
t2: lock
t2: lock
t2: unlock
t2: unlock
Redundancy!
89
9/6/09
{t1,t2}, {t0}
t0: unlock
t1: lock
{t2}, {t1}
t1: unlock
t2: lock
Aggressivelymarkupthestack!
Update the backtrack sets of
ALL dependent operations!
Forms a good allocation scheme
Does not involve any synchronizations
Redundant work may still be
performed
Likelihood is reduced because a node
aggressively owns one operation and
all its dependants
t2: unlock
90
9/6/09
9/6/09
92
9/6/09
Speedup on aget
70
with DdporUpdateBacktrackSets
with UpdateBacktrackSets
60
speedup
50
40
30
20
10
0
0
10
20
30
40
number of nodes
50
60
70
93
Speedup on bbuf
70
with DdporUpdateBacktrackSets
with UpdateBacktrackSets
60
speedup
50
40
30
20
10
0
0
10
20
30
40
number of nodes
50
60
70
94
95
Pedagogical Material
All Examples of MPI book of Pacheco being solved using
ISP
http://www.cs.utah.edu/formal_verification/geof/pacheco
/PachecoTests.html
Similarly we are assembling course material of our
examination of all examples of the Herlihy / Shavit book
using the MSR tool CHESS
For Inspect, we are assembling a case study of verifying a
work-stealing queue
96
End of F
97