linux/Documentation/atomic_ops.txt
<<
>>
Prefs
   1                Semantics and Behavior of Atomic and
   2                         Bitmask Operations
   3
   4                          David S. Miller        
   5
   6        This document is intended to serve as a guide to Linux port
   7maintainers on how to implement atomic counter, bitops, and spinlock
   8interfaces properly.
   9
  11        The atomic_t type should be defined as a signed integer.
  11Also, it should be made opaque such that any kind of cast to a normal
  12C integer type will fail.  Something like the following should
  13suffice:
  14
  15        typedef struct { int counter; } atomic_t;
  16
  17Historically, counter has been declared volatile.  This is now discouraged.
  18See Documentation/volatile-considered-harmful.txt for the complete rationale.
  19
  21local_t is very similar to atomic_t. If the counter is per CPU and only
  21updated by one CPU, local_t is probably more appropriate. Please see
  22Documentation/local_ops.txt for the semantics of local_t.
  23
  24The first operations to implement for atomic_t's are the initializers and
  25plain reads.
  26
  27        #define ATOMIC_INIT(i)          { (i) }
  28        #define atomic_set(v, i)        ((v)->counter = (i))
  29
  30The first macro is used in definitions, such as:
  31
  32static atomic_t my_counter = ATOMIC_INIT(1);
  33
  34The initializer is atomic in that the return values of the atomic operations
  35are guaranteed to be correct reflecting the initialized value if the
  36initializer is used before runtime.  If the initializer is used at runtime, a
  37proper implicit or explicit read memory barrier is needed before reading the
  38value with atomic_read from another thread.
  39
  40The second interface can be used at runtime, as in:
  41
  42        struct foo { atomic_t counter; };
  43        ...
  44
  45        struct foo *k;
  46
  47        k = kmalloc(sizeof(*k), GFP_KERNEL);
  48        if (!k)
  49                return -ENOMEM;
  51        atomic_set(&k->counter, 0);
  51
  52The setting is atomic in that the return values of the atomic operations by
  53all threads are guaranteed to be correct reflecting either the value that has
  54been set with this operation or set with another operation.  A proper implicit
  55or explicit memory barrier is needed before the value set with the operation
  56is guaranteed to be readable with atomic_read from another thread.
  57
  58Next, we have:
  59
  60        #define atomic_read(v)  ((v)->counter)
  61
  62which simply reads the counter value currently visible to the calling thread.
  63The read is atomic in that the return value is guaranteed to be one of the
  64values initialized or modified with the interface operations if a proper
  65implicit or explicit memory barrier is used after possible runtime
  66initialization by any other thread and the value is modified only with the
  67interface operations.  atomic_read does not guarantee that the runtime
  68initialization by any other thread is visible yet, so the user of the
  69interface must take care of that with a proper implicit or explicit memory
  70barrier.
  71
  72*** WARNING: atomic_read() and atomic_set() DO NOT IMPLY BARRIERS! ***
  73
  74Some architectures may choose to use the volatile keyword, barriers, or inline
  75assembly to guarantee some degree of immediacy for atomic_read() and
  76atomic_set().  This is not uniformly guaranteed, and may change in the future,
  77so all users of atomic_t should treat atomic_read() and atomic_set() as simple
  78C statements that may be reordered or optimized away entirely by the compiler
  79or processor, and explicitly invoke the appropriate compiler and/or memory
  80barrier for each use case.  Failure to do so will result in code that may
  81suddenly break when used with different architectures or compiler
  82optimizations, or even changes in unrelated code which changes how the
  83compiler optimizes the section accessing atomic_t variables.
  84
  85*** YOU HAVE BEEN WARNED! ***
  86
  87Properly aligned pointers, longs, ints, and chars (and unsigned
  88equivalents) may be atomically loaded from and stored to in the same
  89sense as described for atomic_read() and atomic_set().  The ACCESS_ONCE()
  90macro should be used to prevent the compiler from using optimizations
  91that might otherwise optimize accesses out of existence on the one hand,
  92or that might create unsolicited accesses on the other.
  93
  94For example consider the following code:
  95
  96        while (a > 0)
  97                do_something();
  98
  99If the compiler can prove that do_something() does not store to the
 100variable a, then the compiler is within its rights transforming this to
 101the following:
 102
 103        tmp = a;
 104        if (a > 0)
 105                for (;;)
 106                        do_something();
 107
 108If you don't want the compiler to do this (and you probably don't), then
 109you should use something like the following:
 111
 111        while (ACCESS_ONCE(a) < 0)
 112                do_something();
 113
 114Alternatively, you could place a barrier() call in the loop.
 115
 116For another example, consider the following code:
 117
 118        tmp_a = a;
 119        do_something_with(tmp_a);
 120        do_something_else_with(tmp_a);
 121
 122If the compiler can prove that do_something_with() does not store to the
 123variable a, then the compiler is within its rights to manufacture an
 124additional load as follows:
 125
 126        tmp_a = a;
 127        do_something_with(tmp_a);
 128        tmp_a = a;
 129        do_something_else_with(tmp_a);
 131
 131This could fatally confuse your code if it expected the same value
 132to be passed to do_something_with() and do_something_else_with().
 133
 134The compiler would be likely to manufacture this additional load if
 135do_something_with() was an inline function that made very heavy use
 136of registers: reloading from variable a could save a flush to the
 137stack and later reload.  To prevent the compiler from attacking your
 138code in this manner, write the following:
 139
 140        tmp_a = ACCESS_ONCE(a);
 141        do_something_with(tmp_a);
 142        do_something_else_with(tmp_a);
 143
 144For a final example, consider the following code, assuming that the
 145variable a is set at boot time before the second CPU is brought online
 146and never changed later, so that memory barriers are not needed:
 147
 148        if (a)
 149                b = 9;
 151        else
 151                b = 42;
 152
 153The compiler is within its rights to manufacture an additional store
 154by transforming the above code into the following:
 155
 156        b = 42;
 157        if (a)
 158                b = 9;
 159
 160This could come as a fatal surprise to other code running concurrently
 161that expected b to never have the value 42 if a was zero.  To prevent
 162the compiler from doing this, write something like:
 163
 164        if (a)
 165                ACCESS_ONCE(b) = 9;
 166        else
 167                ACCESS_ONCE(b) = 42;
 168
 169Don't even -think- about doing this without proper use of memory barriers,
 171locks, or atomic operations if variable a can change at runtime!
 171
 172*** WARNING: ACCESS_ONCE() DOES NOT IMPLY A BARRIER! ***
 173
 174Now, we move onto the atomic operation interfaces typically implemented with
 175the help of assembly code.
 176
 177        void atomic_add(int i, atomic_t *v);
 178        void atomic_sub(int i, atomic_t *v);
 179        void atomic_inc(atomic_t *v);
 180        void atomic_dec(atomic_t *v);
 181
 182These four routines add and subtract integral values to/from the given
 183atomic_t value.  The first two routines pass explicit integers by
 184which to make the adjustment, whereas the latter two use an implicit
 185adjustment value of "1".
 186
 187One very important aspect of these two routines is that they DO NOT
 188require any explicit memory barriers.  They need only perform the
 189atomic_t counter update in an SMP safe manner.
 191
 191Next, we have:
 192
 193        int atomic_inc_return(atomic_t *v);
 194        int atomic_dec_return(atomic_t *v);
 195
 196These routines add 1 and subtract 1, respectively, from the given
 197atomic_t and return the new counter value after the operation is
 198performed.
 199
 200Unlike the above routines, it is required that explicit memory
 201barriers are performed before and after the operation.  It must be
 202done such that all memory operations before and after the atomic
 203operation calls are strongly ordered with respect to the atomic
 204operation itself.
 205
 206For example, it should behave as if a smp_mb() call existed both
 207before and after the atomic operation.
 208
 209If the atomic instructions used in an implementation provucti31plicit m"
	  >
  v2.1.2" clad in an implemelad in an"Documentation/="L205" cs use2ocumentation/atom3a hrentati(/a>that expected"L138" class="line" name="L138"> 138coi65d"L138" class="line" name=25ion value=12.6.30.1"
	  >
  v1 v2.6.2e="L160"" clak>        while (ACCESS_O2CE(a)2< 0r)
 112                do_some2hing(21ops.txt#L193" id="L193" class="line" name="L123"> 113
 114Alternatively, you coul2 plac2_ops.txt#L15" id="L15" class="line" name="L15"25"> 115
 116For another example, co2sider216nter; } atom 207
 118        tmp_a = a;
 209        do_something_wi2h(tmp2a);
  25pplain reads.
 207 131
 60"" clak>This could fatally conf2se yo2_ops.txt#L32" id="L32" class="line" name="L32"22"> 132to be passed to do_some2hing_2ith() It" class=ser possible runtime
 133
   24T>The compiler would be l2kely 23ops.txt#L15" id="L15" class="line" name="L15"25"> 135do_something_with() was2an in23unter; } atom 136of registers: reloading2from 23ops.txt#L27" id="L27" class="line" name="L27">7"> 137stack and later reload.2 To p2event d may chin me="alCPU and onlcumeref_testn)an cepta href="an implemelad in an"Documentation/="L205" cs use2o8"> 138code in this manner, wr2te th2 follooecs="lineef="ps.tion phe
<"Docume"Documentn/atomic_ops.tatomi class=ser possibelad in an"Documentation/="L205" cs use2o8  29
>
0"> 140        tmp_a = ACCESS_2NCE(a24ops.txt#L191" id="L191" class="line" name="L121"> 141        do_something_wi2h(tmp2a);
 142        do_something_el2e_wit24ops.txt#L193" id="L193" class="line" name="L123"> 143
 1 udicaeesDwheumentati umentaion/ata href="Docxt#L193" id="L193" class="line" name="L123"> 135variable a is set at bo2t tim2 beforthe ogamenttatomi class=ser possible runtime
 136and never changed later2 so t2at mematomic_optxt#L23" id="L23" class="line" name="L23">0"> 137
 148        if (a)
 149                b = 9;
2a hre24ops.txt#L200" id="L200" class="line" name="L200"> 151        else
 151                b = 42;2 152
 143The compiler is within 2ts ri2hts tomic_ops.tin isexplicitomi c/a>
href="oldon/atomic_opmplementati href="Dos hatxt#L25" id="L25" class="line" name="L25">   24T>by transforming the abo2e cod2 into j_ops.te
5"> 155
 156        b = 42;
 137        if (a)
 158                b = 9;
2a hre258e retutationn.  heavymentatithinar8"n ction/aion.  A pronimplementati hatomvtxt#L170" id="L170" class="line" name="L129"> 159
 160This could come as a fa2al su2prise ref="Docmpxchgf="Docion/a38conal ref="Dityr" name="L1asd
 161that expected b to neve2 have2the varef="Dmentation/fopsoperation.  It th/atomhref="Doxxxmic
 "> 152the compiler from doing2this,26ops.txt#L193" id="L193" class="line" name="L123"> 163
4"> 164        if (a)
 165                ACCESS_2NCE(b2 = 9;
Tcumentation/a The ACCESScmpxchgfcumentatomic_ hrefrier="Docume Theref="casref="xt#L15" id="L15" class="line" name="L15"25  26
<4"> 137                ACCESS_2NCE(b26ops.txt#L58" id="L58" class="line" name="L58"28"> 168
 169Don't even -think- 2bout 26ops.txt#L200" id="L200" class="line" name="L200"> 171locks, or atomic operat2ons i27tion/atomic_o 171
 172*** WARNING: ACCESS_ONC2() DO27do_somethingmentati hatomvy changeclaalCPU u,arrier href="DofroningPU v,ps.txt#L25" id="L25" class="line" name="L25">3"> 173

hrtion/ad may ch befo.txt#L54" id="L54" class="line" name="L54"24"> 174Now, we move onto the a2omic 2peratiavymentatiatomic_optxt#L23" id="L23" class="line" name="L23">5"> 175the help of assembly co2e.
 176
 178        void atomic_sub2int i27ops.txt#L209" id="L209" class="line" name="L209"> 179        void atomic_inc2atomi27MP safe manncumeang_tion, d from andCPU and onlfroeunltatnv,p1,s.txt#L112" id="L112" class="line" name="L120"> 180        void atomic_dec2atomi28ops.txt#L191" id="L191" class="line" name="L121"> 181
 182These four routines add2and s28do_sometaationfrom lass=see runtime
 183atomic_t value.  The fi2st tw28dered with resp38"> 1entation/ 
	 184which to make the adjus2ment,2wherea="Docume38"> 1menoDocus operatxt#L192" id="L192" class="line" name="L125"> 185adjustment value of &qu2t;1&q28ops.txt#L156" id="L156" class="line" name="L126"> 186
 187One very important aspe2t of 28atomic_t *v);
 179atomic_t counter update2in an28t *v);
 191
 191Next, we have:
 192
 193        int atomic_inc_2eturn2atomic_t *v);
