On Sun, Nov 24, 2024 at 1:13 AM Lénárd Szolnoki via Std-Discussion <std-discussion@lists.isocpp.org> wrote:


On 24 November 2024 02:03:51 GMT, J Decker via Std-Discussion <std-discussion@lists.isocpp.org> wrote:
>https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1152r0.html#parret
>
>
>I have some datatype, which is a volatile list.  What makes it volatile is
>that other threads can change the values associated with the list without
>any other threads being aware of the change.  Primarily, what happens, when
>the objects are not defined as volatile, the optimizers can read the value
>early in a function, and then never read it again.  The only meaning of
>volatile *I* knew of was 'read always'.  Writes and locks and other
>unrelated things mentioned in the paper just confuse the issue.  What I
>need is just a way to tell compiler optimizers 'hey don't be smart, if the
>code needs the value, get the value from the place specified.'   Writes
>could be cached - but it's something the programmer would do.  It(volatile)
>really has nothing to do atomics.
>
>---
>So what I end up with is say this is the existing type.
>
>typedef struct DataBlock volatile * volatile PDATALIST;
>
>Then the creation function is PDATALIST CreateDataList( size_t sz );
>and usage is PDATALIST pdl = CreateDataList( sizeof( int ) );
>or passed as a parameter to PDATALIST AddDataItem( PDATALIST*, POINTER );
>or int GetItemCount( PDATALIST );
>
>That's all great... but then with LLVM's deprecation warning what I end up
>having to do is
>
>
>
>typedef struct DataBlock volatile * volatile PDATALIST;
>typedef struct DataBlock volatile * PDATALIST_rval;
>
>PDATALIST_rval CreateDataList( size_t sz );
>PDATALIST_rval AddDataItem( PDATALIST*, POINTER );
>int GetItemCount( PDATALIST_rval, POINTER );
>
>PDATALIST pdl = CreateDataList( sizeof( int ) );
>
>- it becomes unobvious that one should use PDATALIST as the variable type,
>while the function that creates the list is a PDATALIST_rval.
>
>Hooray for features that improve(err diminish) code clarity?
>
>Maybe should have started with deprecating volatile in typedefs?
>
>How can I code that so it's not mixing a bunch of different types?
>PDATALIST_rval and PDATALIST, or any of the half dozen other thread-safe
>container types that have been implemented since the mid 90's?  (and
>preferably without having to touch many thousands of instances of PLIST
><...> to make it PLIST volatile <...>)
>
>J
>
>Yes, I get it .... in the passing of the volatile variable, it ends up
>being a cached value in a register and loses the original reference... and
>technically the GetItemCount should take a PDATALIST* instead... but that's
>a short time of life of that image anyway, and subsequent calls would end
>up with the new list address anyway; and there's of course times where the
>value ends up cached for several instructions, but when it goes back over
>the line to use the value it gets read again.
>
>I feel that a case study for implications of this wasn't really done very
>well - but then - maybe the usage of multi-threading is just that much less
>than I think it should be that this didn't show up.  None of this has
>anything to do with Atomics and the locking of such a structure - some of
>them are lock-free.

volatile is unsuitable for implementing thread-safe lock-free data structures, you should be using lock-free atomics for that.

Next you'll be telling me I shouldn't be compiling this code with a C and/or a C++ compiler...
 

Cheers,
Lénárd
--
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion