
Consider the following code stamp v x = do t <- getCurrentTime putMVar v (x,t) Is it possible - with GHC - that a thread switch happens after the t <- getCurrentTime and the putMVar v (x,t)? If so, how would it be possible to make sure that the operation of reading the current time and writing the pair to the MVar is an "atomic" operation, in the sense that no thread switch can happen between the two? Would this require STM? Thanks again for sharing your wisdom with me :) Peter

bugfact:
Consider the following code
stamp v x = do t <- getCurrentTime putMVar v (x,t)
Is it possible - with GHC - that a thread switch happens after the t <- getCurrentTime and the putMVar v (x,t)?
Yes. if 't' is heap allocated, there could be a context switch.
If so, how would it be possible to make sure that the operation of reading the current time and writing the pair to the MVar is an "atomic" operation, in the sense that no thread switch can happen between the two? Would this require STM?
Using 'atomically' and TVars in STM, perhaps? Else, use withMVar? Or a modifyMVar in IO? -- Don

On Thu, Feb 12, 2009 at 6:26 PM, Don Stewart
bugfact:
Consider the following code
stamp v x = do t <- getCurrentTime putMVar v (x,t)
Is it possible - with GHC - that a thread switch happens after the t <- getCurrentTime and the putMVar v (x,t)?
Yes. if 't' is heap allocated, there could be a context switch.
If so, how would it be possible to make sure that the operation of reading the current time and writing the pair to the MVar is an "atomic" operation, in the sense that no thread switch can happen between the two? Would this require STM?
Using 'atomically' and TVars in STM, perhaps? Else, use withMVar? Or a modifyMVar in IO?
As I understand it, withMVar or modifyMVar will protect you from
extraneous exceptions, but they won't prevent another thread from
writing to the MVar between the take and the put.
--
Dave Menendez

On Thu, 2009-02-12 at 22:58 -0500, David Menendez wrote:
On Thu, Feb 12, 2009 at 6:26 PM, Don Stewart
wrote: bugfact:
Consider the following code
stamp v x = do t <- getCurrentTime putMVar v (x,t)
Is it possible - with GHC - that a thread switch happens after the t <- getCurrentTime and the putMVar v (x,t)?
Yes. if 't' is heap allocated, there could be a context switch.
If so, how would it be possible to make sure that the operation of reading the current time and writing the pair to the MVar is an "atomic" operation, in the sense that no thread switch can happen between the two? Would this require STM?
Using 'atomically' and TVars in STM, perhaps? Else, use withMVar? Or a modifyMVar in IO?
As I understand it, withMVar or modifyMVar will protect you from extraneous exceptions, but they won't prevent another thread from writing to the MVar between the take and the put.
You have to cooperate with the other users of the MVar. If each thread is using readMVar, withMVar or modifyMVar then it's fine. The read/with/modify actions do a takeMVar followed by a putMVar. If one thread is using withMVar and another is doing putMVar directly then the exclusion scheme does not work. Duncan

Ah yes, then you're doing a double handshaking in a sense, of course. Not
ideal if you just want to put something in the MVar and resume as quick as
possible. However, in that case one could fork a dummy thread that only does
readMVar I guess.
But does it also work when you want multiple threads that are waiting for
the same MVar, and a single thread that writes to the MVar? It think is
does, when you use readMVar one thread will get the value and the others
will get it sequentially since readMVar puts the value back...
Again you guys gave a solution, an amazing brain thank this cafe is...
Usually one gets drunk in a cafe, destroying braincells. Here it's the
opposite :)
On Fri, Feb 13, 2009 at 11:01 AM, Duncan Coutts wrote: On Thu, 2009-02-12 at 22:58 -0500, David Menendez wrote: On Thu, Feb 12, 2009 at 6:26 PM, Don Stewart bugfact: Consider the following code stamp v x = do
t <- getCurrentTime
putMVar v (x,t) Is it possible - with GHC - that a thread switch happens after the t
<-
getCurrentTime and the putMVar v (x,t)? Yes. if 't' is heap allocated, there could be a context switch. If so, how would it be possible to make sure that the operation of
reading the
current time and writing the pair to the MVar is an "atomic"
operation, in the
sense that no thread switch can happen between the two? Would this
require STM? Using 'atomically' and TVars in STM, perhaps? Else, use withMVar? Or
a
modifyMVar in IO? As I understand it, withMVar or modifyMVar will protect you from
extraneous exceptions, but they won't prevent another thread from
writing to the MVar between the take and the put. You have to cooperate with the other users of the MVar. If each thread is using readMVar, withMVar or modifyMVar then it's fine.
The read/with/modify actions do a takeMVar followed by a putMVar. If one
thread is using withMVar and another is doing putMVar directly then the
exclusion scheme does not work. Duncan

