data race detection - purdue university€¦ · c(v) updated, but empty set not reported c(v)...

23
CS390C: Principles of Concurrency and Parallelism Data Race Detection Lecture 11 CS 390 3/20/08

Upload: others

Post on 04-Jul-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Data Race Detection

Lecture 11 CS 390 3/20/08

Page 2: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Data Race● A data race occurs when two concurrently

executing threads access a shared variable and when:− at least one of the accesses is a write− there is no explicit mechanism used to prevent the

accesses from being simultaneous● Meaning of programs with data races depends

upon interleaving of thread executions.− Sometimes this is ok (when?)− Usually, it is not

2

Page 3: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

How can data races be detected and prevented?

● Enforce the use of high-level language mechanisms− monitors, synchronized, etc.− Monitors: (Hoare 1974)

● a group of shared variables along with procedures to access them.

● all accesses protected by the same (anonymous) lock acquired and released upon entry/exit of the monitor

● shared variable not visible outside monitor● lots of issues

− dynamically allocated data, waiting, exceptions, nesting, ...3

Page 4: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Dynamic Approaches

● Happens-before relation− partial order on events of all threads in a concurrent

execution− E.g., basis for Java memory model− Between threads, events are ordered according to the

synchronization objects they access

4

Page 5: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

w h ich t h ese t wo i n t e r act ions a r e exch a nged i n t i m e. F or ex a m p le, F igu r e 1shows on e possible or de r i ng of t wo t h r e a ds execu t i ng t h e sa m e codesegm e n t . T h e t h r ee p rogr a m st a t e m e n ts execu t ed by T h r e a d 1 a r e or de r edby h a p pe ns-befor e beca use t h e y a r e execu t ed seq u e n t i a l l y i n t h e sa m et h r e a d . T h e lock of m u by T h r e a d 2 is or de r ed by h a p pe ns-befor e w i t h t h eu n lock of m u by T h r e a d 1 beca use a lock ca n not be acq u i r ed befor e i tsp r e v ious ow n e r h as r e le ased i t . F i n a l l y , t h e t h r ee st a t e m e n ts execu t ed byT h r e a d 2 a r e or de r ed by h a p pe ns-befor e beca use t h e y a r e execu t ed seq u e n-t i a l l y w i t h i n t h a t t h r e a d .

I f t wo t h r e a ds bot h access a sh a r ed v a r i a ble, a n d t h e accesses a r e notor de r ed by t h e h a p pe ns-befor e r e l a t ion , t h e n i n a not h e r execu t ion of t h ep rogr a m i n w h ich t h e slow e r t h r e a d r a n f ast e r a n d/or t h e f ast e r t h r e a d r a nslow e r , t h e t wo accesses cou l d h a ve h a ppe n ed si m u l t a n eousl y; t h a t is, ad a t a r ace cou l d h a ve occu r r ed , w h e t h e r or not i t act u a l l y d i d occu r . A l lp r e v ious d y n a m ic r ace de t ect ion tools t h a t w e k now of a r e b ased on t h isobse r v a t ion . T h ese r ace de t ectors mon i tor e ve r y d a t a r efe r e nce a n d sy n-ch ron i z a t ion ope r a t ion a n d ch eck for con fl ict i ng accesses to sh a r ed v a r i-a bles t h a t a r e u n r e l a t ed by t h e h a p pe ns-befor e r e l a t ion for t h e p a r t icu l a rexecu t ion t h e y a r e mon i tor i ng.

U n for t u n a t e l y , tools b ased on h a p pe ns-befor e h a ve t wo sign i fica n t d r a w-b ack s. F i rst , t h e y a r e d i ff icu l t to i m p le m e n t eff icie n t l y beca use t h e y r eq u i r epe r-t h r e a d i n for m a t ion a bou t concu r r e n t accesses to e ach sh a r ed-m e mor yloca t ion . M or e i m por t a n t l y , t h e effect i ve n ess of tools b ased on h a p pe ns-befor e is h igh l y depe n de n t on t h e i n t e r le a v i ng p rod uced by t h e sch ed u le r .

F ig. 1. L a m por t ’s h a p pe ns-befor e or de rs e ve n ts i n t h e sa m e t h r e a d i n t e m por a l or de r , a n dor de rs e ve n ts i n d i ffe r e n t t h r e a ds i f t h e t h r e a ds a r e sy nch ron i zed w i t h on e a not h e r be t w ee nt h e e ve n ts.

394 • S t e fa n S a v a g e e t al.

A C M T r a nsact ions on C om p u t e r S yst e ms, V ol . 15, N o. 4, N ove m be r 1997.

CS390C: Principles of Concurrency and Parallelism

Happens-Before

5

Page 6: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Data Race● If two threads access a shared variable, and the

accesses are not ordered under a happens-before relation, then there is a potential data race.

● Dynamic detection of happens-before violations is difficult:− Require per-thread information about concurrent

accesses to shared memory − Highly dependent upon interleaving induced by

scheduler6

Page 7: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

F igu r e 2 shows a si m p le ex a m p le w h e r e t h e h a p pe ns-befor e a pp roach ca nm iss a d a t a r ace. W h i le t h e r e is a pot e n t i a l d a t a r ace on t h e u n p rot ect edaccesses to y , i t w i l l not be de t ect ed i n t h e execu t ion show n i n t h e f igu r e,beca use T h r e a d 1 hol ds t h e lock befor e T h r e a d 2, a n d so t h e accesses to ya r e or de r ed i n t h is i n t e r le a v i ng by h a p pe ns-befor e. A tool b ased on h a p pe ns-befor e wou l d de t ect t h e e r ror on l y i f t h e sch ed u le r p rod uced a n i n t e r le a v i ngi n w h ich t h e f r agm e n t of code for T h r e a d 2 occu r r ed befor e t h e f r agm e n t ofcode for T h r e a d 1. T h us, to be effect i ve, a r ace de t ector b ased on h a p pe ns-befor e n eeds a l a rge n u m be r of t est cases to t est m a n y possible i n t e r le a v-i ngs. I n con t r ast , t h e p rogr a m m i ng e r ror i n F igu r e 2 w i l l be de t ect ed byE r ase r w i t h a n y t est case t h a t exe rcises t h e t wo code p a t hs, beca use t h ep a t hs v iol a t e t h e lock i ng d isci p l i n e for y r ega r d less of t h e i n t e r le a v i ngp rod uced by t h e sch ed u le r . W h i le E r ase r is a t est i ng tool a n d t h e r efor eca n not gu a r a n t ee t h a t a p rogr a m is f r ee f rom r aces, i t ca n de t ect mor er aces t h a n tools b ased on h a p pe ns-befor e.

T h e loc k cove rs t ech n iq u e of D i n n i ng a n d Schon be rg is a n i m p rove m e n tto t h e h a p pe ns-befor e a pp roach for p rogr a ms t h a t m a k e h e a v y use of lock s[ D i n n i ng a n d Schon be rg 1991]. I n deed , on e w a y to descr ibe ou r a pp roachwou l d be t h a t w e ex t e n d D i n n i ng a n d Schon be rg’s i m p rove m e n t a n dd isca r d t h e u n de r l y i ng h a p pe ns-befor e a pp a r a t us t h a t t h e y w e r e i m p rov i ng.

F ig. 2. T h e p rogr a m a l lows a d a t a r ace on y , b u t t h e e r ror is not de t ect ed by h a p pe ns-befor ei n t h is execu t ion i n t e r le a v i ng.

Era s er: A D yn a mic D a t a R a c e D e t e c tor for M ultithre a d Pro gra ms • 395

A C M T r a nsact ions on C om p u t e r S yst e ms, V ol . 15, N o. 4, N ove m be r 1997.

CS390C: Principles of Concurrency and Parallelism

Happens-Before

7

Using happens-before,need a large number oftest cases to catch the error.

Can we do better?

Page 8: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Lockset Algorithm● To avoid data races, every shared variable must

be protected by some lock.● A dynamic tool must infer what these locks are● For each shared variable v, maintain the set C(v)

of candidate locks for v.− This set contains those locks that have protected v for

the computation so far.− Initially, the set holds all possible locks.− When v is accessed, compute the interesection of

C(v) with the current set of locks held by the thread− If the set is empty, there is no lock that consistently

protects v 8

Page 9: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

—R e a d-S h a r e d D a t a : Som e sh a r ed v a r i a bles a r e w r i t t e n d u r i ng i n i t i a l i z a-t ion on l y a n d a r e r e a d-on l y t h e r e a f t e r . T h ese ca n be sa fe l y accessedw i t hou t lock s.

—R e a d-W r i te L oc ks: R e a d-w r i t e lock s a l low m u l t i p le r e a de rs to access ash a r ed v a r i a ble, b u t a l low on l y a si ngle w r i t e r to do so.

I n t h e r e m a i n de r of t h is sect ion w e w i l l ex t e n d t h e L ock se t a lgor i t h m toaccom mod a t e i n i t i a l i z a t ion a n d r e a d-sh a r ed d a t a , a n d t h e n ex t e n d i t f u r-t h e r to accom mod a t e r e a d-w r i t e lock s.

2 .2 Initializ a tion a n d R e a d - S h aring

