Am Wed, 16 Jul 2014 21:59:57 +0200 schrieb Artur Skawina via Digitalmars-d <digitalmars-d@puremagic.com>:
> On 07/16/14 15:02, Johannes Pfau via Digitalmars-d wrote: > > Am Tue, 15 Jul 2014 19:44:51 +0200 > > schrieb Artur Skawina via Digitalmars-d > > <digitalmars-d@puremagic.com>: > > > >> Could you show one (concrete) example where using 'volatile' is > >> better than my approach? > > > > I experimented a little more with Volatile!T and I don't think you > > can make this example work: > > > > struct Timer > > { > > uint control; > > uint data; > > } > > > > enum timerA = (Volatile!Timer)* = cast()0xDEADBEAF; > > > > timerA.control |= 0b1; > > Thank you very much for showing actual code. There are many (wrong) > assumptions being made in this thread (and the one on the gdc list). > Claims like "A is required" or "B is impossible", where A and B are > not actually defined and only vaguely described, do not usually lead > to a productive dialogue. Concrete examples and code make it possible > for the discussion to be about facts and not perceptions. > > struct Timer > { > uint control; > uint data; > } > > enum timerA = cast(Volatile!(Timer)*)0xDEADBEAF; > //enum timerA = volatile_(cast(Timer*)0xDEADBEAF); // works too. > > void main() { > timerA.control |= 0b1; > } > > struct Volatile(PT) { > PT raw; > > auto opDispatch(string M)() @property { return > volatile_(mixin(q{&raw.}~M)); } > > auto opOpAssign(string OP, B)(B b) { > auto a = load(*raw); > auto r = mixin("a "~OP~" b"); > store(*raw, r); > return this; > } > > static: > T load(T)(ref T v) { > asm { "" : "+m" v; } > T res = v; > asm { "" : "+g" res; } > return res; > } > > T store(T)(ref T v, const T a) { > asm { "" : : "m" v; } > v = a; > asm { "" : "+m" v; } > return a; > } > } > auto volatile_(A)(A a) { return Volatile!A(a); } // Just for IFTI. > > > when compiled w/ "gdc -O1" results in > > 0000000000402949 <_Dmain>: > 402949: b8 af be ad de mov $0xdeadbeaf,%eax > 40294e: 8b 10 mov (%rax),%edx > 402950: 83 ca 01 or $0x1,%edx > 402953: 89 10 mov %edx,(%rax) > 402955: b8 00 00 00 00 mov $0x0,%eax > 40295a: c3 retq > > which is the exact op sequence you'd expect. Doing it as just one > R-M-W op would be possible too, but that might not be supported by > all HW/platforms. > And, yes, gdc inlines it even at -O0, if @inline is used. But at -O0 > the generated code is /already/ huge and inefficient, hence not really > usable in constrained mem environments. > > Obviously, this is just a proof of concept and the minimal > implementation that can only handle your example. But it's enough to > disprove the it-cannot-be-made-to-work-without-c-volatile claim. Are > there any other examples of things that cannot be efficiently handled > w/o a built-in volatile type qualifier? > > artur Well I guess this is already decided anyway. I think it's kinda ridiculous that D embedded code will only be usable with strong optimization flags, but whatever. Maybe it works better if the usage is restricted to basic types only.