digitalmars.D - synchronized vs. C volatile
- SK (4/4) Aug 08 2010 Does 'synchronized' mean the exact same thing as the C 'volatile'
- dsimcha (6/10) Aug 09 2010 They're completely different. synchronized is basically a scoped mutex ...
- SK (20/30) Aug 09 2010 t your
- Sean Kelly (3/22) Aug 09 2010 volatile is present in D1 but was deprecated in D2 in favor of shared. ...
- dsimcha (19/41) Aug 09 2010 actually liked D1 volatile, but I think I was among the few. In short, ...
- Sean Kelly (13/32) Aug 09 2010 I wondered the same thing when writing my response. Personally, I would...
- Lutger (5/36) Aug 09 2010 I'm not an expert on this, but if I am not mistaken the shared type qual...
- SK (15/19) Aug 09 2010 Right, shared sounds better. However, atomics must not sneak in:
- bearophile (5/7) Aug 10 2010 D2 has a good chance to become a system language, but it isn't yet.
- Steven Schveighoffer (17/39) Aug 10 2010 As of now, D supports only x86. I think it has nestled itself into a
- Sean Kelly (2/6) Aug 10 2010 It doesn't have to be an OS-level thing. In D, TLS on OSX allocates its...
- Kagamin (3/7) Aug 11 2010 D provides good behavior by default (for most common cases). If you want...
- Kagamin (2/3) Aug 11 2010 *Now
- SK (39/43) Aug 09 2010 compiler
- BCS (5/9) Aug 09 2010 I'm reasonably sure that it doesn't. I think synchronized invokes a mute...
- SK (8/17) Aug 09 2010 Andrei's book does not list volatile as a keyword in D. I'm at a loss
- Sean Kelly (2/9) Aug 09 2010 So you're one of the few people who actually use C volatile as intended,...
- bearophile (4/5) Aug 09 2010 In LDC there are two ways to inline asm statements and functions that co...
- Sean Kelly (2/5) Aug 10 2010 I'm not sure I agree. Unlike C/C++, inline asm in D is a clearly define...
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
On Mon, Aug 9, 2010 at 6:25 AM, dsimcha <dsimcha yahoo.com> wrote:=3D=3D Quote from SK (sk metrokings.com)'s articleandDoes '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=t yourexample does, but it probably shouldn't even compile. =A0Volatile just pr=eventscertain compiler optimizations that can interfere with updates to a varia=ble fromother hardware besides the CPU and is useful for things like device drive=rs.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
SK Wrote:On Mon, Aug 9, 2010 at 6:25 AM, dsimcha <dsimcha yahoo.com> wrote: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.== Quote from SK (sk metrokings.com)'s articleSounds 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.Does '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
== Quote from Sean Kelly (sean invisibleduck.org)'s articleSK Wrote:fromOn 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 variableactually 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.volatile is present in D1 but was deprecated in D2 in favor of shared. Iother 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.As an alternative, Walter has stated before that it is invalid for the compilerto 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. 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 articleI 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);As an alternative, Walter has stated before that it is invalid for the compilerto 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. 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
SK wrote:On Mon, Aug 9, 2010 at 6:25 AM, dsimcha <dsimcha yahoo.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?== Quote from SK (sk metrokings.com)'s articleSounds 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 insteadDoes '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
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: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
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: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.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 errorasm() 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.-steveHey, that's my sig! I guess you can have it as long as you always make it lower case. -Steve :)
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
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
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 typequalifierwill handle the barriers, require atomic ops and prevent reorderingcompileroptimizations so it looks like this one will take care of what volatileused todo, 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
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
On Mon, Aug 9, 2010 at 7:29 AM, BCS <none anon.com> wrote:Hello SK,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. -steveDoes '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
SK Wrote:asm() hacks to fake volatile are too embarrassing to consider in a promising new systems language!I'm not sure I agree. Unlike C/C++, inline asm in D is a clearly defined language feature. Also, making 'volatile' an attribute adds a lot of syntactic clutter for what really is a niche feature. That 'volatile' is almost universally misused in C/C++ supports the assertion that this perhaps should not be so obvious a language feature in D, particularly since it can be accomplished in-language via other means. That D only defines inline asm for x86 shouldn't much matter. It's clear that the D approach is to make inline asm look as much like native asm as possible, so how it will work on other platforms is easy to extrapolate. Until support is added for your platform of choice, just call out to external asm code.
Aug 10 2010