Want reasonable reference counting? Disable automatic sharing of immutable
Stanislav Blinov
stanislav.blinov at gmail.com
Sat Nov 13 23:08:01 UTC 2021
On Saturday, 13 November 2021 at 21:55:21 UTC, Steven
Schveighoffer wrote:
> You are not getting that the GC collecting has nothing to do
> with the pure function's executation. The GC hijacks the
> current thread to do its business, and then passes back control
> to the caller.
...while introducing side effects, which the caller of the pure
function was promised WOULD NOT HAPPEN, by the interface of the
pure function.
>>
>>> Imagine it like a context switch to another thread that runs
>>> the GC code, and then switches back to the pure code.
>>
>> If I imagine that, the assert above should always hold.
>> Because there should be no way that imaginary "another thread"
>> would access main thread's `threadLocal`. Somehow, reality
>> contradicts imagination.
>
> Actually, the GC can run finalizers from ANY thread. So
> accessing thread locals in a GC finalizer is risky behavior
> anyway.
The language allows this, and the runtime does this. There's no
need for speculation. Risky or not. If a language guarantees
something can't happen, it better not happen. Pure functions
cannot mutate global state, except through arguments, in which
case it's a weakly pure function. That's what the language
guarantees. Pure functions can only call pure functions. That's
what the language guarantees.
>>> It's similar to running some kernel code, or signal code --
>>> it's initiated by a separate entity, in this case the GC.
>>>
>>>> Unless that changed and GC isn't doing that anymore, that's
>>>> a bug that's been open for some years now.
>>>
>>> It should be closed as invalid. Which bug is that?
>>
>> https://issues.dlang.org/show_bug.cgi?id=19316
>
> Thanks! I closed it.
Cool. Then it's on you to reopen it back.
> The assert is incorrectly written,
Read `a`, call pure function, read `a`. Where is it possible for
`a` to mutate, after first read and before second read? Can't be
another thread, `a` is a thread-local int. Can't be the pure
function, it's pure and cant mutate `a`. So where is it possible
for `a` to mutate?
> as the thread local can change at any time if the GC happens to
> run on the current thread, and happens to be finalizing a `Bad`
> object (even if it was allocated via a different thread).
...Which means that anything that triggers collection (including
allocation) cannot be pure. Which is exactly my point. Nor can it
be @safe.
> This is how you set it up.
I have no words...
> Honestly, I think accessing thread locals in a GC destructor
> should be in the spec as implementation-defined behavior.
So, then, should be any other side effects. Good luck with that.
More information about the Digitalmars-d
mailing list