Created
February 17, 2017 13:38
-
-
Save Flash3001/da5bd3ca800f674082dd8030ef70cf4e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Threading; | |
namespace TearDateTime | |
{ | |
class Program | |
{ | |
public const int ITERATIONS = 20000; | |
public const int MAX_THREADS = 30; | |
public const int MAX_RERUNS = 10; | |
public const int MAX_FULL_RERUN = 4; | |
static unsafe void Main(string[] args) | |
{ | |
Console.WriteLine("-------------- Trying to Tear --------------"); | |
Console.WriteLine($"Running: {sizeof(IntPtr) * 8}bits"); | |
Console.WriteLine($"Max Threads: {MAX_THREADS}"); | |
Console.WriteLine($"Max Reruns: {MAX_RERUNS}"); | |
Console.WriteLine($"Max Iterations per Thread: {ITERATIONS}"); | |
Console.WriteLine("--------------------------------------------"); | |
for (int i = 0; i < MAX_FULL_RERUN; i++) | |
{ | |
Console.WriteLine("----- Tears ------ | -------- Size ---------"); | |
Tearer<long>.Run((n) => n, sizeof(long)); | |
Tearer<DateTime>.Run((n) => new DateTime(n), sizeof(DateTime)); | |
Tearer<Struct128>.Run((n) => new Struct128(n), sizeof(Struct128)); | |
Tearer<Struct192>.Run((n) => new Struct192(n), sizeof(Struct192)); | |
Tearer<Struct256>.Run((n) => new Struct256(n), sizeof(Struct256)); | |
} | |
Console.WriteLine("------------------- End --------------------"); | |
Console.ReadLine(); | |
} | |
} | |
#region Tearer | |
static class Tearer<T> | |
where T : struct | |
{ | |
static int _threads = 1; // 2x | |
static int _rerun = 0; | |
static T _value; | |
static T[] _values; | |
static int _tearsFound; | |
static object _tearsLock = new object(); | |
static CountdownEvent _threadsEndend; | |
static Random _random = new Random(); | |
static void Setup(Func<long, T> getNew) | |
{ | |
var range = Enumerable.Range(0, _threads); | |
_values = range.Select(c => getNew((long)_random.Next() << 30 | (long)_random.Next())).ToArray(); | |
_threadsEndend = new CountdownEvent(_threads * 2); | |
_value = _values[0]; // Remove to get false positives! You will get 'normal' races, not tears. | |
} | |
static void Assign(int i) | |
{ | |
for (int c = 0; c < Program.ITERATIONS; c++) | |
{ | |
_value = _values[i]; | |
} | |
_threadsEndend.Signal(); | |
} | |
static void FindTear() | |
{ | |
for (int c = 0; c < Program.ITERATIONS; c++) | |
{ | |
var localValue = _value; | |
if (!_values.Contains(localValue)) | |
{ | |
lock (_tearsLock) | |
{ | |
_tearsFound++; | |
Console.CursorTop--; | |
Console.WriteLine($"Total tears {_tearsFound} in {typeof(T).Name}"); | |
} | |
} | |
} | |
_threadsEndend.Signal(); | |
} | |
public static unsafe void Run(Func<long, T> getNew, int size) | |
{ | |
_rerun = 0; | |
_tearsFound = 0; | |
Console.WriteLine($"Running {typeof(T).Name}: {size * 8}bits"); | |
while (_rerun < Program.MAX_RERUNS) | |
{ | |
Setup(getNew); | |
for (int i = 0; i < _threads; i++) | |
{ | |
var l = i; | |
new Thread(() => Assign(l)).Start(); | |
new Thread(FindTear).Start(); | |
} | |
_threadsEndend.Wait(); | |
_threadsEndend.Dispose(); | |
_threads++; | |
if (_threads == Program.MAX_THREADS) | |
{ | |
_rerun++; | |
_threads = 1; | |
} | |
} | |
Console.CursorTop--; | |
Console.WriteLine($"\t{ _tearsFound.ToString().PadLeft(3, ' ')}\t\t{typeof(T).Name} ({size * 8}bits)"); | |
} | |
} | |
#endregion | |
#region Structs | |
struct Struct128 | |
{ | |
long a, b; | |
public Struct128(long num) | |
{ | |
a = b = num; | |
} | |
public override bool Equals(object obj) | |
{ | |
var o = (Struct128)obj; | |
return o.a == this.a && o.b == this.b; | |
} | |
} | |
struct Struct192 | |
{ | |
long a, b, c; | |
public Struct192(long num) | |
{ | |
a = b = c = num; | |
} | |
public override bool Equals(object obj) | |
{ | |
var o = (Struct192)obj; | |
return o.a == this.a && o.b == this.b && o.c == this.c; | |
} | |
} | |
struct Struct256 | |
{ | |
long a, b, c, d; | |
public Struct256(long num) | |
{ | |
a = b = c = d = num; | |
} | |
public override bool Equals(object obj) | |
{ | |
var o = (Struct256)obj; | |
return o.a == this.a && o.b == this.b && o.c == this.c && o.d == this.d; | |
} | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment