[Top][All Lists]

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

Re: question about atomics

From: joakim
Subject: Re: question about atomics
Date: Sat, 27 May 2017 10:28:29 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux)

Chris Vine <address@hidden> writes:

> 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.

For some reason = worked here, I haven't delved further into it.

The named let suggestion was also good thanks.

In the end it turned out I also needed a mutex to synchronize output, so
now I have both a mutex and an atomic for the same thing(a console
progress indicator), which is kind of redundant I guess.

Anyway, I learned new things about guile, so thanks again!

Joakim Verona

reply via email to

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