-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add boxed atomics #407
Comments
Atomicfu has two components: library and plugin. Library provides boxed types, and the plugin rewrites code. You could try to add dependency on library, but skip the plugin. |
@mgroth0 could you please elaborate on your use cases that currently suffer from |
@recursive-rat4 Thank you for the suggestion. Sorry, but I am confused and need to ask you for some explaination. I have reviewed the README again, and I do not see any mention of the technique you are suggesting. I am confused how it would work. Let me make sure I understand. You are suggesting I do the following:
Now on JVM, this is implemented with: private val FU = AtomicIntegerFieldUpdater.newUpdater(AtomicInt::class.java, "value") The README here confuses me. It says:
However, this is confusing because I already see /**
* Maps to [AtomicIntegerFieldUpdater.getAndAdd].
*/
public actual fun getAndAdd(delta: Int): Int {
val oldValue = FU.getAndAdd(this, delta)
if (trace !== None) trace { "getAndAdd($delta):$oldValue" }
return oldValue
} So it seems to me that |
@fzhinkin here is my issue. I start with this: fun main() {
val obj = MyObject()
obj.next(1)
}
class MyObject {
private val counters =
List(10) {
java.util.concurrent.atomic.AtomicInteger()
}
fun next(index: Int): Int = counters[index].getAndIncrement()
} The buisness logic isn't really important (unless that is what you really are asking about?). But for whatever reason, I create boxed atomics like this in a jvm only object. My goal now is to make my object multiplatform in an idiomatic way. So as a newbie to this library my first attempt is: class MyObjectNowMultiplatform {
private val counters =
List(10) {
kotlinx.atomicfu.atomic(0)
}
fun next(index: Int): Int = counters[index].getAndIncrement()
} But then I get a variety of errors. For example: kotlinx.atomicfu.transformer.TransformerException: factory kotlinx.atomicfu.AtomicFU::atomic invocation must be followed by putfield So then, based on the instructions on the explaination in the README that I need to strictly control how atomics from this library are defined, I try creating my own box: class MyObjectNowMultiplatform {
private val counters =
List(10) {
BoxedAtomicInt(0)
}
fun next(index: Int): Int = counters[index].getAndIncrement()
}
class BoxedAtomicInt(
value: Int
) {
private val value = kotlinx.atomicfu.atomic(value)
fun getAndIncrement() = value.getAndIncrement()
} And this works perfectly. The reason I created this issue then, is specifically because I don't really understand why this library doesn't provide classes like And now after reading the comment from @recursive-rat4 and taking another look at the readme and the implementation of I tried doing what @recursive-rat4 suggested, and depended on |
@mgroth0 thank you for elaborating!
That's correct.
Something like that should indeed do the trick:
Could you please share your build config to check why classes are not available to you? |
Ok, I just got it to work the way I expect finally. The issue ended up being that I used Thank you both for the help! |
I am new to this library, and right away I am confronted with unique compiler errors if I try to use
atomic
in an un-sanctioned way. It needs to be in a constructor or class initialization.To get around this, I create a wrapper for myself:
This is a suggestion to add classes such as
BoxedAtomicInt
directly into the atomicfu library itself.As a newbie here, I am sure this is been brought up already. But searching through the issues and README, I couldn't find a discussion.
I understand that boxing has a performance cost. However, it seems unboxed
atomic
introduces novel restrictions on the compiler level that reduces the flexibility of their usage. If all of these restrictions are all in the name of a performance boost, I am not sure this is justified. After all, the performance boost will have practically zero benefit in many applications.I understand that a user of this library can create their own boxes, as I will. But why should they have to? How does this benefit the kotlin world for every usage of this library to write their own set of wrapper classes? Especially since this library is called "the idiomatic way", I am surprised that it is considered idiomatic to have unboxed atomics with very complicated restrictions even in cases where performance doesn't matter.
The text was updated successfully, but these errors were encountered: