Skip to content

Commit df9eb53

Browse files
authored
Mitigate torn writes for current time on 32-bit platforms (#592)
* torn * x86 bench * jit * rem bench ---------
1 parent 80ba526 commit df9eb53

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

BitFaster.Caching/Lru/Time.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,53 @@
1-
namespace BitFaster.Caching.Lru
1+

2+
using System;
3+
using System.Runtime.CompilerServices;
4+
using System.Threading;
5+
6+
namespace BitFaster.Caching.Lru
27
{
38
/// <summary>
49
/// During reads, the policy evaluates ShouldDiscard and Touch. To avoid Getting the current time twice
510
/// introduce a simple time class that holds the last time. This is class with a mutable field, because the
611
/// policy structs are readonly.
712
/// </summary>
13+
/// <remarks>
14+
/// This class mitigates torn writes when running on 32-bit systems using Interlocked read and write.
15+
/// </remarks>
816
internal class Time
917
{
18+
private static readonly bool Is64Bit = Environment.Is64BitProcess;
19+
20+
private long time;
21+
1022
/// <summary>
1123
/// Gets or sets the last time.
1224
/// </summary>
13-
internal long Last { get; set; }
25+
internal long Last
26+
{
27+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
28+
get
29+
{
30+
if (Is64Bit)
31+
{
32+
return time;
33+
}
34+
else
35+
{
36+
return Interlocked.Read(ref time);
37+
}
38+
}
39+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
40+
set
41+
{
42+
if (Is64Bit)
43+
{
44+
time = value;
45+
}
46+
else
47+
{
48+
Interlocked.CompareExchange(ref time, value, time);
49+
}
50+
}
51+
}
1452
}
1553
}

0 commit comments

Comments
 (0)