Welcome! Please see the About page for a little more info on how this works.

+2 votes
in Records and Types by
recategorized by

As a person who is really into atoms and compare and set as a concurrency primitive, it would be nice to be able to do a compare and set on mutable fields in a deftype without incurring the overhead (more objects taking more memory, and more pointers to chase) of either a java AtomicReference or a clojure atom.

The jvm has several mechanisms that allow you to directly cas on a field (AtomicReferenceFieldUpdater , VarHandles. maybe others). It seems like deftype could make such a thing available on request.

It is currently possible to use AtomicReferenceFieldUpdater with deftype, but is somewhat convoluted due to volatile fields being private, and the lack of static initializers.

1 Answer

0 votes
by

This seems like an interesting request but is more of a solution rather than a problem. Can you restate it more from that perspective?

by
I am sorry, I just don't understand what you are asking for.

I think this is the second or third time you given similar feedback on this (previously in #clojure-dev), and I have already rewritten this once to (I thought) incorporate that feedback. Thank you for taking the time, but it seems clear that I just don't get it.
by
As in, "I'm trying to make X, but I can't". What's X? what's the case where you need to do this?
by
what a comedy of errors, I misunderstood things basically the opposite way before and removed all references to my specific problem.

I wrote a custom kind of reference type, not really a clojure reference type, but a similar kind of thing. A box with controlled mutation for the contents of the box. A ends up being vaguely atom or ref like.

My type being a reference type, has a mutable field that points to whatever the reference itself points to, a long with other fields to facilitate other operations. I would like to mutate the mutable field using compare and set.

Writing this in "vanilla" clojure the only way to do this by using an atom or an AtomicReference wrapper around a value held in a deftype field. This works but adds 1 or 2 levels of pointer chasing. I would like to get rid of those extra pointers.

Java provides at least two different facilities for doing a compare and set directly on a mutable field (they may require that the field be volatile, I forget). Both of those mechanisms work by creating a kind of field accessor object. The typical pattern for a class seems to be create the field accessor object in a static initializer and then use it as needed when doing cas type stuff on fields of instances.

The typical pattern doesn't work with deftype as is, because although you an make a deftype field mutable, that also makes it private, which makes constructing a field accessor object difficult. You can't construct one from "outside" because the field is private, and deftype's don't provide a way to do static initialization.  There are ways to work around this, basically you add a method to your deftype that does nothing but create and return the field accessor object, and then in some top level static context construct a dummy instance of your deftype and invoke the method. So it is possible to make this work, it is just kind of terrible.

I initially did the dummy deftype instance thing, but eventually just wrote what is basically an extremely stripped down version of deftype to generate a class with fields and a static initializer that sets up AtomicReferenceFieldUpdater for specific fields. This also works, but relied on having some experience with the asm library, and some care to make it work well with aot compilation (I think I got this part right, but not sure).

Compare and set is great, it would be nice to provide someway to do it on deftype fields that didn't require additional object wrappers around what we want to compare and set. The mechanisms for it exist in java/jvm but are painful to take advantage of in clojure.
...