<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On Jan 4, 2010, at 5:16 PM, Jason House wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>On Jan 4, 2010, at 8:00 PM, Andrei Alexandrescu &lt;<a href="mailto:andrei@erdani.com">andrei@erdani.com</a>&gt; wrote:<font class="Apple-style-span" color="#006312"><font class="Apple-style-span" color="#144FAE"><br></font></font><blockquote type="cite"><br></blockquote><blockquote type="cite">Same here. All - please advise.<br></blockquote><br>I like this style as long as the compiler isn't completely brain dead and incorrectly force sme to put sharedRead and sharedWrite throughout my code base. I actually have a tweaked set of Tango's atomics in my D2 code base. We can't forget CAS and atomic increment/decrement for shared data.<br></div></blockquote><div><br></div>I created the Tango atomics module and would love to roll it into Druntime in some form. &nbsp;At the very least I agree that we need a CAS operation.</div><div><br></div><div><blockquote type="cite"><div><blockquote type="cite"><blockquote type="cite">The only catch with the approach above (and you've mentioned this before) is:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;class A {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fnA() shared { x = 5; }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fnB() synchronized { x = 6; }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int x;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">I had thought that explicitly labeling variables as shared would sidestep this by requiring ops on the vars to always be atomic. &nbsp;An alternative (as you've said before) would be to not allow shared and synchronized methods to both be used in a class, but it's pretty common that I'll want to do something like this:<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;class A {<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fnA() synchronized { sharedWrite( flag, true ); }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void fnB() shared { return sharedRead( flag ); }<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;shared flag;<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"> &nbsp;&nbsp;}<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Maybe my explicitly declaring flag as shared somehow provides an exemption? &nbsp;Or did you have another idea for a way around this?<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Hmmm... if a field is shared in a non-shared object, it means you're not using object's own lock to control access to that field. (You can e.g. assume that other threads have the address of that field.) So that field, inside a synchronized method, will not benefit of the tail-shared exemption and will be subjected to all limitations specific to e.g. a shared global bool.<br></blockquote><br><br>It's worse than that. Notice how in Sean's code that he didn't replace the sharedWrite call with a more conventional assignment. One really wants to keep full protection with (most) lock free variables. This means always using sharedRead and sharedWrite with them. The compiler should facilitate this...<br></div></blockquote></div><br><div>Yeah, if a shared variable is ever accessed outside a synchronized method then all accesses to it must be made atomic. &nbsp;This is why I'd previously thought that shared fields would be explicitly labeled as such, and the non-labeled fields could only be accessed in a synchronized method. &nbsp;I'm personally fine with using sharedRead and sharedWrite in this instance because only a handful of variables would ever be labeled as shared. &nbsp;Things are obviously quite different if the shared attribute of a class instance extends to all of its fields, and the compiler is expected to optimize away what it can though.</div></body></html>