jeudi 15 octobre 2020

Is there a happens before relationship between the use of an stack local object and the destruction of the object?

I watched this Herb Sutter talk: https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2

Around the 1:25 mark, he talks about why the decrement of an atomic reference counter of a shared pointer requires acquire-release memory ordering.

The logic in the video is as follows:

  1. There are two threads, both calling fetch_sub at same time.
  2. Thread 1 has a use of the object before the decrement. It decrements the reference counter from 2 to 1.
  3. Thread 2 decrements from 1->0, and deletes the control block pointer.

The reason for acquire/release being necessary is stated to be that the use of the object in thread 1 could be reordered below the decrement in thread 1 from the perspective of thread 2. Then thread 2 would decrement from 1->0 and delete the object before line A has happened.

Here is the slide: enter image description here

But in a shared pointer implementation, the destructor (ignoring copy assignment, and manual release) does not use the object before the decrement. That means that a function call on the object of the shared pointer would have to be reordered after the destruction of the shared pointer.

It's very confusing to me how this is possible. Here are the specific questions I have:

  1. Is it really possible for a destructor to be reordered before the use of an object? Let's say you had a unique pointer instead of a shared pointer. If the destructor of the unique ptr was reordered before its use, then you would be accessing deleted memory. That can't be right.

  2. Why does it matter whether line A in thread 1 in the slide appears below thread 1's decrement from the perspective of thread 2? Assuming within thread 1 line A appears above the decrement, then won't the object state be updated and any side effects of the function call become apparent to thread 2 once the cache line is pushed to its processor? The code only runs on one thread. The relevant line on the slide is: 'To thread 2, line A could appear to move below thread 1's decrement'.

Aucun commentaire:

Enregistrer un commentaire