Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
On Saturday, December 03, 2011 18:32:15 Andrej Mitrovic wrote:
> I thought this wasn't allowed:
>
> shared uint threadsCount;
>
> void bumpThreadsCount()
> {
> ++threadsCount;
> }
>
> void main()
> {
> }
>
> According to TDPL it should error and we should use atomicOp from std.concurrency instead. atomicOp is what I've used so far if I had to use shared variables. Has ++ suddenly become atomic automatically or is this a bug?
Where in TDPL does it say this? Requiring that all operations on a shared object be atomic would be highly restrictive. Sure, if you use anything other than an atomic operation on a shared object and don't use a synchronized block or a mutex or the like, you risk race conditions, but if every operation on a shared object had to actually be atomic, you couldn't do much of anything to them.
- Jonathan M Davis
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 12/3/11 8:19 PM, Jonathan M Davis wrote:
> Sure, if you use anything other
> than an atomic operation on a shared object and don't use a synchronized block
> or a mutex or the like, you risk race conditions, but if every operation on a
> shared object had to actually be atomic, you couldn't do much of anything to
> them.
Isn't that exactly the point? What are the guarantees of shared otherwise? I agree that the current behavior is counter-intuitive and bug-prone.
David
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Saturday, December 03, 2011 20:22:40 David Nadlinger wrote:
> On 12/3/11 8:19 PM, Jonathan M Davis wrote:
> > Sure, if you use anything other
> > than an atomic operation on a shared object and don't use a synchronized
> > block or a mutex or the like, you risk race conditions, but if every
> > operation on a shared object had to actually be atomic, you couldn't do
> > much of anything to them.
>
> Isn't that exactly the point? What are the guarantees of shared otherwise? I agree that the current behavior is counter-intuitive and bug-prone.
I believe that it disallows the compiler from reordering operations on some level, and the big thing of course is that it means that the object isn't thread-local and _can_ be read by multiple threads. I haven't read TDPL's section on shared in a while though, and I almost never use it, so there could be something that I'm missing.
- Jonathan M Davis
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
On 12/3/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote: > Where in TDPL does it say this? Page 413. > Requiring that all operations on a shared > object be atomic would be highly restrictive. Yeah sorry, my title was wrong, of course you could use synchronization instead of atomics. But shared does need to have guarantees, it should be as useful as, say, const (when it works). |
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
On Saturday, December 03, 2011 20:54:38 Andrej Mitrovic wrote:
> On 12/3/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > Where in TDPL does it say this?
>
> Page 413.
>
> > Requiring that all operations on a shared
> > object be atomic would be highly restrictive.
>
> Yeah sorry, my title was wrong, of course you could use synchronization instead of atomics. But shared does need to have guarantees, it should be as useful as, say, const (when it works).
That page says that reads and writes are guaranteed to be atomic for shared. It does _not_ say that something like ++threadsCount is guaranteed to be atomic. That's a read _and_ a write. You have to do something yourself to guarantee that it's treated as atomic across threads (via sychronized blocks, or mutexes, or whatever).
- Jonathan M Davis
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
On 12/3/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> That page says that reads and writes are guaranteed to be atomic for shared. It does _not_ say that something like ++threadsCount is guaranteed to be atomic.
Woops, sorry it was a typo. I meant page 411, not 413. It says it's an error there. Btw, I never said ++ was atomic, I've asked whether something has changed. IOW I thought perhaps this used to be an error but maybe it was changed to make increment/decrement to be atomic on shared variables. That's not the case of course..
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
On Saturday, December 03, 2011 21:41:45 Andrej Mitrovic wrote:
> On 12/3/11, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > That page says that reads and writes are guaranteed to be atomic for shared. It does _not_ say that something like ++threadsCount is guaranteed to be atomic.
>
> Woops, sorry it was a typo. I meant page 411, not 413. It says it's an error there. Btw, I never said ++ was atomic, I've asked whether something has changed. IOW I thought perhaps this used to be an error but maybe it was changed to make increment/decrement to be atomic on shared variables. That's not the case of course..
Ah, okay. I had completely forgotten about that. That seems _very_ restrictive to me, and for it to work correctly, I would expect the compiler to have to be smart enough to realize when a synchronized block is in use or a mutex is in use, and I don't see how it can be that smart across function calls (since if it isn't that smart, it forces you to use atomicOp even when it's completely unnecessary), so I don't see how that could possibly work without unnecessarily requiring you to use atomicOp all over the place.
I have no idea what the plan on this is at this point, and I'm very surprised that such a requirement was ever suggested. It's the kind of question that you may have to bring up in the main newsgroup if you want a good answer for it though, since the number of people who pay attention to d-learn is much lower, and I don't know if any of the key devs who _would_ know pay attention here.
- Jonathan M Davis
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 12/03/2011 09:49 PM, Jonathan M Davis wrote:
> On Saturday, December 03, 2011 21:41:45 Andrej Mitrovic wrote:
>> On 12/3/11, Jonathan M Davis<jmdavisProg@gmx.com> wrote:
>>> That page says that reads and writes are guaranteed to be atomic for
>>> shared. It does _not_ say that something like ++threadsCount is
>>> guaranteed to be atomic.
>>
>> Woops, sorry it was a typo. I meant page 411, not 413. It says it's an
>> error there. Btw, I never said ++ was atomic, I've asked whether
>> something has changed. IOW I thought perhaps this used to be an error
>> but maybe it was changed to make increment/decrement to be atomic on
>> shared variables. That's not the case of course..
>
> Ah, okay. I had completely forgotten about that. That seems _very_ restrictive
> to me, and for it to work correctly, I would expect the compiler to have to be
> smart enough to realize when a synchronized block is in use or a mutex is in
> use, and I don't see how it can be that smart across function calls (since if
> it isn't that smart, it forces you to use atomicOp even when it's completely
> unnecessary), so I don't see how that could possibly work without
> unnecessarily requiring you to use atomicOp all over the place.
>
> I have no idea what the plan on this is at this point, and I'm very surprised
> that such a requirement was ever suggested. It's the kind of question that you
> may have to bring up in the main newsgroup if you want a good answer for it
> though, since the number of people who pay attention to d-learn is much lower,
> and I don't know if any of the key devs who _would_ know pay attention here.
>
> - Jonathan M Davis
cast()
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Saturday, December 03, 2011 22:56:41 Timon Gehr wrote:
> On 12/03/2011 09:49 PM, Jonathan M Davis wrote:
> > On Saturday, December 03, 2011 21:41:45 Andrej Mitrovic wrote:
> >> On 12/3/11, Jonathan M Davis<jmdavisProg@gmx.com> wrote:
> >>> That page says that reads and writes are guaranteed to be atomic for shared. It does _not_ say that something like ++threadsCount is guaranteed to be atomic.
> >>
> >> Woops, sorry it was a typo. I meant page 411, not 413. It says it's an error there. Btw, I never said ++ was atomic, I've asked whether something has changed. IOW I thought perhaps this used to be an error but maybe it was changed to make increment/decrement to be atomic on shared variables. That's not the case of course..
> >
> > Ah, okay. I had completely forgotten about that. That seems _very_ restrictive to me, and for it to work correctly, I would expect the compiler to have to be smart enough to realize when a synchronized block is in use or a mutex is in use, and I don't see how it can be that smart across function calls (since if it isn't that smart, it forces you to use atomicOp even when it's completely unnecessary), so I don't see how that could possibly work without unnecessarily requiring you to use atomicOp all over the place.
> >
> > I have no idea what the plan on this is at this point, and I'm very surprised that such a requirement was ever suggested. It's the kind of question that you may have to bring up in the main newsgroup if you want a good answer for it though, since the number of people who pay attention to d-learn is much lower, and I don't know if any of the key devs who _would_ know pay attention here.
> >
> > - Jonathan M Davis
>
> cast()
Sure, you could cast away shared, but there's something seriously wrong with shared if you have to constantly cast it away in order to use a shared object.
- Jonathan M Davis
|
December 03, 2011 Re: Non-atomic ops allowed on shared variables? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Saturday, December 03, 2011 22:56:41 Timon Gehr wrote:
> On 12/03/2011 09:49 PM, Jonathan M Davis wrote:
> > On Saturday, December 03, 2011 21:41:45 Andrej Mitrovic wrote:
> >> On 12/3/11, Jonathan M Davis<jmdavisProg@gmx.com> wrote:
> >>> That page says that reads and writes are guaranteed to be atomic for shared. It does _not_ say that something like ++threadsCount is guaranteed to be atomic.
> >>
> >> Woops, sorry it was a typo. I meant page 411, not 413. It says it's an error there. Btw, I never said ++ was atomic, I've asked whether something has changed. IOW I thought perhaps this used to be an error but maybe it was changed to make increment/decrement to be atomic on shared variables. That's not the case of course..
> >
> > Ah, okay. I had completely forgotten about that. That seems _very_ restrictive to me, and for it to work correctly, I would expect the compiler to have to be smart enough to realize when a synchronized block is in use or a mutex is in use, and I don't see how it can be that smart across function calls (since if it isn't that smart, it forces you to use atomicOp even when it's completely unnecessary), so I don't see how that could possibly work without unnecessarily requiring you to use atomicOp all over the place.
> >
> > I have no idea what the plan on this is at this point, and I'm very surprised that such a requirement was ever suggested. It's the kind of question that you may have to bring up in the main newsgroup if you want a good answer for it though, since the number of people who pay attention to d-learn is much lower, and I don't know if any of the key devs who _would_ know pay attention here.
> >
> > - Jonathan M Davis
>
> cast()
Sure, you could cast away shared, but there's something seriously wrong with shared if you have to constantly cast it away in order to use a shared object.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation