Skip to content

Commit 7508d98

Browse files
committed
Remove some volatile use on objects in corelib
From a review of the use, all of this use for lazy initialization now appears to be superfluous, given our documented memory model.
1 parent a344abd commit 7508d98

File tree

16 files changed

+55
-86
lines changed

16 files changed

+55
-86
lines changed

src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,13 @@ internal sealed partial class CultureData
111111
private string? _sAM1159; // (user can override) AM designator
112112
private string? _sPM2359; // (user can override) PM designator
113113
private string? _sTimeSeparator;
114-
private volatile string[]? _saLongTimes; // (user can override) time format
115-
private volatile string[]? _saShortTimes; // (user can override) short time format
116-
private volatile string[]? _saDurationFormats; // time duration format
114+
private string[]? _saLongTimes; // (user can override) time format
115+
private string[]? _saShortTimes; // (user can override) short time format
117116

118117
// Calendar specific data
119118
private int _iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really)
120119
private int _iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really)
121-
private volatile CalendarId[]? _waCalendars; // all available calendar type(s). The first one is the default calendar
120+
private CalendarId[]? _waCalendars; // all available calendar type(s). The first one is the default calendar
122121

123122
// Store for specific data about each calendar
124123
private CalendarData?[]? _calendars; // Store for specific calendar data
@@ -150,7 +149,7 @@ internal sealed partial class CultureData
150149
/// </remarks>
151150
private static Dictionary<string, string> RegionNames =>
152151
s_regionNames ??=
153-
new Dictionary<string, string>(257 /* prime */, StringComparer.OrdinalIgnoreCase)
152+
new Dictionary<string, string>(255, StringComparer.OrdinalIgnoreCase)
154153
{
155154
{ "001", "en-001" },
156155
{ "029", "en-029" },
@@ -411,7 +410,7 @@ internal sealed partial class CultureData
411410

412411
// Cache of regions we've already looked up
413412
private static volatile Dictionary<string, CultureData>? s_cachedRegions;
414-
private static volatile Dictionary<string, string>? s_regionNames;
413+
private static Dictionary<string, string>? s_regionNames;
415414

416415
/// <summary>
417416
/// The culture name to use to interop with the underlying native globalization libraries like ICU or Windows NLS APIs.
@@ -621,7 +620,6 @@ private static CultureData CreateCultureWithInvariantData()
621620
invariant._sPM2359 = "PM"; // PM designator
622621
invariant._saLongTimes = new string[] { "HH:mm:ss" }; // time format
623622
invariant._saShortTimes = new string[] { "HH:mm", "hh:mm tt", "H:mm", "h:mm tt" }; // short time format
624-
invariant._saDurationFormats = new string[] { "HH:mm:ss" }; // time duration format
625623

626624
// Calendar specific data
627625
invariant._iFirstDayOfWeek = 0; // first day of week
@@ -661,7 +659,7 @@ private static CultureData CreateCultureWithInvariantData()
661659
/// We need an invariant instance, which we build hard-coded
662660
/// </summary>
663661
internal static CultureData Invariant => s_Invariant ??= CreateCultureWithInvariantData();
664-
private static volatile CultureData? s_Invariant;
662+
private static CultureData? s_Invariant;
665663

666664
// Cache of cultures we've already looked up
667665
private static volatile Dictionary<string, CultureData>? s_cachedCultures;
@@ -1381,18 +1379,10 @@ internal string[] LongTimes
13811379
{
13821380
if (_saLongTimes == null && !GlobalizationMode.Invariant)
13831381
{
1384-
Debug.Assert(!GlobalizationMode.Invariant);
1385-
13861382
string[]? longTimes = GetTimeFormatsCore(shortFormat: false);
1387-
if (longTimes == null || longTimes.Length == 0)
1388-
{
1389-
_saLongTimes = Invariant._saLongTimes!;
1390-
}
1391-
else
1392-
{
1393-
_saLongTimes = longTimes;
1394-
}
1383+
_saLongTimes = longTimes != null && longTimes.Length != 0 ? longTimes : Invariant._saLongTimes!;
13951384
}
1385+
13961386
return _saLongTimes!;
13971387
}
13981388
}
@@ -1407,23 +1397,13 @@ internal string[] ShortTimes
14071397
{
14081398
if (_saShortTimes == null && !GlobalizationMode.Invariant)
14091399
{
1410-
Debug.Assert(!GlobalizationMode.Invariant);
1411-
14121400
// Try to get the short times from the OS/culture.dll
1401+
// If we couldn't find short times, then compute them from long times
1402+
// (eg: CORECLR on < Win7 OS & fallback for missing culture.dll)
14131403
string[]? shortTimes = GetTimeFormatsCore(shortFormat: true);
1414-
1415-
if (shortTimes == null || shortTimes.Length == 0)
1416-
{
1417-
//
1418-
// If we couldn't find short times, then compute them from long times
1419-
// (eg: CORECLR on < Win7 OS & fallback for missing culture.dll)
1420-
//
1421-
shortTimes = DeriveShortTimesFromLong();
1422-
}
1423-
1424-
// Found short times, use them
1425-
_saShortTimes = shortTimes;
1404+
_saShortTimes = shortTimes != null && shortTimes.Length != 0 ? shortTimes : DeriveShortTimesFromLong();
14261405
}
1406+
14271407
return _saShortTimes!;
14281408
}
14291409
}