T h e r e is no n eed for a t h r e a d to lock ou t ot h e rs i f no ot h e r t h r e a d ca npossibl y hol d a r efe r e nce to t h e d a t a be i ng accessed . P rogr a m m e rs of t e nt a k e a d v a n t age of t h is obse r v a t ion w h e n i n i t i a l i z i ng n e w l y a l loca t ed d a t a .T o a voi d f a lse a l a r ms ca used by t h ese u n lock ed i n i t i a l i z a t ion w r i t es, w ede l a y t h e r ef i n e m e n t of a loca t ion ’s ca n d i d a t e se t u n t i l a f t e r i t h as bee ni n i t i a l i zed . U n for t u n a t e l y , w e h a ve no e asy w a y of k now i ng w h e n i n i t i a l i z a-t ion is com p le t e. E r ase r t h e r efor e consi de rs a sh a r ed v a r i a ble to be i n i t i a l-i zed w h e n i t is fi rst accessed by a secon d t h r e a d . A s long as a v a r i a ble h asbee n accessed by a si ngle t h r e a d on l y , r e a ds a n d w r i t es h a ve no effect ont h e ca n d i d a t e se t .

S i nce si m u l t a n eous r e a ds of a sh a r ed v a r i a ble by m u l t i p le t h r e a ds a r enot r aces, t h e r e is a lso no n eed to p rot ect a v a r i a ble i f i t is r e a d-on l y . T osu ppor t u n lock ed r e a d-sh a r i ng for such d a t a , w e r epor t r aces on l y a f t e r a ni n i t i a l i zed v a r i a ble h as becom e w r i t e-sh a r ed by mor e t h a n on e t h r e a d .

F igu r e 4 i l l ust r a t es t h e st a t e t r a nsi t ions t h a t con t rol w h e n lock se tr ef i n e m e n t occu rs a n d w h e n r aces a r e r epor t ed . W h e n a v a r i a ble is fi rsta l loca t ed , i t is se t to t h e V i r g i n st a t e, i n d ica t i ng t h a t t h e d a t a a r e n e w a n dh a ve not ye t bee n r efe r e nced by a n y t h r e a d . O nce t h e d a t a a r e accessed , i t

F ig. 3. I f a sh a r ed v a r i a ble is som e t i m es p rot ect ed by m u1 a n d som e t i m es by lock m u2, t h e nno lock p rot ects i t for t h e w hole com p u t a t ion . T h e f igu r e shows t h e p rogr essi ve r ef i n e m e n t oft h e se t of ca n d i d a t e lock s C ( v ) for v . W h e n C ( v ) becom es e m p t y , t h e L ock se t a lgor i t h m h asde t ect ed t h a t no lock p rot ects v .

Era s er: A D yn a mic D a t a R a c e D e t e c tor for M ultithre a d Pro gra ms • 397

A C M T r a nsact ions on C om p u t e r S yst e ms, V ol . 15, N o. 4, N ove m be r 1997.

CS390C: Principles of Concurrency and Parallelism

Example

9

Page 10: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Improvements

● Common programming practices often violate locking discipline, but are still race free:− Initialization− Reading shared data− Read-write locks:

● multiple readers, single (exclusive) writer

10

Page 11: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Initialization● How can we tell when initialization is complete?

− Assume initialization is complete if a variable is accessed by a second thread.

− As long as a variable is only accessed by a single thread, reads and writes have no effect on the candidate lock set.

− Similar conditions hold for read-only data

11

Page 12: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

e n t e rs t h e E xc l usi ve st a t e, sign i fy i ng t h a t i t h as bee n accessed , b u t by on et h r e a d on l y . I n t h is st a t e, su bseq u e n t r e a ds a n d w r i t es by t h e sa m e t h r e a ddo not ch a nge t h e v a r i a ble’s st a t e a n d do not u pd a t e C ( v ) . T h is a dd r essest h e i n i t i a l i z a t ion issu e, si nce t h e f i rst t h r e a d ca n i n i t i a l i ze t h e v a r i a blew i t hou t ca usi ng C ( v ) to be r ef i n ed . W h e n a n d i f a not h e r t h r e a d accessest h e v a r i a ble, t h e n t h e st a t e ch a nges. A r e a d access ch a nges t h e st a t e toS h a r e d . I n t h e S h a r e d st a t e, C ( v ) is u pd a t ed , b u t d a t a r aces a r e notr epor t ed , e ve n i f C ( v ) becom es e m p t y . T h is t a k es ca r e of t h e r e a d-sh a r edd a t a issu e, si nce m u l t i p le t h r e a ds ca n r e a d a v a r i a ble w i t hou t ca usi ng ar ace to be r epor t ed . A w r i t e access f rom a n e w t h r e a d ch a nges t h e st a t ef rom E xc l usi ve or S h a r e d to t h e S h a r e d- M od i f i e d st a t e, i n w h ich C ( v ) isu pd a t ed a n d r aces a r e r epor t ed , j ust as descr ibed i n t h e or igi n a l , si m p leve rsion of t h e a lgor i t h m .

O u r su ppor t for i n i t i a l i z a t ion m a k es E r ase r ’s ch eck i ng mor e depe n de n ton t h e sch ed u le r t h a n w e wou l d l i k e. S u ppose t h a t a t h r e a d a l loca t es a n di n i t i a l i zes a sh a r ed v a r i a ble w i t hou t a lock a n d e r ron eousl y m a k es t h ev a r i a ble accessible to a secon d t h r e a d befor e i t h as com p le t ed t h e i n i t i a l i z a-t ion . T h e n E r ase r w i l l de t ect t h e e r ror i f a n y of t h e secon d t h r e a d’s accessesoccu r befor e t h e f i rst t h r e a d’s fi n a l i n i t i a l i z a t ion act ions, b u t ot h e r w iseE r ase r w i l l m iss t h e e r ror . W e do not t h i n k t h is h as bee n a p roble m , b u t w eh a ve no w a y of k now i ng for su r e.

2 .3 R e a d - Writ e Lo c ks

M a n y p rogr a ms use si ngle-w r i t e r , m u l t i p le-r e a de r lock s as w e l l as si m p lelock s. T o accom mod a t e t h is st y le w e i n t rod uce ou r l ast r ef i n e m e n t of t h elock i ng d isci p l i n e: w e r eq u i r e t h a t for e ach v a r i a ble v , som e lock m p rotectsv , m e a n i ng m is h e l d i n w r i t e mode for e ve r y w r i t e of v , a n d m is h e l d i nsom e mode (r e a d or w r i t e) for e ve r y r e a d of v .

F ig. 4. E r ase r k eeps t h e st a t e of a l l loca t ions i n m e mor y . N e w l y a l loca t ed loca t ions begi n i nt h e V i r g i n st a t e. A s v a r ious t h r e a ds r e a d a n d w r i t e a loca t ion , i ts st a t e ch a nges accor d i ng tot h e t r a nsi t ion i n t h e f igu r e. R ace con d i t ions a r e r epor t ed on l y for loca t ions i n t h e S h a r e d-M od i f i e d st a t e.

398 • S t e fa n S a v a g e e t al.

A C M T r a nsact ions on C om p u t e r S yst e ms, V ol . 15, N o. 4, N ove m be r 1997.

CS390C: Principles of Concurrency and Parallelism

State Transition Diagram

12

initial allocation

initialized

C(v) updated, butempty set not reported

C(v) updated, and races reported when it becomes empty

Page 13: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

W e con t i n u e to use t h e st a t e t r a nsi t ions of F igu r e 4, b u t w h e n t h ev a r i a ble e n t e rs t h e S h a r e d- M od i f i e d st a t e, t h e ch eck i ng is sl igh t l y d i ffe r-e n t:

L e t loc ks h e l d( t ) be t h e se t of lock s h e l d i n a n y mode by t h r e a d t .L e t w r i te loc ks h e l d( t ) be t h e se t of lock s h e l d i n w r i t e mode by t h r e a d t .F or e ach v , i n i t i a l i ze C ( v ) to t h e se t of a l l lock s.O n e ach r e a d of v by t h r e a d t ,

se t C ( v ) : C ( v ) loc ks h e l d( t ) ;i f C ( v ) : { }, t h e n issu e a w a r n i ng.

O n e ach w r i t e of v by t h r e a d t ,se t C ( v ) : C ( v ) w r i te loc ks h e l d( t ) ;i f C ( v ) { }, t h e n issu e a w a r n i ng.

T h a t is, lock s h e l d p u r e l y i n r e a d mode a r e r e moved f rom t h e ca n d i d a t ese t w h e n a w r i t e occu rs, as such lock s h e l d by a w r i t e r do not p rot ectaga i nst a d a t a r ace be t w ee n t h e w r i t e r a n d som e ot h e r r e a de r t h r e a d .

3 . IM P L E M E N TIN G E R A S E R

E r ase r is i m p le m e n t ed for t h e D igi t a l U n i x ope r a t i ng syst e m on t h e A l p h ap rocessor , usi ng t h e A T O M [S r i v ast a v a a n d E ust ace 1994] bi n a r y mod i fica-t ion syst e m . E r ase r t a k es a n u n mod i fied p rogr a m bi n a r y as i n p u t a n d a ddsi nst r u m e n t a t ion to p rod uce a n e w bi n a r y t h a t is f u nct ion a l l y i de n t ica l , b u ti ncl u des ca l ls to t h e E r ase r r u n t i m e to i m p le m e n t t h e L ock se t a lgor i t h m .

