Zulip Chat Archive

Stream: lean4

Topic: Concurrency and Parallelism in Lean4


Sofia Rodrigues (Sep 02 2023 at 23:05):

I'm trying to make some code that runs in parallel in Lean4 and I would like to know some things before starting:

  • can IO.asTask cause data races if I'm using IO.Ref?
  • Are there Atomics like Rust or C++ in Lean4 or IO.Ref?
  • Is IO.Ref atomic?

Mac Malone (Sep 03 2023 at 00:40):

@Felipe GS Some quick answers:

Schrodinger ZHU Yifan (Sep 03 2023 at 01:01):

Is there something similar to OCaml's Atomic.t?

Sebastian Ullrich (Sep 03 2023 at 07:57):

Mac Malone said:

There is docs4#IO.Mutex

Those docs specifically state that IO.Ref uses atomics!

Sebastian Ullrich (Sep 03 2023 at 08:04):

Underdefined terms such as "data race" and "atomic" are a bit dangerous to use without further specification. I think the strongest statement we can make about IO.Ref is that its operations are guaranteed to be sequentially consistent (a very strong definition of "data race freedom") but they may not necessarily be implemented as only a single atomic CPU instruction (they do the best they can in a reference-counted object model).

Siddhartha Gadgil (Sep 03 2023 at 11:52):

As I use IO.Ref quite a bit, could someone clarify when it is unsafe to use but IO.Mutex can be used safely (and how)?

Sebastian Ullrich (Sep 03 2023 at 13:15):

Unsafe use should, hopefully!, be restricted to unsafe functions. The only difference between the two types is the kind of lock used as (briefly) described in docs4#IO.Mutex. In short, prefer Mutex when you spend more than a trivial amount of time inside the critical section (Ref.modify*/Mutex.atomically*).

Henrik Böving (Sep 03 2023 at 13:15):

If you want to speak in kernel terms an IO.Ref is a spinlock and a IO.Mutex is a sleep lock I assume?

Mac Malone (Sep 03 2023 at 19:00):

Sebastian Ullrich said:

Those docs specifically state that IO.Ref uses atomics!

Fair enough! However, when I think of an atomic reference, I think of a reference one can modify (e.g., via modify) without race conditions. From past experience, this is not possible with IO.Ref and that is why IO.Mutex was introduced. If I understand correctly, the atomicity of IO.Ref is for its load and store operations (e.g., set, get) to prevent data corruption (and ensure proper reference counting).

Sebastian Ullrich (Sep 03 2023 at 21:12):

I've already stated that Ref.modify is (supposed to be) a critical section and what the difference between the two types is, I'm not sure how I can be more clear here. Should there really be a bug, let's file an issue.

Mac Malone (Sep 04 2023 at 02:38):

@Sebastian Ullrich No, sorry, you were clear! :smile: I was just detailing the difference I observed and why I didn't think of IO.Ref as atomic in my initial answer.


Last updated: Dec 20 2023 at 11:08 UTC