<table cellspacing="0" cellpadding="0" border="0" ><tr><td valign="top" style="font: inherit;">Hi all:<br>I believe there shouldn't be so many for not being counted with fingers of one hand. The memory model was specified and model checked with TLA by Lamport and publicly available for bug finders contest.<br>However being an UNSAFE MODULE I suspect this was intended to explode that relaxed restriction. Also probable a C weak semantics could make things worse or better than they are, so ...<br>Thanks in advance<br><br>--- El <b>lun, 27/8/12, Mika Nystrom <i><mika@async.caltech.edu></i></b> escribió:<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"><br>De: Mika Nystrom <mika@async.caltech.edu><br>Asunto: Re: [M3devel] race conditions in lock-free code...<br>Para: "Jay K" <jay.krell@cornell.edu><br>CC: m3devel@elegosoft.com<br>Fecha: lunes, 27 de agosto, 2012 13:34<br><br><div
 class="plainMail"><br>yeah I agree.<br><br>processor 1 performs...<br><br>x  := alloc_new_text<br>x^ := character<br>return x<br>global := x<br><br>processor 2 performs<br><br>IF global # NIL THEN use(global) END <br><br>now if out of all this, x^ := character is held back, e.g., in a processor<br>write buffer, and if use(global) involves performing global^, the value<br>of global^ will be the value of global^ just after x := alloc_new_text<br>and before x^ := character.<br><br>I believe very aggressive architectures such as Alpha permit reordering<br>to that extent.  If memory serves, on Alpha, if you do not perform a<br>Memory Barrier, pretty much nothing can be inferred on one processor<br>about the ordering of operations on another.<br><br>X86 I am not sure is that aggressive.  In a hardware-synchronized<br>multiprocessor environment without barrier operations using e.g. the<br>Illinois/MESI protocol (doesn't X86?), at the point x^ :=
 character is<br>performed, the cache coherence protocol has to guarantee the cache line<br>is in state Exclusive, which means it has to be evicted from the cache<br>in processor 2 and when use(global) comes around the protocol will<br>have to ensure it is in Shared state on processor 2.  (Or Exclusive,<br>if P1 writes it back and invalidates.)  This would guarantee that you<br>could not actually see a very old value for global^ at the same time<br>as a newer value for global.  The protocol guarantees that the relative<br>ordering of writes is maintained across processors.<br><br>Of course I don't know whether Alphas are actually that aggressive in<br>practice.  I'd suspect that a multiprocessor 21264 could be.  But I do<br>agree it's a bug relative to the Alpha Architecture Manual.  A very nasty<br>one at that.<br><br>    Mika<br><br><br>Jay K
 writes:<br>>--_5c33c9ca-3a7d-4c39-ab66-ab9c151d1539_<br>>Content-Type: text/plain; charset="iso-8859-1"<br>>Content-Transfer-Encoding: quoted-printable<br>><br>>It is NOT benign.<br>>The global can be written before the initialization of what it points to is=<br>> done.<br>>The result is wrong.<br>><br>><br>>It IS benign if multiple threads go and allocate separate multiple initiali=<br>>zed TEXTs.<br>>That's not the problem.<br>><br>><br>> - Jay<br>><br>><br>>> CC: <a ymailto="mailto:jay.krell@cornell.edu" href="/mc/compose?to=jay.krell@cornell.edu">jay.krell@cornell.edu</a>=3B <a ymailto="mailto:m3devel@elegosoft.com" href="/mc/compose?to=m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>>> From: <a ymailto="mailto:hosking@cs.purdue.edu" href="/mc/compose?to=hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>>> Subject: Re: [M3devel] race conditions in lock-free
 code...<br>>> Date: Mon=2C 27 Aug 2012 09:27:38 -0400<br>>> To: <a ymailto="mailto:mika@async.caltech.edu" href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a><br>>>=20<br>>> So why is this anything other than benign? It's a cache and there's no pr=<br>>oblem if different threads get different texts. Don't cripple performance u=<br>>nnecessarily.  The collector will reclaim any unreachable text.<br>>>=20<br>>> Sent from my iPad<br>>>=20<br>>> On Aug 27=2C 2012=2C at 3:17 AM=2C Mika Nystrom <<a ymailto="mailto:mika@async.caltech.edu" href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a>> =<br>>wrote:<br>>>=20<br>>> > Oh I see now.<br>>> >=20<br>>> > It's not that the processor reorders in any tricky way.  It is that the<br>>> > write performed by Text8.New could be sitting around processor 1's
 cach=<br>>e<br>>> > indefinitely without actually getting written back to main memory.<br>>> > Processor 2 might see the new pointer=2C but when reading the memory po=<br>>inted<br>>> > to=2C would get uninitialized memory.  I think this can happen on Alpha=<br>> but<br>>> > maybe not X86 (without further reorderings anyhow)?<br>>> >=20<br>>> > Any chance any of the pthreads bugs could be of this nature?  How are t=<br>>he<br>>> > pthreads doing?  I gathered some bugs were fixed but I haven't tried th=<br>>e<br>>> > system for a while.<br>>> >=20<br>>> >     Mika<br>>> >=20<br>>> >=20<br>>> > Jay K writes:<br>>> >> --_86f22d85-5540-4565-bf73-232aaafdc94b_<br>>> >> Content-Type: text/plain=3B charset=3D"iso-8859-1"<br>>> >> Content-Transfer-Encoding:
 quoted-printable<br>>> >>=20<br>>> >> The processor can reorder. Across call/ret at least in general.<br>>> >>=20<br>>> >>=20<br>>> >> The compiler can also reorder=3D2C if you have whole-program-optimizat=<br>>ion=3D2C =3D<br>>> >> link-time-code-gen (Microsoft "LTCG")=3D2C link-time-optimization (gcc=<br>> "LTO")=3D<br>>> >> . (We don't=3D2C but real world systems certainly do.)<br>>> >>=20<br>>> >>=20<br>>> >> - Jay<br>>> >>=20<br>>> >>=20<br>>> >>> To: <a ymailto="mailto:jay.krell@cornell.edu" href="/mc/compose?to=jay.krell@cornell.edu">jay.krell@cornell.edu</a>=3D3B <a ymailto="mailto:m3devel@elegosoft.com" href="/mc/compose?to=m3devel@elegosoft.com">m3devel@elegosoft.com</a>=3D3B mika@async.=<br>>caltech.=3D<br>>> >> edu<br>>> >>> Subject: Re: [M3devel]
 race conditions in lock-free code...<br>>> >>> Date: Sun=3D2C 26 Aug 2012 22:32:48 -0700<br>>> >>> From: <a ymailto="mailto:mika@async.caltech.edu" href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a><br>>> >>> =3D20<br>>> >>> Sorry=3D2C I can't seem to quote your message.<br>>> >>> =3D20<br>>> >>> You say that Text8.New's result can be assigned to fromCharCache[c]<br>>> >>> before Text8.New is done running.  How is that possible?  Surely<br>>> >>> Text8.New has to calculate its result before it can be assigned<br>>> >>> anywhere.  Yes possibly FromChar allocates space for the result of<br>>> >>> Text8.New but the assignment of whatever appears in that space can't<br>>> >>> happen until *after* Text8.New has run.  Unless you are saying that<br>>>
 >>> the running of Text8.New and FromChar are intertwined somehow..?<br>>> >>> I know compilers do some odd things but that doesn't sound right...<br>>> >>> =3D20<br>>> >>> If Text8.New took fromCharCache[c] as a VAR parameter you might be<br>>> >>> right=3D2C though.  But it doesn't...<br>>> >>> =3D20<br>>> >>> Am I missing something?<br>>> >>> =3D20<br>>> >>>     Mika<br>>> >>> =3D20<br>>> >>> Mika Nystrom writes:<br>>> >>>>=20<br>>> >>>> Yeah it's a race condition=3D2C in theory.  But is it important?  If=<br>> you g=3D<br>>> >> et<br>>> >>>> the wrong copy=3D2C there will be two TEXTs representing one CHAR.  =<br>>But no<br>>> >>>> one ever said FromChar was
 guaranteed to return the same pointer whe=<br>>n<br>>> >>>> you call it with the same CHAR...<br>>> >>>>=20<br>>> >>>>    Mika<br>>> >>>>=20<br>>> >>>> Jay K writes:<br>>> >>>>> --_5f23896e-68ee-44da-82dd-311cd8c58979_<br>>> >>>>> Content-Type: text/plain=3D3B charset=3D3D"iso-8859-1"<br>>> >>>>> Content-Transfer-Encoding: quoted-printable<br>>> >>>>>=20<br>>> >>>>> We have race conditions=3D3D2C like this=3D3D2C m3core/src/Text.m3:<br>>> >>>>>=20<br>>> >>>>>=20<br>>> >>>>> VAR fromCharCache :=3D3D3D ARRAY CHAR OF T {NIL=3D3D2C ..}=3D3D3B (=<br>>* 1-char t=3D<br>>> >> exts *)<br>>> >>>>>=20<br>>> >>>>>=20<br>>>
 >>>>> PROCEDURE FromChar (c: CHAR): T =3D3D3D<br>>> >>>>> VAR buf: ARRAY [0..0] OF CHAR=3D3D3B<br>>> >>>>> BEGIN<br>>> >>>>>   IF fromCharCache [c] =3D3D3D NIL THEN<br>>> >>>>>     buf [0] :=3D3D3D c=3D3D3B<br>>> >>>>>     fromCharCache[c] :=3D3D3D Text8.New (buf)=3D3D3B<br>>> >>>>>   END=3D3D3B<br>>> >>>>>   RETURN fromCharCache [c]<br>>> >>>>> END FromChar=3D3D3B<br>>> >>>>>=20<br>>> >>>>>=20<br>>> >>>>> It should be:<br>>> >>>>>=20<br>>> >>>>>=20<br>>> >>>>> PROCEDURE FromChar (c: CHAR): T =3D3D3D<br>>> >>>>> =3D3D0A=3D3D<br>>>
 >>>>> VAR buf: ARRAY [0..0] OF CHAR=3D3D3B<br>>> >>>>> =3D3D0A=3D3D<br>>> >>>>> BEGIN<br>>> >>>>> =3D3D0A=3D3D<br>>> >>>>>   IF fromCharCache [c] =3D3D3D NIL THEN<br>>> >>>>> =3D3D0A=3D3D<br>>> >>>>>     buf [0] :=3D3D3D c=3D3D3B<br>>> >>>>> =3D3D0A=3D3D<br>>> >>>>>     WITH a =3D3D3D Text8.New (buf) DO<br>>> >>>>>       MemoryBarrier()=3D3D3B<br>>> >>>>>       fromCharCache[c] :=3D3D3D a=3D3D3B<br>>> >>>>>    END=3D3D3B<br>>> >>>>> =3D3D0A=3D3D<br>>> >>>>>   END=3D3D3B<br>>> >>>>> =3D3D0A=3D3D<br>>>
 >>>>>   RETURN fromCharCache [c]<br>>> >>>>> =3D3D0A=3D3D<br>>> >>>>> END FromChar=3D3D3B<br>>> >>>>> =3D3D0A=3D3D<br>>> >>>>>=20<br>>> >>>>>=20<br>>> >>>>> to ensure that all of Text8.New() finishes before the assignment to=<br>> fro=3D<br>>> >> mCha=3D3D<br>>> >>>>> rCache[c] is made.<br>>> >>>>>=20<br>>> >>>>>=20<br>>> >>>>> Can the compiler somehow catch these?<br>>> >>>>> I fear they are a small epidemic.<br>>> >>>>> For a long time people didn't realize where all the compiler and pr=<br>>oces=3D<br>>> >> sor =3D3D<br>>> >>>>> could reorder.<br>>> >>>>>=20<br>>>
 >>>>>=20<br>>> >>>>> Do we have the right constructs by now to fix them?<br>>> >>>>> I think we do.<br>>> >>>>>=20<br>>> >>>>>=20<br>>> >>>>> - Jay<br>>> >>>>>                         =3D3D<br>>> >>>>>=20<br>>> >>>>> --_5f23896e-68ee-44da-82dd-311cd8c58979_<br>>> >>>>> Content-Type: text/html=3D3B charset=3D3D"iso-8859-1"<br>>> >>>>> Content-Transfer-Encoding: quoted-printable<br>>> >>>>>=20<br>>> >>>>> <html><br>>> >>>>> <head><br>>> >>>>> <style><!--<br>>> >>>>> .hmmessage P<br>>> >>>>> {<br>>>
 >>>>> margin:0px=3D3D3B<br>>> >>>>> padding:0px<br>>> >>>>> }<br>>> >>>>> body.hmmessage<br>>> >>>>> {<br>>> >>>>> font-size: 12pt=3D3D3B<br>>> >>>>> font-family:Calibri<br>>> >>>>> }<br>>> >>>>> --></style></head><br>>> >>>>> <body class=3D3D3D'hmmessage'><div dir=3D3D3D'ltr'>We have race con=<br>>ditions=3D<br>>> >> =3D3D2C like =3D3D<br>>> >>>>> this=3D3D2C m3core/src/Text.m3:<br><br><br>VAR fromCharCache :=3D3D=<br>>3D ARRAY=3D<br>>> >> CHAR OF=3D3D<br>>> >>>>> T {NIL=3D3D2C ..}=3D3D3B (* 1-char texts *)<br><br><br>PROCEDURE Fr=<br>>omChar =3D<br>>> >> (c: CHAR=3D3D<br>>> >>>>> ):
 T =3D3D3D<br>&nbsp=3D3D3B VAR buf: ARRAY [0..0] OF CHAR=3D3D3B<b=<br>>r>&nbsp=3D3D=3D<br>>> >> 3B BEGIN<br>=3D3D<br>>> >>>>> &nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B IF fromCharCache [c] =3D3D3D N=<br>>IL THEN<br>&=3D<br>>> >> nbsp=3D3D3B&nbsp=3D3D<br>>> >>>>> =3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B buf [0] :=3D3D3D c=3D3D=<br>>3B<br>&nbsp=3D3D3B=3D<br>>> >> &nbsp=3D3D3B&nbsp=3D3D3B&n=3D3D<br>>> >>>>> bsp=3D3D3B&nbsp=3D3D3B fromCharCache[c] :=3D3D3D Text8.New (buf)=3D=<br>>3D3B<br>&nbs=3D<br>>> >> p=3D3D3B&nbsp=3D3D3B=3D3D<br>>> >>>>> &nbsp=3D3D3B END=3D3D3B<br>&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B RET=<br>>URN fromCharCa=3D<br>>> >> che [c]<br>&nb=3D3D<br>>>
 >>>>> sp=3D3D3B END FromChar=3D3D3B<br><br><br>It should be:<br><br><br>P=<br>>ROCEDURE=3D<br>>> >> FromCha=3D3D<br>>> >>>>> r (c: CHAR): T =3D3D3D<br>=3D3D0A=3D3D<br>>> >>>>> &nbsp=3D3D3B VAR buf: ARRAY [0..0] OF CHAR=3D3D3B<br>=3D3D0A=3D3D<br>>> >>>>> &nbsp=3D3D3B BEGIN<br>=3D3D0A=3D3D<br>>> >>>>> &nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B IF fromCharCache [c] =3D3D3D N=<br>>IL THEN<br>=3D<br>>> >> =3D3D0A=3D3D<br>>> >>>>> &nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B buf [0=<br>>] :=3D3D3D c=3D3D3=3D<br>>> >> B<br>=3D3D0A=3D3D<br>>> >>>>> &nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B WITH a=<br>> =3D3D3D
 Text8.N=3D<br>>> >> ew (buf) DO<br>&=3D3D<br>>> >>>>> nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D=<br>>3D3B&nbsp=3D3D3B M=3D<br>>> >> emoryBarrier()=3D3D3B<=3D3D<br>>> >>>>> br>&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbs=<br>>p=3D3D3B&nbsp=3D3D=3D<br>>> >> 3B fromCharCache[c=3D3D<br>>> >>>>> ] :=3D3D3D a=3D3D3B<br>&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D=<br>>3D3B END=3D3D3B<br=3D<br>>> >>> =3D3D0A=3D3D<br>>> >>>>> &nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B END=3D3D3B<br>=3D3D0A=3D3D<br>>> >>>>> &nbsp=3D3D3B&nbsp=3D3D3B&nbsp=3D3D3B RETURN fromCharCache [c]<br>=<br>>=3D3D0A=3D3D<br>>> >>>>>
 &nbsp=3D3D3B END FromChar=3D3D3B<br>=3D3D0A=3D3D<br>>> >>>>> <br><br>to ensure that all of Text8.New() finishes before the assig=<br>>nmen=3D<br>>> >> t to=3D3D<br>>> >>>>> fromCharCache[c] is made.<br><br><br>Can the compiler somehow catch=<br>> th=3D<br>>> >> ese?=3D3D<br>>> >>>>> <br>I fear they are a small epidemic.<br>For a long time people did=<br>>n't =3D<br>>> >> real=3D3D<br>>> >>>>> ize where all the compiler and processor could reorder.<br><br><br>=<br>>Do w=3D<br>>> >> e ha=3D3D<br>>> >>>>> ve the right constructs by now to fix them?<br>I think we do.<br><b=<br>>r><b=3D<br>>> >> r> -=3D3D<br>>> >>>>> Jay<br>         
                </div></body><br>>> >>>>> </html>=3D3D<br>>> >>>>>=20<br>>> >>>>> --_5f23896e-68ee-44da-82dd-311cd8c58979_--<br>>> >>                         =3D<br>>> >>=20<br>>> >> --_86f22d85-5540-4565-bf73-232aaafdc94b_<br>>> >> Content-Type: text/html=3B charset=3D"iso-8859-1"<br>>> >> Content-Transfer-Encoding: quoted-printable<br>>> >>=20<br>>> >> <html><br>>> >> <head><br>>> >> <style><!--<br>>> >> .hmmessage P<br>>> >> {<br>>> >> margin:0px=3D3B<br>>> >> padding:0px<br>>> >> }<br>>> >> body.hmmessage<br>>> >> {<br>>> >> font-size:
 12pt=3D3B<br>>> >> font-family:Calibri<br>>> >> }<br>>> >> --></style></head><br>>> >> <body class=3D3D'hmmessage'><div dir=3D3D'ltr'>The processor can reord=<br>>er. Acros=3D<br>>> >> s call/ret at least in general.<br><br><br>The compiler can also reord=<br>>er=3D2C=3D<br>>> >> if you have whole-program-optimization=3D2C link-time-code-gen (Micros=<br>>oft "L=3D<br>>> >> TCG")=3D2C link-time-optimization (gcc "LTO"). (We don't=3D2C but real=<br>> world sy=3D<br>>> >> stems certainly do.)<br><br><br>&nbsp=3D3B- Jay<br><br><br><div><div i=<br>>d=3D3D"Sk=3D<br>>> >> yDrivePlaceholder"></div>&gt=3D3B To: <a ymailto="mailto:jay.krell@cornell.edu" href="/mc/compose?to=jay.krell@cornell.edu">jay.krell@cornell.edu</a>=3D3B
 m3dev=<br>>el@elegos=3D<br>>> >> oft.com=3D3B <a ymailto="mailto:mika@async.caltech.edu" href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a><br>&gt=3D3B Subject: Re: [M3devel]=<br>> race con=3D<br>>> >> ditions in lock-free code...<br>&gt=3D3B Date: Sun=3D2C 26 Aug 2012 22=<br>>:32:48 -0=3D<br>>> >> 700<br>&gt=3D3B From: <a ymailto="mailto:mika@async.caltech.edu" href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a><br>&gt=3D3B <br>&gt=3D3B =<br>>Sorry=3D2C I =3D<br>>> >> can't seem to quote your message.<br>&gt=3D3B <br>&gt=3D3B You say tha=<br>>t Text8.N=3D<br>>> >> ew's result can be assigned to fromCharCache[c]<br>&gt=3D3B before Tex=<br>>t8.New =3D<br>>> >> is done running.  How is that possible?  Surely<br>&gt=3D3B
 Text8.New =<br>>has to =3D<br>>> >> calculate its result before it can be assigned<br>&gt=3D3B anywhere.  =<br>>Yes pos=3D<br>>> >> sibly FromChar allocates space for the result of<br>&gt=3D3B Text8.New=<br>> but th=3D<br>>> >> e assignment of whatever appears in that space can't<br>&gt=3D3B happe=<br>>n until=3D<br>>> >> *after* Text8.New has run.  Unless you are saying that<br>&gt=3D3B the=<br>> runni=3D<br>>> >> ng of Text8.New and FromChar are intertwined somehow..?<br>&gt=3D3B I =<br>>know co=3D<br>>> >> mpilers do some odd things but that doesn't sound right...<br>&gt=3D3B=<br>> <br>&g=3D<br>>> >> t=3D3B If Text8.New took fromCharCache[c] as a VAR parameter you might=<br>> be<br>=3D<br>>> >> &gt=3D3B right=3D2C though.  But it
 doesn't...<br>&gt=3D3B <br>&gt=3D3=<br>>B Am I missin=3D<br>>> >> g something?<br>&gt=3D3B <br>&gt=3D3B      Mika<br>&gt=3D3B <br>&gt=3D=<br>>3B Mika Nystr=3D<br>>> >> om writes:<br>&gt=3D3B &gt=3D3B<br>&gt=3D3B &gt=3D3BYeah it's a race c=<br>>ondition=3D2C i=3D<br>>> >> n theory.  But is it important?  If you get<br>&gt=3D3B &gt=3D3Bthe wr=<br>>ong copy=3D<br>>> >> =3D2C there will be two TEXTs representing one CHAR.  But no<br>&gt=3D=<br>>3B &gt=3D3B=3D<br>>> >> one ever said FromChar was guaranteed to return the same pointer when<=<br>>br>&g=3D<br>>> >> t=3D3B &gt=3D3Byou call it with the same CHAR...<br>&gt=3D3B &gt=3D3B<=<br>>br>&gt=3D3B &gt=3D<br>>> >>
 =3D3B     Mika<br>&gt=3D3B &gt=3D3B<br>&gt=3D3B &gt=3D3BJay K writes:<=<br>>br>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3B--_5f23896e-68ee-44da-82dd-311cd8c58979_<br>&gt=3D3B &gt=<br>>=3D3B&gt=3D3BCon=3D<br>>> >> tent-Type: text/plain=3D3B charset=3D3D"iso-8859-1"<br>&gt=3D3B &gt=3D=<br>>3B&gt=3D3BConte=3D<br>>> >> nt-Transfer-Encoding: quoted-printable<br>&gt=3D3B &gt=3D3B&gt=3D3B<br=<br>>>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3BWe have race conditions=3D3D2C like this=3D3D2C m3core/sr=<br>>c/Text.m3:<br=3D<br>>> >>> &gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &g=<br>>t=3D3B&gt=3D3BVAR fromC=3D<br>>> >> harCache :=3D3D3D ARRAY CHAR OF T {NIL=3D3D2C ..}=3D3D3B
 (* 1-char tex=<br>>ts *)<br>&g=3D<br>>> >> t=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=<br>>=3D3B&gt=3D3BPROCEDURE Fr=3D<br>>> >> omChar (c: CHAR): T =3D3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B  VAR buf: ARR=<br>>AY [0..0] OF =3D<br>>> >> CHAR=3D3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B  BEGIN<br>&gt=3D3B &gt=3D3B&g=<br>>t=3D3B    IF fromCh=3D<br>>> >> arCache [c] =3D3D3D NIL THEN<br>&gt=3D3B &gt=3D3B&gt=3D3B      buf [0]=<br>> :=3D3D3D c=3D3D3=3D<br>>> >> B<br>&gt=3D3B &gt=3D3B&gt=3D3B      fromCharCache[c] :=3D3D3D Text8.Ne=<br>>w (buf)=3D3D3B<=3D<br>>> >> br>&gt=3D3B &gt=3D3B&gt=3D3B    END=3D3D3B<br>&gt=3D3B
 &gt=3D3B&gt=3D3=<br>>B    RETURN fromCha=3D<br>>> >> rCache [c]<br>&gt=3D3B &gt=3D3B&gt=3D3B  END FromChar=3D3D3B<br>&gt=3D=<br>>3B &gt=3D3B&gt=3D3B=3D<br>>> >> <br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3BIt should be=<br>>:<br>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3=<br>>BPROCEDURE FromChar (=3D<br>>> >> c: CHAR): T =3D3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B=3D3D0A=3D3D<br>&gt=3D=<br>>3B &gt=3D3B&gt=3D3B  VA=3D<br>>> >> R buf: ARRAY [0..0] OF CHAR=3D3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B=3D3D0A=<br>>=3D3D<br>&gt=3D3B &=3D<br>>> >> gt=3D3B&gt=3D3B  BEGIN<br>&gt=3D3B
 &gt=3D3B&gt=3D3B=3D3D0A=3D3D<br>&gt=<br>>=3D3B &gt=3D3B&gt=3D3B   =3D<br>>> >> IF fromCharCache [c] =3D3D3D NIL THEN<br>&gt=3D3B &gt=3D3B&gt=3D3B=3D3=<br>>D0A=3D3D<br>&gt=3D<br>>> >> =3D3B &gt=3D3B&gt=3D3B      buf [0] :=3D3D3D c=3D3D3B<br>&gt=3D3B &gt=<br>>=3D3B&gt=3D3B=3D3D0A=3D3D<=3D<br>>> >> br>&gt=3D3B &gt=3D3B&gt=3D3B      WITH a =3D3D3D Text8.New (buf) DO<br=<br>>>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3B        MemoryBarrier()=3D3D3B<br>&gt=3D3B &gt=3D3B&gt=3D=<br>>3B        fromCha=3D<br>>> >> rCache[c] :=3D3D3D a=3D3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B     END=3D3D3=<br>>B<br>&gt=3D3B &gt=3D<br>>>
 >> =3D3B&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B    END=3D3D3B<b=<br>>r>&gt=3D3B &gt=3D3B&gt=3D3B=3D<br>>> >> =3D3D0A=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B    RETURN fromCharCache [c]<=<br>>br>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B  END FromChar=<br>>=3D3D3B<br>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=<br>>=3D3B&gt=3D3B<br>&gt=3D3B &=3D<br>>> >> gt=3D3B&gt=3D3Bto ensure that all of Text8.New() finishes before the a=<br>>ssignment=3D<br>>> >> to fromCha=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3BrCache[c] is made.<br>&gt=<br>>=3D3B &gt=3D3B&gt=3D<br>>>
 >> =3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3BCan the=<br>> compiler somehow c=3D<br>>> >> atch these?<br>&gt=3D3B &gt=3D3B&gt=3D3BI fear they are a small epidem=<br>>ic.<br>&gt=3D<br>>> >> =3D3B &gt=3D3B&gt=3D3BFor a long time people didn't realize where all =<br>>the compile=3D<br>>> >> r and processor =3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3Bcould reorder.<br>&g=<br>>t=3D3B &gt=3D3B&g=3D<br>>> >> t=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3BDo we =<br>>have the right cons=3D<br>>> >> tructs by now to fix them?<br>&gt=3D3B &gt=3D3B&gt=3D3BI think we do.<=<br>>br>&gt=3D3B &=3D<br>>> >> gt=3D3B&gt=3D3B<br>&gt=3D3B
 &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=<br>>=3D3B - Jay<br>&gt=3D3B &=3D<br>>> >> gt=3D3B&gt=3D3B                         =3D3D<br>&gt=3D3B &gt=3D3B&gt=<br>>=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B--_=3D<br>>> >> 5f23896e-68ee-44da-82dd-311cd8c58979_<br>&gt=3D3B &gt=3D3B&gt=3D3BCont=<br>>ent-Type: t=3D<br>>> >> ext/html=3D3B charset=3D3D"iso-8859-1"<br>&gt=3D3B &gt=3D3B&gt=3D3BCon=<br>>tent-Transfer-E=3D<br>>> >> ncoding: quoted-printable<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=<br>>=3D3B&gt=3D3B&lt=3D<br>>> >> =3D3Bhtml&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B&lt=3D3Bhead&gt=3D3B<br>=<br>>&gt=3D3B
 &gt=3D3B&gt=3D3B=3D<br>>> >> &lt=3D3Bstyle&gt=3D3B&lt=3D3B!--<br>&gt=3D3B &gt=3D3B&gt=3D3B.hmmessag=<br>>e P<br>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3B{<br>&gt=3D3B &gt=3D3B&gt=3D3Bmargin:0px=3D3D3B<br>&gt=3D=<br>>3B &gt=3D3B&gt=3D3Bpadd=3D<br>>> >> ing:0px<br>&gt=3D3B &gt=3D3B&gt=3D3B}<br>&gt=3D3B &gt=3D3B&gt=3D3Bbody=<br>>.hmmessage<br>&gt=3D<br>>> >> =3D3B &gt=3D3B&gt=3D3B{<br>&gt=3D3B &gt=3D3B&gt=3D3Bfont-size: 12pt=3D=<br>>3D3B<br>&gt=3D3B &gt=3D<br>>> >> =3D3B&gt=3D3Bfont-family:Calibri<br>&gt=3D3B &gt=3D3B&gt=3D3B}<br>&gt=<br>>=3D3B &gt=3D3B&gt=3D3B=3D<br>>> >>
 --&gt=3D3B&lt=3D3B/style&gt=3D3B&lt=3D3B/head&gt=3D3B<br>&gt=3D3B &gt=<br>>=3D3B&gt=3D3B&lt=3D3Bbod=3D<br>>> >> y class=3D3D3D'hmmessage'&gt=3D3B&lt=3D3Bdiv dir=3D3D3D'ltr'&gt=3D3BWe=<br>> have race cond=3D<br>>> >> itions=3D3D2C like =3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3Bthis=3D3D2C m3cor=<br>>e/src/Text.m3:&lt=3D<br>>> >> =3D3Bbr&gt=3D3B&lt=3D3Bbr&gt=3D3B&lt=3D3Bbr&gt=3D3BVAR fromCharCache :=<br>>=3D3D3D ARRAY CHAR =3D<br>>> >> OF=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B T {NIL=3D3D2C ..}=3D3D3B (* 1-cha=<br>>r texts *)&lt=3D3Bb=3D<br>>> >> r&gt=3D3B&lt=3D3Bbr&gt=3D3B&lt=3D3Bbr&gt=3D3BPROCEDURE FromChar (c: CH=<br>>AR=3D3D<br>&gt=3D3B=3D<br>>> >> &gt=3D3B&gt=3D3B): T
 =3D3D3D&lt=3D3Bbr&gt=3D3B&amp=3D3Bnbsp=3D3D3B VAR=<br>> buf: ARRAY [0..0]=3D<br>>> >> OF CHAR=3D3D3B&lt=3D3Bbr&gt=3D3B&amp=3D3Bnbsp=3D3D3B BEGIN&lt=3D3Bbr&g=<br>>t=3D3B=3D3D<br>&gt=3D<br>>> >> =3D3B &gt=3D3B&gt=3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3=<br>>Bnbsp=3D3D3B IF fromCha=3D<br>>> >> rCache [c] =3D3D3D NIL THEN&lt=3D3Bbr&gt=3D3B&amp=3D3Bnbsp=3D3D3B&amp=<br>>=3D3Bnbsp=3D3D<br>&g=3D<br>>> >> t=3D3B &gt=3D3B&gt=3D3B=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B=<br>>&amp=3D3Bnbsp=3D3D3B buf =3D<br>>> >> [0] :=3D3D3D c=3D3D3B&lt=3D3Bbr&gt=3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnb=<br>>sp=3D3D3B&amp=3D3Bnbsp=3D<br>>> >> =3D3D3B&amp=3D3Bn=3D3D<br>&gt=3D3B
 &gt=3D3B&gt=3D3Bbsp=3D3D3B&amp=3D3B=<br>>nbsp=3D3D3B fromCharCac=3D<br>>> >> he[c] :=3D3D3D Text8.New (buf)=3D3D3B&lt=3D3Bbr&gt=3D3B&amp=3D3Bnbsp=<br>>=3D3D3B&amp=3D3Bnbsp=3D<br>>> >> =3D3D3B=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B&amp=3D3Bnbsp=3D3D3B END=3D3D=<br>>3B&lt=3D3Bbr&gt=3D3B&amp=3D<br>>> >> =3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B RETURN fromCh=<br>>arCache [c]&lt=3D3B=3D<br>>> >> br&gt=3D3B&amp=3D3Bnb=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3Bsp=3D3D3B END F=<br>>romChar=3D3D3B&lt=3D3Bb=3D<br>>> >> r&gt=3D3B&lt=3D3Bbr&gt=3D3B&lt=3D3Bbr&gt=3D3BIt should be:&lt=3D3Bbr&g=<br>>t=3D3B&lt=3D3Bbr&gt=3D<br>>> >> =3D3B&lt=3D3Bbr&gt=3D3BPROCEDURE FromCha=3D3D<br>&gt=3D3B &gt=3D3B&gt=<br>>=3D3Br
 (c: CHAR): T =3D<br>>> >> =3D3D3D&lt=3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B&amp=<br>>=3D3Bnbsp=3D3D3B VAR buf:=3D<br>>> >> ARRAY [0..0] OF CHAR=3D3D3B&lt=3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B =<br>>&gt=3D3B&gt=3D3B&amp=3D<br>>> >> =3D3Bnbsp=3D3D3B BEGIN&lt=3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=<br>>=3D3B&gt=3D3B&amp=3D3Bnbsp=3D<br>>> >> =3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B IF fromCharCache [c] =<br>>=3D3D3D NIL THEN&l=3D<br>>> >> t=3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B&amp=3D3Bnbsp=<br>>=3D3D3B&amp=3D3Bnbsp=3D3D3B=3D<br>>> >> &amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B buf [0] :=<br>>=3D3D3D c=3D3D3B&lt=3D<br>>> >>
 =3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B&amp=3D3Bnbsp=<br>>=3D3D3B&amp=3D3Bnbsp=3D3D3B&=3D<br>>> >> amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B WITH a =3D=<br>>3D3D Text8.New (buf=3D<br>>> >> ) DO&lt=3D3Bbr&gt=3D3B&amp=3D3B=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3Bnbsp=<br>>=3D3D3B&amp=3D3Bnbsp=3D3D3=3D<br>>> >> B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3B=<br>>nbsp=3D3D3B&amp=3D3Bnbs=3D<br>>> >> p=3D3D3B MemoryBarrier()=3D3D3B&lt=3D3B=3D3D<br>&gt=3D3B &gt=3D3B&gt=<br>>=3D3Bbr&gt=3D3B&amp=3D3Bn=3D<br>>> >> bsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B=<br>>&amp=3D3Bnbsp=3D3D3B&am=3D<br>>> >> p=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B
 fromCharCache[c=3D3D<br>&gt=3D3B=<br>> &gt=3D3B&gt=3D3B] :=3D<br>>> >> =3D3D3D a=3D3D3B&lt=3D3Bbr&gt=3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D=<br>>3D3B&amp=3D3Bnbsp=3D3D3B&=3D<br>>> >> amp=3D3Bnbsp=3D3D3B END=3D3D3B&lt=3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D=<br>>3B &gt=3D3B&gt=3D3B&amp=3D<br>>> >> =3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B END=3D3D3B&lt=<br>>=3D3Bbr&gt=3D3B=3D3D0A=3D3D=3D<br>>> >> <br>&gt=3D3B &gt=3D3B&gt=3D3B&amp=3D3Bnbsp=3D3D3B&amp=3D3Bnbsp=3D3D3B&=<br>>amp=3D3Bnbsp=3D3D3B RET=3D<br>>> >> URN fromCharCache [c]&lt=3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3B &gt=3D=<br>>3B&gt=3D3B&amp=3D3Bnb=3D<br>>> >> sp=3D3D3B END
 FromChar=3D3D3B&lt=3D3Bbr&gt=3D3B=3D3D0A=3D3D<br>&gt=3D3=<br>>B &gt=3D3B&gt=3D3B&lt=3D<br>>> >> =3D3Bbr&gt=3D3B&lt=3D3Bbr&gt=3D3Bto ensure that all of Text8.New() fin=<br>>ishes before =3D<br>>> >> the assignment to=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B fromCharCache[c] i=<br>>s made.&lt=3D3B=3D<br>>> >> br&gt=3D3B&lt=3D3Bbr&gt=3D3B&lt=3D3Bbr&gt=3D3BCan the compiler somehow=<br>> catch these?=3D<br>>> >> =3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B&lt=3D3Bbr&gt=3D3BI fear they are a =<br>>small epidemic.&l=3D<br>>> >> t=3D3Bbr&gt=3D3BFor a long time people didn't real=3D3D<br>&gt=3D3B &g=<br>>t=3D3B&gt=3D3Bize=3D<br>>> >> where all the compiler and processor could reorder.&lt=3D3Bbr&gt=3D3B&=<br>>lt=3D3Bbr&=3D<br>>>
 >> gt=3D3B&lt=3D3Bbr&gt=3D3BDo we ha=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3Bve =<br>>the right construct=3D<br>>> >> s by now to fix them?&lt=3D3Bbr&gt=3D3BI think we do.&lt=3D3Bbr&gt=3D3=<br>>B&lt=3D3Bbr&gt=3D<br>>> >> =3D3B&lt=3D3Bbr&gt=3D3B -=3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B Jay&lt=3D3=<br>>Bbr&gt=3D3B                         =3D<br>>> >> &lt=3D3B/div&gt=3D3B&lt=3D3B/body&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B=<br>>&lt=3D3B/html&gt=3D3B=3D<br>>> >> =3D3D<br>&gt=3D3B &gt=3D3B&gt=3D3B<br>&gt=3D3B &gt=3D3B&gt=3D3B--_5f23=<br>>896e-68ee-44da-82dd=3D<br>>> >> -311cd8c58979_--<br></div>               
          </div></body><br>>> >> </html>=3D<br>>> >>=20<br>>> >> --_86f22d85-5540-4565-bf73-232aaafdc94b_--<br>>                           =<br>><br>>--_5c33c9ca-3a7d-4c39-ab66-ab9c151d1539_<br>>Content-Type: text/html; charset="iso-8859-1"<br>>Content-Transfer-Encoding: quoted-printable<br>><br>><html><br>><head><br>><style><!--<br>>.hmmessage P<br>>{<br>>margin:0px=3B<br>>padding:0px<br>>}<br>>body.hmmessage<br>>{<br>>font-size: 12pt=3B<br>>font-family:Calibri<br>>}<br>>--></style></head><br>><body class=3D'hmmessage'><div dir=3D'ltr'>It is NOT benign.<br>The global =<br>>can be written before the initialization of what it points to is
 done.<br>T=<br>>he result is wrong.<br><br><br>It IS benign if multiple threads go and allo=<br>>cate separate multiple initialized TEXTs.<br>That's not the problem.<br><br=<br>>><br>&nbsp=3B- Jay<br><br><br><div><div id=3D"SkyDrivePlaceholder"></div>&g=<br>>t=3B CC: <a ymailto="mailto:jay.krell@cornell.edu" href="/mc/compose?to=jay.krell@cornell.edu">jay.krell@cornell.edu</a>=3B <a ymailto="mailto:m3devel@elegosoft.com" href="/mc/compose?to=m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>&gt=3B From: hos=<br>><a ymailto="mailto:king@cs.purdue.edu" href="/mc/compose?to=king@cs.purdue.edu">king@cs.purdue.edu</a><br>&gt=3B Subject: Re: [M3devel] race conditions in lock=<br>>-free code...<br>&gt=3B Date: Mon=2C 27 Aug 2012 09:27:38 -0400<br>&gt=3B T=<br>>o: <a ymailto="mailto:mika@async.caltech.edu"
 href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a><br>&gt=3B <br>&gt=3B So why is this anything othe=<br>>r than benign? It's a cache and there's no problem if different threads get=<br>> different texts. Don't cripple performance unnecessarily.  The collector w=<br>>ill reclaim any unreachable text.<br>&gt=3B <br>&gt=3B Sent from my iPad<br=<br>>>&gt=3B <br>&gt=3B On Aug 27=2C 2012=2C at 3:17 AM=2C Mika Nystrom &lt=3Bmi=<br>><a ymailto="mailto:ka@async.caltech.edu" href="/mc/compose?to=ka@async.caltech.edu">ka@async.caltech.edu</a>&gt=3B wrote:<br>&gt=3B <br>&gt=3B &gt=3B Oh I see now.=<br>><br>&gt=3B &gt=3B <br>&gt=3B &gt=3B It's not that the processor reorders in=<br>> any tricky way.  It is that the<br>&gt=3B &gt=3B write performed by Text8.=<br>>New could be
 sitting around processor 1's cache<br>&gt=3B &gt=3B indefinite=<br>>ly without actually getting written back to main memory.<br>&gt=3B &gt=3B P=<br>>rocessor 2 might see the new pointer=2C but when reading the memory pointed=<br>><br>&gt=3B &gt=3B to=2C would get uninitialized memory.  I think this can h=<br>>appen on Alpha but<br>&gt=3B &gt=3B maybe not X86 (without further reorderi=<br>>ngs anyhow)?<br>&gt=3B &gt=3B <br>&gt=3B &gt=3B Any chance any of the pthre=<br>>ads bugs could be of this nature?  How are the<br>&gt=3B &gt=3B pthreads do=<br>>ing?  I gathered some bugs were fixed but I haven't tried the<br>&gt=3B &gt=<br>>=3B system for a while.<br>&gt=3B &gt=3B <br>&gt=3B &gt=3B     Mika<br>&gt=<br>>=3B &gt=3B <br>&gt=3B
 &gt=3B <br>&gt=3B &gt=3B Jay K writes:<br>&gt=3B &gt=<br>>=3B&gt=3B --_86f22d85-5540-4565-bf73-232aaafdc94b_<br>&gt=3B &gt=3B&gt=3B C=<br>>ontent-Type: text/plain=3B charset=3D"iso-8859-1"<br>&gt=3B &gt=3B&gt=3B Co=<br>>ntent-Transfer-Encoding: quoted-printable<br>&gt=3B &gt=3B&gt=3B <br>&gt=3B=<br>> &gt=3B&gt=3B The processor can reorder. Across call/ret at least in genera=<br>>l.<br>&gt=3B &gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B T=<br>>he compiler can also reorder=3D2C if you have whole-program-optimization=3D=<br>>2C =3D<br>&gt=3B &gt=3B&gt=3B link-time-code-gen (Microsoft "LTCG")=3D2C li=<br>>nk-time-optimization (gcc "LTO")=3D<br>&gt=3B &gt=3B&gt=3B . (We don't=3D2C=<br>> but real world systems certainly
 do.)<br>&gt=3B &gt=3B&gt=3B <br>&gt=3B &g=<br>>t=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B - Jay<br>&gt=3B &gt=3B&gt=3B <br>&gt=3B =<br>>&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B To: <a ymailto="mailto:jay.krell@cornell.edu" href="/mc/compose?to=jay.krell@cornell.edu">jay.krell@cornell.edu</a>=3D3B m=<br>><a ymailto="mailto:3devel@elegosoft.com" href="/mc/compose?to=3devel@elegosoft.com">3devel@elegosoft.com</a>=3D3B <a ymailto="mailto:mika@async.caltech" href="/mc/compose?to=mika@async.caltech">mika@async.caltech</a>.=3D<br>&gt=3B &gt=3B&gt=3B edu=<br>><br>&gt=3B &gt=3B&gt=3B&gt=3B Subject: Re: [M3devel] race conditions in loc=<br>>k-free code...<br>&gt=3B &gt=3B&gt=3B&gt=3B Date: Sun=3D2C 26 Aug 2012 22:3=<br>>2:48 -0700<br>&gt=3B &gt=3B&gt=3B&gt=3B
 From: <a ymailto="mailto:mika@async.caltech.edu" href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a><br>&gt=<br>>=3B &gt=3B&gt=3B&gt=3B =3D20<br>&gt=3B &gt=3B&gt=3B&gt=3B Sorry=3D2C I can'=<br>>t seem to quote your message.<br>&gt=3B &gt=3B&gt=3B&gt=3B =3D20<br>&gt=3B =<br>>&gt=3B&gt=3B&gt=3B You say that Text8.New's result can be assigned to fromC=<br>>harCache[c]<br>&gt=3B &gt=3B&gt=3B&gt=3B before Text8.New is done running. =<br>> How is that possible?  Surely<br>&gt=3B &gt=3B&gt=3B&gt=3B Text8.New has t=<br>>o calculate its result before it can be assigned<br>&gt=3B &gt=3B&gt=3B&gt=<br>>=3B anywhere.  Yes possibly FromChar allocates space for the result of<br>&=<br>>gt=3B &gt=3B&gt=3B&gt=3B Text8.New but the assignment of
 whatever appears i=<br>>n that space can't<br>&gt=3B &gt=3B&gt=3B&gt=3B happen until *after* Text8.=<br>>New has run.  Unless you are saying that<br>&gt=3B &gt=3B&gt=3B&gt=3B the r=<br>>unning of Text8.New and FromChar are intertwined somehow..?<br>&gt=3B &gt=<br>>=3B&gt=3B&gt=3B I know compilers do some odd things but that doesn't sound =<br>>right...<br>&gt=3B &gt=3B&gt=3B&gt=3B =3D20<br>&gt=3B &gt=3B&gt=3B&gt=3B If=<br>> Text8.New took fromCharCache[c] as a VAR parameter you might be<br>&gt=3B =<br>>&gt=3B&gt=3B&gt=3B right=3D2C though.  But it doesn't...<br>&gt=3B &gt=3B&g=<br>>t=3B&gt=3B =3D20<br>&gt=3B &gt=3B&gt=3B&gt=3B Am I missing something?<br>&g=<br>>t=3B &gt=3B&gt=3B&gt=3B =3D20<br>&gt=3B
 &gt=3B&gt=3B&gt=3B     Mika<br>&gt=<br>>=3B &gt=3B&gt=3B&gt=3B =3D20<br>&gt=3B &gt=3B&gt=3B&gt=3B Mika Nystrom writ=<br>>es:<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B =<br>>Yeah it's a race condition=3D2C in theory.  But is it important?  If you g=<br>>=3D<br>&gt=3B &gt=3B&gt=3B et<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B the wrong =<br>>copy=3D2C there will be two TEXTs representing one CHAR.  But no<br>&gt=3B =<br>>&gt=3B&gt=3B&gt=3B&gt=3B one ever said FromChar was guaranteed to return th=<br>>e same pointer when<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B you call it with the=<br>> same CHAR...<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B
 &gt=3B&gt=3B&gt=<br>>=3B&gt=3B    Mika<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=<br>>=3B&gt=3B&gt=3B Jay K writes:<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B --_5=<br>>f23896e-68ee-44da-82dd-311cd8c58979_<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=<br>>=3B Content-Type: text/plain=3D3B charset=3D3D"iso-8859-1"<br>&gt=3B &gt=3B=<br>>&gt=3B&gt=3B&gt=3B&gt=3B Content-Transfer-Encoding: quoted-printable<br>&gt=<br>>=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=<br>>=3B We have race conditions=3D3D2C like this=3D3D2C m3core/src/Text.m3:<br>=<br>>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B
 &gt=3B&gt=3B&gt=3B&gt=3B&g=<br>>t=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B VAR fromCharCache :=3D3D3D A=<br>>RRAY CHAR OF T {NIL=3D3D2C ..}=3D3D3B (* 1-char t=3D<br>&gt=3B &gt=3B&gt=3B=<br>> exts *)<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&g=<br>>t=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B PROCEDURE FromCh=<br>>ar (c: CHAR): T =3D3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B VAR buf: A=<br>>RRAY [0..0] OF CHAR=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B BEGIN<b=<br>>r>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B   IF fromCharCache [c] =3D3D3D NIL =<br>>THEN<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B 
    buf [0] :=3D3D3D c=3D3D3B=<br>><br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B     fromCharCache[c] :=3D3D3D Tex=<br>>t8.New (buf)=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B   END=3D3D3B<b=<br>>r>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B   RETURN fromCharCache [c]<br>&gt=<br>>=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B END FromChar=3D3D3B<br>&gt=3B &gt=3B&gt=<br>>=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B =<br>>&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B It should be:<br>&gt=3B &gt=3B&gt=3B&gt=3B&g=<br>>t=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B
 &gt=3B&gt=<br>>=3B&gt=3B&gt=3B&gt=3B PROCEDURE FromChar (c: CHAR): T =3D3D3D<br>&gt=3B &gt=<br>>=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B=<br>>&gt=3B VAR buf: ARRAY [0..0] OF CHAR=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=<br>>=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B BEGIN<br>&g=<br>>t=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=<br>>=3B&gt=3B&gt=3B   IF fromCharCache [c] =3D3D3D NIL THEN<br>&gt=3B &gt=3B&gt=<br>>=3B&gt=3B&gt=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=<br>>     buf [0] :=3D3D3D c=3D3D3B<br>&gt=3B
 &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D=<br>>3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B     WITH a =3D3D3D Text8=<br>>.New (buf) DO<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B       MemoryBarrier(=<br>>)=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B       fromCharCache[c] :=<br>>=3D3D3D a=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B    END=3D3D3B<br>=<br>>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&g=<br>>t=3B&gt=3B&gt=3B   END=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D3=<br>>D0A=3D3D<br>&gt=3B
 &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B   RETURN fromCharCache [c=<br>>]<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=<br>>=3B&gt=3B&gt=3B&gt=3B END FromChar=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=<br>>=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B =<br>>&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B to=<br>> ensure that all of Text8.New() finishes before the assignment to fro=3D<br=<br>>>&gt=3B &gt=3B&gt=3B mCha=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B rCa=<br>>che[c] is made.<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B
 &gt=3B&=<br>>gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Can the c=<br>>ompiler somehow catch these?<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B I fea=<br>>r they are a small epidemic.<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B For a=<br>> long time people didn't realize where all the compiler and proces=3D<br>&g=<br>>t=3B &gt=3B&gt=3B sor =3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B could =<br>>reorder.<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&g=<br>>t=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Do we have the r=<br>>ight constructs by now to fix them?<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=<br>>=3B
 I think we do.<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=<br>>=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B - Jay=<br>><br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B                         =3D3D<br>=<br>>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&g=<br>>t=3B --_5f23896e-68ee-44da-82dd-311cd8c58979_<br>&gt=3B &gt=3B&gt=3B&gt=3B&=<br>>gt=3B&gt=3B Content-Type: text/html=3D3B charset=3D3D"iso-8859-1"<br>&gt=3B=<br>> &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Content-Transfer-Encoding: quoted-printable=<br>><br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B
 <br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=<br>>=3B&gt=3B &lt=3Bhtml&gt=3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3Bh=<br>>ead&gt=3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3Bstyle&gt=3B&lt=3B!=<br>>--<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B .hmmessage P<br>&gt=3B &gt=3B&g=<br>>t=3B&gt=3B&gt=3B&gt=3B {<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B margin:0p=<br>>x=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B padding:0px<br>&gt=3B &gt=<br>>=3B&gt=3B&gt=3B&gt=3B&gt=3B }<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B body=<br>>.hmmessage<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B {<br>&gt=3B
 &gt=3B&gt=<br>>=3B&gt=3B&gt=3B&gt=3B font-size: 12pt=3D3D3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&g=<br>>t=3B&gt=3B font-family:Calibri<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B }<b=<br>>r>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B --&gt=3B&lt=3B/style&gt=3B&lt=3B/he=<br>>ad&gt=3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3Bbody class=3D3D3D'h=<br>>mmessage'&gt=3B&lt=3Bdiv dir=3D3D3D'ltr'&gt=3BWe have race conditions=3D<br=<br>>>&gt=3B &gt=3B&gt=3B =3D3D2C like =3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&=<br>>gt=3B this=3D3D2C m3core/src/Text.m3:&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3Bbr&g=<br>>t=3BVAR fromCharCache :=3D3D3D ARRAY=3D<br>&gt=3B &gt=3B&gt=3B CHAR
 OF=3D3D=<br>><br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B T {NIL=3D3D2C ..}=3D3D3B (* 1-cha=<br>>r texts *)&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3Bbr&gt=3BPROCEDURE FromChar =3D<=<br>>br>&gt=3B &gt=3B&gt=3B (c: CHAR=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=<br>>=3B ): T =3D3D3D&lt=3Bbr&gt=3B&amp=3Bnbsp=3D3D3B VAR buf: ARRAY [0..0] OF C=<br>>HAR=3D3D3B&lt=3Bbr&gt=3B&amp=3Bnbsp=3D3D=3D<br>&gt=3B &gt=3B&gt=3B 3B BEGIN=<br>>&lt=3Bbr&gt=3B=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bnbsp=3D=<br>>3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B IF fromCharCache [c] =3D3D3D NIL T=<br>>HEN&lt=3Bbr&gt=3B&amp=3B=3D<br>&gt=3B &gt=3B&gt=3B nbsp=3D3D3B&amp=3Bnbsp=<br>>=3D3D<br>&gt=3B
 &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B =3D3D3B&amp=3Bnbsp=3D3D3B&am=<br>>p=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B buf [0] :=3D3D3D c=3D3D3B&lt=3Bbr&gt=3B&a=<br>>mp=3Bnbsp=3D3D3B=3D<br>&gt=3B &gt=3B&gt=3B &amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D=<br>>3D3B&amp=3Bn=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B bsp=3D3D3B&amp=<br>>=3Bnbsp=3D3D3B fromCharCache[c] :=3D3D3D Text8.New (buf)=3D3D3B&lt=3Bbr&gt=<br>>=3B&amp=3Bnbs=3D<br>&gt=3B &gt=3B&gt=3B p=3D3D3B&amp=3Bnbsp=3D3D3B=3D3D<br>=<br>>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bnbsp=3D3D3B END=3D3D3B&lt=3Bbr=<br>>&gt=3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B RETURN fromCha=<br>>rCa=3D<br>&gt=3B &gt=3B&gt=3B che
 [c]&lt=3Bbr&gt=3B&amp=3Bnb=3D3D<br>&gt=3B=<br>> &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B sp=3D3D3B END FromChar=3D3D3B&lt=3Bbr&gt=3B=<br>>&lt=3Bbr&gt=3B&lt=3Bbr&gt=3BIt should be:&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3B=<br>>br&gt=3BPROCEDURE=3D<br>&gt=3B &gt=3B&gt=3B FromCha=3D3D<br>&gt=3B &gt=3B&g=<br>>t=3B&gt=3B&gt=3B&gt=3B r (c: CHAR): T =3D3D3D&lt=3Bbr&gt=3B=3D3D0A=3D3D<br>=<br>>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bnbsp=3D3D3B VAR buf: ARRAY [0.=<br>>.0] OF CHAR=3D3D3B&lt=3Bbr&gt=3B=3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&g=<br>>t=3B&gt=3B &amp=3Bnbsp=3D3D3B BEGIN&lt=3Bbr&gt=3B=3D3D0A=3D3D<br>&gt=3B &gt=<br>>=3B&gt=3B&gt=3B&gt=3B&gt=3B
 &amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=<br>>=3D3D3B IF fromCharCache [c] =3D3D3D NIL THEN&lt=3Bbr&gt=3B=3D<br>&gt=3B &g=<br>>t=3B&gt=3B =3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bnbs=<br>>p=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=<br>>=3D3D3B buf [0] :=3D3D3D c=3D3D3=3D<br>&gt=3B &gt=3B&gt=3B B&lt=3Bbr&gt=3B=<br>>=3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bnbsp=3D3D3B&am=<br>>p=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B WITH =<br>>a =3D3D3D Text8.N=3D<br>&gt=3B &gt=3B&gt=3B ew (buf) DO&lt=3Bbr&gt=3B&amp=<br>>=3B=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B
 nbsp=3D3D3B&amp=3Bnbsp=3D=<br>>3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3=<br>>B&amp=3Bnbsp=3D3D3B M=3D<br>&gt=3B &gt=3B&gt=3B emoryBarrier()=3D3D3B&lt=3B=<br>>=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B br&gt=3B&amp=3Bnbsp=3D3D3B&a=<br>>mp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=<br>>=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D=3D<br>&gt=3B &gt=3B&gt=3B 3B fromCharCache[c=<br>>=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B ] :=3D3D3D a=3D3D3B&lt=3Bbr&=<br>>gt=3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D=<br>>3B END=3D3D3B&lt=3Bbr=3D<br>&gt=3B &gt=3B&gt=3B&gt=3B =3D3D0A=3D3D<br>&gt=<br>>=3B
 &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=<br>>=3Bnbsp=3D3D3B END=3D3D3B&lt=3Bbr&gt=3B=3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&=<br>>gt=3B&gt=3B&gt=3B &amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B&amp=3Bnbsp=3D3D3B RE=<br>>TURN fromCharCache [c]&lt=3Bbr&gt=3B=3D3D0A=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=<br>>=3B&gt=3B&gt=3B &amp=3Bnbsp=3D3D3B END FromChar=3D3D3B&lt=3Bbr&gt=3B=3D3D0A=<br>>=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B &lt=3Bbr&gt=3B&lt=3Bbr&gt=3B=<br>>to ensure that all of Text8.New() finishes before the assignmen=3D<br>&gt=<br>>=3B &gt=3B&gt=3B t to=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B fromCha=<br>>rCache[c] is
 made.&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3Bbr&gt=3BCan the compile=<br>>r somehow catch th=3D<br>&gt=3B &gt=3B&gt=3B ese?=3D3D<br>&gt=3B &gt=3B&gt=<br>>=3B&gt=3B&gt=3B&gt=3B &lt=3Bbr&gt=3BI fear they are a small epidemic.&lt=3B=<br>>br&gt=3BFor a long time people didn't =3D<br>&gt=3B &gt=3B&gt=3B real=3D3D<=<br>>br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B ize where all the compiler and pro=<br>>cessor could reorder.&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3Bbr&gt=3BDo w=3D<br>&=<br>>gt=3B &gt=3B&gt=3B e ha=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B ve th=<br>>e right constructs by now to fix them?&lt=3Bbr&gt=3BI think we do.&lt=3Bbr&=<br>>gt=3B&lt=3Bbr&gt=3B&lt=3Bb=3D<br>&gt=3B &gt=3B&gt=3B
 r&gt=3B -=3D3D<br>&gt=<br>>=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Jay&lt=3Bbr&gt=3B                       =<br>>  &lt=3B/div&gt=3B&lt=3B/body&gt=3B<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=<br>>=3B &lt=3B/html&gt=3B=3D3D<br>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B <br>&gt=<br>>=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B --_5f23896e-68ee-44da-82dd-311cd8c58979_=<br>>--<br>&gt=3B &gt=3B&gt=3B                         =3D<br>&gt=3B &gt=3B&gt=<br>>=3B <br>&gt=3B &gt=3B&gt=3B --_86f22d85-5540-4565-bf73-232aaafdc94b_<br>&gt=<br>>=3B &gt=3B&gt=3B Content-Type: text/html=3B
 charset=3D"iso-8859-1"<br>&gt=<br>>=3B &gt=3B&gt=3B Content-Transfer-Encoding: quoted-printable<br>&gt=3B &gt=<br>>=3B&gt=3B <br>&gt=3B &gt=3B&gt=3B &lt=3Bhtml&gt=3B<br>&gt=3B &gt=3B&gt=3B &=<br>>lt=3Bhead&gt=3B<br>&gt=3B &gt=3B&gt=3B &lt=3Bstyle&gt=3B&lt=3B!--<br>&gt=3B=<br>> &gt=3B&gt=3B .hmmessage P<br>&gt=3B &gt=3B&gt=3B {<br>&gt=3B &gt=3B&gt=3B =<br>>margin:0px=3D3B<br>&gt=3B &gt=3B&gt=3B padding:0px<br>&gt=3B &gt=3B&gt=3B }=<br>><br>&gt=3B &gt=3B&gt=3B body.hmmessage<br>&gt=3B &gt=3B&gt=3B {<br>&gt=3B &=<br>>gt=3B&gt=3B font-size: 12pt=3D3B<br>&gt=3B &gt=3B&gt=3B font-family:Calibri=<br>><br>&gt=3B &gt=3B&gt=3B
 }<br>&gt=3B &gt=3B&gt=3B --&gt=3B&lt=3B/style&gt=3B=<br>>&lt=3B/head&gt=3B<br>&gt=3B &gt=3B&gt=3B &lt=3Bbody class=3D3D'hmmessage'&g=<br>>t=3B&lt=3Bdiv dir=3D3D'ltr'&gt=3BThe processor can reorder. Acros=3D<br>&gt=<br>>=3B &gt=3B&gt=3B s call/ret at least in general.&lt=3Bbr&gt=3B&lt=3Bbr&gt=<br>>=3B&lt=3Bbr&gt=3BThe compiler can also reorder=3D2C=3D<br>&gt=3B &gt=3B&gt=<br>>=3B if you have whole-program-optimization=3D2C link-time-code-gen (Microso=<br>>ft "L=3D<br>&gt=3B &gt=3B&gt=3B TCG")=3D2C link-time-optimization (gcc "LTO=<br>>"). (We don't=3D2C but real world sy=3D<br>&gt=3B &gt=3B&gt=3B stems certai=<br>>nly do.)&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&amp=3Bnbsp=3D3B-
 Jay&lt=<br>>=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3Bbr&gt=3B&lt=3Bdiv&gt=3B&lt=3Bdiv id=3D3D"Sk=<br>>=3D<br>&gt=3B &gt=3B&gt=3B yDrivePlaceholder"&gt=3B&lt=3B/div&gt=3B&amp=3Bg=<br>>t=3D3B To: <a ymailto="mailto:jay.krell@cornell.edu" href="/mc/compose?to=jay.krell@cornell.edu">jay.krell@cornell.edu</a>=3D3B m3devel@elegos=3D<br>&gt=3B &gt=3B&gt=<br>>=3B oft.com=3D3B <a ymailto="mailto:mika@async.caltech.edu" href="/mc/compose?to=mika@async.caltech.edu">mika@async.caltech.edu</a>&lt=3Bbr&gt=3B&amp=3Bgt=3D3B Subject=<br>>: Re: [M3devel] race con=3D<br>&gt=3B &gt=3B&gt=3B ditions in lock-free cod=<br>>e...&lt=3Bbr&gt=3B&amp=3Bgt=3D3B Date: Sun=3D2C 26 Aug 2012 22:32:48 -0=3D<=<br>>br>&gt=3B &gt=3B&gt=3B 700&lt=3Bbr&gt=3B&amp=3Bgt=3D3B From: <a ymailto="mailto:mika@async.cal"
 href="/mc/compose?to=mika@async.cal">mika@async.cal</a>=<br>>tech.edu&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &lt=3Bbr&gt=3B&amp=3Bgt=3D3B Sorry=3D2=<br>>C I =3D<br>&gt=3B &gt=3B&gt=3B can't seem to quote your message.&lt=3Bbr&gt=<br>>=3B&amp=3Bgt=3D3B &lt=3Bbr&gt=3B&amp=3Bgt=3D3B You say that Text8.N=3D<br>&=<br>>gt=3B &gt=3B&gt=3B ew's result can be assigned to fromCharCache[c]&lt=3Bbr&=<br>>gt=3B&amp=3Bgt=3D3B before Text8.New =3D<br>&gt=3B &gt=3B&gt=3B is done run=<br>>ning.  How is that possible?  Surely&lt=3Bbr&gt=3B&amp=3Bgt=3D3B Text8.New =<br>>has to =3D<br>&gt=3B &gt=3B&gt=3B calculate its result before it can be ass=<br>>igned&lt=3Bbr&gt=3B&amp=3Bgt=3D3B anywhere.  Yes pos=3D<br>&gt=3B &gt=3B&gt=<br>>=3B sibly FromChar allocates space for the
 result of&lt=3Bbr&gt=3B&amp=3Bgt=<br>>=3D3B Text8.New but th=3D<br>&gt=3B &gt=3B&gt=3B e assignment of whatever a=<br>>ppears in that space can't&lt=3Bbr&gt=3B&amp=3Bgt=3D3B happen until=3D<br>&=<br>>gt=3B &gt=3B&gt=3B *after* Text8.New has run.  Unless you are saying that&l=<br>>t=3Bbr&gt=3B&amp=3Bgt=3D3B the runni=3D<br>&gt=3B &gt=3B&gt=3B ng of Text8.=<br>>New and FromChar are intertwined somehow..?&lt=3Bbr&gt=3B&amp=3Bgt=3D3B I k=<br>>now co=3D<br>&gt=3B &gt=3B&gt=3B mpilers do some odd things but that doesn'=<br>>t sound right...&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &lt=3Bbr&gt=3B&amp=3Bg=3D<br>&=<br>>gt=3B &gt=3B&gt=3B t=3D3B If Text8.New took fromCharCache[c] as a VAR param=<br>>eter you might be&lt=3Bbr&gt=3B=3D<br>&gt=3B &gt=3B&gt=3B
 &amp=3Bgt=3D3B ri=<br>>ght=3D2C though.  But it doesn't...&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &lt=3Bbr&gt=<br>>=3B&amp=3Bgt=3D3B Am I missin=3D<br>&gt=3B &gt=3B&gt=3B g something?&lt=3Bb=<br>>r&gt=3B&amp=3Bgt=3D3B &lt=3Bbr&gt=3B&amp=3Bgt=3D3B      Mika&lt=3Bbr&gt=3B&=<br>>amp=3Bgt=3D3B &lt=3Bbr&gt=3B&amp=3Bgt=3D3B Mika Nystr=3D<br>&gt=3B &gt=3B&g=<br>>t=3B om writes:&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&lt=3Bbr&gt=3B&am=<br>>p=3Bgt=3D3B &amp=3Bgt=3D3BYeah it's a race condition=3D2C i=3D<br>&gt=3B &g=<br>>t=3B&gt=3B n theory.  But is it important?  If you get&lt=3Bbr&gt=3B&amp=3B=<br>>gt=3D3B &amp=3Bgt=3D3Bthe wrong copy=3D<br>&gt=3B &gt=3B&gt=3B =3D2C there =<br>>will be two TEXTs representing one
 CHAR.  But no&lt=3Bbr&gt=3B&amp=3Bgt=3D3=<br>>B &amp=3Bgt=3D3B=3D<br>&gt=3B &gt=3B&gt=3B one ever said FromChar was guara=<br>>nteed to return the same pointer when&lt=3Bbr&gt=3B&amp=3Bg=3D<br>&gt=3B &g=<br>>t=3B&gt=3B t=3D3B &amp=3Bgt=3D3Byou call it with the same CHAR...&lt=3Bbr&g=<br>>t=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<=<br>>br>&gt=3B &gt=3B&gt=3B =3D3B     Mika&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=<br>>=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3BJay K writes:&lt=3Bbr&gt=3B=<br>>&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B&amp=3Bgt=3D3B--_5f=<br>>23896e-68ee-44da-82dd-311cd8c58979_&lt=3Bbr&gt=3B&amp=3Bgt=3D3B
 &amp=3Bgt=<br>>=3D3B&amp=3Bgt=3D3BCon=3D<br>&gt=3B &gt=3B&gt=3B tent-Type: text/plain=3D3B=<br>> charset=3D3D"iso-8859-1"&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3B=<br>>gt=3D3BConte=3D<br>&gt=3B &gt=3B&gt=3B nt-Transfer-Encoding: quoted-printab=<br>>le&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&a=<br>>mp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B&amp=3Bgt=3D3BWe have=<br>> race conditions=3D3D2C like this=3D3D2C m3core/src/Text.m3:&lt=3Bbr=3D<br>=<br>>&gt=3B &gt=3B&gt=3B&gt=3B &amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3B=<br>>br&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=<br>>=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BVAR fromC=3D<br>&gt=3B
 &gt=3B&gt=3B harCa=<br>>che :=3D3D3D ARRAY CHAR OF T {NIL=3D3D2C ..}=3D3D3B (* 1-char texts *)&lt=<br>>=3Bbr&gt=3B&amp=3Bg=3D<br>&gt=3B &gt=3B&gt=3B t=3D3B &amp=3Bgt=3D3B&amp=3Bg=<br>>t=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=<br>>=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BPROCEDURE Fr=3D<br>&gt=3B &gt=<br>>=3B&gt=3B omChar (c: CHAR): T =3D3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=<br>>=3D3B&amp=3Bgt=3D3B  VAR buf: ARRAY [0..0] OF =3D<br>&gt=3B &gt=3B&gt=3B CH=<br>>AR=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B  BEGIN&l=<br>>t=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B    IF fromCh=3D<br>=<br>>&gt=3B &gt=3B&gt=3B arCache [c] =3D3D3D NIL
 THEN&lt=3Bbr&gt=3B&amp=3Bgt=3D3=<br>>B &amp=3Bgt=3D3B&amp=3Bgt=3D3B      buf [0] :=3D3D3D c=3D3D3=3D<br>&gt=3B &=<br>>gt=3B&gt=3B B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B     =<br>> fromCharCache[c] :=3D3D3D Text8.New (buf)=3D3D3B&lt=3B=3D<br>&gt=3B &gt=3B=<br>>&gt=3B br&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B    END=3D3D3B&lt=<br>>=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B    RETURN fromCha=3D=<br>><br>&gt=3B &gt=3B&gt=3B rCache [c]&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D=<br>>3B&amp=3Bgt=3D3B  END FromChar=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=<br>>=3D3B&amp=3Bgt=3D3B=3D<br>&gt=3B &gt=3B&gt=3B &lt=3Bbr&gt=3B&amp=3Bgt=3D3B
 =<br>>&amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=<br>>=3Bgt=3D3BIt should be:&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B =<br>>&gt=3B&gt=3B =3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B=<br>>&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BPROC=<br>>EDURE FromChar (=3D<br>&gt=3B &gt=3B&gt=3B c: CHAR): T =3D3D3D&lt=3Bbr&gt=<br>>=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&am=<br>>p=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B  VA=3D<br>&gt=3B &gt=3B&gt=3B R bu=<br>>f: ARRAY [0..0] OF CHAR=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&a=<br>>mp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B
 &amp=3B=3D<br>&gt=3B &=<br>>gt=3B&gt=3B gt=3D3B&amp=3Bgt=3D3B  BEGIN&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=<br>>=3Bgt=3D3B&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=<br>>=3D3B&amp=3Bgt=3D3B   =3D<br>&gt=3B &gt=3B&gt=3B IF fromCharCache [c] =3D3D=<br>>3D NIL THEN&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B=3D3D0A=<br>>=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B &amp=3Bgt=3D3B=<br>>&amp=3Bgt=3D3B      buf [0] :=3D3D3D c=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &=<br>>amp=3Bgt=3D3B&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3B=3D<br>&gt=3B &gt=3B&gt=3B br&=<br>>gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B      WITH a =3D3D3D Text8.=<br>>New (buf)
 DO&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=<br>>=3B =3D3B&amp=3Bgt=3D3B        MemoryBarrier()=3D3D3B&lt=3Bbr&gt=3B&amp=3Bg=<br>>t=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B        fromCha=3D<br>&gt=3B &gt=3B&gt=<br>>=3B rCache[c] :=3D3D3D a=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&=<br>>amp=3Bgt=3D3B     END=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&g=<br>>t=3B &gt=3B&gt=3B =3D3B&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D=<br>>3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B    END=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &=<br>>amp=3Bgt=3D3B&amp=3Bgt=3D3B=3D<br>&gt=3B &gt=3B&gt=3B =3D3D0A=3D3D&lt=3Bbr&=<br>>gt=3B&amp=3Bgt=3D3B
 &amp=3Bgt=3D3B&amp=3Bgt=3D3B    RETURN fromCharCache [c=<br>>]&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B&amp=<br>>=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=<br>>=3D3B  END FromChar=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=<br>>=3B &gt=3B&gt=3B =3D3B&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3=<br>>B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&a=<br>>mp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3B=3D<br>&gt=3B &gt=3B&gt=3B =<br>>gt=3D3B&amp=3Bgt=3D3Bto ensure that all of Text8.New() finishes before the =<br>>assignment=3D<br>&gt=3B &gt=3B&gt=3B to fromCha=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=<br>>=3D3B
 &amp=3Bgt=3D3B&amp=3Bgt=3D3BrCache[c] is made.&lt=3Bbr&gt=3B&amp=3Bgt=<br>>=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B&lt=3Bbr&gt=3B=<br>>&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &am=<br>>p=3Bgt=3D3B&amp=3Bgt=3D3BCan the compiler somehow c=3D<br>&gt=3B &gt=3B&gt=<br>>=3B atch these?&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BI f=<br>>ear they are a small epidemic.&lt=3Bbr&gt=3B&amp=3Bgt=3D<br>&gt=3B &gt=3B&g=<br>>t=3B =3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BFor a long time people didn't realiz=<br>>e where all the compile=3D<br>&gt=3B &gt=3B&gt=3B r and processor =3D3D&lt=<br>>=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3Bcould
 reorder.&lt=3Bb=<br>>r&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bg=3D<br>&gt=3B &gt=3B&gt=3B t=3D=<br>>3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&a=<br>>mp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BDo we have the right cons=3D<br>&g=<br>>t=3B &gt=3B&gt=3B tructs by now to fix them?&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &a=<br>>mp=3Bgt=3D3B&amp=3Bgt=3D3BI think we do.&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=<br>>=3B=3D<br>&gt=3B &gt=3B&gt=3B gt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=<br>>=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D=<br>>3B&amp=3Bgt=3D3B - Jay&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3B=3D<br>&gt=3B &gt=<br>>=3B&gt=3B gt=3D3B&amp=3Bgt=3D3B 
                        =3D3D&lt=3Bbr&gt=3B=<br>>&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &am=<br>>p=3Bgt=3D3B&amp=3Bgt=3D3B--_=3D<br>&gt=3B &gt=3B&gt=3B 5f23896e-68ee-44da-8=<br>>2dd-311cd8c58979_&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BC=<br>>ontent-Type: t=3D<br>&gt=3B &gt=3B&gt=3B ext/html=3D3B charset=3D3D"iso-885=<br>>9-1"&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3BContent-Transf=<br>>er-E=3D<br>&gt=3B &gt=3B&gt=3B ncoding: quoted-printable&lt=3Bbr&gt=3B&amp=<br>>=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3B=<br>>gt=3D3B&amp=3Bgt=3D3B&amp=3Blt=3D<br>&gt=3B &gt=3B&gt=3B
 =3D3Bhtml&amp=3Bgt=<br>>=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Blt=3D3=<br>>Bhead&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3=<br>>B=3D<br>&gt=3B &gt=3B&gt=3B &amp=3Blt=3D3Bstyle&amp=3Bgt=3D3B&amp=3Blt=3D3B=<br>>!--&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B.hmmessage P&lt=<br>>=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B&amp=3Bg=<br>>t=3D3B{&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3Bmargin:0px=<br>>=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3Bpadd=3D<br>=<br>>&gt=3B &gt=3B&gt=3B ing:0px&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=<br>>=3Bgt=3D3B}&lt=3Bbr&gt=3B&amp=3Bgt=3D3B
 &amp=3Bgt=3D3B&amp=3Bgt=3D3Bbody.hm=<br>>message&lt=3Bbr&gt=3B&amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B &amp=3Bgt=3D=<br>>3B&amp=3Bgt=3D3B{&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3Bf=<br>>ont-size: 12pt=3D3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B &g=<br>>t=3B&gt=3B =3D3B&amp=3Bgt=3D3Bfont-family:Calibri&lt=3Bbr&gt=3B&amp=3Bgt=3D=<br>>3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B}&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B=<br>>&amp=3Bgt=3D3B=3D<br>&gt=3B &gt=3B&gt=3B --&amp=3Bgt=3D3B&amp=3Blt=3D3B/sty=<br>>le&amp=3Bgt=3D3B&amp=3Blt=3D3B/head&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D=<br>>3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Blt=3D3Bbod=3D<br>&gt=3B &gt=3B&gt=3B =<br>>y
 class=3D3D3D'hmmessage'&amp=3Bgt=3D3B&amp=3Blt=3D3Bdiv dir=3D3D3D'ltr'&am=<br>>p=3Bgt=3D3BWe have race cond=3D<br>&gt=3B &gt=3B&gt=3B itions=3D3D2C like =<br>>=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3Bthis=3D3D2C m=<br>>3core/src/Text.m3:&amp=3Blt=3D<br>&gt=3B &gt=3B&gt=3B =3D3Bbr&amp=3Bgt=3D3B=<br>>&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3BVAR fromCharCac=<br>>he :=3D3D3D ARRAY CHAR =3D<br>&gt=3B &gt=3B&gt=3B OF=3D3D&lt=3Bbr&gt=3B&amp=<br>>=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B T {NIL=3D3D2C ..}=3D3D3B (* 1-char =<br>>texts *)&amp=3Blt=3D3Bb=3D<br>&gt=3B &gt=3B&gt=3B r&amp=3Bgt=3D3B&amp=3Blt=<br>>=3D3Bbr&amp=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3BPROCEDURE FromChar (c:
 C=<br>>HAR=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B=3D<br>&gt=3B &gt=3B&gt=3B &amp=3Bgt=3D=<br>>3B&amp=3Bgt=3D3B): T =3D3D3D&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnb=<br>>sp=3D3D3B VAR buf: ARRAY [0..0]=3D<br>&gt=3B &gt=3B&gt=3B OF CHAR=3D3D3B&am=<br>>p=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B BEGIN&amp=3Blt=3D3Bbr=<br>>&amp=3Bgt=3D3B=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B =<br>>&amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=<br>>=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B IF fromCha=3D<br>&gt=3B &gt=3B&gt=3B rCac=<br>>he [c] =3D3D3D NIL THEN&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D=<br>>3D3B&amp=3Bamp=3D3Bnbsp=3D3D&lt=3Bbr&gt=3B&amp=3Bg=3D<br>&gt=3B &gt=3B&gt=<br>>=3B
 t=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&am=<br>>p=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B buf =3D<br>&gt=3B &gt=3B&=<br>>gt=3B [0] :=3D3D3D c=3D3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnbs=<br>>p=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D<br>&gt=3B &gt=3B&g=<br>>t=3B =3D3D3B&amp=3Bamp=3D3Bn=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3=<br>>B&amp=3Bgt=3D3Bbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B fromCharCac=3D<br>&gt=<br>>=3B &gt=3B&gt=3B he[c] :=3D3D3D Text8.New (buf)=3D3D3B&amp=3Blt=3D3Bbr&amp=<br>>=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D<br>&gt=3B &gt=3B=<br>>&gt=3B =3D3D3B=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3=<br>>B&amp=3Bamp=3D3Bnbsp=3D3D3B
 END=3D3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3B=<br>>amp=3D<br>&gt=3B &gt=3B&gt=3B =3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&am=<br>>p=3Bamp=3D3Bnbsp=3D3D3B RETURN fromCharCache [c]&amp=3Blt=3D3B=3D<br>&gt=3B=<br>> &gt=3B&gt=3B br&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnb=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=<br>>=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3Bsp=3D3D3B END FromChar=3D3D3B&amp=3Blt=3D=<br>>3Bb=3D<br>&gt=3B &gt=3B&gt=3B r&amp=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B=<br>>&amp=3Blt=3D3Bbr&amp=3Bgt=3D3BIt should be:&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&a=<br>>mp=3Blt=3D3Bbr&amp=3Bgt=3D<br>&gt=3B &gt=3B&gt=3B =3D3B&amp=3Blt=3D3Bbr&amp=<br>>=3Bgt=3D3BPROCEDURE FromCha=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B=<br>>&amp=3Bgt=3D3Br (c: CHAR): T
 =3D<br>&gt=3B &gt=3B&gt=3B =3D3D3D&amp=3Blt=3D=<br>>3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&a=<br>>mp=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B VAR buf:=3D<br>&gt=3B &gt=3B&gt=3B A=<br>>RRAY [0..0] OF CHAR=3D3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bb=<br>>r&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Bamp=3D<br>&gt=3B &=<br>>gt=3B&gt=3B =3D3Bnbsp=3D3D3B BEGIN&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3=<br>>D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnb=<br>>sp=3D<br>&gt=3B &gt=3B&gt=3B =3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D=<br>>3Bnbsp=3D3D3B IF fromCharCache [c] =3D3D3D NIL THEN&amp=3Bl=3D<br>&gt=3B &g=<br>>t=3B&gt=3B
 t=3D3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &=<br>>amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D=<br>>3D3B=3D<br>&gt=3B &gt=3B&gt=3B &amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbs=<br>>p=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B buf [0] :=3D3D3D c=3D3D3B&amp=3Blt=3D<br=<br>>>&gt=3B &gt=3B&gt=3B =3D3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3B=<br>>gt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D=<br>>3Bnbsp=3D3D3B&amp=3B=3D<br>&gt=3B &gt=3B&gt=3B amp=3D3Bnbsp=3D3D3B&amp=3Bam=<br>>p=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B WITH a =3D3D3D Text8.New (buf=<br>>=3D<br>&gt=3B &gt=3B&gt=3B ) DO&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Bamp=3D3=<br>>B=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B
 &amp=3Bgt=3D3B&amp=3Bgt=3D3Bnbsp=3D3D3B&=<br>>amp=3Bamp=3D3Bnbsp=3D3D3=3D<br>&gt=3B &gt=3B&gt=3B B&amp=3Bamp=3D3Bnbsp=3D3=<br>>D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=<br>>=3D3D3B&amp=3Bamp=3D3Bnbs=3D<br>&gt=3B &gt=3B&gt=3B p=3D3D3B MemoryBarrier(=<br>>)=3D3D3B&amp=3Blt=3D3B=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=<br>>=3Bgt=3D3Bbr&amp=3Bgt=3D3B&amp=3Bamp=3D3Bn=3D<br>&gt=3B &gt=3B&gt=3B bsp=3D=<br>>3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=<br>>=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bam=3D<br>&gt=3B &gt=3B&gt=3B p=3D3B=<br>>nbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B fromCharCache[c=3D3D&lt=3Bbr&gt=3B&am=<br>>p=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B] :=3D<br>&gt=3B
 &gt=3B&gt=3B =3D3D=<br>>3D a=3D3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Ba=<br>>mp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3B=3D<br>&gt=3B &gt=3B&gt=<br>>=3B amp=3D3Bnbsp=3D3D3B END=3D3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3=<br>>D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Bamp=3D<br>=<br>>&gt=3B &gt=3B&gt=3B =3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D=<br>>3Bnbsp=3D3D3B END=3D3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3D=3D<br>&g=<br>>t=3B &gt=3B&gt=3B &lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B=<br>>&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3D3B&amp=3Bamp=3D3Bnbsp=3D3=<br>>D3B RET=3D<br>&gt=3B &gt=3B&gt=3B URN fromCharCache
 [c]&amp=3Blt=3D3Bbr&amp=<br>>=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=<br>>=3D3B&amp=3Bamp=3D3Bnb=3D<br>&gt=3B &gt=3B&gt=3B sp=3D3D3B END FromChar=3D3=<br>>D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B=3D3D0A=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &=<br>>amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Blt=3D<br>&gt=3B &gt=3B&gt=3B =3D3Bbr&amp=<br>>=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3Bto ensure that all of Text8.New() f=<br>>inishes before =3D<br>&gt=3B &gt=3B&gt=3B the assignment to=3D3D&lt=3Bbr&gt=<br>>=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B fromCharCache[c] is made.&am=<br>>p=3Blt=3D3B=3D<br>&gt=3B &gt=3B&gt=3B br&amp=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=<br>>=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3BCan the compiler somehow catch
 thes=<br>>e?=3D<br>&gt=3B &gt=3B&gt=3B =3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D=<br>>3B&amp=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3BI fear they are a small epide=<br>>mic.&amp=3Bl=3D<br>&gt=3B &gt=3B&gt=3B t=3D3Bbr&amp=3Bgt=3D3BFor a long tim=<br>>e people didn't real=3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3B=<br>>gt=3D3Bize=3D<br>&gt=3B &gt=3B&gt=3B where all the compiler and processor c=<br>>ould reorder.&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3B=3D<br>&g=<br>>t=3B &gt=3B&gt=3B gt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3BDo we ha=3D3D&lt=3Bb=<br>>r&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3Bve the right construct=3D=<br>><br>&gt=3B &gt=3B&gt=3B s by now to fix
 them?&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B=<br>>I think we do.&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D<br=<br>>>&gt=3B &gt=3B&gt=3B =3D3B&amp=3Blt=3D3Bbr&amp=3Bgt=3D3B -=3D3D&lt=3Bbr&gt=<br>>=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3B Jay&amp=3Blt=3D3Bbr&amp=3Bgt=<br>>=3D3B                         =3D<br>&gt=3B &gt=3B&gt=3B &amp=3Blt=3D3B/div=<br>>&amp=3Bgt=3D3B&amp=3Blt=3D3B/body&amp=3Bgt=3D3B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B=<br>> &amp=3Bgt=3D3B&amp=3Bgt=3D3B&amp=3Blt=3D3B/html&amp=3Bgt=3D3B=3D<br>&gt=3B=<br>> &gt=3B&gt=3B =3D3D&lt=3Bbr&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B&amp=3Bgt=3D3=<br>>B&lt=3Bbr&gt=3B&amp=3Bgt=3D3B
 &amp=3Bgt=3D3B&amp=3Bgt=3D3B--_5f23896e-68ee-=<br>>44da-82dd=3D<br>&gt=3B &gt=3B&gt=3B -311cd8c58979_--&lt=3Bbr&gt=3B&lt=3B/di=<br>>v&gt=3B                         &lt=3B/div&gt=3B&lt=3B/body&gt=3B<br>&gt=3B=<br>> &gt=3B&gt=3B &lt=3B/html&gt=3B=3D<br>&gt=3B &gt=3B&gt=3B <br>&gt=3B &gt=3B=<br>>&gt=3B --_86f22d85-5540-4565-bf73-232aaafdc94b_--<br></div>                           </di=<br>>v></body><br>></html>=<br>><br>>--_5c33c9ca-3a7d-4c39-ab66-ab9c151d1539_--<br></div></blockquote></td></tr></table>