T o m a i n t a i n C ( v ) , E r ase r i nst r u m e n ts e ach loa d a n d stor e i n t h e p ro-gr a m . T o m a i n t a i n loc k h e l d( t ) for e ach t h r e a d t , E r ase r i nst r u m e n ts e achca l l to acq u i r e or r e le ase a lock , as w e l l as t h e st u bs t h a t m a n age t h r e a di n i t i a l i z a t ion a n d fi n a l i z a t ion . T o i n i t i a l i ze C ( v ) for d y n a m ica l l y a l loca t edd a t a , E r ase r i nst r u m e n ts e ach ca l l to t h e stor age a l loca tor .

E r ase r t r e a ts e ach 32-bi t wor d i n t h e h e a p or glob a l d a t a as a possiblesh a r ed v a r i a ble, si nce on ou r p l a t for m a 32-bi t wor d is t h e sm a l lestm e mor y-coh e r e n t u n i t . E r ase r does not i nst r u m e n t loa ds a n d stor es w hosea dd r ess mode is i n d i r ect off t h e st ack poi n t e r , si nce t h ese a r e assu m ed to best ack r efe r e nces, a n d sh a r ed v a r i a bles a r e assu m ed to be i n glob a l loca t ionsor i n t h e h e a p . E r ase r w i l l m a i n t a i n ca n d i d a t e se ts for st ack loca t ions t h a ta r e accessed v i a r egist e rs ot h e r t h a n t h e st ack poi n t e r , b u t t h is is a na r t i f act of t h e i m p le m e n t a t ion r a t h e r t h a n a de l ibe r a t e p l a n to su ppor tp rogr a ms t h a t sh a r e st ack loca t ions be t w ee n t h r e a ds.

W h e n a r ace is r epor t ed , E r ase r i n d ica t es t h e f i le a n d l i n e n u m be r a tw h ich i t w as d iscove r ed a n d a b ack t r ace l ist i ng of a l l act i ve st ack f r a m es.T h e r epor t a lso i ncl u des t h e t h r e a d I D , m e mor y a dd r ess, t y pe of m e mor yaccess, a n d i m por t a n t r egist e r v a l u es such as t h e p rogr a m cou n t e r a n dst ack poi n t e r . W h e n used i n con j u nct ion w i t h t h e p rogr a m ’s sou rce code, w eh a ve fou n d t h a t t h is i n for m a t ion is usu a l l y su fficie n t to loca t e t h e or igi n oft h e r ace. I f t h e ca use of a r ace is st i l l u ncle a r , t h e use r ca n d i r ect E r ase r tolog a l l t h e accesses to a p a r t icu l a r v a r i a ble t h a t r esu l t i n a ch a nge to i tsca n d i d a t e lock se t .

Era s er: A D yn a mic D a t a R a c e D e t e c tor for M ultithre a d Pro gra ms • 399

A C M T r a nsact ions on C om p u t e r S yst e ms, V ol . 15, N o. 4, N ove m be r 1997.

CS390C: Principles of Concurrency and Parallelism

Read-Write Locks● For each variable v, some lock m protects v

− m is held in write mode for every write of v− m is held in some mode (read or write) for every read of v

− Locks held in read mode are removed from the candidate set when a write occurs

● such locks held by a writer do not protect against a data race between the writer and some other reader thread

13

=

==

Page 14: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Implementation● Binary instrumentation

− Each load and store● Except loads/stores indirect off the stack

− Each lock/unlock− Storage allocator

● Lockset representation− Each set of locks represented as index into a table of

lock addresses● Use a shadow memory to hold lockset index

14

Page 15: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

oppor t u n i t ies for usi ng st a t ic a n a l ysis to r ed uce t h e ove r h e a d of t h emon i tor i ng code; b u t w e h a ve not ex p lor ed t h e m .

I n sp i t e of ou r l i m i t ed pe r for m a nce t u n i ng, w e h a ve fou n d t h a t E r ase r isf ast e nough to deb ug most p rogr a ms a n d t h e r efor e m ee ts t h e most esse n t i a lpe r for m a nce cr i t e r ion .

3 .3 Pro gra m A nnot a tions

A s ex pect ed , ou r ex pe r ie nce w i t h E r ase r show ed t h a t i t ca n p rod uce f a lsea l a r ms. P a r t of ou r r ese a rch w as a i m ed a t fi n d i ng effect i ve a n not a t ions tosu pp r ess f a lse a l a r ms w i t hou t acci de n t a l l y losi ng usef u l w a r n i ngs. T h is is ak e y to m a k i ng a tool l i k e E r ase r usef u l . I f t h e f a lse a l a r ms a r e su pp r essedw i t h accu r a t e a n d speci f ic a n not a t ions, t h e n w h e n a p rogr a m is mod i fied ,a n d t h e mod i fied p rogr a m is t est ed , on l y f r esh a n d r e le v a n t w a r n i ngs w i l lbe p rod uced .

I n ou r ex pe r ie nce f a lse a l a r ms fe l l m a i n l y i n to t h r ee b roa d ca t egor ies:

— M e mor y R e use: F a lse a l a r ms w e r e r epor t ed beca use m e mor y is r e usedw i t hou t r ese t t i ng t h e sh a dow m e mor y . E r ase r i nst r u m e n ts a l l of t h est a n d a r d C , C , a n d U n i x m e mor y a l loca t ion rou t i n es. H ow e ve r , m a n yp rogr a ms i m p le m e n t f r ee l ists or p r i v a t e a l loca tors, a n d E r ase r h as now a y of k now i ng t h a t a p r i v a t e l y r ecycled p iece of m e mor y is p rot ect ed bya n e w se t of lock s.

F ig. 5. E r ase r associ a t es a lock se t i n dex w i t h e ach v a r i a ble by a dd i ng t h e v a r i a ble’s a dd r essto a fi xed sh a dow m e mor y offse t . T h e i n dex , i n t u r n , se lects a lock vector f rom t h e lock se ti n dex t a ble. I n t h is case, t h e sh a r ed v a r i a ble v is associ a t ed w i t h a se t of lock s con t a i n i ng m u1a n d m u2.

Era s er: A D yn a mic D a t a R a c e D e t e c tor for M ultithre a d Pro gra ms • 401

A C M T r a nsact ions on C om p u t e r S yst e ms, V ol . 15, N o. 4, N ove m be r 1997.

CS390C: Principles of Concurrency and Parallelism

Implementation

15

Page 16: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

Atomizer: A Dynamic Atomicity CheckerFor Multithreaded Programs

Cormac Flanagan Stephen N. FreundDepartment of Computer Science Department of Computer Science

University of California at Santa Cruz Williams CollegeSanta Cruz, CA 95064 Williamstown, MA 01267

Abstract

Ensuring the correctness of multithreaded programs is difficult,due to the potential for unexpected interactions between concurrentthreads. Much previous work has focused on detecting race condi-tions, but the absence of race conditions does not by itself preventundesired thread interactions. We focus on the more fundamentalnon-interference property of atomicity; a method is atomic if its ex-ecution is not affected by and does not interfere with concurrently-executing threads. Atomic methods can be understood accordingto their sequential semantics, which significantly simplifies (formaland informal) correctness arguments.

This paper presents a dynamic analysis for detecting atomicity vi-olations. This analysis combines ideas from both Lipton’s theoryof reduction and earlier dynamic race detectors. Experience witha prototype checker for multithreaded Java code demonstrates thatthis approach is effective for detecting errors due to unintended in-teractions between threads. In particular, our atomicity checker de-tects errors that would be missed by standard race detectors, andit produces fewer false alarms on benign races that do not causeatomicity violations. Our experimental results also indicate thatthe majority of methods in our benchmarks are atomic, supportingour hypothesis that atomicity is a standard methodology in multi-threaded programming.

Categories and Subject Descriptors: D.2.4 [Software Engineer-ing]: Software/Program Verification–reliability; D.2.5 [SoftwareEngineering]: Testing and Debugging–monitors, testing tools; F.3.1[Logics and Meanings of Programs]: Specifying and Verifying andReasoning about Programs.

General Terms: Languages, Algorithms, Verification.

Keywords: Atomicity, dynamic analysis, reduction.

Permission to make digital or hard copies of all or part of this work for personal orclassroom use is granted without fee provided that copies are not made or distributedfor profit or commercial advantage and that copies bear this notice and the full citationon the first page. To copy otherwise, to republish, to post on servers or to redistributeto lists, requires prior specific permission and/or a fee.POPL’04, January 14–16, 2004, Venice, Italy.Copyright 2004 ACM 1-58113-729-X/04/0001 ...$5.00

1 Reliable Threads

Multiple threads of control are widely used in software develop-ment because they help reduce latency, increase throughput, andprovide better utilization of multiprocessor machines. However,reasoning about the behavior and correctness of multithreaded codeis difficult, due to the need to consider all possible interleavings ofthe executions of the various threads. Thus, methods for specifyingand controlling the interference between threads are crucial to thecost-effective development of reliable multithreaded software.

