2

Give the following class:

public class LockfreeThing
{
    public DateTimeOffset? When { get; private set; }

    public void Work(DateTimeOffset? someOffset)
    {
        var copy = When;
        if (copy.HasValue)
        {
            if (copy > someOffset)
            {
                // Use copy safely
            }
            else
            {
                When = null;
            }
        }

        When = someOffset;
    }
}

According to this SO answer the reference assignments here are NOT thread safe due to When backing field being a struct.

Disregarding the possibility of var copy = When perhaps reading off of a CPU cache and missing the most up to date value, is it possible to make such code lock-free and thread-safe?

Bruno Garcia
  • 6,029
  • 3
  • 25
  • 38
  • _"is it possible to make such code lock-free and thread-safe?"_ what part of it? The whole `Work` method? Or only the assignments by themselves? – Fildor Mar 21 '18 at 12:54
  • Being able to read/write to When (nullable of DateTimeOffset) – Bruno Garcia Mar 21 '18 at 12:55
  • 2
    I don't think you can. Just use lock and be done with it. – Evk Mar 21 '18 at 13:20
  • 2
    It is a structure, not just because it is DateTimeOffset, also because it is nullable. Updates of structures are never atomic. Or to put it another way, the processor must use multiple writes to update the value. And that is never thread-safe, another thread might observe the value when it is only partially updated. Producing a "torn read". Very nasty bug to troubleshoot, it doesn't go wrong nearly often enough. You can't debug bugs that only occur once a month. – Hans Passant Mar 21 '18 at 15:23
  • Surely so even a long? and using Ticks wouldn't be possible. Ok so it's simply not possible. Thanks. – Bruno Garcia Mar 21 '18 at 15:26
  • Long you can read with Interlocked. But datetimeoffset is long + short (offset). – Evk Mar 21 '18 at 15:40

1 Answers1

0

Assignment to a DateTime is never thread safe (also if it is null).

You could use Ticks instead of DateTime with Int64 and use Interlocked methods to access it.

However what is wrong with using lock?

dsdel
  • 1,042
  • 1
  • 8
  • 11
  • 1
    Lock will introduce contention and as I'm interested in knowing if there's a 'lock-free' approach for this. I thought about Interlocked though still it can't be nullable as it has the same issue from the OP – Bruno Garcia Mar 21 '18 at 12:54
  • @BrunoGarcia Is that academic interest or do you have a RL usecase? – Fildor Mar 21 '18 at 12:55
  • Since using Ticks (without nullable) is the closest answer. Considering the answer being: It's not possible. I'll accept this as the answer. Thanks! – Bruno Garcia Mar 21 '18 at 15:27