digitalmars.D - synchronized vs. C volatile
- SK <sk metrokings.com> Aug 08 2010
- dsimcha <dsimcha yahoo.com> Aug 09 2010
- Sean Kelly <sean invisibleduck.org> Aug 09 2010
- dsimcha <dsimcha yahoo.com> Aug 09 2010
- Sean Kelly <sean invisibleduck.org> Aug 09 2010
- Lutger <lutger.blijdestijn gmail.com> Aug 09 2010
- bearophile <bearophileHUGS lycos.com> Aug 10 2010
- Sean Kelly <sean invisibleduck.org> Aug 10 2010
- SK <sk metrokings.com> Aug 09 2010
- BCS <none anon.com> Aug 09 2010
- Sean Kelly <sean invisibleduck.org> Aug 09 2010
- bearophile <bearophileHUGS lycos.com> Aug 09 2010
- SK <sk metrokings.com> Aug 09 2010
- SK <sk metrokings.com> Aug 09 2010
- Kagamin <spam here.lot> Aug 11 2010
- Kagamin <spam here.lot> Aug 11 2010
- SK <sk metrokings.com> Aug 09 2010
- "Steven Schveighoffer" <schveiguy yahoo.com> Aug 10 2010
Does 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
Aug 08 2010
== Quote from SK (sk metrokings.com)'s articleDoes 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
They're completely different. synchronized is basically a scoped mutex and applies to a statement, not a variable declaration. I have no idea what your example does, but it probably shouldn't even compile. Volatile just prevents certain compiler optimizations that can interfere with updates to a variable from other hardware besides the CPU and is useful for things like device drivers.
Aug 09 2010
SK Wrote:On Mon, Aug 9, 2010 at 6:25 AM, dsimcha <dsimcha yahoo.com> wrote:== Quote from SK (sk metrokings.com)'s articleDoes 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
They're completely different. synchronized is basically a scoped mutex and applies to a statement, not a variable declaration. I have no idea what your example does, but it probably shouldn't even compile. Volatile just prevents certain compiler optimizations that can interfere with updates to a variable from other hardware besides the CPU and is useful for things like device drivers.
Sounds right to me too. But the compiler warns about deprecated 'volatile'. Is the warning a mistake? Volatile has an important place in a systems language and I'd rather not mess with tradition here.
volatile is present in D1 but was deprecated in D2 in favor of shared. I actually liked D1 volatile, but I think I was among the few. In short, D1 volatile did the bare minimum to ensure that correct multithreaded code could be implemented by constraining compiler optimizations across volatile statement boundaries. For correct synchronized behavior, memory barriers still might have to be added however. As an alternative, Walter has stated before that it is invalid for the compiler to optimize across asm statement boundaries as well, so a similar effect can often be had by writing inline asm. Similar requirements apply to shared variables as well, which can be modified either in-language or by importing std.concurrency or core.atomic to perform more complex atomic ops. Both of these are likely to insert memory barriers when shared variables are accessed however.
Aug 09 2010
== Quote from Sean Kelly (sean invisibleduck.org)'s articleSK Wrote:On Mon, Aug 9, 2010 at 6:25 AM, dsimcha <dsimcha yahoo.com> wrote:== Quote from SK (sk metrokings.com)'s articleDoes 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
They're completely different. synchronized is basically a scoped mutex and applies to a statement, not a variable declaration. I have no idea what your example does, but it probably shouldn't even compile. Volatile just prevents certain compiler optimizations that can interfere with updates to a variable
other hardware besides the CPU and is useful for things like device drivers.
Sounds right to me too. But the compiler warns about deprecated 'volatile'. Is the warning a mistake? Volatile has an important place in a systems language and I'd rather not mess with tradition here.
volatile did the bare minimum to ensure that correct multithreaded code could be implemented by constraining compiler optimizations across volatile statement boundaries. For correct synchronized behavior, memory barriers still might have to be added however.As an alternative, Walter has stated before that it is invalid for the compiler
be had by writing inline asm. Similar requirements apply to shared variables as well, which can be modified either in-language or by importing std.concurrency or core.atomic to perform more complex atomic ops. Both of these are likely to insert memory barriers when shared variables are accessed however. Does this include even empty asm statements, for example: int i; // Volatile. // Do stuff. asm {} // No code motion across this. i++; asm {} // No code motion across this. // Do more stuff.
Aug 09 2010
dsimcha Wrote:== Quote from Sean Kelly (sean invisibleduck.org)'s articleAs an alternative, Walter has stated before that it is invalid for the compiler
be had by writing inline asm. Similar requirements apply to shared variables as well, which can be modified either in-language or by importing std.concurrency or core.atomic to perform more complex atomic ops. Both of these are likely to insert memory barriers when shared variables are accessed however. Does this include even empty asm statements, for example: int i; // Volatile. // Do stuff. asm {} // No code motion across this. i++; asm {} // No code motion across this. // Do more stuff.
I wondered the same thing when writing my response. Personally, I wouldn't consider this safe because the compiler can trivially determine that the block is empty and make it vanish. To be safe I think you'd at least have to put a NOP in there, so I guess you could do something like: property void optbar() { asm { naked; NOP; } } void volatile(lazy void exp) { optbar; exp(); optbar; } int x; /*volatile*/ int y; volatile(x = y);
Aug 09 2010
SK wrote:On Mon, Aug 9, 2010 at 6:25 AM, dsimcha <dsimcha yahoo.com> wrote:== Quote from SK (sk metrokings.com)'s articleDoes 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
They're completely different. synchronized is basically a scoped mutex and applies to a statement, not a variable declaration. I have no idea what your example does, but it probably shouldn't even compile. Volatile just prevents certain compiler optimizations that can interfere with updates to a variable from other hardware besides the CPU and is useful for things like device drivers.
Sounds right to me too. But the compiler warns about deprecated 'volatile'. Is the warning a mistake? Volatile has an important place in a systems language and I'd rather not mess with tradition here. $ cat main.d int main() { volatile int x = 1; synchronized int y = 1; return 0; } $ dmd -w -wi main.d main.d(4): volatile statements deprecated; used synchronized statements instead
I'm not an expert on this, but if I am not mistaken the shared type qualifier will handle the barriers, require atomic ops and prevent reordering compiler optimizations so it looks like this one will take care of what volatile used to do, right?
Aug 09 2010
SK:asm() hacks to fake volatile are too embarrassing to consider in a promising new systems language!
D2 has a good chance to become a system language, but it isn't yet. The main problems don't come from missing features that are easy to add later, the problems are in the possible presence of suboptimally designed features :-) Bye, bearophile
Aug 10 2010
Steven Schveighoffer Wrote:As of now, D supports only x86. I think it has nestled itself into a place where it needs to make tremendous assumptions about the processor and OS. For example, the OS *must* support thread local storage.
It doesn't have to be an OS-level thing. In D, TLS on OSX allocates its storage dynamically within library code because OSX doesn't support __thread yet.
Aug 10 2010
On Mon, Aug 9, 2010 at 6:25 AM, dsimcha <dsimcha yahoo.com> wrote:=3D=3D Quote from SK (sk metrokings.com)'s articleDoes 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
They're completely different. =A0synchronized is basically a scoped mutex=
applies to a statement, not a variable declaration. =A0I have no idea wha=
example does, but it probably shouldn't even compile. =A0Volatile just pr=
certain compiler optimizations that can interfere with updates to a varia=
other hardware besides the CPU and is useful for things like device drive=
Sounds right to me too. But the compiler warns about deprecated 'volatile'. Is the warning a mistake? Volatile has an important place in a systems language and I'd rather not mess with tradition here. $ cat main.d int main() { volatile int x =3D 1; synchronized int y =3D 1; return 0; } $ dmd -w -wi main.d main.d(4): volatile statements deprecated; used synchronized statements ins= tead
Aug 09 2010
Hello SK,Does 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
I'm reasonably sure that it doesn't. I think synchronized invokes a mutex for access and C's volatile just suppresses some optimizations. -- ... <IXOYE><
Aug 09 2010
SK Wrote:Andrei's book does not list volatile as a keyword in D. I'm at a loss unless 'synchronized' performs double duty as volatile. For example, device status registers are "const volatile" in C/C++. The compiler disallows writes and does not optimize away reads. Mutexes are irrelevant and for that matter the processor may not (and need not) even support atomic instructions.
So you're one of the few people who actually use C volatile as intended, huh? :-) I think right now your best bet is to use inline asm, or call out to a function written in assembly if you're targeting something other than x86. As I said in my other post, the compiler won't optimize away ask blocks, nor will it optimize across them. Walter has stated that it's incorrect behavior for a compiler to do so. GDC or LDC might however, I really couldn't say.
Aug 09 2010
Sean Kelly:As I said in my other post, the compiler won't optimize away ask blocks, nor will it optimize across them. Walter has stated that it's incorrect behavior for a compiler to do so. GDC or LDC might however, I really couldn't say.<
In LDC there are two ways to inline asm statements and functions that contain them, but both are explicit, so on default it acts as DMD (but I don't think this is well tested). Bye, bearophile
Aug 09 2010
On Mon, Aug 9, 2010 at 7:29 AM, BCS <none anon.com> wrote:Hello SK,Does 'synchronized' mean the exact same thing as the C 'volatile' qualifier when applied to basic types? As in: synchronized int x;
I'm reasonably sure that it doesn't. I think synchronized invokes a mutex for access and C's volatile just suppresses some optimizations. -- ... <IXOYE><
Andrei's book does not list volatile as a keyword in D. I'm at a loss unless 'synchronized' performs double duty as volatile. For example, device status registers are "const volatile" in C/C++. The compiler disallows writes and does not optimize away reads. Mutexes are irrelevant and for that matter the processor may not (and need not) even support atomic instructions. -steve
Aug 09 2010
On Mon, Aug 9, 2010 at 9:55 AM, Lutger <lutger.blijdestijn gmail.com> wrote:I'm not an expert on this, but if I am not mistaken the shared type qualifier will handle the barriers, require atomic ops and prevent reordering compiler optimizations so it looks like this one will take care of what volatile used to do, right?
Right, shared sounds better. However, atomics must not sneak in: * Many processors do not support atomics Even with processor support, * Many device interconnects do not support atomic transactions Even with interconnect support, * Many devices do not support atomic transactions and will just generate a bus error So long as code does not attempt a read-modify-write operation, shared has the opportunity to do the right thing, namely implement volatile semantics. Cases with volatile read-modify-write would have to be split -- awkward, but maybe ok? asm() hacks to fake volatile are too embarrassing to consider in a promising new systems language! -steve
Aug 09 2010
SK Wrote:So long as code does not attempt a read-modify-write operation, shared has the opportunity to do the right thing, namely implement volatile semantics. Cases with volatile read-modify-write would have to be split -- awkward, but maybe ok?
D provides good behavior by default (for most common cases). If you want alternative behavior, you can still implement it by, say, casting. Not D is more targeted for user application development. For kernel development compiler should be modified (gcc is, for example).
Aug 11 2010
Kagamin Wrote:Not D is more targeted for user application development.
*Now
Aug 11 2010
--0016e64c1800de46c2048d702ddd Content-Type: text/plain; charset=ISO-8859-1 On Mon, Aug 9, 2010 at 9:55 AM, Lutger <lutger.blijdestijn gmail.com> wrote:I'm not an expert on this, but if I am not mistaken the shared type
will handle the barriers, require atomic ops and prevent reordering
optimizations so it looks like this one will take care of what volatile
do, right?
Seems the latest dmd in svn hasn't implemented shared atomics yet anyway. If it had, we'd see a lock prefix in use. $ cat main.d shared int x = 1; int main() { x = x + 1; ++x; return 0; } $ dmd -O -w -wi main.d $ objdump -d main.o main.o: file format elf32-i386 Disassembly of section .text: 00000000 <.text>: 0: c3 ret 1: 60 pusha 2: b8 14 00 00 00 mov $0x14,%eax 7: b9 00 00 00 00 mov $0x0,%ecx c: 8b 11 mov (%ecx),%edx e: 89 10 mov %edx,(%eax) 10: 89 01 mov %eax,(%ecx) 12: 61 popa 13: c3 ret Disassembly of section .text._Dmain: 00000000 <_Dmain>: 0: 55 push %ebp 1: a1 00 00 00 00 mov 0x0,%eax 6: 40 inc %eax 7: a3 00 00 00 00 mov %eax,0x0 c: 8b ec mov %esp,%ebp e: 31 c0 xor %eax,%eax 10: 83 05 00 00 00 00 01 addl $0x1,0x0 17: 5d pop %ebp 18: c3 ret --0016e64c1800de46c2048d702ddd Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On Mon, Aug 9, 2010 at 9:55 AM, Lutger <<a href=3D"mailto:lutger.blijdes= tijn gmail.com" target=3D"_blank">lutger.blijdestijn gmail.com</a>> wrot= e:<br>><br>> I'm not an expert on this, but if I am not mistaken = the shared type qualifier<br> > will handle the barriers, require atomic ops and prevent reordering co= mpiler<br>> optimizations so it looks like this one will take care of wh= at volatile used to<br>> do, right?<br>><br>><br><br>Seems the lat= est dmd in svn hasn't implemented shared atomics yet anyway.=A0 If it h= ad, we'd see a lock prefix in use.<br> <br><span style=3D"font-family: courier new,monospace;">$ cat main.d</span>= <br style=3D"font-family: courier new,monospace;"><span style=3D"font-famil= y: courier new,monospace;">shared int x =3D 1;</span><br style=3D"font-fami= ly: courier new,monospace;"> <span style=3D"font-family: courier new,monospace;">int main()</span><br st= yle=3D"font-family: courier new,monospace;"><span style=3D"font-family: cou= rier new,monospace;">{</span><br style=3D"font-family: courier new,monospac= e;"> <span style=3D"font-family: courier new,monospace;">=A0x =3D x + 1;</span><= br style=3D"font-family: courier new,monospace;"><span style=3D"font-family= : courier new,monospace;">=A0++x;</span><br style=3D"font-family: courier n= ew,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0return 0;</span><br = style=3D"font-family: courier new,monospace;"><span style=3D"font-family: c= ourier new,monospace;">}</span><br style=3D"font-family: courier new,monosp= ace;"> <span style=3D"font-family: courier new,monospace;">$ dmd -O -w -wi main.d<= /span><br style=3D"font-family: courier new,monospace;"><span style=3D"font= -family: courier new,monospace;">$ objdump -d main.o</span><br style=3D"fon= t-family: courier new,monospace;"> <br style=3D"font-family: courier new,monospace;"><span style=3D"font-famil= y: courier new,monospace;">main.o:=A0=A0=A0=A0 file format elf32-i386</span=<br style=3D"font-family: courier new,monospace;"><br style=3D"font-family=
<br style=3D"font-family: courier new,monospace;"><span style=3D"font-famil= y: courier new,monospace;">Disassembly of section .text:</span><br style=3D= "font-family: courier new,monospace;"><br style=3D"font-family: courier new= ,monospace;"> <span style=3D"font-family: courier new,monospace;">00000000 <.text>:= </span><br style=3D"font-family: courier new,monospace;"><span style=3D"fon= t-family: courier new,monospace;">=A0=A0 0:=A0=A0 c3=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ret=A0=A0=A0 </span><br style=3D= "font-family: courier new,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0=A0 1:=A0=A0 60=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 pusha=A0 </spa= n><br style=3D"font-family: courier new,monospace;"><span style=3D"font-fam= ily: courier new,monospace;">=A0=A0 2:=A0=A0 b8 14 00 00 00=A0=A0=A0=A0=A0= =A0=A0=A0=A0 mov=A0=A0=A0 $0x14,%eax</span><br style=3D"font-family: courie= r new,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0=A0 7:=A0=A0 b9 00 0= 0 00 00=A0=A0=A0=A0=A0=A0=A0=A0=A0 mov=A0=A0=A0 $0x0,%ecx</span><br style= =3D"font-family: courier new,monospace;"><span style=3D"font-family: courie= r new,monospace;">=A0=A0 c:=A0=A0 8b 11=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0 mov=A0=A0=A0 (%ecx),%edx</span><br style=3D"font-family:= courier new,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0=A0 e:=A0=A0 89 10= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 mov=A0=A0=A0 %edx,(%= eax)</span><br style=3D"font-family: courier new,monospace;"><span style=3D= "font-family: courier new,monospace;">=A0 10:=A0=A0 89 01=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 mov=A0=A0=A0 %eax,(%ecx)</span><br sty= le=3D"font-family: courier new,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0 12:=A0=A0 61=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 popa=A0=A0 </span=<br style=3D"font-family: courier new,monospace;"><span style=3D"font-fami=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ret=A0=A0=A0 </span><br style=3D"font-fam= ily: courier new,monospace;"> <br style=3D"font-family: courier new,monospace;"><span style=3D"font-famil= y: courier new,monospace;">Disassembly of section .text._Dmain:</span><br s= tyle=3D"font-family: courier new,monospace;"><br style=3D"font-family: cour= ier new,monospace;"> <span style=3D"font-family: courier new,monospace;">00000000 <_Dmain>= :</span><br style=3D"font-family: courier new,monospace;"><span style=3D"fo= nt-family: courier new,monospace;">=A0=A0 0:=A0=A0 55=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 push=A0=A0 %ebp</span><br style= =3D"font-family: courier new,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0=A0 1:=A0=A0 a1 00 0= 0 00 00=A0=A0=A0=A0=A0=A0=A0=A0=A0 mov=A0=A0=A0 0x0,%eax</span><br style=3D= "font-family: courier new,monospace;"><span style=3D"font-family: courier n= ew,monospace;">=A0=A0 6:=A0=A0 40=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0 inc=A0=A0=A0 %eax</span><br style=3D"font-family: cou= rier new,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0=A0 7:=A0=A0 a3 00 0= 0 00 00=A0=A0=A0=A0=A0=A0=A0=A0=A0 mov=A0=A0=A0 %eax,0x0</span><br style=3D= "font-family: courier new,monospace;"><span style=3D"font-family: courier n= ew,monospace;">=A0=A0 c:=A0=A0 8b ec=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 mov=A0=A0=A0 %esp,%ebp</span><br style=3D"font-family: cour= ier new,monospace;"> <span style=3D"font-family: courier new,monospace;">=A0=A0 e:=A0=A0 31 c0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xor=A0=A0=A0 %eax,%e= ax</span><br style=3D"font-family: courier new,monospace;"><span style=3D"f= ont-family: courier new,monospace;">=A0 10:=A0=A0 83 05 00 00 00 00 01=A0= =A0=A0 addl=A0=A0 $0x1,0x0</span><br style=3D"font-family: courier new,mono= space;"> <span style=3D"font-family: courier new,monospace;">=A0 17:=A0=A0 5d=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 pop=A0=A0=A0 %ebp= </span><br style=3D"font-family: courier new,monospace;"><span style=3D"fon= t-family: courier new,monospace;">=A0 18:=A0=A0 c3=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ret</span><br> --0016e64c1800de46c2048d702ddd--
Aug 09 2010
On Mon, 09 Aug 2010 20:09:54 -0400, SK <sk metrokings.com> wrote:On Mon, Aug 9, 2010 at 9:55 AM, Lutger <lutger.blijdestijn gmail.com> wrote:I'm not an expert on this, but if I am not mistaken the shared type qualifier will handle the barriers, require atomic ops and prevent reordering compiler optimizations so it looks like this one will take care of what volatile used to do, right?
Right, shared sounds better. However, atomics must not sneak in: * Many processors do not support atomics Even with processor support, * Many device interconnects do not support atomic transactions Even with interconnect support, * Many devices do not support atomic transactions and will just generate a bus error
As of now, D supports only x86. I think it has nestled itself into a place where it needs to make tremendous assumptions about the processor and OS. For example, the OS *must* support thread local storage. Many embedded processors are not even close to as complex as x86, so you may not need to worry about a lot of the things D takes care of. I'd expect a version of D for embedded systems may be a different language altogether.asm() hacks to fake volatile are too embarrassing to consider in a promising new systems language!
In the land D is targeting -- namely the application/system space, not the kernel space -- volatile is not exactly needed much. I think shared is fine for thread-safe access to variables. Registers aren't really used in user-land code. I don't pretend to understand why Walter decided volatile wasn't adequate, but there were some discussions a while back.-steve
Hey, that's my sig! I guess you can have it as long as you always make it lower case. -Steve :)
Aug 10 2010









Sean Kelly <sean invisibleduck.org> 