Much previous work on controlling thread interference has focusedon race conditions. A race condition occurs when two threads si-multaneously access the same data variable, and at least one of theaccesses is a write [47]. In practice, race conditions are commonlyavoided by protecting each data structure with a lock [6]. This lock-based synchronization discipline is supported by a variety of typesystems [21, 20, 19, 22, 8, 7, 28] and other static [49, 23, 10, 13]and dynamic [47, 11, 51, 42, 45] analyses.

Unfortunately, the absence of race conditions is not sufficient toensure the absence of errors due to unexpected interference betweenthreads. As a concrete illustration of this limitation, consider thefollowing excerpt from the class java.lang.StringBuffer. Allfields of a StringBuffer object are protected by the implicit lockassociated with the object, and all StringBuffer methods shouldbe safe for concurrent use by multiple threads.

Excerpt from java.lang.StringBuffer

public final class StringBuffer {

public synchronizedStringBuffer append(StringBuffer sb) {

int len = sb.length();... // other threads may change sb.length(),... // so len does not reflect the length of sbsb.getChars(0, len, value, count);...

}

public synchronized int length() { ... }public synchronized void getChars(...) { ... }...

}

The append method shown above first calls sb.length(), whichacquires the lock sb, retrieves the length of sb, and releases thelock. The length of sb is stored in the variable len. At this point,a second thread could remove characters from sb. In this situation,

256

CS390C: Principles of Concurrency and Parallelism

Is Race Detection Enough?

16

Page 17: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Atomicity● A method (or code block) is atomic if for every

interleaved execution, there is an equivalent execution with the same overall behavior where the code block is executed serially, without any interleaving.

● Atomicity provides a strong (maximal) guarantee of non-interference between threads.

● How can we check atomicity violations?

17

Page 18: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

ment. (The restriction ¬A(!) avoids consideration of partially-executed atomic blocks.)

3 Dynamic Atomicity Checking

In this section, we present an instrumented semantics that dynam-ically detects violations of the above atomicity requirement. Westart by reviewing Lipton’s theory of reduction [38], which formsthe basis of our approach.

3.1 Reduction

The theory of reduction is based on the notion of right-mover andleft-mover actions. An action b is a right-mover if, for any executionwhere the action b performed by one thread is immediately followedby an action c of a concurrent thread, the actions b and c can beswapped without changing the resulting state, as shown below:

Commuting actions

"0 "2c b

"!1

"1"0 "2b c

For example, if the operation b is a lock acquire, then the action cof the second thread neither acquires nor releases the lock, and socannot affect the state of that lock. Hence the acquire operation canbe moved to the right of c without changing the resulting state, andwe classify each lock acquire operation as a right-mover.

Conversely, an action c is a left-mover if whenever c immediatelyfollows an action b of a different thread, the actions b and c can beswapped, again without changing the resulting state. Suppose theoperation c by the second thread is a lock release. During b, thesecond thread holds the lock, and b can neither acquire nor releasethe lock. Hence the lock release operation can be moved to the leftof b without changing the resulting state, and we classify each lockrelease operation as a left-mover.

Next, consider an access (read or write) to a variable that is sharedby multiple threads. If the variable is protected by some lock that isheld whenever the variable is accessed, then two threads can neveraccess the variable at the same time, and we classify each access tothat variable as a both-mover, which means that it is both a right-mover and a left-mover. If the variable is not consistently protectedby some lock, we classify the variable access as a non-mover.

To illustrate how the classification of actions as various kinds ofmovers enables us to verify atomicity, consider the first executiontrace in the diagram below. In this trace, a thread (1) acquires alockm, (2) reads a variable x protected by that lock, (3) updates x,and then (4) releases m. The execution path of this thread is inter-leaved with arbitrary actions b1, b2, b3 of other threads. Becausethe acquire operation is a right-mover and the write and release op-erations are left-movers, there exists an equivalent serial executionin which the operations of this path are not interleaved with opera-tions of other threads, as illustrated by the following diagram. Thusthe execution path is atomic.

Reduced execution sequence

!!1 !!

2 !!3 !!

4 !!5 !!

6

acq(m) wr(x,1)rd(x,0) rel(m)!7

!2 !3 !4 !5 !6 !7!1!0

!0

b3

b3b2

b1

b1

b2 wr(x,1)acq(m) rd(x,0) rel(m)

More generally, suppose a path through a code block contains asequence of right-movers, followed by at most one non-mover ac-tion and then a sequence of left-movers. Then this path can bereduced to an equivalent serial execution, with the same resultingstate, where the path is executed without any interleaved actions byother threads.

3.2 Checking atomicity via reduction

We next leverage the theory of reduction to verify atomicity dy-namically. In an initial presentation of our approach, we assumethe programmer provides a partial function

P : Var !"# Lock

that maps protected shared variables to associated locks; if P (x) isundefined, then x is not protected by any lock.

We develop an instrumented semantics that only admits code pathsthat are reducible, and which goes wrong on irreducible paths. Torecord whether each thread is in the right-mover or left-mover partof an atomic block, we extend the state space with an instrumenta-tion store:

! : Tid " {InRight, InLeft}

