guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: question about atomics


From: Chris Vine
Subject: Re: question about atomics
Date: Fri, 26 May 2017 13:51:22 +0100

On Fri, 26 May 2017 13:42:39 +0200
address@hidden wrote:
> Chris Vine <address@hidden> writes:
> 
> > On Fri, 26 May 2017 12:37:47 +0200
> > address@hidden wrote:  
> >> Hello,
> >> 
> >> I'm making a simple program that processes a lot of mail in
> >> separate guile threads.
> >> 
> >> I would like a counter of how many messages have been processed so
> >> I made an attempt with atomics.
> >> 
> >> first:
> >>     (define *msgcount* (make-atomic-box 0))
> >> 
> >> and later:
> >>     (atomic-box-swap! *msgcount* (+ 1 (atomic-box-ref *msgcount*)))
> >> 
> >> This of course doesn't work very well, and I didnt expect it to
> >> either. (usually the count is low by a couple of hundred messages)
> >> 
> >> So basically, how do I get something similar to the swap! function
> >> in clojure? Did I miss something in the documentation for guiles
> >> atomics?
> >> 
> >> I think I expected to be able to do the following:
> >>     (atomic-box-swap! *msgcount* (lambda (atom) (+ 1
> >> (atomic-box-ref atom))))  
> >
> > That won't work.  You have to use atomic-box-compare-and-swap!, in
> > order to detect interleaving by other threads.  For more on this,
> > google "compare and swap".  
> 
> I wound up with this, is there some better way to do this? Feels a
> bit verbose.
> 
> (define (incatom atom)
>   (let ((expected (atomic-box-ref atom)))
>     (while (not (= expected (atomic-box-compare-and-swap! atom expected (+ 1 
> expected))))
>       (set! expected (atomic-box-ref atom)))))

I would be inclined to use a named let rather than while and set!, but
that is a matter of taste.

I have not used guile's atomic-box, but looking at the documentation it
says that atomic-box-compare-and-swap! takes a scheme object as 'expected'
and compares using eq?.  In that case, your use of the = comparator on the
return value is wrong.  I find that part of the documentation quite
difficult to penetrate: if atomic-box is capable of holding numbers
then presumably it wraps the number into an object capable of being
compared using eq? for you, if not you would have to wrap the number in,
say, a single element list yourself.  Dunno, sorry, I know how to do CAS
in C but not using this scheme procedure.  You may need to look at the
implementation in the guile source to see how to use it correctly.

If in doubt, you could always go back to using a mutex and a number, I
guess.  Less efficient but it may be sufficient for your purposes.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]