src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ private static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs<Cul
126126
s_currentThreadUICulture = args.CurrentValue;
127127
}
128128

129-
private static volatile Dictionary<string, CultureInfo>? s_cachedCulturesByName;
130-
private static volatile Dictionary<int, CultureInfo>? s_cachedCulturesByLcid;
129+
private static Dictionary<string, CultureInfo>? s_cachedCulturesByName;
130+
private static Dictionary<int, CultureInfo>? s_cachedCulturesByLcid;
131131

132132
// The parent culture.
133133
private CultureInfo? _parent;

src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,8 +1914,8 @@ internal bool YearMonthAdjustment(ref int year, ref int month, bool parsedMonthN
19141914
internal const string JapaneseLangName = "ja";
19151915
internal const string EnglishLangName = "en";
19161916

1917-
private static volatile DateTimeFormatInfo? s_jajpDTFI;
1918-
private static volatile DateTimeFormatInfo? s_zhtwDTFI;
1917+
private static DateTimeFormatInfo? s_jajpDTFI;
1918+
private static DateTimeFormatInfo? s_zhtwDTFI;
19191919

19201920
/// <summary>
19211921
/// Create a Japanese DTFI which uses JapaneseCalendar. This is used to parse

src/libraries/System.Private.CoreLib/src/System/Globalization/GregorianCalendar.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class GregorianCalendar : Calendar
2626

2727
internal static ReadOnlySpan<int> DaysToMonth366 => [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];
2828

29-
private static volatile Calendar? s_defaultInstance;
29+
private static Calendar? s_defaultInstance;
3030

3131
public override DateTime MinSupportedDateTime => DateTime.MinValue;
3232

src/libraries/System.Private.CoreLib/src/System/Globalization/JapaneseCalendar.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public partial class JapaneseCalendar : Calendar
4242

4343
// Using a field initializer rather than a static constructor so that the whole class can be lazy
4444
// init.
45-
private static volatile EraInfo[]? s_japaneseEraInfo;
45+
private static EraInfo[]? s_japaneseEraInfo;
4646

4747
// m_EraInfo must be listed in reverse chronological order. The most recent era
4848
// should be the first element.
@@ -67,20 +67,19 @@ public partial class JapaneseCalendar : Calendar
6767
internal static EraInfo[] GetEraInfo()
6868
{
6969
// See if we need to build it
70-
return s_japaneseEraInfo ??
71-
(s_japaneseEraInfo = GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras()) ??
70+
return s_japaneseEraInfo ??=
71+
(GlobalizationMode.UseNls ? NlsGetJapaneseEras() : IcuGetJapaneseEras()) ??
7272
// See if we have to use the built-in eras
73-
(s_japaneseEraInfo = new EraInfo[]
74-
{
73+
[
7574
new EraInfo(5, 2019, 5, 1, 2018, 1, GregorianCalendar.MaxYear - 2018, "\x4ee4\x548c", "\x4ee4", "R"),
7675
new EraInfo(4, 1989, 1, 8, 1988, 1, 2019 - 1988, "\x5e73\x6210", "\x5e73", "H"),
7776
new EraInfo(3, 1926, 12, 25, 1925, 1, 1989 - 1925, "\x662d\x548c", "\x662d", "S"),
7877
new EraInfo(2, 1912, 7, 30, 1911, 1, 1926 - 1911, "\x5927\x6b63", "\x5927", "T"),
7978
new EraInfo(1, 1868, 1, 1, 1867, 1, 1912 - 1867, "\x660e\x6cbb", "\x660e", "M")
80-
});
79+
];
8180
}
8281

83-
internal static volatile Calendar? s_defaultInstance;
82+
internal static Calendar? s_defaultInstance;
8483
internal GregorianCalendarHelper _helper;
8584

8685
internal static Calendar GetDefaultInstance() => s_defaultInstance ??= new JapaneseCalendar();

src/libraries/System.Private.CoreLib/src/System/Globalization/NumberFormatInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace System.Globalization
3939
/// </remarks>
4040
public sealed class NumberFormatInfo : IFormatProvider, ICloneable
4141
{
42-
private static volatile NumberFormatInfo? s_invariantInfo;
42+
private static NumberFormatInfo? s_invariantInfo;
4343
internal static readonly string[] s_asciiDigits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
4444
internal static readonly int[] s_intArrayWithElement3 = [3];
4545

src/libraries/System.Private.CoreLib/src/System/Globalization/RegionInfo.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class RegionInfo
2121
private readonly CultureData _cultureData;
2222

2323
// The RegionInfo for our current region
24-
internal static volatile RegionInfo? s_currentRegionInfo;
24+
internal static RegionInfo? s_currentRegionInfo;
2525

2626
public RegionInfo(string name)
2727
{
@@ -84,7 +84,6 @@ internal RegionInfo(CultureData cultureData)
8484

8585
/// <summary>
8686
/// This instance provides methods based on the current user settings.
87-
/// These settings are volatile and may change over the lifetime of the
8887
/// </summary>
8988
public static RegionInfo CurrentRegion
9089
{

src/libraries/System.Private.CoreLib/src/System/Globalization/TaiwanCalendar.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class TaiwanCalendar : Calendar
2727
new EraInfo(1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
2828
};
2929

30-
private static volatile Calendar? s_defaultInstance;
30+
private static Calendar? s_defaultInstance;
3131

3232
private readonly GregorianCalendarHelper _helper;
3333

src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ public abstract class Stream : MarshalByRefObject, IDisposable, IAsyncDisposable
2222
private protected SemaphoreSlim EnsureAsyncActiveSemaphoreInitialized() =>
2323
// Lazily-initialize _asyncActiveSemaphore. As we're never accessing the SemaphoreSlim's
2424
// WaitHandle, we don't need to worry about Disposing it in the case of a race condition.
25-
#pragma warning disable CS8774 // We lack a NullIffNull annotation for Volatile.Read
26-
Volatile.Read(ref _asyncActiveSemaphore) ??
27-
#pragma warning restore CS8774
25+
_asyncActiveSemaphore ??
2826
Interlocked.CompareExchange(ref _asyncActiveSemaphore, new SemaphoreSlim(1, 1), null) ??
2927
_asyncActiveSemaphore;
3028

src/libraries/System.Private.CoreLib/src/System/IO/StringWriter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace System.IO
1212
// the resulting sequence of characters to be presented as a string.
1313
public class StringWriter : TextWriter
1414
{
15-
private static volatile UnicodeEncoding? s_encoding;
15+
private static UnicodeEncoding? s_encoding;
1616

1717
private readonly StringBuilder _sb;
1818
private bool _isOpen;

0 commit comments

Comments
 (0)