Chris Vine <[email protected]> writes: > On Fri, 26 May 2017 13:42:39 +0200 > [email protected] wrote: >> Chris Vine <[email protected]> writes: >> >> > On Fri, 26 May 2017 12:37:47 +0200 >> > [email protected] 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 [email protected]
