Concurrency Coordination Reports
Lazy Init Coordination Report
Record write-once initialization and report whether later reads were locked out.
write-once value
A coordination report can record write-once initialization. A `Lazy<int>` runs its build function the first time the value is read and caches the result, so later reads are served from the cached value and never build again. The build count stays at one however many times the value is read. The status line summarizes whether the slot stayed unset, was set by a single read, or stayed locked at one build while later reads were served.
Lazy Init Coordination Report
LazyInitCoordinationReport.cs
Replay: real traced execution (multi-file project)
using System;
class Program
{
static int builds = 0;
static int Build()
{
builds++;
return 7;
}
static void Main()
{
int reads = 1;
var slot = new Lazy<int>(Build);
int served = 0;
for (int i = 0; i < reads; i++)
{
int value = slot.Value;
served++;
}
bool created = slot.IsValueCreated;
string status;
if (!created)
{
status = "unset";
}
else if (served <= 1)
{
status = "set";
}
else
{
status = "locked";
}
Console.WriteLine("reads=" + reads + " served=" + served + " builds=" + builds + " " + status);
}
}
using System;
class Program
{
static int builds = 0;
static int Build()
{
builds++;
return 7;
}
static void Main()
{
int reads = 0;
var slot = new Lazy<int>(Build);
int served = 0;
for (int i = 0; i < reads; i++)
{
int value = slot.Value;
served++;
}
bool created = slot.IsValueCreated;
string status;
if (!created)
{
status = "unset";
}
else if (served <= 1)
{
status = "set";
}
else
{
status = "locked";
}
Console.WriteLine("reads=" + reads + " served=" + served + " builds=" + builds + " " + status);
}
}
using System;
class Program
{
static int builds = 0;
static int Build()
{
builds++;
return 7;
}
static void Main()
{
int reads = 2;
var slot = new Lazy<int>(Build);
int served = 0;
for (int i = 0; i < reads; i++)
{
int value = slot.Value;
served++;
}
bool created = slot.IsValueCreated;
string status;
if (!created)
{
status = "unset";
}
else if (served <= 1)
{
status = "set";
}
else
{
status = "locked";
}
Console.WriteLine("reads=" + reads + " served=" + served + " builds=" + builds + " " + status);
}
}
reads ← 1, slot ← Value is not created., served ← 0
13static void Main()14{15 int reads→ 1 = 1; //@reads=0, 216 var slot→ Value is not created. = new Lazy<int>(Build);17 int served→ 0 = 0;for (int i = 0; i < reads; i++)
19for (int i0 = 0; i < reads1; i++)20{21 int value = slot.Value;builds ← 1
7static int Build()8{9 builds→ 1++;10 return 7;11}value ← 7, served ← 1
20{21 int value→ 7 = slot.Value7;22 served→ 1++;23}created ← True
25bool created→ True = slot.IsValueCreatedTrue;2627string status;28if (!created)status ← set
31}32else if (served1 <= 1)33{34 status→ set = "set";35}Console.WriteLine("reads=" + reads + " served=" + served + " builds=" …
41 Console.WriteLine("reads=" + reads1 + " served=" + served1 + " builds=" + builds1 + " " + statusset);42}outputreads=1 served=1 builds=1 set
reads ← 0, slot ← Value is not created., served ← 0, created ← False
13static void Main()14{15 int reads→ 0 = 0;16 var slot→ Value is not created. = new Lazy<int>(Build);17 int served→ 0 = 0;1819 for (int i = 0; i < reads; i++)20 {21 int value = slot.Value;22 served++;23 }2425 bool created→ False = slot.IsValueCreatedFalse;2627 string status;28 if (!created)status ← unset
27string status;28if (!createdFalse)29{30 status→ unset = "unset";31}Console.WriteLine("reads=" + reads + " served=" + served + " builds=" …
41 Console.WriteLine("reads=" + reads0 + " served=" + served0 + " builds=" + builds0 + " " + statusunset);42}outputreads=0 served=0 builds=0 unset
reads ← 2, slot ← Value is not created., served ← 0
13static void Main()14{15 int reads→ 2 = 2;16 var slot→ Value is not created. = new Lazy<int>(Build);17 int served→ 0 = 0;for (int i = 0; i < reads; i++)
pass 1 of 219for (int i0 = 0; i < reads2; i++)20{21 int value = slot.Value;builds ← 1
7static int Build()8{9 builds→ 1++;10 return 7;11}value ← 7, served ← 1
20{21 int value→ 7 = slot.Value7;22 served→ 1++;23}value ← 7, served ← 2
pass 2 of 219for (int i1 = 0; i < reads2; i++)20{21 int value→ 7 = slot.Value7;22 served→ 2++;23}created ← True
25bool created→ True = slot.IsValueCreatedTrue;2627string status;28if (!created)status ← locked
35}36else37{38 status→ locked = "locked";39}Console.WriteLine("reads=" + reads + " served=" + served + " builds=" …
41 Console.WriteLine("reads=" + reads2 + " served=" + served2 + " builds=" + builds1 + " " + statuslocked);42}outputreads=2 served=2 builds=1 locked