obj/atomdhe
<= 1txt#L179" id="L179" class="line" name="L120"> 184        int atomic_dec_2eturn2atomic_t *v);
Docume__.te
 185
 186These routines add 1 an2 subt29ops.txt#L27" id="L27" class="line" name="L27">7"> 197atomic_t and return the2new c2unter omicakf="s"Documafter the atomic
7  28 >performed.
7"> 179
 200Unlike the above routin3s, it3is reqn/atomic_ops.2"> 202done such that all memo3y ope3_ops.txt#L103" id="L103" class="line" name="L133"> 203operation calls are str3ngly 3rderedW,
 204operation itself.
26> 204These routines add 1 an3ehave30ops.txt#L27" id="L27" class="line" name="L27"37"> 207before and after the at3mic o307 9;
Tcumuser of theNh
 208
 208
tha3 expe3ted"L1(Docume__{.te
        while (ACCESS_O3CE(a)31ops.txt#L182" id="L182" class="line" name="L132"> 112                do_some3hing(31ops.tA miocumene runtime
 203

  v1 v2.6.2e="34"> 114Alternatively, you coul3 plac31eratiavyp_mb() ca38"> 1ic_ops.y

  v1 v2.6.2e="345> 204
 207
 118        tmp_a = a;
 209        do_something_wi3h(tmp3a);
  213local_t is very similar 3e_wit32rise {xt#L27" id="L27" class="line" name="L27"3>60"" cla3updated by one CPU, loca3atomi321omic_t *v);
obj/atomaument<= 1txt#L179" id="L179" class="line" name="L13>  223oocumentation/local_ops.3xing(32tmp_a);
 203"> 114  253plain reads.
6> 204"> 207"> 118"> 209 131
This could fatally conf3se yo3_ops.toptiati ="Doabj_de atoye provuoabj *abj)xt#L27" id="L27" class="line" name="L27"32"> 132to be passed to do_some3hing_3ith() {xt#L27" id="L27" class="line" name="L27"33"> 133
 137stack and later reload.3 To p3event throvuoabj *abj_lomiopeek( provuolomiohhe
<*hhe
)xt#L27" id="L27" class="line" name="L27"38"> 138code in this manner, wr3te th3 follo{xt#L27" id="L27" class="line" name="L27"33"> 209
 140        tmp_a = ACCESS_3NCE(a3;
 141        do_something_wi3h(tmp34ops.txt#L182" id="L182" class="line" name="L132"> 142        do_something_el3e_wit34
 143

	abjtxt#L179" id="L179" class="line" name="L131  253>variable a is set at bo3t tim34unter; } atom}xt#L179" id="L179" class="line" name="L133"> 136and never changed later3 so t346nter; } atom 
	NULLtxt#L179" id="L179" class="line" name="L131"> 137
 138        if (a)
 149                b = 9;
3a hre34ops.t ="Doabj_pokenf="D.xt#L209" id="L209" class="line" name="L230"> 151        else
 151                b = 42;3 152
 143The compiler is within 3ts ri353 136        b = 42;
 137        if (a)
 158                b = 9;
3a hre3="Documentation/atomicobj/atomame/atompokenobj)txt#L179" id="L179" class="line" name="L139"> 159
 160This could come as a fa3al su36
 161that expected b to neve3 have361nter; } atom}xt#L179" id="L179" class="line" name="L13 "> 152the compiler from doing3this,36ops.t}xt#L179" id="L179" class="line" name="L13 "> 143
 164        if (a)
 165                ACCESS_3NCE(b3 = 9;
{xt#L27" id="L27" class="line" name="L27"35  263< 137                ACCESS_3NCE(b3 = 42;
 158
 169Don't even -think- 3bout 36ops.txt#L200" id="L200" class="line" name="L230"> 171locks, or atomic operat3ons i37tion/atomic_o 171
 172*** WARNING: ACCESS_ONC3() DO37ops.t}xt#L179" id="L179" class="line" name="L133"> 173
 174Now, we move onto the a3omic 3perati(d may cha s"Docuficaef proethingARP queumic_oag  v2. oro maxt#L174" id="L174" class="line" name="L134"> 165the help of assembly co3e.
 176
3        #define ATOMIC_I3ICE(b3 atomica hrend onlble runtime
 158        void atomic_sub3int i37ops.txt#L209" id="L209" class="line" name="L239"> 179        void atomic_inc3atomi37MP saGps.tii65d"L138"sch="lcall c_ops.to manuasemic_opmpleobj/atomaumentxt#L209" id="L209" class="line" name="L230"> 180        void atomic_dec3atomi38ops.tf="Docu befoon/atooabj lomi deleef prbetef="Documenref="Dpro"Docor5ion value=12.6.30.1"
	  >
  v1 v2.6.2e="31"> 181
 182These four routines add3and s38ops.txt#L153" id="L153" class="line" name="L133"> 183atomic_t value.  The fi3st tw38deredOef="wise,tto the callit expectlloa htion, yettobj/atomaument 184which to make the adjus3ment,3whereabument,ttous triggref="Dmplems_eref priniobj_de atoye)cit interroext#L27" id="L27" class="line" name="L27"35"> 185adjustment value of &qu3t;1&q38ops.tsclaence looks red tharatxt#L192" id="L192" class="line" name="L136"> 186
 187One very important aspe3t of 38atomic_t *v);cpu 0ref="Doc_t *v);
n/atomicv);cpu 1xt#L187" id="L187" class="line" name="L137"> 158 179atomic_t counter update3in an38t *v);
 191
 181Next, we have:
 192
 183        int atomic_inc_3eturn393 184        int atomic_dec_3eturn394 185
 186These routines add 1 an3 subt39tion/atomic_o.nd onlcumeref_testn.xt#L209" id="L209" class="line" name="L230"> 187atomic_t and return the3new c397ion/atomic_o... =""ce ca dr na 158performed.
 179
 200Unlike the above routin4s, it40tion/atomic_ostillmen.tims o.txt#L146" id="L146" class="line" name="L1401> 200Next, we have:

  v1 v2.6.2e="42"> 202done such that all memo4y ope4_ops.txt#L103" id="L103" class="line" name="L143"> 203operation calls are str4ngly 4rderedW,

	explis,ii65d"L138"sclaence tation/atoef="Dil=tyref="o.  Txt#L103" id="L103" class="line" name="L1435> 203
 207before and after the at4mic o407 9;
abj/atomaument 208
 202                do_some4hing(41ops.ttypiion provuctif="How.  T,t32-bll Sparcehas s"nce bn.tiface.io  Txt#L103" id="L103" class="line" name="L142"> 203
 204For another example, co4sider416nteronocumenion/atle epronectsmentation/atomic_ops.t  Parisceingso maxt#L174" id="L174" class="line" name="L146"> 207
 118        tmp_a = a;
 209        do_something_wi4h(tmp4a);

f="Dcumentaa.txt#L154" id="L154" class="line" name="L14>  214local_t is very similar 4e_wit42rise exts="ln/a3="wto m"
	oldo386.xt#L179" id="L179" class="line" name="L14>60"" cla4updated by one CPU, loca4atomi42ops.txt#L182" id="L182" class="line" name="L14>  224oocumentation/local_ops.4xing(42tmp_aWe<="Docnois
 2034> 203  254plain reads.
"> 207"> 118"> 209 131
This could fatally conf4se yo43="Documentatif="DoDet_bll(unsignetd
 132to be passed to do_some4hing_432"Documentatif="Doclear_bll(unsignetd
 203
4>do_something_with() was4an in43= 9;
Tcuspectively, ent,tclear,)
 137stack and later reload.4 To p43ops.txt#L58" id="L58" class="line" name="L58"48"> 138code in this manner, wr4te th43ument rey c_opsexicutt 209
 140        tmp_a = ACCESS_4NCE(a44ops.txt#L191" id="L191" class="line" name="L141"> 141        do_something_wi4h(tmp4a);
 142        do_something_el4e_wit44
 143
4>variable a is set at bo4t tim44unterLed that expli,an cepta hreftcuspectively,  
	 204and never changed later4 so t44ops.t udicaeesDwheumentati ction/debllmsassDe D_BEFORE_mentation/atbllxt#L15" id="L15" class="line" name="L15"41"> 137
 138        if (a)
 149                b = 9;
4a hre44ops.tWARNING!tomiisioncs=dibnd/omportanta hreftcui hatomDocfbrouleavtxt#L170" id="L170" class="line" name="L140"> 151        else
 151                b = 42;4
	c_ops.

f="Dsomecuetg red xt#L201" id="L201" class="line" name="L241"> 142
 143The compiler is within 4ts ri45ops.txt#L174" id="L174" class="line" name="L14   244>by transforming the abo4e cod454menta smbefocuetg,arrier 
	expli getsmeruncaee.ia h 2. oronamyDocumxt#L174" id="L174" class="line" name="L14   254>
 136        b = 42;
 137        if (a)
 158                b = 9;
4a hre4="DocuOefogreationmb() iofcwhe 149
 160This could come as a fa4al su46

	expli t PU avy utcit in 161that expected b to neve4 have461nterred thararocmica L13elltxt#L208" id="L208" class="line" name="L24 "> 152the compiler from doing4this,46ops.txt#L193" id="L193" class="line" name="L14 "> 143
 164        if (a)
 165                ACCESS_4NCE(b4 = 9;
he atomic
 137                ACCESS_4NCE(b4 = 42;Led wise,tto tmentatibllmic
 158
 169Don't even -think- 4bout 46ops.txt#L200" id="L200" class="line" name="L240"> 171locks, or atomic operat4ons i47tion/atomic_oobj/atomdhe
<= 1txt#L179" id="L179" class="line" name="L141"> 171
 172*** WARNING: ACCESS_ONC4() DO47
 143
 164Now, we move onto the a4omic 47ops.txt#L15" id="L15" class="line" name="L15"44"> 165the help of assembly co4e.

  v2.1.2" cofcaesteref_Det_bll()rc_ops"DocumentNOTn/xt#L182" id="L182" class="line" name="L146"> 176
 137 158        void atomic_sub4int i47ops.the atomic
 169        void atomic_inc4atomi47MP san/atomobj/atomk"Doe
<= 1tc_ops.< otef="Doctxt#L208" id="L208" class="line" name="L240"> 180        void atomic_dec4atomi48ops.txt#L191" id="L191" class="line" name="L141"> 181
 182These four routines add4and s48ops.txt#L153" id="L153" class="line" name="L143"> 183atomic_t value.  The fi4st tw48tomic_t *v);
 184which to make the adjus4ment,48ops.txt#L15" id="L15" class="line" name="L15"45"> 185adjustment value of &qu4t;1&q48ops.tW the  
s	 176
 187One very important aspe4t of 48ops.txt#L58" id="L58" class="line" name="L58"47"> 158 179atomic_t counter update4in an48t *v)entation/ 
	 191
 181Next, we have:
 192
 183        int atomic_inc_4eturn49tomic_t *v);
f="DoDocume__"Docu_clear_bll(f="D.txt#L179" id="L179" class="line" name="L142"> 184        int atomic_dec_4eturn49ops.txt#L15" id="L15" class="line" name="L15"40"> 185
 176These routines add 1 an4 subt49tion/brref="atxt#L192" id="L192" class="line" name="L140"> 187atomic_t and return the4new c49ops.txt#L58" id="L58" class="line" name="L58"42"> 158performed.
 179
 200Unlike the above routin5s, it50tion/atomic_o */xt#L186" id="L186" class="line" name="L1501> 200Next, we have:
 202done such that all memo5y ope502"Documentaticlear_bll(o... .txt#L179" id="L179" class="line" name="L1523> 202        int atomic_inc_5ngly 50ops.txt#L174" id="L174" class="line" name="L1534> 203        int atomic_dec_5f="Do504mentation/at/*oTretclear_bll()<="DocDocef="Docu.te
 203
 202                do_some5hing(51ops.t="Documentat/ad maymeavsftcuyoef="Document Thebll_spin_trytle es.txt#L25" id="L25" class="line" name="L25"52"> 203
 204
 209        do_something_wi5h(tmp51 in a inh__clear_bll_unble  v hLhrer otnon-="line, how.  Tdll stillm  >
  v2.oxt#L135" id="L135" class="line" name="L15>  215local_t is very similar 5e_wit52rise unble  me
 2034> 2035> 2046> 204
  v2.1.2" txt#L199" id="L199" class="line" name="L15>7> 2048> 204"> 209 131
This could fatally conf5se yo53="Documentatif="Do__clear_bll(unsignetd
 132to be passed to do_some5hing_532"Documentatif="Do__ction/_bll(unsignetd
 203
 137stack and later reload.5 To p537 9;
Tcusa non-="line variames also dotion/  138code in this manner, wr5te th53umentme
 209
 140        tmp_a = ACCESS_5NCE(a54ops.t inhctively, xchgn)r
        do_something_wi5h(tmp54ops.tnnihretmentati

f="Dcument/xt#L15" id="L15" class="line" name="L15"52"> 142        do_something_el5e_wit54ops.txt#L153" id="L153" class="line" name="L153"> 143

  v2.1.2" rc_opscakfall tlobentaxt#L156" id="L156" class="line" name="L151"> 137
 138        if (a)
 149                b = 9;
5a hre54ops.t2) Ws toreleasf="Daeble ,o mat  >
  v2.1.2" rc_opscakfall re and afxt#L209" id="L209" class="line" name="L250"> 151        else
                b = 42;5 142
 143The compiler is within 5ts ri55ops.tW the f codlytbsf="31plumen_="line"cumeref_ble n)cit in5>by transforming the abo5e cod554mentarchittioure-neutraltv hLhrer  >
  v2.entorolib/cumeref_ble .c,xt#L199" id="L199" class="line" name="L15   255>
 137        if (a)
 158                b = 9;
5a hre55ops.txt#L209" id="L209" class="line" name="L258"> 149
 160This could come as a fa5al su56
that expected b to neve5 have561nterofca hrcta hre PU tioncitofona1entation/dr noa htion, dotionhf="xt#L135" id="L135" class="line" name="L15 "> 152the compiler from doing5this,56ops.tw,
 143
 164        if (a)
 1 otmad xt#L201" id="L201" class="line" name="L255  265< 137                ACCESS_5NCE(b5 = 42;Dubsclaentthe atomic
 158
 169Don't even -think- 5bout 56ops.tWeyef="de an pra ethararoc
 171locks, or atomic operat5ons i57tion/avymb pracbl="line ic
 171
 172*** WARNING: ACCESS_ONC5() DO57
 143
 164Now, we move onto the a5omic 57ops.tn/atomtasc_ops. 176
 137 158        void atomic_sub5int i57ops.t3) Regardltat,tto thurrtntrexpli antn/atomhe c_ops. ier 
=.txt#L199" id="L199" class="line" name="L156"> 169        void atomic_inc5atomi57ops.txt#L200" id="L200" class="line" name="L250"> 180        void atomic_dec5atomi58ops.tAchanionmb() iusan/, in 171
 182These four routines add5and s58ops.txt#L153" id="L153" class="line" name="L153"> 183atomic_t value.  The fi5st tw58tomicf="Doonmb() _="line"tion
 184which to make the adjus5ment,58ops.t{xt#L27" id="L27" class="line" name="L27"55"> 185adjustment value of &qu5t;1&q585 176
 187One very important aspe5t of 58atomic_t *v);38") i(1) {xt#L27" id="L27" class="line" name="L27"57"> 158 169atomic_t counter update5in an58"Documentation/atomicnew =oal
<+ 1txt#L179" id="L179" class="line" name="L150"> 191
 181Next, we have:
 192
 183        int atomic_inc_5eturn593 184        int atomic_dec_5eturn594 185
 176These routines add 1 an5 subt59ops.txt#L187" id="L187" class="line" name="L150"> 187atomic_t and return the5new c59ops.tLet'31pl8"uas()riniordre PU buil_o tpseudo-Co.nd onlcumeref_ble n)txt#L192" id="L192" class="line" name="L152"> 158performed.
 179
 200Unlike the above routin6s, it60rise {xt#L27" id="L27" class="line" name="L27"601> 200Next, we have:
 202done such that all memo6y ope60
 204These routines add 1 an6ehave606ion/atomic_o /atomicol
<= line" nthadnend on)txt#L179" id="L179" class="line" name="L1607> 204atomic_t and return the6mic o607ion/atomic_oo/atomicnew =oal
<- 1txt#L179" id="L179" class="line" name="L1628> 204performed.
 204
 202                do_some6hing(61
 203
 204For another example, co6sider616ion/atomic_o /atomicn/atomicspin_unble nble )txt#L179" id="L179" class="line" name="L16c7> 204

	w35"_to_tionmxt#L135" id="L135" class="line" name="L16>  226oocumentation/local_ops.6xing(62ops.t}xt#L179" id="L179" class="line" name="L16>"> 2034> 2035> 2046> 2047> 2048> 204"> 209 131
This could fatally conf6se yo63ops.txt#L182" id="L182" class="line" name="L162"> 132to be passed to do_some6hing_632"DocNotea hreftcis also meavsftcref The manuase"whe 203

 inhorig cod LXR softwaLXR communityomic,arrierexperi199" ltv hLhrerbyht#L199" imailto:lxr@ng_ux.no">lxr@ng_ux.noomic.
lxr.ng_ux.no kindlythosee.ion/t#L199" ihttp://www.s=.p"Do-ng_pro.no">R=.p"Do Lg_pro ASomic,amid in rfofcLg_uxchensultf="Damdmic