Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can DateTime tear in a 64 bit environment?

In C# setting a value to a variable is atomic as long as its size is at most native int (i.e. 4 bytes in a 32-bit runtime environment and 8 bytes on a 64-bit one). In a 64-bit environment that includes all references types and most built-in value types (byte, short, int, long, etc.).

Setting a bigger value isn't atomic and can cause tearing where only part of the memory is updated.

DateTime is a struct that includes only a single ulong field containing all its data (Ticks and the DateTimeKind) and ulong by itself is atomic in a 64-bit environment.

Does that mean that DateTime is atomic as well? Or Can the following code lead to tearing at some point?

static DateTime _value; static void Main() {     for (int i = 0; i < 10; i++)     {         new Thread(_ =>         {             var random = new Random();             while (true)             {                 _value = new DateTime((long)random.Next() << 30 | (long)random.Next());             }         }).Start();     }      Console.ReadLine(); } 
like image 923
i3arnon Avatar asked Feb 15 '17 19:02

i3arnon


People also ask

Is DateTime a data type in C#?

Date and Time in C# are two commonly used data types. Both Date and Time in C# are represented using C# DateTime class. This tutorial is all about how to work with Date and Time in C# using C# DateTime class and its methods and properties.

Why DateTime is a structure?

Because it is a single point. It doesn't have multiple pieces of data. Under the hood it is represented by a long. I didn't down vote, but from your answer follow that structures are always contain a single "piece of data" and this is the only reason that DateTime is the structure.

Is DateTime a struct?

DateTime is a struct .

What is a DateTime?

The DateTime value type represents dates and times with values ranging from 00:00:00 (midnight), January 1, 0001 Anno Domini (Common Era) through 11:59:59 P.M., December 31, 9999 A.D. (C.E.) in the Gregorian calendar. Time values are measured in 100-nanosecond units called ticks.


1 Answers

From the ECMA specification section "I.12.6.6 Atomic reads and writes"

A conforming CLI shall guarantee that read and write access to properly aligned memory locations no larger than the native word size (the size of type native int) is atomic (see §I.12.6.2) when all the write accesses to a location are the same size. Atomic writes shall alter no bits other than those written. Unless explicit layout control (see Partition II (Controlling Instance Layout)) is used to alter the default behavior, data elements no larger than the natural word size (the size of a native int) shall be properly aligned. Object references shall be treated as though they are stored in the native word size.

A native int is a IntPtr in C#.

So long as sizeof(IntPtr) >= sizeof(DateTime) is true for the runtime environment (aka: running as 64 bit), and they don't alter the internal structure to be explicit layout with misaligned bytes instead of the [StructLayout(LayoutKind.Auto)] it currently has, then reads and writes of a DateTime struct (or any other struct that follows those rules) are guaranteed to be atomic by the ECMA specification.

You can verify that by running the following code in a 64-bit environment:

public unsafe static void Main() {     Console.WriteLine(sizeof(DateTime)); // Outputs 8     Console.WriteLine(sizeof(IntPtr)); // Outputs 8     Console.WriteLine(sizeof(ulong)); // Outputs 8 } 
like image 165
Scott Chamberlain Avatar answered Oct 04 '22 12:10

Scott Chamberlain