Each state is now a triple (", !,!). If A(!(t)) $= 0, then threadt is inside an atomic block, and !(t) indicates whether the threadis in the right-mover or left-mover part of that atomic block. Theinitial instrumentation store !0 is given by !0(t) = InRight for allt % Tid .

The following relation " &at !! updates the instrumentation store

whenever thread t performs operation a. The rule [INS ACCESSPROT] deals with an access to a protected variable while holding theappropriate lock. This action is a both-mover and so the instrumen-tation store ! does not change. Accesses to unprotected variablesare non-movers, and they can occur outside atomic blocks: see [INSACCESS OUTSIDE]. Unprotected accesses are also allowed insidean atomic block, and they cause a transition from the right-moverto the left-mover part of the atomic block: see [INS ACCESS COM-MIT]. Acquire operations are right-movers, and they can occur out-side or in the right-mover part of an atomic block, and converselyfor release operations.

The relation " &at wrong holds if the operation a by thread t

would go wrong by accessing a protected variable without hold-ing the correct lock [WRONG RACE], or by performing a non-left-mover action in the left-mover part of an atomic block. Non-left-mover actions include accessing an unprotected variable [WRONGUNPROTECT] or acquiring a lock [WRONG ACQUIRE].

259

CS390C: Principles of Concurrency and Parallelism

Lipton Theory of Reduction

18

If b is a lock acquire, then c neither acquires or releases the lock. Hence b can be moved to the right of c. (b is a right mover)

If c is a lock release, then b can neither acquire or release the lock. Hence c can be moved to the left of c. (c is a left mover)

Suppose we have a read (or write) of a variable that is shared by multiple threads. If the variable is protected by a lock, then only one thread can access the variable at a time. Such accesses are both movers.

If a variable is not consistently protected by the same lock, then the variable access is a non-mover.

Page 19: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

ment. (The restriction ¬A(!) avoids consideration of partially-executed atomic blocks.)

3 Dynamic Atomicity Checking

In this section, we present an instrumented semantics that dynam-ically detects violations of the above atomicity requirement. Westart by reviewing Lipton’s theory of reduction [38], which formsthe basis of our approach.

3.1 Reduction

The theory of reduction is based on the notion of right-mover andleft-mover actions. An action b is a right-mover if, for any executionwhere the action b performed by one thread is immediately followedby an action c of a concurrent thread, the actions b and c can beswapped without changing the resulting state, as shown below:

Commuting actions

"0 "2c b

"!1

"1"0 "2b c

For example, if the operation b is a lock acquire, then the action cof the second thread neither acquires nor releases the lock, and socannot affect the state of that lock. Hence the acquire operation canbe moved to the right of c without changing the resulting state, andwe classify each lock acquire operation as a right-mover.

Conversely, an action c is a left-mover if whenever c immediatelyfollows an action b of a different thread, the actions b and c can beswapped, again without changing the resulting state. Suppose theoperation c by the second thread is a lock release. During b, thesecond thread holds the lock, and b can neither acquire nor releasethe lock. Hence the lock release operation can be moved to the leftof b without changing the resulting state, and we classify each lockrelease operation as a left-mover.

Next, consider an access (read or write) to a variable that is sharedby multiple threads. If the variable is protected by some lock that isheld whenever the variable is accessed, then two threads can neveraccess the variable at the same time, and we classify each access tothat variable as a both-mover, which means that it is both a right-mover and a left-mover. If the variable is not consistently protectedby some lock, we classify the variable access as a non-mover.

To illustrate how the classification of actions as various kinds ofmovers enables us to verify atomicity, consider the first executiontrace in the diagram below. In this trace, a thread (1) acquires alockm, (2) reads a variable x protected by that lock, (3) updates x,and then (4) releases m. The execution path of this thread is inter-leaved with arbitrary actions b1, b2, b3 of other threads. Becausethe acquire operation is a right-mover and the write and release op-erations are left-movers, there exists an equivalent serial executionin which the operations of this path are not interleaved with opera-tions of other threads, as illustrated by the following diagram. Thusthe execution path is atomic.

Reduced execution sequence

!!1 !!

2 !!3 !!

4 !!5 !!

6

acq(m) wr(x,1)rd(x,0) rel(m)!7

!2 !3 !4 !5 !6 !7!1!0

!0

b3

b3b2

b1

b1

b2 wr(x,1)acq(m) rd(x,0) rel(m)

More generally, suppose a path through a code block contains asequence of right-movers, followed by at most one non-mover ac-tion and then a sequence of left-movers. Then this path can bereduced to an equivalent serial execution, with the same resultingstate, where the path is executed without any interleaved actions byother threads.

3.2 Checking atomicity via reduction

We next leverage the theory of reduction to verify atomicity dy-namically. In an initial presentation of our approach, we assumethe programmer provides a partial function

P : Var !"# Lock

that maps protected shared variables to associated locks; if P (x) isundefined, then x is not protected by any lock.

We develop an instrumented semantics that only admits code pathsthat are reducible, and which goes wrong on irreducible paths. Torecord whether each thread is in the right-mover or left-mover partof an atomic block, we extend the state space with an instrumenta-tion store:

! : Tid " {InRight, InLeft}

Each state is now a triple (", !,!). If A(!(t)) $= 0, then threadt is inside an atomic block, and !(t) indicates whether the threadis in the right-mover or left-mover part of that atomic block. Theinitial instrumentation store !0 is given by !0(t) = InRight for allt % Tid .

The following relation " &at !! updates the instrumentation store

whenever thread t performs operation a. The rule [INS ACCESSPROT] deals with an access to a protected variable while holding theappropriate lock. This action is a both-mover and so the instrumen-tation store ! does not change. Accesses to unprotected variablesare non-movers, and they can occur outside atomic blocks: see [INSACCESS OUTSIDE]. Unprotected accesses are also allowed insidean atomic block, and they cause a transition from the right-moverto the left-mover part of the atomic block: see [INS ACCESS COM-MIT]. Acquire operations are right-movers, and they can occur out-side or in the right-mover part of an atomic block, and converselyfor release operations.

The relation " &at wrong holds if the operation a by thread t

would go wrong by accessing a protected variable without hold-ing the correct lock [WRONG RACE], or by performing a non-left-mover action in the left-mover part of an atomic block. Non-left-mover actions include accessing an unprotected variable [WRONGUNPROTECT] or acquiring a lock [WRONG ACQUIRE].

259

CS390C: Principles of Concurrency and Parallelism

Example

19

acquire operation by thread 1 is a right mover.read and write operations are left moversrelease is a left mover

In general: a path through a code block that contains a series of right movers, followed by at most one non-mover action, followed by a sequence of left movers is reducible to a serial execution

Page 20: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

2 Multithreaded Programs

To provide a formal basis for reasoning about interference betweenthreads, we start by formalizing an execution semantics for multi-threaded programs. In this semantics, a multithreaded program con-sists of a number of concurrently executing threads, each of whichhas an associated thread identifier t ! Tid . The threads communi-cate through a global store !, which is shared by all threads. Theglobal store maps program variables x to values v. The global storealso records the state of each lock variablem ! Lock . If !(m) = t,then the lock m is held by thread t; if !(m) = ", then that lock isnot held by any thread.

In addition to operating on the shared global store, each thread alsohas its own local store " containing data not manipulated by otherthreads, such as the program counter of that thread. A state ! =(!, ") of the multithreaded system consists of a global store ! anda mapping" from thread identifiers t to the local store"(t) of eachthread. Program execution starts in an initial state !0 = (!0, "0).

Domains

u, t ! Tidx ! Varv ! Value

m ! Lock! ! GlobalStore = (Var " Value) # (Lock " (Tid # {$}))" ! LocalStore! ! LocalStores = Tid " LocalStore" ! State = GlobalStore % LocalStores

2.1 Standard semantics

We model the behavior of each thread in a multithreaded programas the transition relation T :

T # Tid $ LocalStore $ Operation $ LocalStore

The relation T (t,", a, "!) holds if the thread t can take a step froma state with local store ", performing the operation a ! Operationon the global store, yielding a new local store "!. The set of possibleoperations on the global store includes: rd(x, v), which reads avalue v from a variable x; wr(x, v), which writes a value v to avariable x; acq(m) and rel(m), which acquire and release a lockm, respectively; begin and end, which mark the beginning and endof an atomic block; and #, the empty operation.

a ! Operation ::= rd(x, v) | wr(x, v)| acq(m) | rel(m)| begin | end | #

The following relation ! %at !! models the effect of an operation

a by thread t on the global store !. The global store ![x := v] isidentical to ! except that it maps the variable x to the value v.

Effect of operations: ! %at !!

[ACT READ]!(x) = v

! "rd(x,v)t !

[ACT WRITE]

! "wr(x,v)t ![x := v]

[ACT OTHER]a ! {begin, end, #}

! "at !

[ACT ACQUIRE]!(m) = $

! "acq(m)t ![m := t]

[ACT RELEASE]!(m) = t

! "rel(m)t ![m := $]

The following transition relation ! % !! performs a single stepof an arbitrarily chosen thread. We use%" to denote the reflexive-transitive closure of %. A transition sequence !0 %" ! modelsthe arbitrary interleaving of the various threads of a multithreadedprogram, starting from the initial state !0. Although dynamicthread creation is not explicitly supported by the semantics, it canbe modeled within the semantics in a straightforward way.

Standard semantics: ! % !!

[STD STEP]T (t, !(t), a, "!) ! "a

t !!

(!, !) " (!!, ![t := "!])

2.2 Serialized semantics

We assume the functionA : LocalStore % Nat indicates the num-ber of atomic blocks that are currently active, perhaps by exam-ining the program counter and thread stack recorded in the localstore. This count should be zero in the initial state, and should onlychange when entering or leaving an atomic block. We formalizethese requirements as follows:

• A("0(t)) = 0 for all t ! Tid ;

• if T (t, ", begin,"!) then A("!) = A(") + 1;

• if T (t, ", end, "!), then A(") > 0 and A("!) = A(") & 1;

• if T (t, ", a, "!) for a '! {begin, end}, then A(") = A("!).

The relation A(") holds if any thread is inside an atomic block:

A(")def= (t ! Tid . A("(t)) '= 0

The following serialized transition relation )% is similar to the stan-dard relation %, except that a thread cannot perform a step if an-other thread is inside an atomic block. Thus, the serialized relation)% does not interleave the execution of an atomic block with in-structions of concurrent threads.

Serialized semantics: ! )% !!

[SERIAL STEP]T (t, !(t), a, "!) ! "a

t !! &u '= t. A(!(u)) = 0(!, !) (" (!!, ![t := "!])

Reasoning about program behavior and correctness is much easierunder the serialized semantics ()%) than under the standard seman-tics (%), since each atomic block can be understood sequentially,without the need to consider all possible interleaved actions of con-current threads. However, standard language implementations onlyprovide the standard semantics (%), which admits additional transi-tion sequences and behaviors. In particular, a program that behavescorrectly according to the serialized semantics may still behave er-roneously under the standard semantics. Thus, in addition to beingcorrect with respect to the serialized semantics, the program shouldalso use sufficient synchronization to ensure the atomicity of eachblock of code that is intended to be atomic. Thus, for any programexecution (!0, "0) %" (!, ")where¬A("), there should exist anequivalent serialized execution (!0, "0) )%" (!, "). We call thisthe atomicity requirement on program executions, and any execu-tion of a correctly synchronized program should satisfy this require-

258

2 Multithreaded Programs

To provide a formal basis for reasoning about interference betweenthreads, we start by formalizing an execution semantics for multi-threaded programs. In this semantics, a multithreaded program con-sists of a number of concurrently executing threads, each of whichhas an associated thread identifier t ! Tid . The threads communi-cate through a global store !, which is shared by all threads. Theglobal store maps program variables x to values v. The global storealso records the state of each lock variablem ! Lock . If !(m) = t,then the lock m is held by thread t; if !(m) = ", then that lock isnot held by any thread.

In addition to operating on the shared global store, each thread alsohas its own local store " containing data not manipulated by otherthreads, such as the program counter of that thread. A state ! =(!, ") of the multithreaded system consists of a global store ! anda mapping" from thread identifiers t to the local store"(t) of eachthread. Program execution starts in an initial state !0 = (!0, "0).

Domains

u, t ! Tidx ! Varv ! Value

m ! Lock! ! GlobalStore = (Var " Value) # (Lock " (Tid # {$}))" ! LocalStore! ! LocalStores = Tid " LocalStore" ! State = GlobalStore % LocalStores

2.1 Standard semantics

We model the behavior of each thread in a multithreaded programas the transition relation T :

T # Tid $ LocalStore $ Operation $ LocalStore

The relation T (t,", a, "!) holds if the thread t can take a step froma state with local store ", performing the operation a ! Operationon the global store, yielding a new local store "!. The set of possibleoperations on the global store includes: rd(x, v), which reads avalue v from a variable x; wr(x, v), which writes a value v to avariable x; acq(m) and rel(m), which acquire and release a lockm, respectively; begin and end, which mark the beginning and endof an atomic block; and #, the empty operation.

a ! Operation ::= rd(x, v) | wr(x, v)| acq(m) | rel(m)| begin | end | #

The following relation ! %at !! models the effect of an operation

a by thread t on the global store !. The global store ![x := v] isidentical to ! except that it maps the variable x to the value v.

Effect of operations: ! %at !!

[ACT READ]!(x) = v

! "rd(x,v)t !

[ACT WRITE]

! "wr(x,v)t ![x := v]

[ACT OTHER]a ! {begin, end, #}

! "at !

[ACT ACQUIRE]!(m) = $

! "acq(m)t ![m := t]

[ACT RELEASE]!(m) = t

! "rel(m)t ![m := $]

The following transition relation ! % !! performs a single stepof an arbitrarily chosen thread. We use%" to denote the reflexive-transitive closure of %. A transition sequence !0 %" ! modelsthe arbitrary interleaving of the various threads of a multithreadedprogram, starting from the initial state !0. Although dynamicthread creation is not explicitly supported by the semantics, it canbe modeled within the semantics in a straightforward way.

Standard semantics: ! % !!

[STD STEP]T (t, !(t), a, "!) ! "a

t !!

(!, !) " (!!, ![t := "!])

2.2 Serialized semantics

We assume the functionA : LocalStore % Nat indicates the num-ber of atomic blocks that are currently active, perhaps by exam-ining the program counter and thread stack recorded in the localstore. This count should be zero in the initial state, and should onlychange when entering or leaving an atomic block. We formalizethese requirements as follows:

• A("0(t)) = 0 for all t ! Tid ;

• if T (t, ", begin,"!) then A("!) = A(") + 1;

• if T (t, ", end, "!), then A(") > 0 and A("!) = A(") & 1;

• if T (t, ", a, "!) for a '! {begin, end}, then A(") = A("!).

The relation A(") holds if any thread is inside an atomic block:

A(")def= (t ! Tid . A("(t)) '= 0

The following serialized transition relation )% is similar to the stan-dard relation %, except that a thread cannot perform a step if an-other thread is inside an atomic block. Thus, the serialized relation)% does not interleave the execution of an atomic block with in-structions of concurrent threads.

Serialized semantics: ! )% !!

[SERIAL STEP]T (t, !(t), a, "!) ! "a

t !! &u '= t. A(!(u)) = 0(!, !) (" (!!, ![t := "!])

Reasoning about program behavior and correctness is much easierunder the serialized semantics ()%) than under the standard seman-tics (%), since each atomic block can be understood sequentially,without the need to consider all possible interleaved actions of con-current threads. However, standard language implementations onlyprovide the standard semantics (%), which admits additional transi-tion sequences and behaviors. In particular, a program that behavescorrectly according to the serialized semantics may still behave er-roneously under the standard semantics. Thus, in addition to beingcorrect with respect to the serialized semantics, the program shouldalso use sufficient synchronization to ensure the atomicity of eachblock of code that is intended to be atomic. Thus, for any programexecution (!0, "0) %" (!, ")where¬A("), there should exist anequivalent serialized execution (!0, "0) )%" (!, "). We call thisthe atomicity requirement on program executions, and any execu-tion of a correctly synchronized program should satisfy this require-

258

ment. (The restriction ¬A(!) avoids consideration of partially-executed atomic blocks.)

3 Dynamic Atomicity Checking

In this section, we present an instrumented semantics that dynam-ically detects violations of the above atomicity requirement. Westart by reviewing Lipton’s theory of reduction [38], which formsthe basis of our approach.

3.1 Reduction

The theory of reduction is based on the notion of right-mover andleft-mover actions. An action b is a right-mover if, for any executionwhere the action b performed by one thread is immediately followedby an action c of a concurrent thread, the actions b and c can beswapped without changing the resulting state, as shown below:

Commuting actions

"0 "2c b

"!1

"1"0 "2b c

For example, if the operation b is a lock acquire, then the action cof the second thread neither acquires nor releases the lock, and socannot affect the state of that lock. Hence the acquire operation canbe moved to the right of c without changing the resulting state, andwe classify each lock acquire operation as a right-mover.

Conversely, an action c is a left-mover if whenever c immediatelyfollows an action b of a different thread, the actions b and c can beswapped, again without changing the resulting state. Suppose theoperation c by the second thread is a lock release. During b, thesecond thread holds the lock, and b can neither acquire nor releasethe lock. Hence the lock release operation can be moved to the leftof b without changing the resulting state, and we classify each lockrelease operation as a left-mover.

Next, consider an access (read or write) to a variable that is sharedby multiple threads. If the variable is protected by some lock that isheld whenever the variable is accessed, then two threads can neveraccess the variable at the same time, and we classify each access tothat variable as a both-mover, which means that it is both a right-mover and a left-mover. If the variable is not consistently protectedby some lock, we classify the variable access as a non-mover.

To illustrate how the classification of actions as various kinds ofmovers enables us to verify atomicity, consider the first executiontrace in the diagram below. In this trace, a thread (1) acquires alockm, (2) reads a variable x protected by that lock, (3) updates x,and then (4) releases m. The execution path of this thread is inter-leaved with arbitrary actions b1, b2, b3 of other threads. Becausethe acquire operation is a right-mover and the write and release op-erations are left-movers, there exists an equivalent serial executionin which the operations of this path are not interleaved with opera-tions of other threads, as illustrated by the following diagram. Thusthe execution path is atomic.

Reduced execution sequence

!!1 !!

2 !!3 !!

4 !!5 !!

6

acq(m) wr(x,1)rd(x,0) rel(m)!7

!2 !3 !4 !5 !6 !7!1!0

!0

b3

b3b2

b1

b1

b2 wr(x,1)acq(m) rd(x,0) rel(m)

More generally, suppose a path through a code block contains asequence of right-movers, followed by at most one non-mover ac-tion and then a sequence of left-movers. Then this path can bereduced to an equivalent serial execution, with the same resultingstate, where the path is executed without any interleaved actions byother threads.

3.2 Checking atomicity via reduction

We next leverage the theory of reduction to verify atomicity dy-namically. In an initial presentation of our approach, we assumethe programmer provides a partial function

P : Var !"# Lock

that maps protected shared variables to associated locks; if P (x) isundefined, then x is not protected by any lock.

We develop an instrumented semantics that only admits code pathsthat are reducible, and which goes wrong on irreducible paths. Torecord whether each thread is in the right-mover or left-mover partof an atomic block, we extend the state space with an instrumenta-tion store:

! : Tid " {InRight, InLeft}

Each state is now a triple (", !,!). If A(!(t)) $= 0, then threadt is inside an atomic block, and !(t) indicates whether the threadis in the right-mover or left-mover part of that atomic block. Theinitial instrumentation store !0 is given by !0(t) = InRight for allt % Tid .

The following relation " &at !! updates the instrumentation store

whenever thread t performs operation a. The rule [INS ACCESSPROT] deals with an access to a protected variable while holding theappropriate lock. This action is a both-mover and so the instrumen-tation store ! does not change. Accesses to unprotected variablesare non-movers, and they can occur outside atomic blocks: see [INSACCESS OUTSIDE]. Unprotected accesses are also allowed insidean atomic block, and they cause a transition from the right-moverto the left-mover part of the atomic block: see [INS ACCESS COM-MIT]. Acquire operations are right-movers, and they can occur out-side or in the right-mover part of an atomic block, and converselyfor release operations.

The relation " &at wrong holds if the operation a by thread t

would go wrong by accessing a protected variable without hold-ing the correct lock [WRONG RACE], or by performing a non-left-mover action in the left-mover part of an atomic block. Non-left-mover actions include accessing an unprotected variable [WRONGUNPROTECT] or acquiring a lock [WRONG ACQUIRE].

259

ment. (The restriction ¬A(!) avoids consideration of partially-executed atomic blocks.)

3 Dynamic Atomicity Checking

In this section, we present an instrumented semantics that dynam-ically detects violations of the above atomicity requirement. Westart by reviewing Lipton’s theory of reduction [38], which formsthe basis of our approach.

3.1 Reduction

The theory of reduction is based on the notion of right-mover andleft-mover actions. An action b is a right-mover if, for any executionwhere the action b performed by one thread is immediately followedby an action c of a concurrent thread, the actions b and c can beswapped without changing the resulting state, as shown below:

Commuting actions

"0 "2c b

"!1

"1"0 "2b c

For example, if the operation b is a lock acquire, then the action cof the second thread neither acquires nor releases the lock, and socannot affect the state of that lock. Hence the acquire operation canbe moved to the right of c without changing the resulting state, andwe classify each lock acquire operation as a right-mover.

Conversely, an action c is a left-mover if whenever c immediatelyfollows an action b of a different thread, the actions b and c can beswapped, again without changing the resulting state. Suppose theoperation c by the second thread is a lock release. During b, thesecond thread holds the lock, and b can neither acquire nor releasethe lock. Hence the lock release operation can be moved to the leftof b without changing the resulting state, and we classify each lockrelease operation as a left-mover.

Next, consider an access (read or write) to a variable that is sharedby multiple threads. If the variable is protected by some lock that isheld whenever the variable is accessed, then two threads can neveraccess the variable at the same time, and we classify each access tothat variable as a both-mover, which means that it is both a right-mover and a left-mover. If the variable is not consistently protectedby some lock, we classify the variable access as a non-mover.

To illustrate how the classification of actions as various kinds ofmovers enables us to verify atomicity, consider the first executiontrace in the diagram below. In this trace, a thread (1) acquires alockm, (2) reads a variable x protected by that lock, (3) updates x,and then (4) releases m. The execution path of this thread is inter-leaved with arbitrary actions b1, b2, b3 of other threads. Becausethe acquire operation is a right-mover and the write and release op-erations are left-movers, there exists an equivalent serial executionin which the operations of this path are not interleaved with opera-tions of other threads, as illustrated by the following diagram. Thusthe execution path is atomic.

Reduced execution sequence

!!1 !!

2 !!3 !!

4 !!5 !!

6

acq(m) wr(x,1)rd(x,0) rel(m)!7

!2 !3 !4 !5 !6 !7!1!0

!0

b3

b3b2

b1

b1

b2 wr(x,1)acq(m) rd(x,0) rel(m)

More generally, suppose a path through a code block contains asequence of right-movers, followed by at most one non-mover ac-tion and then a sequence of left-movers. Then this path can bereduced to an equivalent serial execution, with the same resultingstate, where the path is executed without any interleaved actions byother threads.

3.2 Checking atomicity via reduction

We next leverage the theory of reduction to verify atomicity dy-namically. In an initial presentation of our approach, we assumethe programmer provides a partial function

P : Var !"# Lock

that maps protected shared variables to associated locks; if P (x) isundefined, then x is not protected by any lock.

We develop an instrumented semantics that only admits code pathsthat are reducible, and which goes wrong on irreducible paths. Torecord whether each thread is in the right-mover or left-mover partof an atomic block, we extend the state space with an instrumenta-tion store:

! : Tid " {InRight, InLeft}

Each state is now a triple (", !,!). If A(!(t)) $= 0, then threadt is inside an atomic block, and !(t) indicates whether the threadis in the right-mover or left-mover part of that atomic block. Theinitial instrumentation store !0 is given by !0(t) = InRight for allt % Tid .

The following relation " &at !! updates the instrumentation store

whenever thread t performs operation a. The rule [INS ACCESSPROT] deals with an access to a protected variable while holding theappropriate lock. This action is a both-mover and so the instrumen-tation store ! does not change. Accesses to unprotected variablesare non-movers, and they can occur outside atomic blocks: see [INSACCESS OUTSIDE]. Unprotected accesses are also allowed insidean atomic block, and they cause a transition from the right-moverto the left-mover part of the atomic block: see [INS ACCESS COM-MIT]. Acquire operations are right-movers, and they can occur out-side or in the right-mover part of an atomic block, and converselyfor release operations.

The relation " &at wrong holds if the operation a by thread t

would go wrong by accessing a protected variable without hold-ing the correct lock [WRONG RACE], or by performing a non-left-mover action in the left-mover part of an atomic block. Non-left-mover actions include accessing an unprotected variable [WRONGUNPROTECT] or acquiring a lock [WRONG ACQUIRE].

259

CS390C: Principles of Concurrency and Parallelism

Formalization

20

Page 21: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

Instrumented operations: ! !at !! and ! !a

t wrong

[INS ACCESS PROT]a ! {rd(x, v), wr(x, v)}

P (x) defined!(P (x)) = t

(!, ", !) "at "

[INS ACCESS COMMIT]a ! {rd(x, v), wr(x, v)}

P (x) undefinedA(!(t)) #= 0 "(t) = InRight

(!, ",!) "at "[t := InLeft]

[INS ACCESS OUTSIDE]a ! {rd(x, v), wr(x, v)}

P (x) undefined A(!(t)) = 0(!, ",!) "a

t "

[INS ACQUIRE]

or"(t) = InRightA(!(t)) = 0

(!, ",!) "acq(m)t "

[INS RELEASE]

(!, ",!) "rel(m)t "[t := InLeft]

[INS ENTER]

(!, ",!) "begint "[t := InRight ]

[INS OTHER]a ! {end, #}

(!, ", !) "at "

[WRONG RACE]a ! {rd(x, v), wr(x, v)}

P (x) defined!(P (x)) #= t

(!, ",!) "at wrong

[WRONG UNPROTECT]a ! {rd(x, v), wr(x, v)}

P (x) undefinedA(!(t)) #= 0 "(t) = InLeft

(!, ",!) "at wrong

[WRONG ACQUIRE]A(!(t)) #= 0 "(t) = InLeft

(!, ", !) "acq(m)t wrong

The instrumented transition relation ! ! !! performs an instru-mented step of an arbitrary thread; and ! ! wrong holds if a stepfrom! could violate the synchronization discipline or the atomicityrequirement.

Instrumented semantics: ! ! !! and ! ! wrong

[INS STEP]T (t, !(t), a, $!)

! $at !!

(!, ",!) "at "!

(!, ",!) " (!!, "!, ![t := $!])

[INS WRONG]T (t, !(t), a, $!)

! $at !!

(!, ",!) "at wrong

(!, ",!) " wrong

The following theorems state that the instrumented semantics isidentical to the standard semantics, except that the instrumentedsemantics records additional information and may go wrong. In ad-dition, any instrumented execution that does not go wrong satisfiesthe atomicity requirement.

THEOREM 1 (EQUIVALENCE OF SEMANTICS).

1. If (", !, ") !" ("!, !!, "!), then (", ") "" ("!, "!).

2. If (", ") "" ("!, "!) then #! either

(a) (", !,") !" wrong , or

(b) $!! such that (", !, ") !" ("!, !!, "!).

PROOF: By induction over derivations.

THEOREM 2 (INSTRUMENTED REDUCTION).If ("0, !0, "0) !" (", !,") and ¬A(") then ("0, "0) %""

(", ").

PROOF: See Appendix.

If the instrumented semantics admits a particular execution, thennot only is that execution reducible, but many similar executionsare also reducible. In particular, when an atomic block is beingexecuted, the only scheduling decision that affects program behav-ior is when the commit operation (the transition from InRight toInLeft) is scheduled. Scheduling decisions regarding when otheroperations in the atomic block are scheduled are irrelevant, in thatthey do not affect program behavior or reducibility. Hence, one testrun under our instrumented semantics can simultaneously verify thereducibility of many executions of the standard semantics.

3.3 Inferring protecting locks

The instrumented semantics of the previous section relies on theprogrammer to specify protecting locks for shared variables. Toavoid burdening the programmer, we next extend the instrumentedsemantics to infer protecting locks, using a variant of Eraser’s Lock-set algorithm [47]. We extend the instrumentation store ! to mapeach variable x to a set of candidate locks for x, such that thesecandidate locks have all been held on every access to x seen so far:

! : (Tid " {InRight , InLeft}) & (Var " 2Lock )

The initial candidate lock set for each variable is the set of all locks,that is, !0(x) = Lock for all x ' Var .

The relation ! !at !! updates the extended instrumentation store

whenever thread t performs operation a on the global store. Therule [INS2 ACCESS] for a variable access removes from the vari-able’s candidate lock set all locks not held by the current thread.We use H(t, ") to denote the set of locks held by thread t in state":

H(t,") = {m ' Lock | "(m) = t}

If the candidate lock set for a variable becomes empty, then all ac-cesses to that variable should be treated as non-movers, but previ-ous accesses may already have been incorrectly classified as both-movers. For example, if !(x) = {m} when thread t enters thefollowing function double, then the first access to x by thread twill be classified as a both-mover. If, at that point, an action of aconcurrent thread causes !(x) to become empty, the analysis willclassify the second access to x by t as a non-mover, but will not re-classify the first access, and thus the analysis will fail to recognizethat double may not be reducible.

/*# atomic */ void double() {synchronized (m) {int t = x;

x = 2 * t;

}}

Thus, to ensure soundness, the lock inference semantics does notsupport unprotected variables, and instead requires every variableto have a protecting lock. If the candidate lock set becomes empty,then that state goes wrong, via [WRONG2 RACE].

260

CS390C: Principles of Concurrency and Parallelism

Rules

21

Page 22: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

Instrumented operations: ! !at !! and ! !a

t wrong

[INS ACCESS PROT]a ! {rd(x, v), wr(x, v)}

P (x) defined!(P (x)) = t

(!, ", !) "at "

[INS ACCESS COMMIT]a ! {rd(x, v), wr(x, v)}

P (x) undefinedA(!(t)) #= 0 "(t) = InRight

(!, ",!) "at "[t := InLeft]

[INS ACCESS OUTSIDE]a ! {rd(x, v), wr(x, v)}

P (x) undefined A(!(t)) = 0(!, ",!) "a

t "

[INS ACQUIRE]

or"(t) = InRightA(!(t)) = 0

(!, ",!) "acq(m)t "

[INS RELEASE]

(!, ",!) "rel(m)t "[t := InLeft]

[INS ENTER]

(!, ",!) "begint "[t := InRight ]

[INS OTHER]a ! {end, #}

(!, ", !) "at "

[WRONG RACE]a ! {rd(x, v), wr(x, v)}

P (x) defined!(P (x)) #= t

(!, ",!) "at wrong

[WRONG UNPROTECT]a ! {rd(x, v), wr(x, v)}

P (x) undefinedA(!(t)) #= 0 "(t) = InLeft

(!, ",!) "at wrong

[WRONG ACQUIRE]A(!(t)) #= 0 "(t) = InLeft

(!, ", !) "acq(m)t wrong

The instrumented transition relation ! ! !! performs an instru-mented step of an arbitrary thread; and ! ! wrong holds if a stepfrom! could violate the synchronization discipline or the atomicityrequirement.

Instrumented semantics: ! ! !! and ! ! wrong

[INS STEP]T (t, !(t), a, $!)

! $at !!

(!, ",!) "at "!

(!, ",!) " (!!, "!, ![t := $!])

[INS WRONG]T (t, !(t), a, $!)

! $at !!

(!, ",!) "at wrong

(!, ",!) " wrong

The following theorems state that the instrumented semantics isidentical to the standard semantics, except that the instrumentedsemantics records additional information and may go wrong. In ad-dition, any instrumented execution that does not go wrong satisfiesthe atomicity requirement.

THEOREM 1 (EQUIVALENCE OF SEMANTICS).

1. If (", !, ") !" ("!, !!, "!), then (", ") "" ("!, "!).

2. If (", ") "" ("!, "!) then #! either

(a) (", !,") !" wrong , or

(b) $!! such that (", !, ") !" ("!, !!, "!).

PROOF: By induction over derivations.

THEOREM 2 (INSTRUMENTED REDUCTION).If ("0, !0, "0) !" (", !,") and ¬A(") then ("0, "0) %""

(", ").

PROOF: See Appendix.

If the instrumented semantics admits a particular execution, thennot only is that execution reducible, but many similar executionsare also reducible. In particular, when an atomic block is beingexecuted, the only scheduling decision that affects program behav-ior is when the commit operation (the transition from InRight toInLeft) is scheduled. Scheduling decisions regarding when otheroperations in the atomic block are scheduled are irrelevant, in thatthey do not affect program behavior or reducibility. Hence, one testrun under our instrumented semantics can simultaneously verify thereducibility of many executions of the standard semantics.

3.3 Inferring protecting locks

The instrumented semantics of the previous section relies on theprogrammer to specify protecting locks for shared variables. Toavoid burdening the programmer, we next extend the instrumentedsemantics to infer protecting locks, using a variant of Eraser’s Lock-set algorithm [47]. We extend the instrumentation store ! to mapeach variable x to a set of candidate locks for x, such that thesecandidate locks have all been held on every access to x seen so far:

! : (Tid " {InRight , InLeft}) & (Var " 2Lock )

The initial candidate lock set for each variable is the set of all locks,that is, !0(x) = Lock for all x ' Var .

The relation ! !at !! updates the extended instrumentation store

whenever thread t performs operation a on the global store. Therule [INS2 ACCESS] for a variable access removes from the vari-able’s candidate lock set all locks not held by the current thread.We use H(t, ") to denote the set of locks held by thread t in state":

H(t,") = {m ' Lock | "(m) = t}

If the candidate lock set for a variable becomes empty, then all ac-cesses to that variable should be treated as non-movers, but previ-ous accesses may already have been incorrectly classified as both-movers. For example, if !(x) = {m} when thread t enters thefollowing function double, then the first access to x by thread twill be classified as a both-mover. If, at that point, an action of aconcurrent thread causes !(x) to become empty, the analysis willclassify the second access to x by t as a non-mover, but will not re-classify the first access, and thus the analysis will fail to recognizethat double may not be reducible.

/*# atomic */ void double() {synchronized (m) {int t = x;

x = 2 * t;

}}

Thus, to ensure soundness, the lock inference semantics does notsupport unprotected variables, and instead requires every variableto have a protecting lock. If the candidate lock set becomes empty,then that state goes wrong, via [WRONG2 RACE].

260

Instrumented operations: ! !at !! and ! !a

t wrong

[INS ACCESS PROT]a ! {rd(x, v), wr(x, v)}

P (x) defined!(P (x)) = t

(!, ", !) "at "

[INS ACCESS COMMIT]a ! {rd(x, v), wr(x, v)}

P (x) undefinedA(!(t)) #= 0 "(t) = InRight

(!, ",!) "at "[t := InLeft]

[INS ACCESS OUTSIDE]a ! {rd(x, v), wr(x, v)}

P (x) undefined A(!(t)) = 0(!, ",!) "a

t "

[INS ACQUIRE]

or"(t) = InRightA(!(t)) = 0

(!, ",!) "acq(m)t "

[INS RELEASE]

(!, ",!) "rel(m)t "[t := InLeft]

[INS ENTER]

(!, ",!) "begint "[t := InRight ]

[INS OTHER]a ! {end, #}

(!, ", !) "at "

[WRONG RACE]a ! {rd(x, v), wr(x, v)}

P (x) defined!(P (x)) #= t

(!, ",!) "at wrong

[WRONG UNPROTECT]a ! {rd(x, v), wr(x, v)}

P (x) undefinedA(!(t)) #= 0 "(t) = InLeft

(!, ",!) "at wrong

[WRONG ACQUIRE]A(!(t)) #= 0 "(t) = InLeft

(!, ", !) "acq(m)t wrong

The instrumented transition relation ! ! !! performs an instru-mented step of an arbitrary thread; and ! ! wrong holds if a stepfrom! could violate the synchronization discipline or the atomicityrequirement.

Instrumented semantics: ! ! !! and ! ! wrong

[INS STEP]T (t, !(t), a, $!)

! $at !!

(!, ",!) "at "!

(!, ",!) " (!!, "!, ![t := $!])

[INS WRONG]T (t, !(t), a, $!)

! $at !!

(!, ",!) "at wrong

(!, ",!) " wrong

The following theorems state that the instrumented semantics isidentical to the standard semantics, except that the instrumentedsemantics records additional information and may go wrong. In ad-dition, any instrumented execution that does not go wrong satisfiesthe atomicity requirement.

THEOREM 1 (EQUIVALENCE OF SEMANTICS).

1. If (", !, ") !" ("!, !!, "!), then (", ") "" ("!, "!).

2. If (", ") "" ("!, "!) then #! either

(a) (", !,") !" wrong , or

(b) $!! such that (", !, ") !" ("!, !!, "!).

PROOF: By induction over derivations.

THEOREM 2 (INSTRUMENTED REDUCTION).If ("0, !0, "0) !" (", !,") and ¬A(") then ("0, "0) %""

(", ").

PROOF: See Appendix.

If the instrumented semantics admits a particular execution, thennot only is that execution reducible, but many similar executionsare also reducible. In particular, when an atomic block is beingexecuted, the only scheduling decision that affects program behav-ior is when the commit operation (the transition from InRight toInLeft) is scheduled. Scheduling decisions regarding when otheroperations in the atomic block are scheduled are irrelevant, in thatthey do not affect program behavior or reducibility. Hence, one testrun under our instrumented semantics can simultaneously verify thereducibility of many executions of the standard semantics.

3.3 Inferring protecting locks

The instrumented semantics of the previous section relies on theprogrammer to specify protecting locks for shared variables. Toavoid burdening the programmer, we next extend the instrumentedsemantics to infer protecting locks, using a variant of Eraser’s Lock-set algorithm [47]. We extend the instrumentation store ! to mapeach variable x to a set of candidate locks for x, such that thesecandidate locks have all been held on every access to x seen so far:

! : (Tid " {InRight , InLeft}) & (Var " 2Lock )

The initial candidate lock set for each variable is the set of all locks,that is, !0(x) = Lock for all x ' Var .

The relation ! !at !! updates the extended instrumentation store

whenever thread t performs operation a on the global store. Therule [INS2 ACCESS] for a variable access removes from the vari-able’s candidate lock set all locks not held by the current thread.We use H(t, ") to denote the set of locks held by thread t in state":

H(t,") = {m ' Lock | "(m) = t}

If the candidate lock set for a variable becomes empty, then all ac-cesses to that variable should be treated as non-movers, but previ-ous accesses may already have been incorrectly classified as both-movers. For example, if !(x) = {m} when thread t enters thefollowing function double, then the first access to x by thread twill be classified as a both-mover. If, at that point, an action of aconcurrent thread causes !(x) to become empty, the analysis willclassify the second access to x by t as a non-mover, but will not re-classify the first access, and thus the analysis will fail to recognizethat double may not be reducible.

/*# atomic */ void double() {synchronized (m) {int t = x;

x = 2 * t;

}}

Thus, to ensure soundness, the lock inference semantics does notsupport unprotected variables, and instead requires every variableto have a protecting lock. If the candidate lock set becomes empty,then that state goes wrong, via [WRONG2 RACE].

260

CS390C: Principles of Concurrency and Parallelism

Rules

22

Page 23: Data Race Detection - Purdue University€¦ · C(v) updated, but empty set not reported C(v) updated, and races reported when it becomes empty. We continue to use the state transitions

CS390C: Principles of Concurrency and Parallelism

Atomizer

● Can use an extended version of the lockset algorithm to infer the locks that should protect variable access.

● Extensions to reduce false alarms:− re-entrant locks− thread-local locks− write-protected data

23