[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: question about atomics
Re: question about atomics
Sat, 27 May 2017 10:28:29 +0200
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
>> (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!