Conversation
|
|
||
| type Layer = u32; | ||
| static NUM_LEVELS: AtomicU32 = AtomicU32::new(0); | ||
| static NUM_LEVELS: RuntimeCell<u32> = RuntimeCell::new(0); |
There was a problem hiding this comment.
As long as we have the native runtime, this isn't safe. The native runtime can be executed from different threads.
There was a problem hiding this comment.
Really? Multiple threads operate on the same memory at the same time? Why would that be the case?
There was a problem hiding this comment.
Native runtime. This static is shared within the entire context of the binary.
There was a problem hiding this comment.
Sure but you still don't call into any runtime code concurrently with more than one thread? That would make no sense.
There was a problem hiding this comment.
Not the runtime itself, however you can call from different threads into the runtime. Imagine some thread importing a block and another validating an extrinsic. Both will call into the runtime
There was a problem hiding this comment.
I assume in the wasm case we spawn different instances for those calls which are then called in parallel.
To me it sounds like those calls need to be serialized to have the same behavior as with the wasm runtime.
There was a problem hiding this comment.
How do you want to serialize them? The point is, we don't use any global context and if we use it it needs to be thread local.
There was a problem hiding this comment.
Okay I get it now. The native runtime recycles the memory from other calls while the wasm gets fresh memory. Yeah this makes this wrong, unfortunately.
This PR adds a
Syncwrapper aroundCellandRefCell. This allows us to have interior mutability in non-mutable static variables. It is essentially a way to have global mutable state without resorting to spinlocks. This is safe because it is added to FRAME and we know that the runtime is single threaded.As a first user I migrated the code added in #10808 to use
RuntimeCell.