Download presentation
Presentation is loading. Please wait.
1
Efficient dynamic race detection int x; void * t1(){ x = 2; } void * t2(){ x = 3; } main(){ pthread_create( t1 ); pthread_create( t2 ); printf( “x is %d\n”, x ); } public static Singleton getInstance(){ if (instance == null) { synchronized(Singleton.class) { if (instance == null){ instance = new Singleton(); } return instance; }
2
Modern algorithms Eraser – uses locksets, but imprecise. Used in valgrind Clock vectors – maintains vector of time quantum. Precise, but slow? Goldilocks – uses locksets but precise and.. fast?
3
Clock vectors Thread 1 Begin; fork(); lock(); x = 2; unlock(); end. {0,0} {1,0} {2,0} {3,0} {4,0} Thread 2 Begin; Lock(); X = 2; unlock(); end. {1,0} {1,1} {1,2} {1,3} ??
4
Goldilocks Each variable has a lockset, L. Synchronization actions update L according to a set of rules action(t) = Access( x ): if L(x) != {} and t not in L(x) then report race on x otherwise L(x) = { t } action(t) = Acquire( m ): foreach global, if m is in L(global) then add t to L(global) action(t) = Release( m ): foreach global, if t is in L(global) then add m to L(global) action(t) = Fork( u ): foreach global, if t is in L(global) then add u to L(global) action(t) = Join( u ): foreach global, if u is in L(global) then add t to L(global) action(t) = alloc( o ): L(o) = {}
5
Goldilocks Each variable has a lockset, L. Synchronization actions update L according to a set of rules action(t) = Access( x ): if L(x) != {} and t not in L(x) then report race on x otherwise L(x) = { t } action(t) = Acquire( m ): foreach global, if m is in L(global) then add t to L(global) action(t) = Release( m ): foreach global, if t is in L(global) then add m to L(global) action(t) = Fork( u ): foreach global, if t is in L(global) then add u to L(global) action(t) = Join( u ): foreach global, if u is in L(global) then add t to L(global) action(t) = alloc( o ): L(o) = {} Slow!
6
Lazy Goldilocks Only want to run rules when access occurs and only for the variable being accessed, so store non-access actions in a list for later usage. ForkLock(m1)Lock(m2)X = 2 Fork Lock(m1) Fork Lock(m1) Lock(m2)
7
Lazy Goldilocks Code def action( act ) if act.is_read? or act.is_write? if act.obj.position != nil if act.obj.owner != act.thread act.obj.lockset.clear act.obj.lockset << act.obj.owner apply_rules( act.obj.position, act.obj ) act.apply( act.obj ) end act.obj.position = @@tail act.obj.owner = act.thread else @@tail.thread = act.thread @@tail.action = act @@tail.next = Cell.new @@tail = @@tail.next end How expensive is this?
8
Goldilocks vs Clock Vectors *: if the thread accessing the shared variable owns the lock for that variable
9
Inspect State exploration tool by Yu Yang for real C programs that use pthreads int x; int main(){ pthread_mutex_t m; pthread_mutex_init( &m, NULL ); pthread_mutex_lock( &m ); x += 1; pthread_mutex_unlock( &m ); } Int x; int main(void){ pthread_mutex_t m ; { inspect_main_start(); inspect_obj_reg((void *)(& x)); tmp = & m; inspect_mutex_init(tmp, (pthread_mutexattr_t const *)((void *)0)); inspect_mutex_lock(&m); __cil_tmp7 = read_shared_0(& x) + 1; write_shared_1(& x, __cil_tmp7); inspect_mutex_unlock(&m); __retres5 = 0; inspect_main_end(); return (__retres5); }
10
Contribution Implement the goldilocks algorithm in Inspect Compare performance between goldilocks and clock vectors Analyze results
11
Results Lots of threads and lots of variablesLots of threads and one variable Goldilocks is faster when there are lots of threads and lots of variables.
12
Future work Static analysis can reduce number of dynamic checks that need to be done Apply goldilocks to OpenMP and submit to PADTAD 08 Implemented as a language extension to PLT Scheme
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.