Hello Peter, Friday, February 13, 2009, 2:17:52 AM, you wrote:
If so, how would it be possible to make sure that the operation of reading the current time and writing the pair to the MVar is an "atomic" operation, in the sense that no thread switch can happen between the two? Would this require STM?
it may be better to change architecture so that you no more need atomic operations - these are "unnatural" for mvar/chan approach -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Peter Verswyvelen wrote:
Consider the following code
stamp v x = do t <- getCurrentTime putMVar v (x,t)
Is it possible - with GHC - that a thread switch happens after the t <- getCurrentTime and the putMVar v (x,t)?
If so, how would it be possible to make sure that the operation of reading the current time and writing the pair to the MVar is an "atomic" operation, in the sense that no thread switch can happen between the two? Would this require STM?
Thanks again for sharing your wisdom with me :)
Peter
I'm not entirely sure what you are trying to achieve here. Presumably you want v to contain the (value, time) pair as soon as possible after time "t". Of course it won't be instantaneous. So another thread could observe that at time (t+delta) the variable "v" does not yet contain (x,t). Is this a problem? Atomic transactions won't work because "getCurrentTime" is of type "IO Time", whereas anything inside "atomic" has to be of type "STM a". In theory you could lock out context switches by messing around with the GHC runtime, but if you are running on a multicore machine then that won't work either. Paul.

If you have two streams of time/value pairs - using MVars as write-once
sampling variables - and both streams are fed from another thread (e.g.
timers firing), and you want to merge these two streams into a single stream
with monotonic time stamps, then you want to be able to check if at time t
an occurrence exists in a stream. In the case an old time was read but not
yet written to an mvar, this could lead to the merged stream not being
monotonic. At least in my C# prototype that was the case, I used many very
high frequency timers to stress test the merger, and this bug popped up. I
found similar code in the Reactive library, but Reactive is much more clever
operationally (and semantically) than my little prototype so it might not be
a problem. But if it is, I guess it can be solved by introducing another
MVar to indicate "I'm reading time", at least I solved it in the C#
prototype in that way.
On Sat, Feb 14, 2009 at 8:01 PM, Paul Johnson
I'm not entirely sure what you are trying to achieve here. Presumably you want v to contain the (value, time) pair as soon as possible after time "t". Of course it won't be instantaneous. So another thread could observe that at time (t+delta) the variable "v" does not yet contain (x,t). Is this a problem?
Atomic transactions won't work because "getCurrentTime" is of type "IO Time", whereas anything inside "atomic" has to be of type "STM a".
In theory you could lock out context switches by messing around with the GHC runtime, but if you are running on a multicore machine then that won't work either.
Paul.

2009/2/14 Peter Verswyvelen
If you have two streams of time/value pairs - using MVars as write-once sampling variables - and both streams are fed from another thread (e.g. timers firing), and you want to merge these two streams into a single stream with monotonic time stamps, then you want to be able to check if at time t an occurrence exists in a stream.
What you want to do isn't actually achievable on multi-processor machines without some form of mutual exclusion. Time on different cores does not progress monotonically, and you'll pay an enormous performance penalty to do what you want to do (the nature of which is somewhat unclear).

I'm not sure what you mean with "Time on different cores does not progress
monotonically". Time could come from a dedicated clock device. E.g. in the
broadcast television sector a time signal is distributed across all hardware
components to keep them all in sync within some margin, or you could use the
clock from a local sound card, etc. I guess each operating system provides
such a clock.
I'm also not sure about the performance penalty. One would surely get a
penalty with a global lock on the clock (serializing time), but I think the
problem can be solved with a local lock per stream. But I would have to
think about this more before claiming such things :-)
Maybe you could elaborate a bit more on your claims?
On Sun, Feb 15, 2009 at 5:38 AM, Bryan O'Sullivan
2009/2/14 Peter Verswyvelen
If you have two streams of time/value pairs - using MVars as write-once sampling variables - and both streams are fed from another thread (e.g. timers firing), and you want to merge these two streams into a single stream with monotonic time stamps, then you want to be able to check if at time t an occurrence exists in a stream.
What you want to do isn't actually achievable on multi-processor machines without some form of mutual exclusion. Time on different cores does not progress monotonically, and you'll pay an enormous performance penalty to do what you want to do (the nature of which is somewhat unclear).

Peter Verswyvelen
"Time on different cores does not progress monotonically"
Two cores executing the same code are not guaranteed to finish them in the same time span, due to caching, temperature, voltage jaggies, quantum-mechanic inference, ... -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.
participants (8)
-
Achim Schneider
-
Bryan O'Sullivan
-
Bulat Ziganshin
-
David Menendez
-
Don Stewart
-
Duncan Coutts
-
Paul Johnson
-
Peter Verswyvelen