diff --git a/Building and Running Singularity RDK 1.1.pdf b/Building and Running Singularity RDK 1.1.pdf
deleted file mode 100644
index a25dc83..0000000
Binary files a/Building and Running Singularity RDK 1.1.pdf and /dev/null differ
diff --git a/Building and Running Singularity RDK 2.0.pdf b/Building and Running Singularity RDK 2.0.pdf
new file mode 100644
index 0000000..55be364
Binary files /dev/null and b/Building and Running Singularity RDK 2.0.pdf differ
diff --git a/Release notes.pdf b/Release notes.pdf
new file mode 100644
index 0000000..1f2c3de
Binary files /dev/null and b/Release notes.pdf differ
diff --git a/Singularity RDK 1.1 License.pdf b/Singularity RDK 2.0 License.pdf
similarity index 100%
rename from Singularity RDK 1.1 License.pdf
rename to Singularity RDK 2.0 License.pdf
diff --git a/base/Applications/AppendFormat/AppendFormat.csproj b/base/Applications/AppendFormat/AppendFormat.csproj
index 284eb64..3d42123 100644
--- a/base/Applications/AppendFormat/AppendFormat.csproj
+++ b/base/Applications/AppendFormat/AppendFormat.csproj
@@ -1,8 +1,6 @@

diff --git a/base/Applications/Benchmarks/BartokH/Child/Child.sg b/base/Applications/Benchmarks/BartokH/Child/Child.sg
index d8c4f15..dcad87f 100644
--- a/base/Applications/Benchmarks/BartokH/Child/Child.sg
+++ b/base/Applications/Benchmarks/BartokH/Child/Child.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: BartokP.sg
-//
// Note: Compiler Phase
//
@@ -95,10 +93,9 @@ namespace Bartok.Child
uint region;
regionSize = (uint)bytes.Length;
unsafe {
- fixed (byte *pdst = &bytes[0]) {
- region = (uint)pdst;
- cs.ReadOpen(region, regionSize);
- }
+ byte *pdst = &bytes[0];
+ region = (uint)pdst;
+ cs.ReadOpen(region, regionSize);
}
}
@@ -119,10 +116,9 @@ namespace Bartok.Child
uint region;
regionSize = (uint)bytes.Length;
unsafe {
- fixed (byte *pdst = &bytes[0]) {
- region = (uint)pdst;
- cs.WriteOpen(region, regionSize);
- }
+ byte *pdst = &bytes[0];
+ region = (uint)pdst;
+ cs.WriteOpen(region, regionSize);
}
}
diff --git a/base/Applications/Benchmarks/BartokH/Contracts/BartokHContracts.csproj b/base/Applications/Benchmarks/BartokH/Contracts/BartokHContracts.csproj
index 6f7a166..fa7f3cd 100644
--- a/base/Applications/Benchmarks/BartokH/Contracts/BartokHContracts.csproj
+++ b/base/Applications/Benchmarks/BartokH/Contracts/BartokHContracts.csproj
@@ -1,5 +1,4 @@

-
diff --git a/base/Applications/Benchmarks/BartokH/Contracts/CompilerPhaseContract.sg b/base/Applications/Benchmarks/BartokH/Contracts/CompilerPhaseContract.sg
index 4284674..64fc4c6 100644
--- a/base/Applications/Benchmarks/BartokH/Contracts/CompilerPhaseContract.sg
+++ b/base/Applications/Benchmarks/BartokH/Contracts/CompilerPhaseContract.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: CompilerPhaseContract.sg
-//
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Endpoint;
diff --git a/base/Applications/Benchmarks/BartokH/Imported.txt b/base/Applications/Benchmarks/BartokH/Imported.txt
new file mode 100644
index 0000000..56f3b36
--- /dev/null
+++ b/base/Applications/Benchmarks/BartokH/Imported.txt
@@ -0,0 +1 @@
+
diff --git a/base/Applications/Benchmarks/BartokH/README.TXT b/base/Applications/Benchmarks/BartokH/README.TXT
new file mode 100644
index 0000000..5479469
--- /dev/null
+++ b/base/Applications/Benchmarks/BartokH/README.TXT
@@ -0,0 +1,8 @@
+Hosted Bartok requires the following change to System\RuntimeType.cs:
+
+ public override int GetHashCode() {
+ return unchecked((int)(
+ (int)Magic.addressOf(this.classVtable)
+ + ((int)this.classVtable.arrayOf << 8 + rank)
+ + (int)this.classVtable.structuralView));
+ }
diff --git a/base/Applications/Benchmarks/BartokH/host/Bartok.cs b/base/Applications/Benchmarks/BartokH/host/Bartok.cs
index 52dc058..ff4fffe 100644
--- a/base/Applications/Benchmarks/BartokH/host/Bartok.cs
+++ b/base/Applications/Benchmarks/BartokH/host/Bartok.cs
@@ -1,5 +1,5 @@
//
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
//
#define NONONNULLTYPECHECK // required on Singularity, no affect on other Windows.
@@ -422,25 +422,25 @@ namespace Bartok {
analysisRegistry));
}
- /*
- phases.Add
- (new DynamicCount
- ("VirtualCallsStart",
- new DynamicCount.OpcodeFilter
- (Operator.OpCodes.CallVirtual,
- Operator.OpCodes.InterfaceCall),
- DynamicCount.Granularity.PerSite));
- */
+ //
+ //phases.Add
+ // (new DynamicCount
+ // ("VirtualCallsStart",
+ // new DynamicCount.OpcodeFilter
+ // (Operator.OpCodes.CallVirtual,
+ // Operator.OpCodes.InterfaceCall),
+ // DynamicCount.Granularity.PerSite));
+ //
- /*
- phases.Add
- (new DynamicCount
- ("ASCstart",
- new DynamicCount.OpcodeFilter
- (Operator.OpCodes.CheckArrayStore,
- Operator.OpCodes.CheckVectorStore),
- DynamicCount.Granularity.PerSite));
- */
+ //
+ //phases.Add
+ // (new DynamicCount
+ // ("ASCstart",
+ // new DynamicCount.OpcodeFilter
+ // (Operator.OpCodes.CheckArrayStore,
+ // Operator.OpCodes.CheckVectorStore),
+ // DynamicCount.Granularity.PerSite));
+ //
if (StageControl.PtrAnalysis) {
phases.Add(PtrTypeSimpleSystem.CreateAnalysis());
@@ -467,23 +467,23 @@ namespace Bartok {
phases.Add(new Convert.ToMir(mask));
}
- /* SPOONS: region related phases:
- // A temporary pass that cleans up the scratch objects so that the
- // DemandAnalysis is not confused by the randomness that the tree
- // shaker leaves behind.
- phases.Add(new CleanScratch());
-
- // Build a "Foo_layout" for each class "Foo"; other setup required
- // by DemandAnalysis.
- phases.Add(new LayoutBuilder());
-
- // Perform first- and last-use analysis; add explicit region
- // variables and effects.
- phases.Add(new DemandAnalysis());
-
- // Print the code
- phases.Add(new TypeDataPrettyPhase("After Demand:"));
- */
+ // SPOONS: region related phases:
+ //// A temporary pass that cleans up the scratch objects so that the
+ //// DemandAnalysis is not confused by the randomness that the tree
+ //// shaker leaves behind.
+ //phases.Add(new CleanScratch());
+//
+ //// Build a "Foo_layout" for each class "Foo"; other setup required
+ //// by DemandAnalysis.
+ //phases.Add(new LayoutBuilder());
+//
+ //// Perform first- and last-use analysis; add explicit region
+ //// variables and effects.
+ //phases.Add(new DemandAnalysis());
+//
+ //// Print the code
+ //phases.Add(new TypeDataPrettyPhase("After Demand:"));
+ //
// Perform first- and last-use analysis; add explicit region
// variables and effects.
@@ -774,67 +774,67 @@ namespace Bartok {
(new Convert.ToMir(Convert.ToMir.Mask.Vararg2)));
}
- /*
- // We do not know where all of the calls will be because lowering can
- // introduce calls. We make a best guess here. If we moved all
- // call-generating lowering to HIR (via ToMir or equivalent), then
- // this could be easily done. We are currently missing calls for the
- // following:
- // - pinvoke, stubs, etc
- // - some arithmetic conversions
- // - casts - can't add because not all are calls
- // - RC, tryall, atomic
- // - others?
- phases.Add
- (new DynamicCount
- ("Calls",
- new DynamicCount.OpcodeFilter
- (Operator.OpCodes.Call,
- Operator.OpCodes.CallIndirect,
- Operator.OpCodes.CallVirtual,
- Operator.OpCodes.InterfaceCall,
- Operator.OpCodes.MonitorEnter,
- Operator.OpCodes.MonitorExit,
- Operator.OpCodes.IndirectToData,
- Operator.OpCodes.CustomGetSize,
- Operator.OpCodes.CheckVectorStore,
- Operator.OpCodes.CheckVectorElementAddress,
- Operator.OpCodes.InitVector,
- Operator.OpCodes.CheckArrayStore,
- Operator.OpCodes.CheckArrayElementAddress,
- Operator.OpCodes.InitArray,
- Operator.OpCodes.InitType,
- Operator.OpCodes.GetITable,
- Operator.OpCodes.NewObject,
- Operator.OpCodes.NewVector,
- Operator.OpCodes.NewArray),
- DynamicCount.Granularity.Global));
- phases.Add(new TypeDataDummyPhase());
- phases.Add
- (new DynamicCount
- ("VirtualCallsEnd",
- new DynamicCount.OpcodeFilter
- (Operator.OpCodes.CallVirtual,
- Operator.OpCodes.InterfaceCall),
- DynamicCount.Granularity.PerSite));
-
- phases.Add
- (new DynamicCount
- ("ASCend",
- new DynamicCount.OpcodeFilter
- (Operator.OpCodes.CheckArrayStore,
- Operator.OpCodes.CheckVectorStore),
- DynamicCount.Granularity.PerSite));
- phases.Add(new TypeDataDummyPhase());
-
- phases.Add
- (new DynamicCount
- ("WB",
- new DynamicCount.OpcodeFilter
- (Operator.OpCodes.LocWriteBarrier),
- DynamicCount.Granularity.Global));
- phases.Add(new TypeDataDummyPhase());
- */
+ //
+ //// We do not know where all of the calls will be because lowering can
+ //// introduce calls. We make a best guess here. If we moved all
+ //// call-generating lowering to HIR (via ToMir or equivalent), then
+ //// this could be easily done. We are currently missing calls for the
+ //// following:
+ //// - pinvoke, stubs, etc
+ //// - some arithmetic conversions
+ //// - casts - can't add because not all are calls
+ //// - RC, tryall, atomic
+ //// - others?
+ //phases.Add
+ // (new DynamicCount
+ // ("Calls",
+ // new DynamicCount.OpcodeFilter
+ // (Operator.OpCodes.Call,
+ // Operator.OpCodes.CallIndirect,
+ // Operator.OpCodes.CallVirtual,
+ // Operator.OpCodes.InterfaceCall,
+ // Operator.OpCodes.MonitorEnter,
+ // Operator.OpCodes.MonitorExit,
+ // Operator.OpCodes.IndirectToData,
+ // Operator.OpCodes.CustomGetSize,
+ // Operator.OpCodes.CheckVectorStore,
+ // Operator.OpCodes.CheckVectorElementAddress,
+ // Operator.OpCodes.InitVector,
+ // Operator.OpCodes.CheckArrayStore,
+ // Operator.OpCodes.CheckArrayElementAddress,
+ // Operator.OpCodes.InitArray,
+ // Operator.OpCodes.InitType,
+ // Operator.OpCodes.GetITable,
+ // Operator.OpCodes.NewObject,
+ // Operator.OpCodes.NewVector,
+ // Operator.OpCodes.NewArray),
+ // DynamicCount.Granularity.Global));
+ //phases.Add(new TypeDataDummyPhase());
+ //phases.Add
+ // (new DynamicCount
+ // ("VirtualCallsEnd",
+ // new DynamicCount.OpcodeFilter
+ // (Operator.OpCodes.CallVirtual,
+ // Operator.OpCodes.InterfaceCall),
+ // DynamicCount.Granularity.PerSite));
+//
+ //phases.Add
+ // (new DynamicCount
+ // ("ASCend",
+ // new DynamicCount.OpcodeFilter
+ // (Operator.OpCodes.CheckArrayStore,
+ // Operator.OpCodes.CheckVectorStore),
+ // DynamicCount.Granularity.PerSite));
+ //phases.Add(new TypeDataDummyPhase());
+//
+ //phases.Add
+ // (new DynamicCount
+ // ("WB",
+ // new DynamicCount.OpcodeFilter
+ // (Operator.OpCodes.LocWriteBarrier),
+ // DynamicCount.Granularity.Global));
+ //phases.Add(new TypeDataDummyPhase());
+ //
if (StageControl.WholeProgram && StageControl.OptRuntimeData) {
phases.Add(new RuntimeData());
diff --git a/base/Applications/Benchmarks/BartokH/host/BartokHHost.csproj b/base/Applications/Benchmarks/BartokH/host/BartokHHost.csproj
index 00f16d1..93effec 100644
--- a/base/Applications/Benchmarks/BartokH/host/BartokHHost.csproj
+++ b/base/Applications/Benchmarks/BartokH/host/BartokHHost.csproj
@@ -1,5 +1,4 @@

-
diff --git a/base/Applications/Benchmarks/BartokH/host/Proxy.sg b/base/Applications/Benchmarks/BartokH/host/Proxy.sg
index a15127a..7f6acb9 100644
--- a/base/Applications/Benchmarks/BartokH/host/Proxy.sg
+++ b/base/Applications/Benchmarks/BartokH/host/Proxy.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Proxy.sg
-//
// Note: Compiler Phase
//
@@ -57,10 +55,9 @@ namespace Bartok.Regalloc
uint region;
regionSize = (uint)bytes.Length;
unsafe {
- fixed (byte *pdst = &bytes[0]) {
- region = (uint)pdst;
- cs.ReadOpen(region, regionSize);
- }
+ byte *pdst = &bytes[0];
+ region = (uint)pdst;
+ cs.ReadOpen(region, regionSize);
}
}
@@ -81,10 +78,9 @@ namespace Bartok.Regalloc
uint region;
regionSize = (uint)bytes.Length;
unsafe {
- fixed (byte *pdst = &bytes[0]) {
- region = (uint)pdst;
- cs.WriteOpen(region, regionSize);
- }
+ byte *pdst = &bytes[0];
+ region = (uint)pdst;
+ cs.WriteOpen(region, regionSize);
}
}
@@ -131,7 +127,7 @@ namespace Bartok.Regalloc
// Start up our child
string[] args = new string[3];
- args[0] = "BartokP.x86";
+ args[0] = "BartokP";
args[1] = "-where";
args[2] = "!";
Process cproc = new Process(args, (Endpoint * in ExHeap)ep);
@@ -388,5 +384,5 @@ namespace Bartok.Regalloc
private const string coloringName = "Back End Coloring Coloring";
private static int coloringId;
#endif
- } /* class GraphColoring */
+ } // class GraphColoring
}
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Analysis.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Analysis.pdb
deleted file mode 100644
index 35e4bf3..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Analysis.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Backend.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Backend.pdb
deleted file mode 100644
index 27f1b84..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Backend.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.CfgUtil.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.CfgUtil.pdb
deleted file mode 100644
index 80d2018..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.CfgUtil.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Cheap.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Cheap.pdb
deleted file mode 100644
index 48f438a..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Cheap.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Coff.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Coff.pdb
deleted file mode 100644
index fe11439..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Coff.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Convert.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Convert.pdb
deleted file mode 100644
index 994861c..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Convert.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Datatype.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Datatype.pdb
deleted file mode 100644
index 02d8276..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Datatype.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.DebugInfo.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.DebugInfo.pdb
deleted file mode 100644
index b79fc31..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.DebugInfo.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Encode.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Encode.pdb
deleted file mode 100644
index cba2032..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Encode.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Ir.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Ir.pdb
deleted file mode 100644
index 15507f2..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Ir.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Lir.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Lir.pdb
deleted file mode 100644
index b49d630..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Lir.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.MSIL.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.MSIL.pdb
deleted file mode 100644
index 727f8a4..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.MSIL.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Mangle.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Mangle.pdb
deleted file mode 100644
index 55c9193..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Mangle.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Marshal.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Marshal.pdb
deleted file mode 100644
index 412b8ea..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Marshal.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Opt.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Opt.pdb
deleted file mode 100644
index 578ae1f..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Opt.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Profile.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Profile.pdb
deleted file mode 100644
index 07f6d0b..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Profile.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Proxy.dll b/base/Applications/Benchmarks/BartokH/msil/Bartok.Proxy.dll
new file mode 100644
index 0000000..c08c4c7
Binary files /dev/null and b/base/Applications/Benchmarks/BartokH/msil/Bartok.Proxy.dll differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Proxy.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Proxy.pdb
deleted file mode 100644
index 21432fc..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Proxy.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Regalloc.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Regalloc.pdb
deleted file mode 100644
index 4c6a2d3..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Regalloc.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Regreal.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Regreal.pdb
deleted file mode 100644
index b56f699..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Regreal.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Regstub.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Regstub.pdb
deleted file mode 100644
index 12cd1eb..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Regstub.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Tables.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Tables.pdb
deleted file mode 100644
index 64589d1..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Tables.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/BartokH/msil/Bartok.Utility.pdb b/base/Applications/Benchmarks/BartokH/msil/Bartok.Utility.pdb
deleted file mode 100644
index 6a4dfa6..0000000
Binary files a/base/Applications/Benchmarks/BartokH/msil/Bartok.Utility.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/Benchmarks.proj b/base/Applications/Benchmarks/Benchmarks.proj
index d3e437e..75856b8 100644
--- a/base/Applications/Benchmarks/Benchmarks.proj
+++ b/base/Applications/Benchmarks/Benchmarks.proj
@@ -1,3 +1,11 @@
+
+
diff --git a/base/Applications/Benchmarks/CreateProcess/CreateProcess.cs b/base/Applications/Benchmarks/CreateProcess/CreateProcess.cs
index 545647c..67004cc 100644
--- a/base/Applications/Benchmarks/CreateProcess/CreateProcess.cs
+++ b/base/Applications/Benchmarks/CreateProcess/CreateProcess.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: CreateProcess.cs
-//
// Note: Singularity micro-benchmark program.
//
using Microsoft.Singularity;
@@ -175,7 +173,7 @@ namespace Microsoft.Singularity.Applications
public void Start()
{
if (!AtRing3) {
- disabled = Processor.DisableInterrupts();
+ disabled = Processor.DisableLocalPreemption();
}
int collectorCount;
@@ -218,7 +216,8 @@ namespace Microsoft.Singularity.Applications
Reset(1, PerfEvtSel.COUNT | PerfEvtSel.RetiredInstructions);
Reset(2, PerfEvtSel.COUNT | PerfEvtSel.RetiredBranchInstructions);
Reset(3, PerfEvtSel.COUNT | PerfEvtSel.RequestsToL2Cache | 0x400);
- } else {
+ }
+ else {
// We're not allowed to reset the perf counters, so take note
// of their current values; we will subtract from this later.
x64_i0 = Processor.ReadPmc(0);
@@ -275,7 +274,7 @@ namespace Microsoft.Singularity.Applications
endStackRets = stackRets;
if (!AtRing3) {
- Processor.RestoreInterrupts(disabled);
+ Processor.RestoreLocalPreemption(disabled);
}
this.iterations = iterations;
@@ -327,7 +326,8 @@ namespace Microsoft.Singularity.Applications
EvtSelToString(e1),
EvtSelToString(e2),
EvtSelToString(e3)));
- } else {
+ }
+ else {
// Subtract from the initial perf-counter values to
// get the delta we want
x64_p0 -= x64_i0;
@@ -353,7 +353,7 @@ namespace Microsoft.Singularity.Applications
string [] arguments;
for (long i = 0; i < repetitions; i++) {
arguments = new string[2];
- arguments[0] = "testpe.x86";
+ arguments[0] = "testpe";
arguments[1] = "!"; // Special flag to not notify debugger.
TimeProcess(arguments, runQuiet);
}
diff --git a/base/Applications/Benchmarks/CreateProcess/CreateProcess.csproj b/base/Applications/Benchmarks/CreateProcess/CreateProcess.csproj
index d1d0b64..15ea5f9 100644
--- a/base/Applications/Benchmarks/CreateProcess/CreateProcess.csproj
+++ b/base/Applications/Benchmarks/CreateProcess/CreateProcess.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ schedbench
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Benchmarks/SchedBench/SchedBench.sg b/base/Applications/Benchmarks/SchedBench/SchedBench.sg
new file mode 100644
index 0000000..aee92ee
--- /dev/null
+++ b/base/Applications/Benchmarks/SchedBench/SchedBench.sg
@@ -0,0 +1,1072 @@
+//------------------------------------------------------------------------------
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Description: $filename$
+// SchedBench is a benchmark based on SingBench that measures the CPU scheduler
+// performance.
+//------------------------------------------------------------------------------
+
+using System;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Diagnostics.Contracts;
+using Microsoft.Singularity.Endpoint;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications.SchedBench
+{
+ /// Application wrapper class and argument options
+ [ConsoleCategory(HelpMessage="Singularity Scheduling Benchmark Application", DefaultAction=true)]
+ internal sealed class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef memoryRef;
+
+ /// When true break in debugger before running benchmark
+ [BoolParameter( "b", Default=false , HelpMessage="Break at start of tests.")]
+ internal bool breakIn;
+
+ /// When set no GC during benchmarks
+ [BoolParameter( "n", Default=true , HelpMessage="No GC between tests.")]
+ internal bool allowGC;
+
+ /// Wait for a key between benchmarks
+ [BoolParameter( "w", Default=false , HelpMessage="Wait for key press between tests.")]
+ internal bool pauseForKeys;
+
+ /// Produce XML output
+ [BoolParameter( "x", Default=false , HelpMessage="XML output.")]
+ internal bool xmlOutput;
+
+ /// Iterations per benchmark (when applicable)
+ [LongParameter( "i", Default=10000 , HelpMessage="Iterate tests times.")]
+ internal long iterations;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return SchedBench.AppMain(this);
+ }
+ }
+
+ /// CPU Scheduler Benchmark
+ public class SchedBench
+ {
+ ///
+ ///
+ /// Display on the console and in the debugger
+ ///
+ /// Message displayed
+ ///
+ private static void DualWriteLine(string message)
+ {
+ Console.WriteLine(message);
+ DebugStub.WriteLine(message);
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // Yield Tests
+ // ----------------------------------------------------------------------------------------
+
+ ///
+ ///
+ /// Thread Yield Test - Create threads that each yields a
+ /// predefined number of times. Report yields per tick.
+ ///
+ /// Number of threads yielding
+ /// Number of yield operations
+ ///
+ public static void DoYieldPerf(uint numThreads, uint iterations)
+ {
+ Thread[] yieldThreads = new Thread[numThreads];
+
+ // Set worker thread iteration count
+ workerIterations = iterations;
+
+ // Initialize sync signal before starting threads
+ syncStart.Reset();
+
+ // Create and start yield worker threads
+ for( uint i = 0; i < numThreads; i++ ) {
+ yieldThreads[i] = new Thread(YieldThread);
+ ((!)yieldThreads[i]).Start();
+ }
+
+ // Start performance snap
+ PerfSnap snap = new PerfSnap();
+
+ snap.Start();
+
+ // Synchnously start threads by signalling
+ syncStart.Set();
+
+ // Wait for threads to complete
+ for( uint i = 0; i < numThreads; i++ ) {
+ ((!)yieldThreads[i]).Join();
+ }
+
+ snap.Finish(iterations);
+
+ snap.Display("Yield " + numThreads.ToString());
+ DualWriteLine(String.Format("Yield {0}:Ticks per yield: {1,2:F}",
+ numThreads.ToString(),
+ (float)snap.ElapsedTicks /
+ (float)(iterations*numThreads)));
+ }
+
+ ///
+ ///
+ /// YieldThread - Yield a number of times and synchnoize with
+ /// main thread
+ ///
+ /// Number of yield operations
+ ///
+ public static void YieldThread()
+ {
+ // Wait for signal from master thread to start
+ syncStart.WaitOne();
+
+ for (uint i = 0; i < workerIterations; i++) {
+ Thread.Yield();
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // Wait/Set Tests
+ // ----------------------------------------------------------------------------------------
+
+ ///
+ ///
+ /// Wait / Set Benchmarks - Create pairs of threads that wait and set events
+ ///
+ /// Number of threads
+ /// Number of wait/set operations
+ ///
+ public static void DoWaitPerf(uint numThreads, uint iterations)
+ {
+ // Number of ping-pong pairs
+ uint pairs = numThreads / 2;
+
+ // Allocate AutoResetEvents
+ waitPerfEvent1 = new AutoResetEvent[pairs];
+ waitPerfEvent2 = new AutoResetEvent[pairs];
+
+ for(uint i = 0; i < pairs; i++) {
+ waitPerfEvent1[i] = new AutoResetEvent(false);
+ waitPerfEvent2[i] = new AutoResetEvent(false);
+ }
+
+ // Create threads
+ Thread[] pingThreads = new Thread[pairs];
+ Thread[] pongThreads = new Thread[pairs];
+
+ // Set worker thread iteration count
+ workerIterations = iterations;
+
+ // Initialize sync signal before starting threads
+ syncStart.Reset();
+ syncContext.Reset();
+
+ // Create and start yield worker threads
+ for( uint i = 0; i < pairs; i++ ) {
+ // Use curWorkerThread to set the context of worker thread
+ curWorkerThread = i;
+
+ // Begin ping thread
+ pingThreads[i] = new Thread(PingThread);
+ ((!)pingThreads[i]).Start();
+
+ // Wait for ping thread to notify that has acquired context
+ syncContext.WaitOne();
+ syncContext.Reset();
+
+ // Begin pong thread
+ pongThreads[i] = new Thread(PongThread);
+ ((!)pongThreads[i]).Start();
+
+ // Wait for pong thread to notify that has acquired context
+ syncContext.WaitOne();
+ syncContext.Reset();
+ }
+
+ // Start performance snap
+ PerfSnap snap = new PerfSnap();
+
+ snap.Start();
+
+ // Synchnously start threads by signalling
+ syncStart.Set();
+
+ // Wait for threads to complete
+ for( uint i = 0; i < pairs; i++ ) {
+ ((!)pingThreads[i]).Join();
+ ((!)pongThreads[i]).Join();
+ }
+
+ snap.Finish(iterations);
+
+ snap.Display("Wait " + numThreads.ToString());
+ DualWriteLine(String.Format("Wait {0}:Ticks per wait: {1,2:F}",
+ numThreads.ToString(),
+ (float)snap.ElapsedTicks /
+ (float)(iterations*numThreads)));
+ }
+
+ ///
+ ///
+ /// Perform a ping operation in the wait handle (Set-Wait)
+ ///
+ ///
+ private static void PingThread()
+ {
+ // Acquire context and notify master thread
+ uint myIdx = curWorkerThread;
+ syncContext.Set();
+
+ // Wait for signal from master thread to start
+ syncStart.WaitOne();
+
+ for (uint i = 0; i < workerIterations; i++) {
+ // Set event (ping)
+ ((!)waitPerfEvent1[myIdx]).Set();
+ // Wait event (pong)
+ ((!)waitPerfEvent2[myIdx]).WaitOne();
+ }
+ }
+
+ ///
+ ///
+ /// Perform a pong operation in the wait handle (Wait-Set)
+ ///
+ ///
+ private static void PongThread()
+ {
+ // Acquire context and notify master thread
+ uint myIdx = curWorkerThread;
+ syncContext.Set();
+
+ // Wait for signal from master thread to start
+ syncStart.WaitOne();
+
+ for (uint i = 0; i < workerIterations; i++) {
+ // Wait event (pong)
+ ((!)waitPerfEvent1[myIdx]).WaitOne();
+ // Set event (ping)
+ ((!)waitPerfEvent2[myIdx]).Set();
+ }
+ }
+
+
+ // ----------------------------------------------------------------------------------------
+ // WaitAny Benchmark
+ // ----------------------------------------------------------------------------------------
+
+ ///
+ ///
+ /// WaitAny benchmark - Main thread waits for any of the slave thread to set event
+ /// Measures average time to receive signal.
+ ///
+ /// Number of wait/set operations
+ ///
+ public static void DoWaitAnyPerf(uint numThreads,uint iterations)
+ {
+
+ // Allocate AutoResetEvents
+ waitPerfEvent1 = new AutoResetEvent[numThreads];
+
+ for(uint i = 0; i < numThreads; i++) {
+ waitPerfEvent1[i] = new AutoResetEvent(false);
+ }
+
+ // Create slave threads
+ Thread[] setEventThread = new Thread[numThreads];
+
+ // Set worker thread iteration count
+ workerIterations = iterations;
+
+ // Set operation flag array for worker threads
+ opFlag = new bool[numThreads];
+
+ // Initialize barrier
+ loopBarrier = new SyncBarrier(numThreads);
+
+ // Create and start worker threads
+ for( uint i = 0; i < numThreads; i++ ) {
+ // Use curWorkerThread to set the context of worker thread
+ curWorkerThread = i;
+
+ // Begin SetEvent thread
+ setEventThread[i] = new Thread(WaitAnyThread);
+ ((!)setEventThread[i]).Start();
+
+ // Wait for SetEvent thread to notify that has acquired context
+ syncContext.WaitOne();
+ syncContext.Reset();
+ }
+
+ // Start performance snap
+ PerfSnap snap = new PerfSnap();
+
+ // Random generator used to pick threads to set event
+ // Use fix seed to replicate same sequence
+ Random rnd = new Random(0);
+
+ // Aggregate time for operation
+ long opTimer = 0;
+
+ snap.Start();
+
+ // Run the benchmark iteration
+ for( uint i = 0; i < iterations; i++ ) {
+ // Number of events to be set
+ int nevent = 0;
+
+ // Pick random threads to set events
+ for( uint j = 0; j < numThreads; j++ ) {
+ // 50% chance to pick thread to set event
+ opFlag[j] = rnd.NextDouble() < 0.5 ? true : false;
+ if( opFlag[j] == true ) {
+ nevent++;
+ }
+ }
+
+ // if no events picked (very unlikely)
+ if( nevent == 0 ) {
+ // Select one thread randomly
+ opFlag[rnd.Next(0,(int)numThreads)] = true;
+ }
+
+ // Join barrier
+ loopBarrier.Join();
+
+ // Start timer
+ long begTicks = DateTime.Now.Ticks;
+
+ WaitHandle.WaitAny(waitPerfEvent1);
+
+ // Start timer
+ opTimer += DateTime.Now.Ticks - begTicks;
+
+ loopBarrier.Signal();
+ }
+
+ snap.Finish(iterations);
+
+ snap.Display("WaitAny " + numThreads.ToString());
+ DualWriteLine(String.Format("WaitAny {0}:Ticks per WaitAny: {1,2:F}",
+ numThreads.ToString(),
+ (float)opTimer/ (float)iterations));
+ }
+
+ ///
+ ///
+ /// Set event to contribute in WaitAny
+ ///
+ ///
+ private static void WaitAnyThread()
+ {
+ // Acquire context and notify master thread
+ uint myIdx = curWorkerThread;
+ syncContext.Set();
+
+ for (uint i = 0; i < workerIterations; i++) {
+ // Increase the barrier (completed worker threads) counter
+ loopBarrier.JoinWorker();
+
+ // If thread selected to perform set
+ if( opFlag[myIdx] ) {
+ // Set event (ping)
+ ((!)waitPerfEvent1[myIdx]).Set();
+ }
+
+ // Wait for randevouz when everybody is done
+ loopBarrier.Wait();
+
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // Context Switch Performance
+ // ----------------------------------------------------------------------------------------
+
+ ///
+ ///
+ /// Calculate the cost of context switches
+ ///
+ /// Number of threads yielding
+ /// Number of yield operations
+ ///
+ public static void DoContextSwitchPerf(uint numThreads, uint iterations)
+ {
+ Thread[] workerThreads = new Thread[numThreads];
+
+ // Set worker thread iteration count
+ workerIterations = iterations;
+
+ // Initialize sync signal before starting threads
+ syncStart.Reset();
+ syncContext.Reset();
+
+ // Calculate the minimum mandelbrot time - use fix point (0.0,0.0)
+ long mbrotTicks = MandelbrotTicks(0.0,0.0,iterations);
+
+ // Create and start worker threads
+ for( uint i = 0; i < numThreads; i++ ) {
+ // Initialize wallClock
+ wallClock[i] = 0;
+
+ // Use curWorkerThread to set the context of worker thread
+ curWorkerThread = i;
+
+ // Begin worket thread
+ workerThreads[i] = new Thread(ContextThread);
+ ((!)workerThreads[i]).Start();
+
+ // Wait for ping thread to notify that has acquired context
+ syncContext.WaitOne();
+ syncContext.Reset();
+ }
+
+ // Start performance snap
+ PerfSnap snap = new PerfSnap();
+
+ snap.Start();
+
+ // Synchonously start threads by signalling
+ syncStart.Set();
+
+ // Wait for threads to complete
+ for( uint i = 0; i < numThreads; i++ ) {
+ ((!)workerThreads[i]).Join();
+ }
+
+ snap.Finish(iterations);
+
+ snap.Display("Context " + numThreads.ToString());
+
+ // Calculate context overhead
+ float contextOverhead = 0;
+
+ for( uint i = 0; i < numThreads; i++ ) {
+ contextOverhead += (float)wallClock[i] / (float)iterations;
+ }
+
+ contextOverhead = (float)contextOverhead / numThreads - mbrotTicks;
+
+ if( contextOverhead < 0.0 ) {
+ // It is possible that the context overhead is not valid especially in hosted
+ // execution environments such as Win32. This might occur if during the
+ // calculation of the mbrot baseline computation (single thread) an execution
+ // environment process context switch causes S to stall mbrot operation
+ DualWriteLine(String.Format("Context {0}:Context overhead: Invalid",
+ numThreads.ToString()));
+ } else {
+ DualWriteLine(String.Format("Context {0}:Context overhead: {1,2:F}",
+ numThreads.ToString(), contextOverhead));
+ }
+
+ // Calculate fairness variation
+ long min = 0;
+ long max = 0;
+ float avg = 0.0F;
+ float stddev = 0.0F;
+
+ CalcTimeStats(wallClock, numThreads, iterations, out min, out max, out avg, out stddev);
+
+ DualWriteLine(String.Format("Context {0}:Operations per cycle: {1,4:F}",
+ numThreads.ToString(),
+ (float)(iterations*numThreads) / snap.ElapsedTicks));
+ DualWriteLine(String.Format("Context {0}:Fairness min:{1}",
+ numThreads.ToString(), min));
+ DualWriteLine(String.Format("Context {0}:Fairness max:{1}",
+ numThreads.ToString(), max));
+ DualWriteLine(String.Format("Context {0}:Fairness avg:{1,2:F}",
+ numThreads.ToString(), avg));
+ DualWriteLine(String.Format("Context {0}:Fairness stddev:{1,2:F}",
+ numThreads.ToString(), stddev));
+ }
+
+
+ ///
+ ///
+ /// Thread that calculate a mandelbrot pixels
+ ///
+ /// Number of yield operations
+ ///
+ public static void ContextThread()
+ {
+ // Acquire context and notify master thread
+ uint myIdx = curWorkerThread;
+ syncContext.Set();
+
+ // Wait for signal from master thread to start
+ syncStart.WaitOne();
+
+ // Start timer
+ long begTicks = DateTime.Now.Ticks;
+
+ for (uint i = 0; i < workerIterations; i++) {
+ // Calc point - use fix point
+ ComputePoint(0.0,0.0);
+ }
+
+ // Add to wall clock
+ wallClock[myIdx] = DateTime.Now.Ticks - begTicks;
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // Latency Benchmark
+ // ----------------------------------------------------------------------------------------
+
+ ///
+ ///
+ /// Multiple threads a series of mbrot calculations / Sleeps. The sleep random interval.
+ /// The latency of the operation is measured.
+ ///
+ /// Number of threads yielding
+ /// Number of operations
+ ///
+ public static void DoLatencyPerf(uint numThreads, uint iterations)
+ {
+ Thread[] workerThreads = new Thread[numThreads];
+
+ // Set worker thread iteration count
+ workerIterations = iterations;
+
+ // Initialize sync signal before starting threads
+ syncStart.Reset();
+ syncContext.Reset();
+
+ // Create and start worker threads
+ for( uint i = 0; i < numThreads; i++ ) {
+ // Initialize wallClock, min and max latencies
+ wallClock[i] = 0;
+
+ // Use curWorkerThread to set the context of worker thread
+ curWorkerThread = i;
+
+ // Begin worket thread
+ workerThreads[i] = new Thread(LatencyThread);
+ ((!)workerThreads[i]).Start();
+
+ // Wait for ping thread to notify that has acquired context
+ syncContext.WaitOne();
+ syncContext.Reset();
+ }
+
+ // Start performance snap
+ PerfSnap snap = new PerfSnap();
+
+ snap.Start();
+
+ // Synchonously start threads by signalling
+ syncStart.Set();
+
+ // Wait for threads to complete
+ for( uint i = 0; i < numThreads; i++ ) {
+ ((!)workerThreads[i]).Join();
+ }
+
+ snap.Finish(iterations);
+
+ snap.Display("Latency " + numThreads.ToString());
+
+ // Calculate latency statistics
+ long min = 0;
+ long max = 0;
+ float avg = 0.0F;
+ float stddev = 0.0F;
+
+ CalcTimeStats(wallClock, numThreads, iterations, out min, out max, out avg, out stddev);
+
+ DualWriteLine(String.Format("Latency {0}:min:{1}",
+ numThreads.ToString(), min));
+ DualWriteLine(String.Format("Latency {0}:max:{1}",
+ numThreads.ToString(), max));
+ DualWriteLine(String.Format("Latency {0}:mean:{1,2:F}",
+ numThreads.ToString(), avg));
+ DualWriteLine(String.Format("Latency {0}:stddev:{1,2:F}",
+ numThreads.ToString(), stddev));
+ }
+
+ ///
+ ///
+ /// Thread that calculate a mandelbrot pixels and then sleeps random interval
+ ///
+ /// Number of yield operations
+ ///
+ public static void LatencyThread()
+ {
+ // Max sleep time interval
+ const uint MaxSleep = 5;
+
+ // Random generator used for a random interval
+ Random rnd = new Random(0);
+
+ // Acquire context and notify master thread
+ uint myIdx = curWorkerThread;
+ syncContext.Set();
+
+ // Wait for signal from master thread to start
+ syncStart.WaitOne();
+
+ for (uint i = 0; i < workerIterations; i++) {
+ // Start timer
+ long begTicks = DateTime.Now.Ticks;
+
+ // Calc point - use fix point
+ ComputePoint(0.0,0.0);
+
+ // Store timers
+ long computeTime = DateTime.Now.Ticks - begTicks;
+ wallClock[myIdx] += computeTime;
+
+ // Sleep for random period
+ Thread.Sleep(rnd.Next(0,MaxSleep));
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // Mandelbrot computation task and helper functions
+ // ----------------------------------------------------------------------------------------
+
+ ///
+ ///
+ /// Return the time required to calculate a mandelbrot pixel
+ /// Run multiple times and return minimum time trying to exclude
+ /// context switching time.
+ ///
+ /// X coordinate
+ /// Y coordinate
+ /// Number of iterations
+ ///
+ private static long MandelbrotTicks(double x, double y, uint iterations)
+ {
+ long ticks = 0; // Min ticks for mandelbrot point calculation
+
+ // Calc the same pixel many times
+ for( uint i = 0; i < iterations; i++ ) {
+ //Start timer
+ long begTicks = DateTime.Now.Ticks;
+
+ // Disable interrupts only mandelbrot is running
+ bool saved = Processor.DisableLocalPreemption();
+
+ // Calc point
+ ComputePoint(x,y);
+
+ Processor.RestoreLocalPreemption(saved);
+
+ //Stop timer
+ long endTicks = DateTime.Now.Ticks;
+
+ // Save value of minimum
+ ticks = i == 0 || ticks > endTicks - begTicks ?
+ endTicks - begTicks : ticks;
+
+ }
+
+ return ticks;
+ }
+
+ ///
+ ///
+ /// Calculate a single mandelbrot point
+ ///
+ /// X coordinate
+ /// Y coordinate
+ ///
+ static private int ComputePoint(double x, double y)
+ {
+ const int maxIterations = 128; // Maximum number of iterations for mandelbrot loop
+ const int convergence = 4; // Convergence value
+ int nIterations = 0; // Result of calculation
+
+ // Temp vars for mandelbrot calculation
+ double x1 = 0;
+ double y1 = 0;
+ double xx;
+
+ // Mandelbrot magic
+ while (nIterations < maxIterations && ((x1 * x1) + (y1 * y1)) < convergence) {
+ nIterations++;
+ xx = (x1 * x1) - (y1 * y1) + x;
+ y1 = 2 * x1 * y1 + y;
+ x1 = xx;
+ }
+
+ return nIterations;
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // Helper functions
+ // ----------------------------------------------------------------------------------------
+
+ ///
+ ///
+ /// Calculate statistics on wall clock times
+ ///
+ /// Wall clock times
+ /// Number of worker threads (ignore other array entries)
+ /// Experiment iterations per thread
+ /// Min value (out)
+ /// Max value (out)
+ /// Mean value (out)
+ /// Standard deviation (out)
+ ///
+ private static void CalcTimeStats(long[] wallClock,
+ uint numThreads,
+ uint iterations,
+ out long min,
+ out long max,
+ out float avg,
+ out float stddev)
+ {
+ min = 0;
+ max = 0;
+ avg = 0;
+ stddev = 0;
+
+ for( uint i = 0; i < numThreads; i++ ) {
+ // Calc time per iteration
+ long clockPerIter= ((!)wallClock)[i] / iterations;
+
+ // Find min / max / avg
+ min = i == 0 ? clockPerIter :
+ min > clockPerIter ? clockPerIter :
+ min;
+ max = max < clockPerIter ? clockPerIter : max;
+ avg += clockPerIter;
+ }
+
+ avg /= numThreads;
+
+ // Standard deviation
+ for( uint i = 0; i < numThreads; i++ ) {
+ long clockPerIter= ((!)wallClock)[i] / iterations;
+
+ stddev += (float)Math.Pow((float)clockPerIter - avg,2.0);
+ }
+
+ stddev = (float)Math.Sqrt(stddev / ((float)numThreads - 1.0) );
+ }
+
+ /// Write log trace profile in console
+ public static int GetTrace()
+ {
+#if false
+ Tracing.LogEntry * lstart;
+ Tracing.LogEntry * llimit;
+ Tracing.LogEntry ** lhead;
+ byte * tstart;
+ byte * tlimit;
+ byte ** thead;
+
+ Tracing.GetTracingHeaders(out lstart, out llimit, out lhead,
+ out tstart, out tlimit, out thead);
+ Console.WriteLine("Log: {0:X} {1:X}, {2:X}, {3:X}",
+ (UIntPtr)lstart, (UIntPtr)llimit, (UIntPtr)lhead, (UIntPtr)(*lhead));
+ Console.WriteLine("Text: {0:X} {1:X}, {2:X}, {3:X}",
+ (UIntPtr)tstart, (UIntPtr)tlimit, (UIntPtr)thead, (UIntPtr)(*thead));
+#endif
+ return 0;
+ }
+
+ /// Clean up after each benchmark
+ public static void ClearEnvironment(MemoryContract.Imp:ReadyState! imp)
+ {
+ if (allowGC) {
+ GC.Collect();
+ }
+ }
+
+ /// Pause between benchmarks
+ public static void Pause()
+ {
+ if (pauseForKeys) {
+ Console.WriteLine("Press any key to continue.");
+ Console.Read();
+ }
+ }
+
+ internal static int AppMain(Parameters! config)
+ {
+
+ // Command-line parsing options
+ int iterations = (int) config.iterations;
+ bool xmlOutput = config.xmlOutput;
+ allowGC = config.allowGC;
+ pauseForKeys = config.pauseForKeys;
+ breakIn = config.breakIn;
+
+ if( breakIn ) {
+ DebugStub.Break();
+ }
+
+ // Display CPU privilidge level and set flag
+ if (Processor.AtKernelPrivilege()) {
+ atRing3 = false;
+ DualWriteLine("Schedbench running at KERNEL privilege");
+ } else {
+ atRing3 = true;
+ DualWriteLine("Schedbench running at USER privilege");
+ }
+
+ // Allocate clock arrays for each worker thread
+ wallClock = new long[threadCountTests[threadCountTests.Length-1]];
+
+ // Connect to memory channel
+ MemoryContract.Imp impMem = config.memoryRef.Acquire();
+ if (impMem == null) {
+ throw new ApplicationException("Error: Unable to bind to " +
+ MemoryContract.ModuleName);
+ }
+
+ impMem.RecvReady();
+
+ // Set options for performance snap module
+ PerfSnap.SetOptions(atRing3, xmlOutput);
+
+ GetTrace();
+
+ Console.WriteLine("Benchmarks: entered");
+
+ try {
+
+ // Run yield benchmark
+ foreach( uint threads in threadCountTests ) {
+ ClearEnvironment(impMem);
+ DoYieldPerf(threads,(uint)iterations);
+ Pause();
+ }
+
+ // Run wait-set benchmark
+ foreach( uint threads in threadCountTests ) {
+ ClearEnvironment(impMem);
+ DoWaitPerf(threads, (uint)iterations);
+ Pause();
+ }
+
+ // Run wait-set benchmark
+ foreach( uint threads in threadCountTests ) {
+ ClearEnvironment(impMem);
+ DoWaitAnyPerf(threads, (uint)iterations);
+ Pause();
+ }
+
+ // Run context switch benchmark
+ foreach( uint threads in threadCountTests ) {
+ ClearEnvironment(impMem);
+ DoContextSwitchPerf(threads, (uint)iterations);
+ Pause();
+ }
+
+ // Run latency benchmark
+ foreach( uint threads in threadCountTests ) {
+ ClearEnvironment(impMem);
+ // Because latency test is slow run 1/10th of iterations
+ DoLatencyPerf(threads, (uint)iterations / 10 );
+ Pause();
+ }
+
+ } catch (Exception e) {
+ Console.WriteLine("Caught {0}", e.Message);
+ delete impMem;
+ return 1;
+ }
+
+ delete impMem;
+
+ return 0;
+
+ } // AppMain
+
+ ///
+ /// Experiments are repeated with the numbers of threads specified in the array
+ ///
+ private static readonly uint[] threadCountTests = {25, 50, 100 };
+
+ /// Signal for notification that worker thread acquired context
+ private static ManualResetEvent syncContext = new ManualResetEvent(false);
+
+ /// Signal for synchonous start of working threads
+ private static ManualResetEvent syncStart = new ManualResetEvent(false);
+
+ /// Signal for synchonous start of working threads
+ private static SyncBarrier loopBarrier;
+
+ /// Iterations of an operation for worker threads
+ private static uint workerIterations;
+
+ ///
+ /// Thread id is used to communicate to worker therads its current id.
+ /// This is necessary because Thread.Start(object) is not supported
+ ///
+ private static uint curWorkerThread;
+
+ /// Wall clock for each worker thread
+ private static long[] wallClock;
+
+ /// True when running in Ring 3 processor mode
+ private static bool atRing3;
+
+ /// Wait events used in Wait/Set benchmarks
+ private static AutoResetEvent[] waitPerfEvent1;
+
+ /// Wait events used in Wait/Set benchmarks
+ private static AutoResetEvent[] waitPerfEvent2;
+
+ ///
+ /// When opFlag[idx] is set to true, Thread idx performs an operation (e.g. Event.Set)
+ ///
+ private static bool[] opFlag;
+
+ private static bool allowGC = false;
+ private static bool pauseForKeys = false;
+ private static bool breakIn = false;
+
+ } //class SchedBench
+
+ ///
+ /// SyncBarrier
+ /// A master thread runs a loop and assigns work to worker threads.
+ /// All of the slave threads need to synchnonize at the end of the loop
+ /// before proceeding to the next iteration.
+ ///
+ /// Usage pattern for master thread:
+ /// - FixedSyncBarrier barrier = new FixedSyncBarrier(numThreads)
+ /// - Loop
+ /// barrier.Join()
+ /// Do work here
+ /// barrier.Signal()
+ ///
+ /// Usage pattern for worker thread:
+ /// - Loop
+ /// barrier.JoinWorker()
+ /// Do work here
+ /// barrier.Wait()
+ ///
+ /// Currently works with fixed number of workers to simplify APIs
+ ///
+ public class SyncBarrier
+ {
+
+ /// Constructor
+ /// Number of worker threads participating in loop
+ public SyncBarrier(uint numThreads)
+ {
+ this.numThreads = numThreads;
+ }
+
+
+ // ----------------------------------------------------------------------------------------
+ // Master thread operations
+ // ----------------------------------------------------------------------------------------
+
+ /// Master thread joins barrier at the beggining of the loop
+ public void Join()
+ {
+ // Wait for all threads to be ready
+ notifyMaster.WaitOne();
+
+ // Reset ready count and end event - all worker threads are ready for next loop
+ this.cntJoin = 0;
+ this.syncEnd.Reset();
+
+ // Synchonously start threads by signalling
+ this.syncStart.Set();
+ }
+
+
+ // Master thread signals workers when everybody is done
+ public void Signal()
+ {
+ // Wait for all threads to complete
+ notifyMaster.WaitOne();
+
+ // Reset thread start synchonization objects so no worker gets ahead of master
+ this.syncStart.Reset();
+
+ // Signal workers to continue
+ this.syncEnd.Set();
+
+ // Reset completed counter
+ this.cntCompleted = 0;
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // Worker thread operations
+ // ----------------------------------------------------------------------------------------
+
+ /// Worker thread joins barrier
+ public void JoinWorker()
+ {
+ // Increase the barrier join cnt (ready worker threads)
+ int incJoin = Interlocked.Increment(ref this.cntJoin);
+
+ // If this is the last worker notify master thread that we are done
+ if( incJoin == this.numThreads ) {
+ // Notify master thread that we are done
+ notifyMaster.Set();
+ }
+
+ // Wait for signal from master thread to proceed
+ this.syncStart.WaitOne();
+ }
+
+ /// Worker thread waits for randevouz signal
+ public void Wait()
+ {
+ // Increase the barrier (completed worker threads) counter
+ int incCompleted = Interlocked.Increment(ref this.cntCompleted);
+
+ // If this is the last worker notify master thread that we are done
+ if( incCompleted == this.numThreads ) {
+ notifyMaster.Set();
+ }
+
+ // Wait for signal from master thread to proceed
+ this.syncEnd.WaitOne();
+ }
+
+
+ /// Number of working threads
+ private uint numThreads;
+
+ /// Signal for synchonous start of working threads
+ private ManualResetEvent syncStart = new ManualResetEvent(false);
+
+ /// Signal for synchonous start of working threads
+ private ManualResetEvent syncEnd = new ManualResetEvent(false);
+
+ /// Signal master thread that all workers are done
+ private AutoResetEvent notifyMaster = new AutoResetEvent(false);
+
+ /// Number of worker threads completed the iteration
+ private int cntCompleted = 0;
+
+ /// Number of worker threads joined in barrier
+ private int cntJoin = 0;
+ } // SyncBarrier
+
+
+} // namespace SchedBench
diff --git a/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.cs b/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.cs
index d0f9695..b76bfba 100644
--- a/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.cs
+++ b/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: SharedHeapBench.cs
-//
// Note: Singularity micro-benchmark program.
//
using Microsoft.Singularity;
@@ -24,7 +22,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(HelpMessage="Show attributes associated with a file", DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.csproj b/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.csproj
index 488507b..33cf754 100644
--- a/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.csproj
+++ b/base/Applications/Benchmarks/SharedHeap/SharedHeapBench.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Library
+ Singbench.Contracts
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Benchmarks/SingBench/Contracts/SingBench.Contracts.csproj b/base/Applications/Benchmarks/SingBench/Contracts/SingBench.Contracts.csproj
index f20c244..b415650 100644
--- a/base/Applications/Benchmarks/SingBench/Contracts/SingBench.Contracts.csproj
+++ b/base/Applications/Benchmarks/SingBench/Contracts/SingBench.Contracts.csproj
@@ -1,8 +1,6 @@

+
diff --git a/base/Applications/Benchmarks/SingBench/SingBench/Child.sg b/base/Applications/Benchmarks/SingBench/SingBench/Child.sg
new file mode 100644
index 0000000..6d0625a
--- /dev/null
+++ b/base/Applications/Benchmarks/SingBench/SingBench/Child.sg
@@ -0,0 +1,127 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Diagnostics.Contracts;
+using Microsoft.Singularity.Endpoint;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+
+using Allocation = Microsoft.Singularity.V1.Services.SharedHeapService.Allocation;
+
+namespace Microsoft.Singularity.Applications.Singbench
+{
+ public sealed class Child
+ {
+ public static void ReceivePerf(int iterations)
+ {
+ int doit = iterations / 2;
+
+ // Make a new channel.
+ SendTestContract.Imp! childImp;
+ SendTestContract.Exp! childExp;
+ SendTestContract.NewChannel(out childImp, out childExp);
+
+ // Start up our child
+ string[] args = new string[3];
+ args[0] = "BenchChild";
+ args[1] = "-where";
+ args[2] = "!";
+ Process child = new Process(args, (Endpoint * in ExHeap)childExp);
+
+ // set the where parameter to true
+ ParameterCode code;
+ code = child.SetStartupBoolArg(0, true);
+ if (code != ParameterCode.Success) {
+ Console.WriteLine("unable to set bool index 0. error={0}", code);
+ delete childImp;
+ return;
+ }
+
+ child.Start();
+
+ childImp.RecvTestReady();
+
+ PerfSnap snap = new PerfSnap();
+
+ snap.Start();
+ try {
+ int arg;
+ for (int i = 0; i < doit; i++) {
+ arg = i;
+ childImp.SendReq(arg);
+ childImp.RecvResp(out arg);
+ }
+ }
+ finally {
+ snap.Finish(iterations);
+ }
+
+ childImp.SendReq(-1);
+ delete childImp;
+ child.Join();
+
+ snap.Display("CHILD S/R");
+ }
+
+ ////////////////////////////// Child send-receive performance test
+ //
+ public static void ReceivePerf2(int iterations, int messageBytes)
+ {
+ // Make a new channel.
+ BufferTestContract.Imp! childImp;
+ BufferTestContract.Exp! childExp;
+ BufferTestContract.NewChannel(out childImp, out childExp);
+
+ // Start up our child
+ string[] args = new string[2];
+ args[0] = "BenchChild";
+ args[1] = "!";
+ Process child = new Process(args, (Endpoint * in ExHeap)childExp);
+ child.Start();
+
+ childImp.RecvBufferReady();
+
+ byte[]! in ExHeap buffer = new [ExHeap] byte[messageBytes];
+
+ PerfSnap snap = new PerfSnap();
+
+ snap.Start();
+ try {
+ for (int i = 0; i < iterations; i++) {
+ childImp.SendReq(iterations - i - 1, buffer);
+ childImp.RecvResp(out buffer);
+ }
+ }
+ finally {
+ // Factor of two for one-sided send-receive only
+ snap.Finish(2 * iterations);
+ delete buffer;
+ }
+
+ delete childImp;
+ child.Join();
+
+ if (messageBytes < 1024) {
+ snap.Display(String.Format("Child S/RB-{0}", messageBytes));
+ }
+ else {
+ snap.Display(String.Format("Child S/RB-{0}K",
+ messageBytes / 1024));
+ }
+ }
+ }
+}
diff --git a/base/Applications/Benchmarks/SingBench/SingBench/Parameters.sg b/base/Applications/Benchmarks/SingBench/SingBench/Parameters.sg
new file mode 100644
index 0000000..a89adb2
--- /dev/null
+++ b/base/Applications/Benchmarks/SingBench/SingBench/Parameters.sg
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Diagnostics.Contracts;
+using Microsoft.Singularity.Endpoint;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+
+using Allocation = Microsoft.Singularity.V1.Services.SharedHeapService.Allocation;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+namespace Microsoft.Singularity.Applications.Singbench
+{
+ [ConsoleCategory(HelpMessage="Singularity Benchmark Application", DefaultAction=true)]
+ internal sealed class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef memoryRef;
+
+ [BoolParameter( "b", Default=false , HelpMessage="Break at start of tests.")]
+ internal bool breakIn;
+
+ [LongParameter( "i", Default=10000 , HelpMessage="Iterate tests times.")]
+ internal long iterations;
+
+ [BoolParameter( "n", Default=true , HelpMessage="No GC between tests.")]
+ internal bool allowGC;
+
+ [BoolParameter( "w", Default=false , HelpMessage="Wait for key press between tests.")]
+ internal bool pauseForKeys;
+
+ [BoolParameter( "x", Default=false , HelpMessage="XML output.")]
+ internal bool xmlOutput;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return SingBench.AppMain(this);
+ }
+ }
+}
diff --git a/base/Applications/Benchmarks/SingBench/SingBench/PerfSnap.sg b/base/Applications/Benchmarks/SingBench/SingBench/PerfSnap.sg
index 11eb7ab..edc492c 100644
--- a/base/Applications/Benchmarks/SingBench/SingBench/PerfSnap.sg
+++ b/base/Applications/Benchmarks/SingBench/SingBench/PerfSnap.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: PerfSnap.sg
-//
// Note: Performance measurer for Singularity Benchmark
//
@@ -62,7 +60,7 @@ namespace Microsoft.Singularity.Applications.Singbench
public void Start()
{
if (!atRing3) {
- disabled = Processor.DisableInterrupts();
+ // disabled = Processor.DisableInterrupts();
// flush out pending IO interrupts
Thread.Yield();
Thread.Yield();
@@ -111,7 +109,8 @@ namespace Microsoft.Singularity.Applications.Singbench
Reset(1, PerfEvtSel.COUNT | PerfEvtSel.RetiredInstructions);
Reset(2, PerfEvtSel.COUNT | PerfEvtSel.RetiredBranchInstructions);
Reset(3, PerfEvtSel.COUNT | PerfEvtSel.RequestsToL2Cache | 0x400);
- } else {
+ }
+ else {
// We're not allowed to reset the perf counters, so take note
// of their current values; we will subtract from this later.
x64_i0 = Processor.ReadPmc(0);
@@ -168,7 +167,7 @@ namespace Microsoft.Singularity.Applications.Singbench
endStackRets = stackRets;
if (!atRing3) {
- Processor.RestoreInterrupts(disabled);
+ // Processor.RestoreInterrupts(disabled);
}
this.iterations = iterations;
@@ -178,7 +177,8 @@ namespace Microsoft.Singularity.Applications.Singbench
{
if (xmlOutput) {
DisplayXml(name);
- } else {
+ }
+ else {
DisplayText(name);
}
}
@@ -263,7 +263,8 @@ namespace Microsoft.Singularity.Applications.Singbench
EvtSelToString(e1),
EvtSelToString(e2),
EvtSelToString(e3)));
- } else {
+ }
+ else {
// Subtract from the initial perf-counter values to
// get the delta we want
x64_p0 -= x64_i0;
diff --git a/base/Applications/Benchmarks/SingBench/SingBench/SingBench.sg b/base/Applications/Benchmarks/SingBench/SingBench/SingBench.sg
index 899b93c..62b47c8 100644
--- a/base/Applications/Benchmarks/SingBench/SingBench/SingBench.sg
+++ b/base/Applications/Benchmarks/SingBench/SingBench/SingBench.sg
@@ -4,10 +4,7 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: SingBench.sg
-//
-// Note: Benchmark suite for Singularity primitives
-//
+
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Diagnostics.Contracts;
using Microsoft.Singularity.Endpoint;
@@ -23,44 +20,11 @@ using System.Threading;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
-[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+using Allocation = Microsoft.Singularity.V1.Services.SharedHeapService.Allocation;
namespace Microsoft.Singularity.Applications.Singbench
{
- [ConsoleCategory(HelpMessage="Singularity Benchmark Application", DefaultAction=true)]
- internal sealed class Parameters
- {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- [Endpoint]
- public readonly TRef memoryRef;
-
- [BoolParameter( "b", Default=false , HelpMessage="Break at start of tests.")]
- internal bool breakIn;
-
- [BoolParameter( "n", Default=true , HelpMessage="No GC between tests.")]
- internal bool allowGC;
-
- [BoolParameter( "w", Default=false , HelpMessage="Wait for key press between tests.")]
- internal bool pauseForKeys;
-
- [BoolParameter( "x", Default=false , HelpMessage="XML output.")]
- internal bool xmlOutput;
-
- [LongParameter( "i", Default=10000 , HelpMessage="Iterate tests times.")]
- internal long iterations;
-
- reflective internal Parameters();
-
- internal int AppMain() {
- return SingBench.AppMain(this);
- }
- }
-
public class SingBench
{
private static bool atRing3;
@@ -244,19 +208,22 @@ namespace Microsoft.Singularity.Applications.Singbench
PerfSnap snap = new PerfSnap();
- bool saved = Processor.DisableInterrupts();
- System.Diagnostics.Debug.Assert(saved == true);
+ bool saved = Processor.DisableLocalPreemption();
+ // We no longer disable interrupts for this test.
+ // When the scheduler implements the SIP scheduling,
+ // we can enable this back after switching to the local preemption
+ //System.Diagnostics.Debug.Assert(saved == true);
try {
snap.Start();
for (int i = 0; i < iterations; i++) {
- Processor.RestoreInterrupts(saved);
- saved = Processor.DisableInterrupts();
+ Processor.RestoreLocalPreemption(saved);
+ saved = Processor.DisableLocalPreemption();
}
}
finally {
snap.Finish(iterations);
- Processor.RestoreInterrupts(saved);
+ Processor.RestoreLocalPreemption(saved);
}
snap.Display("Irq SVE/RSTR");
@@ -431,6 +398,8 @@ namespace Microsoft.Singularity.Applications.Singbench
snap.Display("Wait/Set");
}
+ //==============START SEND/RECV TESTS==================================
+
/////////////////////////////////////////// Receive Performance Tests.
//
public contract ReceivePerfTest
@@ -482,7 +451,7 @@ namespace Microsoft.Singularity.Applications.Singbench
snap.Start();
- if (breakIn) {
+ if (breakIn) {
DebugStub.Break();
}
@@ -557,7 +526,7 @@ namespace Microsoft.Singularity.Applications.Singbench
snap.Start();
- if (breakIn) {
+ if (breakIn) {
DebugStub.Break();
}
@@ -585,106 +554,6 @@ namespace Microsoft.Singularity.Applications.Singbench
}
}
- /////////////////////////////////////////// Child-Receive performance tests
- //
- public static void DoChildReceivePerf(int iterations)
- {
- int doit = iterations / 2;
-
- // Make a new channel.
- SendTestContract.Imp! childImp;
- SendTestContract.Exp! childExp;
- SendTestContract.NewChannel(out childImp, out childExp);
-
- // Start up our child
- string[] args = new string[3];
- args[0] = "BenchChild.x86";
- args[1] = "-where";
- args[2] = "!";
- Process child = new Process(args, (Endpoint * in ExHeap)childExp);
-
- // set the where parameter to true
- ParameterCode code;
- code = child.SetStartupBoolArg(0, true);
- if (code != ParameterCode.Success){
- Console.WriteLine("unable to set bool index 0. error={0}", code);
- delete childImp;
- return;
- }
-
- child.Start();
-
- childImp.RecvTestReady();
-
- PerfSnap snap = new PerfSnap();
-
- snap.Start();
- try {
- int arg;
- for (int i = 0; i < doit; i++) {
- arg = i;
- childImp.SendReq(arg);
- childImp.RecvResp(out arg);
- }
- }
- finally {
- snap.Finish(iterations);
- }
-
- childImp.SendReq(-1);
- delete childImp;
- child.Join();
-
- snap.Display("CHILD S/R");
- }
-
- ////////////////////////////// Child send-receive performance test
- //
- public static void DoChildReceivePerf2(int iterations, int messageBytes)
- {
- // Make a new channel.
- BufferTestContract.Imp! childImp;
- BufferTestContract.Exp! childExp;
- BufferTestContract.NewChannel(out childImp, out childExp);
-
- // Start up our child
- string[] args = new string[2];
- args[0] = "BenchChild.x86";
- args[1] = "!";
- Process child = new Process(args, (Endpoint * in ExHeap)childExp);
- child.Start();
-
- childImp.RecvBufferReady();
-
- byte[]! in ExHeap buffer = new [ExHeap] byte[messageBytes];
-
- PerfSnap snap = new PerfSnap();
-
- snap.Start();
- try {
- for (int i = 0; i < iterations; i++) {
- childImp.SendReq(iterations - i - 1, buffer);
- childImp.RecvResp(out buffer);
- }
- }
- finally {
- // Factor of two for one-sided send-receive only
- snap.Finish(2 * iterations);
- delete buffer;
- }
-
- delete childImp;
- child.Join();
-
- if (messageBytes < 1024) {
- snap.Display(String.Format("Child S/RB-{0}", messageBytes));
- }
- else {
- snap.Display(String.Format("Child S/RB-{0}K",
- messageBytes / 1024));
- }
- }
-
//////////////////////////////////////////// Switch Performance Tests.
//
public contract SwitchPerfTest
@@ -706,8 +575,7 @@ namespace Microsoft.Singularity.Applications.Singbench
peerReady.Set();
for (int i = 0; i != -1;) {
- switch receive
- {
+ switch receive {
case ep.Req(arg) in s:
i = arg;
if (i != -1) {
@@ -754,11 +622,10 @@ namespace Microsoft.Singularity.Applications.Singbench
e.SendReq(0);
s.Add(e);
for (int i = 0; i < doit; i++) {
- switch receive
- {
+ switch receive {
case ep.Resp(arg) in s:
i = arg;
- if (i == doit -1) {
+ if (i == doit - 1) {
ep.SendReq(-1);
}
else {
@@ -782,6 +649,8 @@ namespace Microsoft.Singularity.Applications.Singbench
snap.Display("Send/Switch");
}
+ //==============END SEND/RECV TESTS==================================
+
//////////////////////////////////////////// Create Directory Channel.
//
public static void DoPageAllocPerf(int iterations)
@@ -927,7 +796,7 @@ namespace Microsoft.Singularity.Applications.Singbench
public static void SelectThread()
{
for (int i = 0; i < SELECT_ITERATIONS; i++) {
- for (int j = 0; j < NSELECT; j+=3) {
+ for (int j = 0; j < NSELECT; j += 3) {
SelectTest.Imp imp = ((!)impEndpoints[j]).Acquire();
imp.SendA();
@@ -935,7 +804,7 @@ namespace Microsoft.Singularity.Applications.Singbench
((!)impEndpoints[j]).Release(imp);
}
- for (int j = 1; j < NSELECT; j+=3) {
+ for (int j = 1; j < NSELECT; j += 3) {
SelectTest.Imp imp = ((!)impEndpoints[j]).Acquire();
imp.SendB();
@@ -943,7 +812,7 @@ namespace Microsoft.Singularity.Applications.Singbench
((!)impEndpoints[j]).Release(imp);
}
- for (int j = 2; j < NSELECT; j+=3) {
+ for (int j = 2; j < NSELECT; j += 3) {
SelectTest.Imp imp = ((!)impEndpoints[j]).Acquire();
imp.SendC();
@@ -1020,7 +889,7 @@ namespace Microsoft.Singularity.Applications.Singbench
bool failed = false;
for (int i = 0; i < SELECT_ITERATIONS; i++) {
- for(int j = 0; j < NSELECT-2; j++) {
+ for (int j = 0; j < NSELECT - 2; j++) {
SelectTest.Exp a = ((!)expEndpoints[j+0]).Acquire();
SelectTest.Exp b = ((!)expEndpoints[j+1]).Acquire();
SelectTest.Exp c = ((!)expEndpoints[j+2]).Acquire();
@@ -1110,7 +979,7 @@ namespace Microsoft.Singularity.Applications.Singbench
bool failed = false;
Console.WriteLine(" Starting server loop - {0} iterations", SELECT_ITERATIONS);
- for (i = 0 ; i < SELECT_ITERATIONS; i++) {
+ for (i = 0; i < SELECT_ITERATIONS; i++) {
ActuallySelect(eset, 0, ref failed);
ActuallySelect(eset, 0, ref failed);
ActuallySelect(eset, 0, ref failed);
@@ -1177,7 +1046,7 @@ namespace Microsoft.Singularity.Applications.Singbench
Process[] process = new Process[iterations];
string[] args = new string[2];
- args[0] = "testpe.x86";
+ args[0] = "testpe";
args[1] = "!"; // Special flag to not notify debugger.
PerfSnap snap = new PerfSnap();
@@ -1232,6 +1101,8 @@ namespace Microsoft.Singularity.Applications.Singbench
//
public static int GetTrace()
{
+
+#if false
Tracing.LogEntry * lstart;
Tracing.LogEntry * llimit;
Tracing.LogEntry ** lhead;
@@ -1245,6 +1116,7 @@ namespace Microsoft.Singularity.Applications.Singbench
(UIntPtr)lstart, (UIntPtr)llimit, (UIntPtr)lhead, (UIntPtr)(*lhead));
Console.WriteLine("Text: {0:X} {1:X}, {2:X}, {3:X}",
(UIntPtr)tstart, (UIntPtr)tlimit, (UIntPtr)thead, (UIntPtr)(*thead));
+#endif
return 0;
}
@@ -1279,12 +1151,13 @@ namespace Microsoft.Singularity.Applications.Singbench
bool xmlOutput = config.xmlOutput;
allowGC = config.allowGC;
pauseForKeys = config.pauseForKeys;
- breakIn = config.breakIn;
-
+ breakIn = config.breakIn;
+
if (Processor.AtKernelPrivilege()) {
atRing3 = false;
DualWriteLine("Singbench running at KERNEL privilege");
- } else {
+ }
+ else {
atRing3 = true;
DualWriteLine("Singbench running at USER privilege");
}
@@ -1293,14 +1166,14 @@ namespace Microsoft.Singularity.Applications.Singbench
peerBegin = new AutoResetEvent(false);
peerFinish = new AutoResetEvent(false);
- MemoryContract.Imp impMem = config.memoryRef.Acquire();
+ MemoryContract.Imp impMem = config.memoryRef.Acquire();
if (impMem == null) {
throw new ApplicationException("Error: Unable to bind to " +
MemoryContract.ModuleName);
}
- impMem.RecvReady();
-
+ impMem.RecvReady();
+
PerfSnap.SetOptions(atRing3, xmlOutput);
GetTrace();
@@ -1345,25 +1218,24 @@ namespace Microsoft.Singularity.Applications.Singbench
Pause();
ClearEnvironment(impMem);
- DoReceivePerf(1000);
+ DoReceivePerf(1024);
Pause();
for (int i = 1; i <= 65536; i *= 2) {
ClearEnvironment(impMem);
DoReceivePerf2(iterations, i);
- Pause();
+ Pause();
}
// Child-channel tests
ClearEnvironment(impMem);
- DoChildReceivePerf(1000);
+ Child.ReceivePerf(1000);
Pause();
-
for (int i = 1; i <= 65536; i *= 2) {
ClearEnvironment(impMem);
- DoChildReceivePerf2(iterations, i);
- Pause();
+ Child.ReceivePerf2(iterations, i);
+ Pause();
}
ClearEnvironment(impMem);
@@ -1419,8 +1291,8 @@ namespace Microsoft.Singularity.Applications.Singbench
ClearEnvironment(impMem);
DoSelectSet();
#endif
-
- } catch (Exception e) {
+ }
+ catch (Exception e) {
Console.WriteLine("Caught {0}", e.Message);
// How do I work out where an exception was thrown from these days?
//Console.WriteLine(e.StackTrace);
diff --git a/base/Applications/Benchmarks/SingBench/SingBench/SingBenchApp.csproj b/base/Applications/Benchmarks/SingBench/SingBench/SingBenchApp.csproj
index d4dbf6a..c8a5bb6 100644
--- a/base/Applications/Benchmarks/SingBench/SingBench/SingBenchApp.csproj
+++ b/base/Applications/Benchmarks/SingBench/SingBench/SingBenchApp.csproj
@@ -1,8 +1,6 @@

-
+
Bartok
Exe
@@ -50,13 +48,18 @@ Note: This is the template for a basic console app.
-
+
-
+
+
+
+
+
+
diff --git a/base/Applications/Benchmarks/bartok/ImportFromBartok.cmd b/base/Applications/Benchmarks/bartok/ImportFromBartok.cmd
new file mode 100644
index 0000000..10d763c
--- /dev/null
+++ b/base/Applications/Benchmarks/bartok/ImportFromBartok.cmd
@@ -0,0 +1,29 @@
+@echo.
+@echo *** Checking out Bartok MSIL files.
+@echo.
+sd edit msil\bartok.*
+@if errorlevel 1 goto exit
+
+@echo.
+@echo *** Copying files from Bartok enlistment.
+@echo.
+
+@if exist c:\othercode\act\bartok\obj\sing-debug-x86-x86\nul (
+ copy c:\othercode\act\bartok\obj\sing-debug-x86-x86\bartok.* msil
+ @if errorlevel 1 goto exit
+)
+
+@if exist c:\act\bartok\obj\sing-debug-x86-x86\nul (
+ copy c:\act\bartok\obj\sing-debug-x86-x86\bartok.* msil
+ @if errorlevel 1 goto exit
+)
+
+@if exist c:\home\act-dev7\bartok\obj\sing-debug-x86-x86\nul (
+ copy c:\home\act-dev7\bartok\obj\sing-debug-x86-x86\bartok.* msil
+ @if errorlevel 1 goto exit
+)
+
+@echo.
+@echo *** Deleting unused files.
+@echo.
+del msil\bartok.tryallextension.* 2>nul
diff --git a/base/Applications/Benchmarks/bartok/Imported.txt b/base/Applications/Benchmarks/bartok/Imported.txt
new file mode 100644
index 0000000..56f3b36
--- /dev/null
+++ b/base/Applications/Benchmarks/bartok/Imported.txt
@@ -0,0 +1 @@
+
diff --git a/base/Applications/Benchmarks/bartok/kernel/Diagnostics.Contracts.pdb b/base/Applications/Benchmarks/bartok/kernel/Diagnostics.Contracts.pdb
deleted file mode 100644
index 955101f..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Diagnostics.Contracts.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Diagnostics.pdb b/base/Applications/Benchmarks/bartok/kernel/Diagnostics.pdb
deleted file mode 100644
index cbcd9d1..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Diagnostics.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Directory.Contracts.pdb b/base/Applications/Benchmarks/bartok/kernel/Directory.Contracts.pdb
deleted file mode 100644
index 39dc5df..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Directory.Contracts.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Directory.pdb b/base/Applications/Benchmarks/bartok/kernel/Directory.pdb
deleted file mode 100644
index c4515bd..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Directory.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Drivers.pdb b/base/Applications/Benchmarks/bartok/kernel/Drivers.pdb
deleted file mode 100644
index 2a98a38..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Drivers.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/FileSystem.Contracts.pdb b/base/Applications/Benchmarks/bartok/kernel/FileSystem.Contracts.pdb
deleted file mode 100644
index 68e7e6c..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/FileSystem.Contracts.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Hal.LegacyPC.pdb b/base/Applications/Benchmarks/bartok/kernel/Hal.LegacyPC.pdb
deleted file mode 100644
index 1b8ed56..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Hal.LegacyPC.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Hypercall.Contracts.pdb b/base/Applications/Benchmarks/bartok/kernel/Hypercall.Contracts.pdb
deleted file mode 100644
index aa3b935..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Hypercall.Contracts.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Hypercall.pdb b/base/Applications/Benchmarks/bartok/kernel/Hypercall.pdb
deleted file mode 100644
index add584c..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Hypercall.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/ILHelpers.pdb b/base/Applications/Benchmarks/bartok/kernel/ILHelpers.pdb
deleted file mode 100644
index 461e888..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/ILHelpers.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Io.Contracts.pdb b/base/Applications/Benchmarks/bartok/kernel/Io.Contracts.pdb
deleted file mode 100644
index f529bdd..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Io.Contracts.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/IoSystem.pdb b/base/Applications/Benchmarks/bartok/kernel/IoSystem.pdb
deleted file mode 100644
index e9cf95c..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/IoSystem.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Loader.pdb b/base/Applications/Benchmarks/bartok/kernel/Loader.pdb
deleted file mode 100644
index 3ac2c5a..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Loader.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Microsoft.SingSharp.Runtime.pdb b/base/Applications/Benchmarks/bartok/kernel/Microsoft.SingSharp.Runtime.pdb
deleted file mode 100644
index 0661fd0..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Microsoft.SingSharp.Runtime.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Security.Contracts.pdb b/base/Applications/Benchmarks/bartok/kernel/Security.Contracts.pdb
deleted file mode 100644
index 0d44de1..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Security.Contracts.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Security.pdb b/base/Applications/Benchmarks/bartok/kernel/Security.pdb
deleted file mode 100644
index 7c19321..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Security.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/SecurityService.pdb b/base/Applications/Benchmarks/bartok/kernel/SecurityService.pdb
deleted file mode 100644
index e7119d9..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/SecurityService.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Stress.Contracts.pdb b/base/Applications/Benchmarks/bartok/kernel/Stress.Contracts.pdb
deleted file mode 100644
index 01b462e..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Stress.Contracts.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/Stress.pdb b/base/Applications/Benchmarks/bartok/kernel/Stress.pdb
deleted file mode 100644
index 6395486..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/Stress.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/System.Compiler.Runtime.pdb b/base/Applications/Benchmarks/bartok/kernel/System.Compiler.Runtime.pdb
deleted file mode 100644
index dd77d31..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/System.Compiler.Runtime.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/kernel/kernel.pdb b/base/Applications/Benchmarks/bartok/kernel/kernel.pdb
deleted file mode 100644
index 3d37732..0000000
Binary files a/base/Applications/Benchmarks/bartok/kernel/kernel.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Analysis.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Analysis.dll
index ad77e57..cd97082 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Analysis.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Analysis.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Analysis.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Analysis.pdb
deleted file mode 100644
index 91a6364..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Analysis.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Backend.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Backend.dll
index 6c6b6a4..cbabfee 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Backend.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Backend.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Backend.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Backend.pdb
deleted file mode 100644
index 8290412..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Backend.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.CfgUtil.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.CfgUtil.dll
index cbd7f2a..7ea9d66 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.CfgUtil.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.CfgUtil.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.CfgUtil.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.CfgUtil.pdb
deleted file mode 100644
index afe07cd..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.CfgUtil.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Coff.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Coff.dll
index 566f09d..ce9601b 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Coff.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Coff.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Coff.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Coff.pdb
deleted file mode 100644
index db6145e..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Coff.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Convert.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Convert.dll
index 0689e53..49dbd19 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Convert.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Convert.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Convert.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Convert.pdb
deleted file mode 100644
index 82714b2..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Convert.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Datatype.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Datatype.dll
index 1f87802..3b1c9ad 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Datatype.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Datatype.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Datatype.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Datatype.pdb
deleted file mode 100644
index 192a02d..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Datatype.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.DebugInfo.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.DebugInfo.dll
index a90246e..b9e2b9f 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.DebugInfo.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.DebugInfo.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.DebugInfo.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.DebugInfo.pdb
deleted file mode 100644
index 3dfa377..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.DebugInfo.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Encode.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Encode.dll
index 2b2bb0d..8172457 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Encode.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Encode.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Encode.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Encode.pdb
deleted file mode 100644
index 8348722..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Encode.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Ir.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Ir.dll
index 1302eb7..e25f8ce 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Ir.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Ir.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Ir.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Ir.pdb
deleted file mode 100644
index 2a0b027..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Ir.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Lir.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Lir.dll
index 3a76816..20fd3f7 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Lir.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Lir.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Lir.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Lir.pdb
deleted file mode 100644
index cefe573..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Lir.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.MSIL.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.MSIL.dll
index 14d3911..9fbaa61 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.MSIL.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.MSIL.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.MSIL.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.MSIL.pdb
deleted file mode 100644
index ccc1973..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.MSIL.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Mangle.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Mangle.dll
index b24109d..75bd9f0 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Mangle.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Mangle.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Mangle.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Mangle.pdb
deleted file mode 100644
index ee3587c..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Mangle.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Opt.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Opt.dll
index 0832b85..9dce515 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Opt.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Opt.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Opt.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Opt.pdb
deleted file mode 100644
index 4fe153f..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Opt.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Profile.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Profile.dll
index 51c5ed5..7678312 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Profile.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Profile.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Profile.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Profile.pdb
deleted file mode 100644
index 2a85b46..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Profile.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Regalloc.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Regalloc.dll
index bd5059e..91976f4 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Regalloc.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Regalloc.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Regalloc.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Regalloc.pdb
deleted file mode 100644
index 10fcc94..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Regalloc.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Runtime.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Runtime.pdb
deleted file mode 100644
index eaf779f..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Runtime.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.SystemExtension.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.SystemExtension.dll
index a67e204..a37326e 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.SystemExtension.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.SystemExtension.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.SystemExtension.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.SystemExtension.pdb
deleted file mode 100644
index e6f6105..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.SystemExtension.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Tables.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Tables.dll
index 18bf6c9..9ca6419 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Tables.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Tables.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Tables.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Tables.pdb
deleted file mode 100644
index 10da284..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Tables.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Utility.dll b/base/Applications/Benchmarks/bartok/msil/Bartok.Utility.dll
index dcbdb4e..ecbaba2 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Utility.dll and b/base/Applications/Benchmarks/bartok/msil/Bartok.Utility.dll differ
diff --git a/base/Applications/Benchmarks/bartok/msil/Bartok.Utility.pdb b/base/Applications/Benchmarks/bartok/msil/Bartok.Utility.pdb
deleted file mode 100644
index f7c9950..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/Bartok.Utility.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/bartok/msil/bartok.exe b/base/Applications/Benchmarks/bartok/msil/bartok.exe
index e703037..e728626 100644
Binary files a/base/Applications/Benchmarks/bartok/msil/bartok.exe and b/base/Applications/Benchmarks/bartok/msil/bartok.exe differ
diff --git a/base/Applications/Benchmarks/bartok/msil/bartok.pdb b/base/Applications/Benchmarks/bartok/msil/bartok.pdb
deleted file mode 100644
index 6b2fdf8..0000000
Binary files a/base/Applications/Benchmarks/bartok/msil/bartok.pdb and /dev/null differ
diff --git a/base/Applications/Benchmarks/diskreadperf/diskreadperf.csproj b/base/Applications/Benchmarks/diskreadperf/diskreadperf.csproj
index 776bf4c..c947eed 100644
--- a/base/Applications/Benchmarks/diskreadperf/diskreadperf.csproj
+++ b/base/Applications/Benchmarks/diskreadperf/diskreadperf.csproj
@@ -1,8 +1,6 @@

-
+
-
- Exe
- diskrw
- true
-
-
-
-
-
-
-
+
+ Exe
+ diskrw
+ true
+
-
+
+
+
+
+
+
+
diff --git a/base/Applications/Benchmarks/diskrw/diskrw.sg b/base/Applications/Benchmarks/diskrw/diskrw.sg
index 5912f83..edf6291 100644
--- a/base/Applications/Benchmarks/diskrw/diskrw.sg
+++ b/base/Applications/Benchmarks/diskrw/diskrw.sg
@@ -4,10 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: diskrw.sg
-//
-// Note:
-//
using System;
using System.Runtime.CompilerServices;
@@ -23,12 +19,13 @@ using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
+
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
+namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
{
[ConsoleCategory(HelpMessage="Disk r/w performance test", DefaultAction=true)]
- internal class Parameters
+ internal class Parameters
{
[InputEndpoint("data")]
public readonly TRef Stdin;
@@ -72,11 +69,11 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
return DiskBenchmark.AppMain(this);
}
}
-
+
public class DiskBenchmark
{
- private const uint BytesPerSector = 512;
- private const uint SectorsPerMB = 1024 * 1024 / BytesPerSector;
+ internal const uint BytesPerSector = 512;
+ internal const uint SectorsPerMB = 1024 * 1024 / BytesPerSector;
public static DiskDeviceContract.Imp:Ready OpenDevice(String! devname)
{
@@ -90,42 +87,39 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
ns = DirectoryService.NewClientEndpoint();
bool success;
success = SdsUtils.Bind(devname,ns, exp, out errorOut);
- if (!success)
- {
+ if (!success) {
Console.WriteLine("Bind of {0} failed. Reason:{1}\n",
- devname, SdsUtils.ErrorCodeToString(errorOut));
+ devname, SdsUtils.ErrorCodeToString(errorOut));
delete imp;
delete ns;
return null;
}
- switch receive
- {
- case imp.Success():
- break;
- case imp.ContractNotSupported():
- Console.WriteLine("{0} does not support DiskDevice", devname);
- delete imp;
- delete ns;
- return null;
- case imp.ChannelClosed():
- Console.WriteLine("DiskDevice channel to {0} closed unexpectedly", devname);
- delete imp;
- delete ns;
- return null;
- }
+ switch receive {
+ case imp.Success():
+ break;
+ case imp.ContractNotSupported():
+ Console.WriteLine("{0} does not support DiskDevice", devname);
+ delete imp;
+ delete ns;
+ return null;
+ case imp.ChannelClosed():
+ Console.WriteLine("DiskDevice channel to {0} closed unexpectedly", devname);
+ delete imp;
+ delete ns;
+ return null;
+ }
delete ns;
return imp;
}
- private static ulong GetRandomOffset(SRandom! rng,
+ internal static ulong GetRandomOffset(SRandom! rng,
ulong diskSectorCount,
ulong blockBytes)
{
ulong maxBlock = diskSectorCount * 512 / blockBytes;
ulong offset = 0;
- for (int i = 0; i < 64; i += 30)
- {
+ for (int i = 0; i < 64; i += 30) {
offset ^= (ulong)(rng.Next() << i);
}
offset &= 0x7fffffffffffffff;
@@ -133,7 +127,7 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
return offset * blockBytes;
}
- private static void DisplayPerf(bool didRead,
+ internal static void DisplayPerf(bool didRead,
bool didRandom,
TimeSpan elapsed,
ulong blockCount,
@@ -170,8 +164,7 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
// Open device
//
DiskDeviceContract.Imp imp = OpenDevice(deviceName);
- if (null == imp)
- {
+ if (null == imp) {
Console.WriteLine("Could not open {0}", deviceName);
return 1;
}
@@ -182,15 +175,14 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
ulong diskSectorCount;
imp.SendGetSectorCount();
- switch receive
- {
- case imp.AckGetSectorCount(sectorCount):
- diskSectorCount = sectorCount;
- break;
- case imp.ChannelClosed():
- Console.WriteLine("Channel closed unexpectedly");
- throw new Exception("Unexpected channel close");
- }
+ switch receive {
+ case imp.AckGetSectorCount(sectorCount):
+ diskSectorCount = sectorCount;
+ break;
+ case imp.ChannelClosed():
+ Console.WriteLine("Channel closed unexpectedly");
+ throw new Exception("Unexpected channel close");
+ }
// Constrain disk size if user requested
if (diskLimitMB != 0 &&
@@ -201,13 +193,11 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
diskLimitMB = diskSectorCount / SectorsPerMB;
// Constrain block count if it overflows available blocks
- if (blockCount * blockBytes > diskSectorCount * BytesPerSector)
- {
+ if (blockCount * blockBytes > diskSectorCount * BytesPerSector) {
blockCount = diskSectorCount * BytesPerSector / blockBytes;
}
- if (runNumber == 0)
- {
+ if (runNumber == 0) {
Console.WriteLine("# Type: {0} {1}",
doRandom ? "Random" : "Sequential",
doRead ? "Read" : "Write");
@@ -224,8 +214,7 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
SRandom rng = new SRandom();
ulong diskPos = 0;
- if (doRandom)
- {
+ if (doRandom) {
diskPos = GetRandomOffset(rng, diskSectorCount, blockBytes);
}
@@ -241,30 +230,25 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
TimeSpan startTime = ProcessService.GetUpTime();
- for (ulong i = 0; i < blockCount; i++)
- {
+ for (ulong i = 0; i < blockCount; i++) {
ulong sector = diskPos / BytesPerSector;
byte[]! in ExHeap outBuffer;
- if (doRead)
- {
+ if (doRead) {
imp.SendRead(buffer, 0, blockBytes, sector);
imp.RecvAckRead(out outBuffer);
}
- else
- {
+ else {
imp.SendWrite(buffer, 0, blockBytes, sector);
imp.RecvAckWrite(out outBuffer);
}
buffer = outBuffer;
- if (doRandom)
- {
+ if (doRandom) {
diskPos =
GetRandomOffset(rng, diskSectorCount, blockBytes);
}
- else
- {
+ else {
diskPos += blockBytes;
}
}
@@ -284,11 +268,11 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
out endGcBytes);
Console.WriteLine("[AppGC :- cnt {0} bytes {1} Kern: ints {2} swi {3} gcs {4}]",
- endGcCount - startGcCount,
- endGcBytes - startGcBytes,
- ProcessService.GetKernelInterruptCount() - startIrqCount,
- ProcessService.GetContextSwitchCount() - startSwitchCount,
- ProcessService.GetKernelGcCount() - startKernelGcCount);
+ endGcCount - startGcCount,
+ endGcBytes - startGcBytes,
+ ProcessService.GetKernelInterruptCount() - startIrqCount,
+ ProcessService.GetContextSwitchCount() - startSwitchCount,
+ ProcessService.GetKernelGcCount() - startKernelGcCount);
return 0;
}
@@ -298,24 +282,22 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
out ulong value)
{
// arg should look like "[-/][A-z]:[0-9]"
- if (arg.Length >= 4)
- {
- try
- {
+ if (arg.Length >= 4) {
+ try {
value = UInt64.Parse(arg.Substring(3));
return true;
}
- catch (FormatException)
- {}
- catch (OverflowException)
- {}
+ catch (FormatException) {
+ }
+ catch (OverflowException) {
+ }
}
Console.WriteLine("Could not parse {0}", name);
value = 0;
return false;
}
- static void Usage()
+ internal static void Usage()
{
}
@@ -333,38 +315,34 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
bool doRead = config.doRead;
ulong dataMB = (ulong) config.dataMB;
- if (blockBytes < 512 || (blockBytes & (blockBytes - 1)) != 0)
- {
+ if (blockBytes < 512 || (blockBytes & (blockBytes - 1)) != 0) {
Console.WriteLine("Block size must be a power of two greater than or equal to 512.");
Usage();
return -1;
}
- if (doRead == doWrite)
- {
+ if (doRead == doWrite) {
Console.WriteLine("Need to specify either read or write test.");
Usage();
return -1;
}
- else if (doRead)
- {
+ else if (doRead) {
diskReadTest = true;
}
- if (dataMB != 0)
- {
+ if (dataMB != 0) {
blockCount = dataMB * 1024 * 1024 / blockBytes;
}
- for (int run = 0; run < (int)repeatCount; run++)
- {
- if (run != 0)
+ for (int run = 0; run < (int)repeatCount; run++) {
+ if (run != 0) {
System.Threading.Thread.Sleep(1000 * (int)pauseSecs);
+ }
+
Tracing.Log(Tracing.Debug, "Starting diskrw run {0}",
(UIntPtr) run);
- if (DoDevice(deviceName, run, blockCount, blockBytes,
- diskLimitMB, randomIO, diskReadTest) != 0)
- {
+ if (DoDevice((!)deviceName, run, blockCount, blockBytes,
+ diskLimitMB, randomIO, diskReadTest) != 0) {
return -1;
}
Tracing.Log(Tracing.Debug, "Ending diskrw run {0}",
diff --git a/base/Applications/Benchmarks/diskrw/srandom.cs b/base/Applications/Benchmarks/diskrw/srandom.cs
new file mode 100644
index 0000000..fbaa932
--- /dev/null
+++ b/base/Applications/Benchmarks/diskrw/srandom.cs
@@ -0,0 +1,63 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using Microsoft.Contracts;
+
+namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
+{
+ ///
+ /// Low-cost Integer random number generator. The
+ /// implementation is based on the description of Park and
+ /// Miller's RNG on page 278 of Numerical Recipes in C, 2nd
+ /// Edition, by Press, Teukolsky, Vetterling, and Flannery.
+ ///
+ /// The same random number generator is used for our disk
+ /// benchmarks on other platforms.
+ ///
+ public class SRandom
+ {
+ public const uint Maximum = 0x7fffffffu;
+
+ const ulong m = 2147483647;
+ const ulong a = 16807;
+ const uint initialValue = 0x23456789;
+ uint last;
+
+ public SRandom()
+ {
+ Reset();
+ }
+
+ [Delayed]
+ public void Reset()
+ {
+ last = initialValue;
+ }
+
+ public int Next()
+ {
+ // Use 64-bit multiplication to preserve high bits.
+ ulong tmp = (a * last) % m;
+ last = (uint) tmp;
+ return (int)(last & Maximum);
+ }
+
+ public static void Check()
+ {
+ const int test_iterations = 10000000;
+ SRandom r = new SRandom();
+ int hash = 0;
+ for (int i = 0; i < test_iterations; i++) {
+ int n = r.Next();
+ System.Diagnostics.Debug.Assert(n != 0);
+ hash ^= n;
+ }
+ Console.Write("xor sum 1...{0} = {1}\n", test_iterations, hash);
+ System.Diagnostics.Debug.Assert(hash == 1080076236);
+ }
+ }
+}
diff --git a/base/Applications/Benchmarks/diskrw/srandom.sg b/base/Applications/Benchmarks/diskrw/srandom.sg
deleted file mode 100644
index 8752efe..0000000
--- a/base/Applications/Benchmarks/diskrw/srandom.sg
+++ /dev/null
@@ -1,64 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-
-
-using System;
-using Microsoft.Contracts;
-
-namespace Microsoft.Singularity.Applications.Benchmarks.DiskRW
-{
- ///
- /// Low-cost Integer random number generator. The
- /// implementation is based on the description of Park and
- /// Miller's RNG on page 278 of Numerical Recipes in C, 2nd
- /// Edition, by Press, Teukolsky, Vetterling, and Flannery.
- ///
- /// The same random number generator is used for our disk
- /// benchmarks on other platforms.
- ///
- public class SRandom
- {
- public const int Maximum = 0x7fffffffu;
-
- const ulong m = 2147483647;
- const ulong a = 16807;
- const uint initialValue = 0x23456789;
- uint last;
-
- public SRandom()
- {
- Reset();
- }
-
- [Delayed]
- public void Reset()
- {
- last = initialValue;
- }
-
- public int Next()
- {
- // Use 64-bit multiplication to preserve high bits.
- ulong tmp = (a * last) % m;
- last = (uint) tmp;
- return (int)(last & Maximum);
- }
-
- public static void Check()
- {
- const int test_iterations = 10000000;
- SRandom r = new SRandom();
- int hash = 0;
- for (int i = 0; i < test_iterations; i++)
- {
- int n = r.Next();
- System.Diagnostics.Debug.Assert(n != 0);
- hash ^= n;
- }
- Console.Write("xor sum 1...{0} = {1}\n", test_iterations, hash);
- System.Diagnostics.Debug.Assert(hash == 1080076236);
- }
- }
-}
diff --git a/base/Applications/Benchmarks/diskrwnull/diskrw.sg b/base/Applications/Benchmarks/diskrwnull/diskrw.sg
index 78bb024..220e724 100644
--- a/base/Applications/Benchmarks/diskrwnull/diskrw.sg
+++ b/base/Applications/Benchmarks/diskrwnull/diskrw.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: diskrw.sg
-//
// Note:
//
@@ -94,8 +92,7 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRWNull
{
ulong maxBlock = diskSectorCount * 512 / blockBytes;
ulong offset = 0;
- for (int i = 0; i < 64; i += 30)
- {
+ for (int i = 0; i < 64; i += 30) {
offset ^= (ulong)(rng.Next() << i);
}
offset &= 0x7fffffffffffffff;
@@ -132,8 +129,7 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRWNull
bool doRead)
{
- for(int i = 0; i < 4000; i++)
- {
+ for (int i = 0; i < 4000; i++) {
Hack.Imp! imp;
Hack.Exp! exp;
Hack.NewChannel(out imp, out exp);
@@ -151,13 +147,11 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRWNull
diskLimitMB = diskSectorCount / SectorsPerMB;
// Constrain block count if it overflows available blocks
- if (blockCount * blockBytes > diskSectorCount * BytesPerSector)
- {
+ if (blockCount * blockBytes > diskSectorCount * BytesPerSector) {
blockCount = diskSectorCount * BytesPerSector / blockBytes;
}
- if (runNumber == 0)
- {
+ if (runNumber == 0) {
Console.WriteLine("# Type: {0} {1}",
doRandom ? "Random" : "Sequential",
doRead ? "Read" : "Write");
@@ -174,8 +168,7 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRWNull
SRandom rng = new SRandom();
ulong diskPos = 0;
- if (doRandom)
- {
+ if (doRandom) {
diskPos = GetRandomOffset(rng, diskSectorCount, blockBytes);
}
@@ -192,59 +185,58 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRWNull
Hack.Imp! imph = himp.Acquire();
Hack.Exp! exph = hexp.Acquire();
- /***/
+ ///
ESet eset = new ESet();
eset.Add(exph);
- /***/
+ ///
TimeSpan startTime = ProcessService.GetUpTime();
- for (ulong i = 0; i < blockCount; i++)
- {
+ for (ulong i = 0; i < blockCount; i++) {
byte[]! in ExHeap outBuffer;
- if (doRead)
- {
+ if (doRead) {
//ProcessService.GetUpTime();
//imph.SendHak();
//switch receive { case exph.Hak(): exph.SendHak(); break; case unsatisfiable: throw new System.Exception(); }
//imph.RecvHak();
- /***/
+ ///
imph.SendHak();
- switch receive { case ep.Hak() in eset: ep.SendHak(); eset.Add(ep); break; case unsatisfiable: throw new System.Exception(); }
+ switch receive {
+ case ep.Hak() in eset: ep.SendHak(); eset.Add(ep); break; case unsatisfiable: throw new System.Exception();
+ }
imph.RecvHak();
- /***/
+ ///
//imph.SendHak(); exph.RecvHak(); exph.SendHak(); imph.RecvHak();
outBuffer = buffer;
}
- else
- {
+ else {
outBuffer = buffer;
}
buffer = outBuffer;
- if (doRandom)
- {
+ if (doRandom) {
diskPos =
GetRandomOffset(rng, diskSectorCount, blockBytes);
}
- else
- {
+ else {
diskPos += blockBytes;
}
}
TimeSpan endTime = ProcessService.GetUpTime();
- /***/
+ ///
imph.SendHak();
- switch receive { case ep.Hak() in eset: ep.SendHak(); hexp.Release(ep); break; case unsatisfiable: throw new System.Exception(); }
+ switch receive {
+ case ep.Hak() in eset: ep.SendHak(); hexp.Release(ep); break; case unsatisfiable: throw new System.Exception();
+ }
imph.RecvHak();
himp.Release(imph);
eset.Dispose();
- /***/
+ ///
//hexp.Release(exph);
//himp.Release(imph);
@@ -277,17 +269,15 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRWNull
out ulong value)
{
// arg should look like "[-/][A-z]:[0-9]"
- if (arg.Length >= 4)
- {
- try
- {
+ if (arg.Length >= 4) {
+ try {
value = UInt64.Parse(arg.Substring(3));
return true;
}
- catch (FormatException)
- {}
- catch (OverflowException)
- {}
+ catch (FormatException) {
+ }
+ catch (OverflowException) {
+ }
}
Console.WriteLine("Could not parse {0}", name);
value = 0;
@@ -316,29 +306,24 @@ namespace Microsoft.Singularity.Applications.Benchmarks.DiskRWNull
hexp = new TRef(exp);
- if (blockBytes < 512 || (blockBytes & (blockBytes - 1)) != 0)
- {
+ if (blockBytes < 512 || (blockBytes & (blockBytes - 1)) != 0) {
Console.WriteLine("Block size must be a power of two greater than or equal to 512.");
return -1;
}
- if (doRead == doWrite)
- {
+ if (doRead == doWrite) {
Console.WriteLine("Need to specify either read or write test.");
return -1;
}
- else if (doRead)
- {
+ else if (doRead) {
diskReadTest = true;
}
- if (dataMB != 0)
- {
+ if (dataMB != 0) {
blockCount = dataMB * 1024 * 1024 / blockBytes;
}
- for (int run = 0; run < (int)repeatCount; run++)
- {
+ for (int run = 0; run < (int)repeatCount; run++) {
if (run != 0)
System.Threading.Thread.Sleep(1000 * (int)pauseSecs);
Tracing.Log(Tracing.Debug, "Starting diskrw run {0}",
diff --git a/base/Applications/Benchmarks/diskrwnull/diskrwnull.csproj b/base/Applications/Benchmarks/diskrwnull/diskrwnull.csproj
index 43dd557..d983cbb 100644
--- a/base/Applications/Benchmarks/diskrwnull/diskrwnull.csproj
+++ b/base/Applications/Benchmarks/diskrwnull/diskrwnull.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ bootCount
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/BounceBackTest/BounceBackClient.csproj b/base/Applications/BounceBackTest/BounceBackClient.csproj
new file mode 100644
index 0000000..eb5f75a
--- /dev/null
+++ b/base/Applications/BounceBackTest/BounceBackClient.csproj
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+ Exe
+ BounceBackClient
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/BounceBackTest/BounceBackClient.sg b/base/Applications/BounceBackTest/BounceBackClient.sg
new file mode 100644
index 0000000..5e28ee1
--- /dev/null
+++ b/base/Applications/BounceBackTest/BounceBackClient.sg
@@ -0,0 +1,66 @@
+using System;
+using Microsoft.Singularity.V1;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Security;
+using Microsoft.Singularity.V1.Processes;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity;
+
+
+[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
+[assembly: System.Reflection.AssemblyKeyFileAttribute("public.snk")]
+[assembly: System.Reflection.AssemblyDelaySignAttribute(true)]
+
+namespace Microsoft.Singularity.Applications
+{
+ public class BounceBackClient
+ {
+ public static int Main(String[] args)
+ {
+ DirectoryServiceContract.Imp! dirImp;
+
+ dirImp = DirectoryService.NewClientEndpoint();
+ string bindPath = "/BounceBackServer";
+
+ CalculatorContract.Imp! calculatorImp;
+ CalculatorContract.Exp! calculatorExp;
+ CalculatorContract.NewChannel(out calculatorImp, out calculatorExp);
+
+ ErrorCode error;
+ if (!SdsUtils.Bind(bindPath, dirImp, calculatorExp, out error)) {
+ DebugStub.WriteLine("Bind to calculator server failed error {0}\n",
+ __arglist(SdsUtils.ErrorCodeToString(error)));
+ delete dirImp;
+ delete calculatorImp;
+ return -1;
+ }
+
+
+ calculatorImp.RecvSuccess();
+
+ for (int i = 0; i < 5; i++) {
+ DebugStub.WriteLine("Sending add {0} + {1}\n", __arglist(i, (i + 1)));
+ calculatorImp.SendAddInteger(i, i+1);
+ switch receive {
+ case calculatorImp.IntegerResult(result) :
+ DebugStub.WriteLine("received {0}\n",
+ __arglist(result));
+ break;
+
+ case calculatorImp.ChannelClosed() :
+ DebugStub.WriteLine("calculator channel closed\n");
+ delete calculatorImp;
+ delete dirImp;
+ return -1;
+ break;
+
+ }
+ }
+
+ delete calculatorImp;
+ delete dirImp;
+
+ return 0;
+ }
+ }
+}
diff --git a/base/Applications/BounceBackTest/BounceBackServer.csproj b/base/Applications/BounceBackTest/BounceBackServer.csproj
new file mode 100644
index 0000000..5e739ff
--- /dev/null
+++ b/base/Applications/BounceBackTest/BounceBackServer.csproj
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ Exe
+ BounceBackServer
+ Custom
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/BounceBackTest/BounceBackServer.sg b/base/Applications/BounceBackTest/BounceBackServer.sg
new file mode 100644
index 0000000..6079a1e
--- /dev/null
+++ b/base/Applications/BounceBackTest/BounceBackServer.sg
@@ -0,0 +1,106 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+
+using System;
+using System.Collections;
+using Microsoft.SingSharp;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.V1;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Security;
+using Microsoft.Singularity.V1.Processes;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity;
+
+[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
+[assembly: System.Reflection.AssemblyKeyFileAttribute("public.snk")]
+[assembly: System.Reflection.AssemblyDelaySignAttribute(true)]
+
+[assembly: ApplicationPublisherAttribute("singularity.microsoft.com")]
+[assembly: AssertPrivilegeAttribute("$register-privilege.localhost")]
+
+namespace Microsoft.Singularity.Applications
+{
+ public class BounceBackServer
+ {
+ public static int Main(String[] args)
+ {
+ DirectoryServiceContract.Imp! dirImp;
+
+ dirImp = DirectoryService.NewClientEndpoint();
+
+ ServiceProviderContract.Imp! nsImp;
+ ServiceProviderContract.Exp! nsExp;
+ ServiceProviderContract.NewChannel(out nsImp, out nsExp);
+
+ string location = "/BounceBackServer";
+ ErrorCode error;
+ if (!SdsUtils.Register(location, dirImp, nsImp, out error)) {
+ DebugStub.WriteLine("Failed to register in BSP namespace error {0}\n",
+ __arglist(SdsUtils.ErrorCodeToString(error)));
+ delete nsExp;
+ delete dirImp;
+ return -1;
+ }
+
+ // Here is the set of client channels we service
+ ESet epSet = new ESet();
+ while (true) {
+ switch receive {
+
+ case nsExp.Connect(ServiceContract.Exp:Start! exp) :
+ CalculatorContract.Exp calculatorExp = exp as CalculatorContract.Exp;
+ if(calculatorExp == null) {
+ nsExp.SendNackConnect(exp);
+ }
+ else {
+ DebugStub.Print("Received new ServerControl\n");
+ calculatorExp.SendSuccess();
+ epSet.Add(calculatorExp);
+ nsExp.SendAckConnect();
+ }
+ break;
+
+ case ep.AddInteger(int first, int second) in epSet :
+ DebugStub.Print("Server received add integer request\n");
+ int result = first + second;
+ ep.SendIntegerResult(result);
+ epSet.Add(ep);
+ break;
+
+ case ep.SubtractInteger(int first, int second) in epSet :
+ DebugStub.Print("Server received subtract integer request\n");
+ int result = first - second;
+ ep.SendIntegerResult(result);
+ epSet.Add(ep);
+ break;
+
+ case ep.ChannelClosed() in epSet :
+ delete ep;
+ break;
+
+ case epSet.Empty() && nsExp.ChannelClosed() :
+ delete nsExp;
+ epSet.Dispose();
+ delete dirImp;
+ return -1;
+ break;
+
+ case unsatisfiable :
+ DebugStub.Break();
+ break;
+ }
+ }
+ delete dirImp;
+
+ return 0;
+ }
+ }
+}
+
diff --git a/base/Applications/BounceBackTest/CalculatorContract.sg b/base/Applications/BounceBackTest/CalculatorContract.sg
new file mode 100644
index 0000000..e007fac
--- /dev/null
+++ b/base/Applications/BounceBackTest/CalculatorContract.sg
@@ -0,0 +1,26 @@
+using System;
+using Microsoft.SingSharp;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+
+namespace Microsoft.Singularity.Applications
+{
+ public contract CalculatorContract : ServiceContract {
+ out message Success();
+
+ in message AddInteger(int first, int second);
+ out message IntegerResult(int answer);
+
+ in message SubtractInteger(int first, int second);
+
+ override state Start: one {
+ Success! -> Ready;
+ }
+
+ state Ready: one {
+ AddInteger? -> IntegerResult! -> Ready;
+
+ SubtractInteger? -> IntegerResult! -> Ready;
+ }
+ }
+}
diff --git a/base/Applications/CHello/CHello.csproj b/base/Applications/CHello/CHello.csproj
index 63ef4a0..9a1aa70 100644
--- a/base/Applications/CHello/CHello.csproj
+++ b/base/Applications/CHello/CHello.csproj
@@ -1,8 +1,6 @@

-
-
-
-
-
- Exe
- CHello2
-
-
- true
- true
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/CHello2/CHello2.sg b/base/Applications/CHello2/CHello2.sg
deleted file mode 100644
index aec2237..0000000
--- a/base/Applications/CHello2/CHello2.sg
+++ /dev/null
@@ -1,708 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: CHello.cs
-//
-// Note: Simple Singularity test program.
-//
-using System;
-using System.Runtime.CompilerServices;
-using System.Threading;
-
-using Microsoft.Singularity;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.V1.Services;
-using Microsoft.Singularity.Io;
-
-namespace Microsoft.Singularity.Applications
-{
- public class CHello
- {
- public static int Main(String[] args)
- {
- Console.WriteLine("Hello World!");
-
- ProtocolTester.UnitTest_LDPC o = new ProtocolTester.UnitTest_LDPC();
-
- o.Run();
-
- return 0;
- }
- }
-}
-
-namespace Microsoft.SPOT
-{
- ///
- public abstract class Trace
- {
- ///
- [System.Diagnostics.ConditionalAttribute("TINYCLR_TRACE")]
- static public void Print( string text )
- {
- Debug.Print( text );
- }
- }
-
- ///
- public abstract class Debug
- {
- static public void Print( string text )
- {
- Console.WriteLine( text );
- }
-
- static public void DumpBuffer( byte[] buf, bool fCRC, bool fOffset )
- {
- if(buf == null) return;
-
- int offset = 0;
- int len = buf.Length;
-
- while(len > 0)
- {
- int row = len > 16 ? 16 : len;
- int i;
-
- if(fOffset) Console.Write( "{0:X8}:", offset );
-
- for(i=0; i<16; i++)
- {
- if(i= 0x7F) c = (byte)'.';
-
- Console.Write( "{0}", (char)c );
- }
-
- offset += row;
- len -= row;
-
- Console.WriteLine();
- }
-
- Console.WriteLine();
- }
- }
-
- public abstract class Math
- {
- static System.Random s_rnd = new System.Random();
-
- static public int Random( int modulo )
- {
- return s_rnd.Next( modulo );
- }
- }
-}
-
-namespace Microsoft.SPOT.Hardware
-{
- public abstract class Radio
- {
- static public void XorData( byte[]! left, byte[]! right )
- {
- for(int i=0; i
- {
- T[]! elements;
- int count;
-
- public CreateNonNullArray( int n )
- {
- this.elements = new T[n];
- this.count = 0;
- base();
- }
-
- public void InitNext( T elem )
- {
- if(this.count < elements.Length)
- {
- this.elements[this.count++] = elem;
- }
- else
- {
- throw new InvalidOperationException( "Too many elements initialized" );
- }
- }
-
- public T[]! GetArray()
- {
- if(count != elements.Length)
- {
- throw new InvalidOperationException("Not all elements initialized");
- }
-
- return this.elements;
- }
- }
-
- public class LDPC
- {
- public static T[]![]! ConstructArray( int i, int j )
- {
- CreateNonNullArray nna = new CreateNonNullArray( i );
-
- for(int k=0; k < i; k++)
- {
- nna.InitNext( new T[j] );
- }
-
- return nna.GetArray();
- }
-
- static public byte[]![]! Solve( byte[][] dataPackets, byte[][] eccPackets, int[] eccIndex, int totalEccPackets, int totalDataPackets, int missedDataPackets, int receivedEccPackets, int pktLen )
- {
- // dataPackets x0 = actual N - k data packets received (blanks in the missing locations)
- // eccPackets rhs = actual kp EC packets received
- // eccIndex gotec = array contains indices of EC packet received
- // totalEccPackets M = total length of EC stream
- // totalDataPackets N = total length of data stream
- // missedDataPackets kk = number of data packets missed
- // receivedEccPackets kp = number of EC packets received
- // AA = M * N matrix used to get the EC packets at encoder
-
- if(dataPackets == null) throw new NullReferenceException();
- if(eccPackets == null) throw new NullReferenceException();
- if(eccIndex == null) throw new NullReferenceException();
-
- int maxMN = (totalEccPackets > totalDataPackets) ? totalEccPackets : totalDataPackets;
- bool[] pseudo = new bool[maxMN];
- int i;
- int j;
- int k;
-
- for(i=0; i < maxMN; i += 5) pseudo[i] = true;
- for(i=0; i < maxMN; i += 7) pseudo[i] = true;
- for(i=0; i < maxMN; i += 13) pseudo[i] = true;
- for(i=0; i < maxMN; i += 17) pseudo[i] = true;
- for(i=0; i < maxMN; i += 19) pseudo[i] = true;
- for(i=0; i < maxMN; i += 33) pseudo[i] = true;
- for(i=0; i < maxMN; i += 37) pseudo[i] = true;
-
- //bool[][] A = new bool[receivedEccPackets][];
- //for(i=0; i < receivedEccPackets; i++)
- //{
- // A[i] = new bool[missedDataPackets];
- //} // The actual matrix to be inverted (submatrix of AA)
- bool[]![]! A = ConstructArray( receivedEccPackets, missedDataPackets );
-
- int[]! miss = new int[missedDataPackets + 1]; // Indices of the missing data packets
-
- int c = 0;
-
- for(i = 0; i < missedDataPackets; i++)
- {
- while(c < totalDataPackets && dataPackets[c] != null)
- {
- c++;
- }
-
- //Microsoft.SPOT.Debug.Print( "Missing: " + c );
- miss[i] = c++;
- }
- // Get miss array
- miss[missedDataPackets] = -1;
-
- for(i=0; i < receivedEccPackets; i++)
- {
- byte[] t = eccPackets[i]; if(t == null) throw new NullReferenceException();
-
- t = (byte[])t.Clone(); if(t == null) throw new NullReferenceException();
-
- eccPackets[i] = t;
-
- // What's the actual system we have to solve
-
- for(j=0; j < missedDataPackets; j++)
- {
- int idx = eccIndex[i] + miss[j];
-
- //A[i][j] = AA[eccIndex[i]][miss[j]];
- A[i][j] = pseudo[ idx < maxMN ? idx : idx - maxMN ];
- }
- }
-
- for(j = 0; j < totalDataPackets; j++)
- {
- byte[] dataPacket = dataPackets[j];
-
- if(dataPacket != null)
- {
- // Packet j is not a missing packet
- for(i = 0; i < receivedEccPackets; i++)
- {
- int idx = eccIndex[i] + j;
-
- if(pseudo[ idx < maxMN ? idx : idx - maxMN ]) /*AA[eccIndex[i]][j]*/
- {
- //Microsoft.SPOT.Debug.Print( "XOR: eccPackets[" + i + "], dataPackets[" + j + "]" );
- byte[] eccPacket = eccPackets[i];
-
- if(eccPacket != null)
- {
- Microsoft.SPOT.Hardware.Radio.XorData( eccPacket, dataPacket );
- }
- }
- }
- }
- }
-
- //DumpMatrix( "Beginning:", A, kp, kk );
-
- // Now set up some variables and do the LU decomposition
-
- //byte[][] y = new byte[missedDataPackets+1][]; // Intermediate solution
- //byte[][] xhat = new byte[missedDataPackets+1][];
- //
- //
- //for(i=0; i < missedDataPackets+1; i++)
- //{
- // y [i] = new byte[ pktLen ];
- // xhat[i] = new byte[ pktLen ];
- //}
- byte[]![]! y = ConstructArray( missedDataPackets+1, missedDataPackets+1 );
- byte[]![]! xhat = ConstructArray( missedDataPackets+1, missedDataPackets+1 );
-
- int i2;
- int j2;
- int p;
-
- //DumpMatrix( "Beginning:", A, kp, kk );
-
- for(k = 0; k < missedDataPackets; k++)
- {
- p = k;
-
- // Find a remaining row with non-zero k-th element
- while(A[p][k] == false)
- {
- p++;
-
- if(p == receivedEccPackets)
- {
- //Microsoft.SPOT.Debug.Print( "Non-triangular matrix?" );
- //return null;
- throw new Exception( "Non-triangular matrix?" );
- }
- }
-
-
- if(p != k)
- {
- //Microsoft.SPOT.Debug.Print( "Swap: " + p + " " + k );
- // Swap row k and row p
- for(j2 = 0; j2 < missedDataPackets; j2++)
- {
- bool temp = A[k][j2];
- A[k][j2] = A[p][j2];
- A[p][j2] = temp;
- }
-
- byte[] packetTemp = eccPackets[k];
- eccPackets[k] = eccPackets[p];
- eccPackets[p] = packetTemp;
-
- //DumpMatrix( "After:", A, kp, kk );
- }
-
- for(i2 = k + 1; i2 < receivedEccPackets; i2++)
- {
- if(A[i2][k] == A[k][k])
- {
- //Microsoft.SPOT.Debug.Print( "Mix rows: " + i2 + " " + k );
- for(j2 = k + 1; j2 < missedDataPackets; j2++)
- {
- A[i2][j2] ^= A[k][j2];
- }
-
- //DumpMatrix( "After:", A, kp, kk );
- }
- }
- }
- //DumpMatrix( "After:", A, kp, kk );
-
- //////////////////////////////////////////////////////////
-
- // Solve Ly = Pb
-
- for(i2 = 0; i2 < missedDataPackets; i2++)
- {
- y[i2] = (byte[]!)eccPackets[i2];
-
- for(j2 = 0; j2 < i2; j2++)
- {
- //y[i2] = (sbyte) (((y[i2] ^ (A[i2][j2] * y[j2])) & 0x000000ff));
-
- if(A[i2][j2])
- {
- //Microsoft.SPOT.Debug.Print( "XOR: y[" + i2 + "], y[" + j2 + "]" );
- Microsoft.SPOT.Hardware.Radio.XorData( y[i2], y[j2] );
- }
- }
- }
-
- // Now solve Ux = y
- for(i2 = missedDataPackets - 1; i2 >= 0; i2--)
- {
- xhat[i2] = y[i2];
-
- for(j2 = i2 + 1; j2 < missedDataPackets; j2++)
- {
- //xhat[i2] = (sbyte) (((xhat[i2] ^ (A[i2][j2] * xhat[j2])) & 0x000000ff));
- if(A[i2][j2])
- {
- //Microsoft.SPOT.Debug.Print( "XOR: xhat[" + i2 + "], xhat[" + j2 + "]" );
- Microsoft.SPOT.Hardware.Radio.XorData( xhat[i2], xhat[j2] );
- }
- }
- }
-
- for(i2 = 0; i2 < missedDataPackets; i2++)
- {
- // Rogue value to indicate non-invertible
- if(A[i2][i2] == false)
- {
- //return null;
- throw new Exception( "Non-invertible matrix?" );
- }
- }
-
- return xhat;
- }
-
- static public byte[][] GenerateEC( byte[][] dataPackets, int totalEccPackets, int totalDataPackets, int pktLen )
- {
- int maxMN = (totalEccPackets > totalDataPackets) ? totalEccPackets : totalDataPackets;
- int i;
- int j;
-
- if(dataPackets == null) throw new NullReferenceException();
-
- bool[] pseudo = new bool[maxMN];
-
- for(i=0; i < maxMN; i += 5) pseudo[i] = true;
- for(i=0; i < maxMN; i += 7) pseudo[i] = true;
- for(i=0; i < maxMN; i += 13) pseudo[i] = true;
- for(i=0; i < maxMN; i += 17) pseudo[i] = true;
- for(i=0; i < maxMN; i += 19) pseudo[i] = true;
- for(i=0; i < maxMN; i += 33) pseudo[i] = true;
- for(i=0; i < maxMN; i += 37) pseudo[i] = true;
-
- byte[][] eccPackets = new byte[totalEccPackets][];
-
- for(i=0; i < totalEccPackets; i++)
- {
- eccPackets[i] = new byte[ pktLen ];
- }
-
- for(i=0; i < totalEccPackets; i++)
- {
- // Generate the EC stream
-
- for(j=0; j < totalDataPackets; j++)
- {
- //ec[i] = (sbyte) (((ec[i] ^ (AA[i][j] * x[j])) & 0x000000ff));
-
- int idx = i + j;
-
- if(pseudo[ idx < maxMN ? idx : idx - maxMN ]) /*AA[i][j]*/
- {
- byte[] eccPacket = eccPackets[i];
- byte[] dataPacket = dataPackets[j];
-
- if(eccPacket != null && dataPacket != null)
- {
- Microsoft.SPOT.Hardware.Radio.XorData( eccPacket, dataPacket );
- }
- }
- }
- }
-
- return eccPackets;
- }
- }
-}
-
-namespace ProtocolTester
-{
- public class UnitTest_LDPC
- {
- // main program written by hpleung
- // Procedure:
- // 1. Generate Random Data Unit
- // 2. Generate Error Correction Unit
- // 3. Inject Errors in The Random Data Unit
- // 4. Decode
- // 5. Make sure after decoding data is fully received
- // Run it with run.exe nDataPacket nErrorCorrection nPercentageLoss nIteration
- //
- public void Run()
- {
- //for quick correctness verification
- Microsoft.SPOT.Debug.Print( "LPDC Test Started" );
-
-// for(int i=0; i<100; i++)
-// {
-// RunPass( 40, 40, 40, 106 );
-// }
-// return;
- for(int nPacketLength=10; nPacketLength <= 120; nPacketLength = nPacketLength + 10)
- {
- RunPass( nPacketLength, nPacketLength, 40, 106 );
- }
- }
-
- public void RunPass( int nDataPacketCount, int nErrorCorrectionCount, int nPercentageLoss, int nPacketSize )
- {
- byte[][] arrDataPacket = new byte[nDataPacketCount][];
- byte[][] arrDataReceived = new byte[nDataPacketCount][];
- byte[][] arrErrorCorrectionStream = null;
- int nDataLossCount = 0;
- int i;
-
- //randomly generate some data
- PopulatePacket( arrDataPacket, nPacketSize );
-
- for(i=0; i= nPacketToLossFix)
- {
- arrDataReceived[i] = arrDataPacket[i];
- }
- else
- {
- arrDataReceived[i] = null;
- }
- }
-#else
- int nPacketToGet = nDataPacketCount - nPacketToLossFix;
- while(nPacketToGet > 0)
- {
- i = Microsoft.SPOT.Math.Random( nDataPacketCount - 1 );
- //Microsoft.SPOT.Debug.Print( "Picked " + i );
-
- if(arrDataReceived[i] == null)
- {
- arrDataReceived[i] = arrDataPacket[i];
- nPacketToGet--;
- }
- }
-#endif
-
- for(i=0; i (nDataLossCount + 5) * 100)
- {
- nErrorPacketToReceive = (int)((nDataLossCount * 108)/100) ;
- }
- else
- {
- nErrorPacketToReceive = nDataLossCount + 5;
- }
-
- if(nErrorPacketToReceive > nErrorCorrectionCount)
- {
- nErrorPacketToReceive = nErrorCorrectionCount;
- }
-
- int[]! arrECPacketReceived = new int [nErrorPacketToReceive];
- byte[][] arrRHS = new byte[nErrorPacketToReceive][];
-
- // Randomly Pick up Error Packets
- for(i=0; i Stdin;
@@ -47,6 +45,9 @@ namespace Microsoft.Singularity.Applications
[OutputEndpoint("data")]
public readonly TRef Stdout;
+ [Endpoint]
+ public readonly TRef nsRef;
+
[StringParameter( "d", Mandatory=true, HelpMessage="Directory in which to gen files")]
internal string directory;
@@ -173,16 +174,17 @@ public class FILE
// TODO
get {
long size;
- NodeType nodeType;
- ErrorCode error;
+ FileAttributesRecord fileAttributes;
+ ErrorCode error;
DirectoryServiceContract.Imp! rootNS = DirectoryService.NewClientEndpoint();
- bool ok = FileUtils.GetAttributes(path, rootNS, out size, out nodeType, out error);
- delete rootNS;
+ bool ok = FileUtils.GetAttributes(path, rootNS, out fileAttributes, out error);
+ delete rootNS;
if (!ok) {
throw new Exception("Failed to get attributes");
- } else {
- return unchecked((int)size);
+ }
+ else {
+ return unchecked((int)fileAttributes.FileSize);
}
}
}
@@ -208,7 +210,7 @@ public class CadGen99
private const int CADFILE_ENTRIES = 360;
private const int MAX_CAD_WEIGHT = 75;
- private const string AdsFile = "Custom.Ads";
+ private static readonly string AdsFile = "Custom.Ads";
private static void Usage()
{
@@ -221,18 +223,18 @@ public class CadGen99
internal static void AppMain(Parameters! config)
{
-
- string! directory;
+
+ string /*!*/ directory = "";
int pttime = 0;
int maxthread = 0;
-
+
int [] expired = new int[2];
-
+
pttime = (int) config.pttime;
- maxthread = (int) config.maxthread;
- expired[0] = (int) config.expiredAd1;
- expired[1] = (int) config.expiredAd2;
- directory = config.directory;
+ maxthread = (int) config.maxthread;
+ expired[0] = (int) config.expiredAd1;
+ expired[1] = (int) config.expiredAd2;
+ directory = config.directory;
if (pttime == 0) {
pttime = 1800;
@@ -259,29 +261,29 @@ public class CadGen99
int j;
int i;
- for (j = 0; j> 4) & 0xf;
int c2 = (k >> 8) & 0xf;
- // int c1 = (k >> 12) & 0xf; // XXX not used in test
+ // int c1 = (k >> 12) & 0xf; // XXX [oh]: not used in test
int gender = (k) % 2;
- if ( gender == 1 ) gender = 0x20000000;
+ if (gender == 1) gender = 0x20000000;
else gender = 0x10000000;
int age = (k) % 4;
- if ( age == 0 ) age = 0x08000000;
- else if ( age == 1 ) age = 0x04000000;
- else if ( age == 2 ) age = 0x02000000;
- else if ( age == 3 ) age = 0x01000000;
+ if (age == 0) age = 0x08000000;
+ else if (age == 1) age = 0x04000000;
+ else if (age == 2) age = 0x02000000;
+ else if (age == 3) age = 0x01000000;
int area = (c4 + c2) % 4;
- if ( area == 0 ) area = 0x00800000;
- else if ( area == 1 ) area = 0x00400000;
- else if ( area == 2 ) area = 0x00200000;
- else if ( area == 3 ) area = 0x00100000;
+ if (area == 0) area = 0x00800000;
+ else if (area == 1) area = 0x00400000;
+ else if (area == 2) area = 0x00200000;
+ else if (area == 3) area = 0x00100000;
int interest1 = (c4 + c3) % 10;
if (interest1 == 0) interest1 = 0x00080000;
@@ -297,7 +299,7 @@ public class CadGen99
int interest2 = c4 % 10;
- if (interest2 == 0) interest2 = 0x00000200;
+ if (interest2 == 0) interest2 = 0x00000200;
else if (interest2 == 1) interest2 = 0x00000100;
else if (interest2 == 2) interest2 = 0x00000080;
else if (interest2 == 3) interest2 = 0x00000040;
@@ -320,7 +322,7 @@ public class CadGen99
expired_date[j] = ts;
}
- for (j=0; j < CADFILE_ENTRIES; j++) {
+ for (j = 0; j < CADFILE_ENTRIES; j++) {
if (j == match1) {
minmatch[j] = 1;
weight[j] = 0x3ffff;
@@ -329,9 +331,9 @@ public class CadGen99
}
}
- /* Mark two ranges as expired */
+ // Mark two ranges as expired
j = expired[0];
- for (i=0; i CADFILE_ENTRIES - 1)
expired_date[j-CADFILE_ENTRIES] = exp_ts;
else
@@ -339,7 +341,7 @@ public class CadGen99
j = j+1;
}
j = expired[1];
- for (i=0; i CADFILE_ENTRIES - 1)
expired_date[j-CADFILE_ENTRIES] = exp_ts;
else
diff --git a/base/Applications/ChildPing/ChildPing.csproj b/base/Applications/ChildPing/ChildPing.csproj
index 2dc2914..a1261b1 100644
--- a/base/Applications/ChildPing/ChildPing.csproj
+++ b/base/Applications/ChildPing/ChildPing.csproj
@@ -1,31 +1,30 @@
-
-
-
-
- Exe
- ChildPing
-
+
+
+ ChildPing
+ Exe
+
+
-
+
-
+
+
+
-
-
+
diff --git a/base/Applications/ChildPing/ChildPing.sg b/base/Applications/ChildPing/ChildPing.sg
index f0846a9..138cbe4 100644
--- a/base/Applications/ChildPing/ChildPing.sg
+++ b/base/Applications/ChildPing/ChildPing.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ChildPing.sg
-//
// Note: Simple ping-pong test child app #1
//
@@ -61,7 +59,7 @@ namespace Microsoft.Singularity.PingPong
PongContract.NewChannel(out childImp, out childExp);
string[] args = new string[1];
- args[0] = "ChildPong.x86";
+ args[0] = "ChildPong";
Process child = new Process(args, (Endpoint * in ExHeap)childExp);
child.Start();
diff --git a/base/Applications/ChildPong/ChildPong.csproj b/base/Applications/ChildPong/ChildPong.csproj
index bd474c0..f17d48d 100644
--- a/base/Applications/ChildPong/ChildPong.csproj
+++ b/base/Applications/ChildPong/ChildPong.csproj
@@ -1,31 +1,30 @@
-
-
-
-
- Exe
- ChildPong
-
+
+
+ ChildPong
+ Exe
+
+
-
+
-
+
+
+
-
-
+
diff --git a/base/Applications/ChildPong/ChildPong.sg b/base/Applications/ChildPong/ChildPong.sg
index 2af2bee..6429a90 100644
--- a/base/Applications/ChildPong/ChildPong.sg
+++ b/base/Applications/ChildPong/ChildPong.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ChildPong.sg
-//
// Note: Simple ping-pong second child process
//
@@ -57,7 +55,7 @@ namespace Microsoft.Singularity.PingPong
conn.SendPongReady();
try {
- while(true) {
+ while (true) {
switch receive {
case conn.Ping(int data):
conn.SendPong(data);
diff --git a/base/Applications/Contracts/Counter.Contracts/CounterContract.sg b/base/Applications/Contracts/Counter.Contracts/CounterContract.sg
index abfac1e..5707aa8 100644
--- a/base/Applications/Contracts/Counter.Contracts/CounterContract.sg
+++ b/base/Applications/Contracts/Counter.Contracts/CounterContract.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Contracts\Test.Contracts\CounterContract.sg
-//
// Note:
//
using System;
diff --git a/base/Applications/CredentialsControl/CredentialsControl.csproj b/base/Applications/CredentialsControl/CredentialsControl.csproj
index 5cdaf56..64e8486 100644
--- a/base/Applications/CredentialsControl/CredentialsControl.csproj
+++ b/base/Applications/CredentialsControl/CredentialsControl.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ DebugPipe
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/AntiVirus/AntiVirus.csproj b/base/Applications/EmailServer/AntiVirus/AntiVirus.csproj
new file mode 100644
index 0000000..9ebbf68
--- /dev/null
+++ b/base/Applications/EmailServer/AntiVirus/AntiVirus.csproj
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+ AntiVirus
+ Exe
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/AntiVirus/AntiVirus.sg b/base/Applications/EmailServer/AntiVirus/AntiVirus.sg
new file mode 100644
index 0000000..2686da3
--- /dev/null
+++ b/base/Applications/EmailServer/AntiVirus/AntiVirus.sg
@@ -0,0 +1,419 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Anti-virus scanner.
+//
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+using Microsoft.SingSharp;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Crypto;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Email.Contracts;
+using Microsoft.Singularity.Endpoint;
+using Microsoft.Singularity.Extending;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Security;
+using Microsoft.Singularity.V1.Services;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+[assembly: ApplicationPublisherAttribute("singularity.microsoft.com")]
+[assembly: AssertPrivilegeAttribute("$register-privilege.localhost")]
+
+namespace Microsoft.Singularity.Email
+{
+ // VirusDef
+ //
+ // This class holds the information from the virus definition files,
+ // such as the virus name, pattern, and type of file to which the
+ // definition applies. Some virus definitions refer to MD5 hashes,
+ // in which case the pattern represents the hash.
+
+ class VirusDefError : ApplicationException { }
+
+ class VirusDef
+ {
+ public VirusDef(string name, int length, Pattern pattern)
+ {
+ Name = name;
+ Type = TargetType.TYPE_ANY;
+ IsMD5 = true;
+ AnyOffset = false;
+ Offset = 0;
+ Length = length;
+ Pattern = pattern;
+ }
+
+ public VirusDef(string name, int type, string! offset, Pattern pattern)
+ {
+ Name = name;
+ Type = (TargetType)type;
+ IsMD5 = false;
+ Length = 0;
+ Pattern = pattern;
+
+ if (offset == "*") {
+ AnyOffset = true;
+ Offset = 0;
+ } else if (offset.Length >= 4 && offset.Substring(0, 4) == "EOF-") {
+ AnyOffset = false;
+ Offset = Int32.Parse(offset.Substring(3));
+ } else if (Type != TargetType.TYPE_PE && Type != TargetType.TYPE_ELF) {
+ AnyOffset = false;
+ Offset = Int32.Parse(offset);
+ } else {
+ AnyOffset = false;
+ Offset = 0;
+ }
+ }
+
+ public enum TargetType
+ {
+ TYPE_ANY = 0,
+ TYPE_PE = 1,
+ TYPE_OLE = 2,
+ TYPE_HTML = 3,
+ TYPE_MAIL = 4,
+ TYPE_GRAPHICS = 5,
+ TYPE_ELF = 6,
+ }
+
+ public string Name;
+ public TargetType Type;
+ public bool IsMD5;
+ public bool AnyOffset;
+ public int Offset;
+ public int Length;
+ public Pattern Pattern;
+ }
+
+ // AntiVirus
+ //
+ // This class contains the main appliation logic for the virus scanner.
+ // We load three virus definition files from disk, set up the pattern
+ // matcher, and then wait for incoming requests for virus checking.
+
+ [ConsoleCategory(HelpMessage="Anti-Virus Service", DefaultAction=true)]
+ internal class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [StringParameter("db", Mandatory=false, Default="/init/virus.db",
+ HelpMessage="File with universal virus signatures (.db).")]
+ internal string dbfile;
+
+ [StringParameter("hdb", Mandatory=false, Default="/init/virus.hdb",
+ HelpMessage="File with h virus signatures (.hdb).")]
+ internal string hdbfile;
+
+ [StringParameter("ndb", Mandatory=false, Default="/init/virus.ndb",
+ HelpMessage="File with n virus signatures (.ndb).")]
+ internal string ndbfile;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return AntiVirus.AppMain(this);
+ }
+ }
+
+ class AntiVirus
+ {
+ internal static int AppMain(Parameters! config)
+ {
+ // Publish our service endpoint before loading virus definitions as
+ // they can take minutes to load.
+ DirectoryServiceContract.Imp ds = (config.nsRef).Acquire();
+ if (ds == null) {
+ throw new Exception("AntiVirus: Unable to acquire handle to Directory Service.");
+ }
+ ds.RecvSuccess();
+
+ ServiceProviderContract.Imp! nsImp;
+ ServiceProviderContract.Exp! nsExp;
+ ServiceProviderContract.NewChannel(out nsImp, out nsExp);
+
+ try {
+ ds.SendRegister(Bitter.FromString2(AntiVirusContract.ModuleName), nsImp);
+
+ switch receive {
+ case ds.AckRegister() :
+ // All is well.
+ break;
+
+ case ds.NakRegister(ServiceProviderContract.Imp:Start rejectedEP, error) :
+ // All is very much not well; abort.
+ Console.WriteLine("AntiVirus: Failed to register endpoint as {0}.",
+ AntiVirusContract.ModuleName);
+ delete nsExp;
+ delete rejectedEP;
+ return -1;
+
+ case ds.ChannelClosed():
+ Console.WriteLine("AntiVirus: ds channel closed");
+ delete nsExp;
+ return -1;
+ }
+ }
+ finally {
+ delete ds;
+ }
+
+ Console.WriteLine("AntiVirus: Loading virus definition files.");
+ LoadDefinitions(config.dbfile);
+ LoadDefinitions(config.hdbfile);
+ LoadDefinitions(config.ndbfile);
+
+ PrepareMatcher();
+
+ Console.WriteLine("AntiVirus: Ready at {0}", AntiVirusContract.ModuleName);
+
+ // Here is the set of client channels we service
+
+ for (;;) {
+ switch receive {
+ // ------------------------------- Requests for new connections
+
+ case nsExp.Connect(ServiceContract.Exp:Start! newEp):
+ // We expect people top give us AntiVirusContract.Exp instances
+ AntiVirusContract.Exp newClient = newEp as AntiVirusContract.Exp;
+
+ if (newClient == null) {
+ // Invalid contract type. Fail.
+ nsExp.SendNackConnect(newEp);
+ }
+ else {
+ // Signal ready and start servicing this contract
+ nsExp.SendAckConnect();
+
+ // Launch the thread to handle the incoming requests.
+ AntiVirus child = new AntiVirus(newClient);
+ Thread thread = new Thread(child.Run);
+ thread.Start();
+ }
+ break;
+
+ case nsExp.ChannelClosed():
+ // The namespace channel is closed so quit.
+ delete nsExp;
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+ //
+ public AntiVirus([Claims]AntiVirusContract.Exp:Start! ep)
+ {
+ epRef = new TRef(ep);
+ }
+
+ private TRef epRef;
+
+ public void Run()
+ {
+ AntiVirusContract.Exp ep = epRef.Acquire();
+
+ if (ep == null) {
+ return;
+ }
+
+ ep.SendAntiVirusReady();
+ int arg;
+
+ for (;;) {
+ switch receive {
+ case ep.CheckFile(byte[]! in ExHeap buffer):
+#if false
+ Console.WriteLine("AnitVirus: CheckFile");
+#endif
+ // decide if the buffer contains a virus
+ // possible crack the MIME content.
+ string virus = CheckData(Bitter.ToByteArray(buffer));
+
+ delete buffer;
+ if (virus != null) {
+ ep.SendFileContaminated(Bitter.FromString2(virus));
+ }
+ else {
+ ep.SendFileClean();
+ }
+ break;
+
+ case ep.ChannelClosed():
+ delete ep;
+ return;
+ }
+ }
+ }
+
+ delegate VirusDef VirusDefParser(string! line);
+
+ static void LoadDefinitions(string! filename)
+ {
+ VirusDefParser parser = null;
+
+ string ext = GetExtension(filename);
+ switch (ext) {
+ case "db":
+ parser = LoadDB;
+ break;
+ case "hdb":
+ parser = LoadHDB;
+ break;
+ case "ndb":
+ parser = LoadNDB;
+ break;
+ default:
+ Console.WriteLine("Invalid definition file {0}.", filename);
+ break;
+ }
+
+ if (parser != null) {
+ FileStream fsInput = new FileStream(filename, FileMode.Open, FileAccess.Read);
+ StreamReader reader = new StreamReader(fsInput);
+ // StreamReader reader = new StreamReader(filename);
+ string line;
+ int linenum = 1;
+
+ while ((line = reader.ReadLine()) != null) {
+ try {
+ VirusDef def = parser(line);
+ if (def != null) {
+ defs.Add(def);
+ }
+ } catch (VirusDefError) {
+ Console.WriteLine("Invalid virus definition at {0}:{1}.", filename, linenum);
+ }
+ linenum++;
+ }
+ }
+ }
+
+ static string GetExtension(string! filename)
+ {
+ int dot = filename.LastIndexOf('.');
+ return (dot >= 0) ? filename.Substring(dot + 1) : null;
+ }
+
+ static VirusDef LoadDB(string! line)
+ {
+ VirusDef def = null;
+
+ string[] split = line.Split(new char[] { '=' });
+ if (split.Length == 2) {
+ string name = (!)split[0];
+ string pattern = (!)split[1];
+ def = new VirusDef(name, 0, "*", parser.Parse(name, pattern));
+ } else {
+ throw new VirusDefError();
+ }
+
+ return def;
+ }
+
+ static VirusDef LoadHDB(string! line)
+ {
+ VirusDef def = null;
+
+ string[] split = line.Split(new char[] { ':' });
+ if (split.Length == 3) {
+ string hash = (!)split[0];
+ string length = (!)split[1];
+ string name = (!)split[2];
+ def = new VirusDef(name, Int32.Parse(length), parser.Parse(name, hash));
+ } else {
+ throw new VirusDefError();
+ }
+
+ return def;
+ }
+
+ static VirusDef LoadNDB(string! line)
+ {
+ VirusDef def = null;
+
+ string[] split = line.Split(new char[] { ':' });
+ if (split.Length >= 4 && split.Length <= 6) {
+ string name = (!)split[0];
+ string type = (!)split[1];
+ string offset = (!)split[2];
+ string pattern = (!)split[3];
+
+ def = new VirusDef(name, Int32.Parse(type), offset, parser.Parse(name, pattern));
+
+ // Discard PE, ELF, and HTML definitions for now
+ if (def.Type == VirusDef.TargetType.TYPE_PE ||
+ def.Type == VirusDef.TargetType.TYPE_ELF ||
+ def.Type == VirusDef.TargetType.TYPE_HTML) {
+ def = null;
+ }
+ } else {
+ throw new VirusDefError();
+ }
+
+ return def;
+ }
+
+ static void PrepareMatcher()
+ {
+ // TODO: Handle Length & Type fields.
+
+ foreach (VirusDef! def in defs) {
+ if (def.IsMD5) {
+ Debug.Assert(!def.AnyOffset);
+ md5Matcher.AddPattern(def.Pattern, def.Offset);
+ } else {
+ if (def.AnyOffset) {
+ matcher.AddPattern(def.Pattern);
+ } else {
+ matcher.AddPattern(def.Pattern, def.Offset);
+ }
+ }
+ }
+ }
+
+ static string CheckData(byte[]! data)
+ {
+ byte[] hash = (!)hasher.Hash(data);
+
+ string found;
+
+ found = md5Matcher.Match(hash);
+ if (found == null) {
+ found = matcher.Match(data);
+ }
+
+ return found;
+ }
+
+ static private MD5 hasher = new MD5();
+
+ static private ArrayList defs = new ArrayList();
+
+ static private PatternParser parser = new PatternParser();
+
+ static private PatternMatcher matcher = new PatternMatcher();
+ static private PatternMatcher md5Matcher = new PatternMatcher();
+ }
+}
diff --git a/base/Applications/EmailServer/AntiVirus/AntiVirusContracts.csproj b/base/Applications/EmailServer/AntiVirus/AntiVirusContracts.csproj
new file mode 100644
index 0000000..62df35c
--- /dev/null
+++ b/base/Applications/EmailServer/AntiVirus/AntiVirusContracts.csproj
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ Library
+ AntiVirusContracts
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/AntiVirus/AntiVirusContracts.sg b/base/Applications/EmailServer/AntiVirus/AntiVirusContracts.sg
new file mode 100644
index 0000000..50d243c
--- /dev/null
+++ b/base/Applications/EmailServer/AntiVirus/AntiVirusContracts.sg
@@ -0,0 +1,32 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Contract used by SMTP Agents to talk to storage.
+//
+
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Endpoint;
+
+using Microsoft.Singularity.Extending;
+
+namespace Microsoft.Singularity.Email.Contracts
+{
+ public contract AntiVirusContract : ExtensionContract //ServiceContract
+ {
+ public const string ModuleName = "/service/antivirus";
+
+ out message AntiVirusReady();
+
+ in message CheckFile(byte[]! in ExHeap buffer);
+ out message FileClean();
+ out message FileContaminated(char[]! in ExHeap virus);
+
+ override state Start : AntiVirusReady! -> ReadyState;
+ state ReadyState : CheckFile? -> (FileClean! or FileContaminated!) -> ReadyState;
+
+ }
+}
diff --git a/base/Applications/EmailServer/AntiVirus/Matcher.sg b/base/Applications/EmailServer/AntiVirus/Matcher.sg
new file mode 100644
index 0000000..c2e8bbf
--- /dev/null
+++ b/base/Applications/EmailServer/AntiVirus/Matcher.sg
@@ -0,0 +1,312 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Anti-virus pattern matcher.
+//
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+
+namespace Microsoft.Singularity.Email
+{
+ // FutureTable
+ //
+ // The future table stores a list of patterns that we should try to match
+ // against an upcoming range of bytes in the input. This range is
+ // indicated by lower and upper bounds (inclusive).
+ //
+ // Callers can add patterns to the table with AddPattern, and they can
+ // match against the patterns in the table by calling Start.
+ //
+ // Internally, the future table stores a list of futures sorted by lower
+ // bound.
+
+ class Future
+ {
+ public Future(Pattern pattern, int lower, int upper)
+ {
+ Pattern = pattern;
+ Lower = lower;
+ Upper = upper;
+ }
+
+ public Pattern Pattern;
+ public int Lower;
+ public int Upper;
+
+ public Future Next;
+ }
+
+ class FutureTable
+ {
+ // AddPattern
+ //
+ // Add a pattern with specified file offset bounds to the table.
+ // We first attempt to consolidate with any overlapping entries for
+ // this pattern that are already in the table. We then insert the
+ // new future at the appropriate location.
+
+ public void AddPattern(Pattern pattern, int lower, int upper)
+ {
+ Future prev;
+ Future cur;
+
+ // Remove any overlapping ranges for this pattern, updating lower and upper as appropriate.
+ for (prev = null, cur = head;
+ cur != null && cur.Lower - 1 <= upper;
+ prev = cur, cur = cur.Next) {
+ // If the new pattern overlaps with an existing one...
+ if (pattern == cur.Pattern && lower - 1 <= cur.Upper) {
+ // Remove it.
+ if (prev != null) {
+ prev.Next = cur.Next;
+ } else {
+ head = cur.Next;
+ }
+ // Widen the bounds if necessary.
+ lower = Math.Min(lower, cur.Lower);
+ upper = Math.Max(upper, cur.Upper);
+ }
+ }
+
+ // Find the location where we should insert this new item.
+ for (prev = null, cur = head;
+ cur != null && cur.Lower < lower;
+ prev = cur, cur = cur.Next) {
+ // Do nothing; we're just searching for the insert location.
+ }
+
+ // Insert the item.
+ Future item = new Future(pattern, lower, upper);
+ item.Next = cur;
+ if (prev != null) {
+ prev.Next = item;
+ } else {
+ head = item;
+ }
+ }
+
+ // Start
+ //
+ // Given an input file and an index in that file, try to match all
+ // applicable patterns. We use the fact that the list of futures
+ // is sorted in order to avoid trying to match against all patterns.
+ // We also discard any patterns that will no longer be matched.
+ //
+ // We assume that the index will increase with each call to Start.
+
+ public void Start(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ ArrayList runnable = new ArrayList();
+
+ for (Future prev = null, cur = head;
+ cur != null && cur.Lower <= index;
+ prev = cur, cur = cur.Next) {
+ if (index <= cur.Upper) {
+ // The index is between lower and upper, so check this pattern.
+ runnable.Add(cur.Pattern);
+ } else {
+ // This pattern is no longer relevant; remove it.
+ if (prev != null) {
+ prev.Next = cur.Next;
+ } else {
+ head = cur.Next;
+ }
+ }
+ }
+
+ foreach (Pattern! pattern in runnable) {
+ pattern.Match(input, index, enqueue);
+ }
+ }
+
+ public void Clear()
+ {
+ head = null;
+ }
+
+ public int Count()
+ {
+ int i = 0;
+ for (Future cur = head; cur != null; cur = cur.Next) {
+ i += 1;
+ }
+ return i;
+ }
+
+ // List of future patterns to match, sorted by lower bound.
+ private Future head;
+ }
+
+ // OffsetTable
+ //
+ // The offset table stores patterns that should be applied at a particular
+ // offset in the file. This offset can be positive or negative, where
+ // the latter indicates an offset from the end of the file.
+ //
+ // Callers can add pattersn to the table with AddPattern, and they can
+ // match against patterns in the table with Start.
+
+ class OffsetTable
+ {
+ public void AddPattern(Pattern pattern, int offset)
+ {
+ if (table[offset] == null) {
+ table[offset] = new ArrayList();
+ }
+
+ ArrayList list = (!)(table[offset] as ArrayList);
+ list.Add(pattern);
+ }
+
+ public void Start(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ StartList(table[index] as ArrayList, input, index, enqueue);
+ StartList(table[index - input.Length] as ArrayList, input, index, enqueue);
+ }
+
+ private void StartList(ArrayList list, byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ if (list != null) {
+ foreach (Pattern! pattern in list) {
+ pattern.Match(input, index, enqueue);
+ }
+ }
+ }
+
+ private Hashtable table = new Hashtable();
+ }
+
+ // StartTable
+ //
+ // The start table stores patterns that should be applied at *any* offset
+ // in the input file. For efficiency, we construct an n-level table
+ // mapping the first n bytes of the input to the relevant set of patterns.
+ // If a pattern doesn't start with a sequence of n bytes (e.g., it has a
+ // wildcard in front), we'll look for a shorter prefix.
+ //
+ // Callers can add patterns to the table with AddPattern, and they can
+ // match against the patterns in the table with Start.
+
+ class StartTable
+ {
+ public StartTable(int d)
+ {
+ Debug.Assert(d >= 0);
+ depth = d;
+ }
+
+ public void AddPattern(Pattern pattern)
+ {
+ AddPattern(pattern, 0);
+ }
+
+ private void AddPattern(Pattern pattern, int offset)
+ {
+ SeqPattern seq = pattern as SeqPattern;
+ if (depth > 0 && seq != null && offset < seq.Bytes.Length) {
+ byte b = seq.Bytes[offset];
+ if (table == null) {
+ table = new StartTable[256];
+ }
+ if (table[b] == null) {
+ table[b] = new StartTable(depth - 1);
+ }
+ StartTable subTable = (!)table[b];
+ subTable.AddPattern(pattern, offset + 1);
+ } else {
+ patterns.Add(pattern);
+ }
+ }
+
+ public void Start(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ Start(input, index, 0, enqueue);
+ }
+
+ private void Start(byte[]! input, int index, int offset, EnqueueDelegate! enqueue)
+ {
+ foreach (Pattern! pattern in patterns) {
+ pattern.Match(input, index, enqueue);
+ }
+
+ if (index + offset < input.Length) {
+ byte b = input[index + offset];
+ if (table != null && table[b] != null) {
+ StartTable subTable = (!)table[b];
+ subTable.Start(input, index, offset + 1, enqueue);
+ }
+ }
+ }
+
+ private int depth;
+ private StartTable[] table;
+ private ArrayList patterns = new ArrayList();
+ }
+
+ // PatternMatcher
+ //
+ // The pattern matcher stores one of each of the above tables:
+ //
+ // FutureTable: Pattern matches in progress.
+ // OffsetTable: Patterns to be matched at a specific offset.
+ // StartTable: Patterns to be matched at every offset.
+ //
+ // We set up the matcher by calling AddPattern, which adds patterns
+ // to the offset table or the start table. We then call Match to
+ // match an input array against the provided patterns.
+
+ class PatternMatcher
+ {
+ public void AddPattern(Pattern pattern)
+ {
+ startTable.AddPattern(pattern);
+ }
+
+ public void AddPattern(Pattern pattern, int offset)
+ {
+ offsetTable.AddPattern(pattern, offset);
+ }
+
+ public string Match(byte[]! input)
+ {
+ found = null;
+ futureTable.Clear();
+
+ int length = input.Length;
+ for (int index = 0; found == null && index < length; index++) {
+ startTable.Start(input, index, Enqueue);
+ offsetTable.Start(input, index, Enqueue);
+ futureTable.Start(input, index, Enqueue);
+ }
+
+ futureTable.Clear();
+
+ return found;
+ }
+
+ private void Enqueue(Pattern pattern, int lower, int upper)
+ {
+ Debug.Assert(pattern != null);
+
+ if (pattern is EmptyPattern) {
+ found = ((EmptyPattern)pattern).Name;
+ } else {
+ futureTable.AddPattern(pattern, lower, upper);
+ }
+ }
+
+ private string found;
+
+ const int TableDepth = 2;
+ private StartTable startTable = new StartTable(TableDepth);
+ private OffsetTable offsetTable = new OffsetTable();
+ private FutureTable futureTable = new FutureTable();
+ }
+}
diff --git a/base/Applications/EmailServer/AntiVirus/Pattern.sg b/base/Applications/EmailServer/AntiVirus/Pattern.sg
new file mode 100644
index 0000000..ff3f71b
--- /dev/null
+++ b/base/Applications/EmailServer/AntiVirus/Pattern.sg
@@ -0,0 +1,368 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Anti-virus patterns.
+//
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+
+namespace Microsoft.Singularity.Email
+{
+ // Patterns
+ //
+ // A pattern is a restricted regular expression that can be matched
+ // against a location in an input file. It is represented as a linked
+ // list of Pattern subclasses that should be matched in sequence.
+ //
+ // EmptyPattern:
+ // Terminates every pattern, indicating successful match.
+ // Stores the name of the matched virus.
+ //
+ // SeqPattern:
+ // Holds a sequence of bytes that must be matched in order.
+ //
+ // AltPattern:
+ // Holds an array of bytes, one of which must match the next
+ // input byte.
+ //
+ // WildPattern:
+ // Matches an arbitrary sequence of bytes whose length is between
+ // lower and upper (inclusive).
+ //
+ // NibblePattern:
+ // Matches a masked version of the next input byte.
+ //
+ // Each pattern contains a Match method, which matches the pattern
+ // against an input array at a given index. If the pattern matches, it
+ // should call the "enqueue" delegate to queue up the next pattern in
+ // the list for matching. This delegate is also given the lower and
+ // upper bounds (inclusive) where the next pattern might potentially
+ // start.
+
+ class PatternError : ApplicationException
+ {
+ public PatternError(string message) { }
+ public PatternError(string message, Object o1)
+ : this(String.Format(message, o1)) { }
+ public PatternError(string message, Object o1, Object o2)
+ : this(String.Format(message, o1, o2)) { }
+ }
+
+ delegate void EnqueueDelegate(Pattern pattern, int lower, int upper);
+
+ abstract class Pattern
+ {
+ public Pattern Next;
+
+ abstract public void Match(byte[]! input, int index, EnqueueDelegate! enqueue);
+
+ virtual public string GetName()
+ {
+ return Next != null ? Next.GetName() : null;
+ }
+ }
+
+ class EmptyPattern : Pattern
+ {
+ public EmptyPattern(string name)
+ {
+ Name = name;
+ }
+
+ override public void Match(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ Debug.Assert(false);
+ }
+
+ override public string GetName()
+ {
+ return Name;
+ }
+
+ public string Name;
+ }
+
+ class SeqPattern : Pattern
+ {
+ public SeqPattern(byte[] bytes)
+ {
+ Bytes = bytes;
+ }
+
+ override public void Match(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ int patternLength = Bytes.Length;
+ int inputLength = input.Length;
+
+ if (index + patternLength <= inputLength) {
+ for (int i = 0; i < patternLength; i++) {
+ if (input[index + i] != Bytes[i]) {
+ return;
+ }
+ }
+
+ enqueue(Next, index + patternLength, index + patternLength);
+ }
+ }
+
+ public byte[] Bytes;
+ }
+
+ class AltPattern : Pattern
+ {
+ public AltPattern(byte[] options)
+ {
+ Options = options;
+ }
+
+ override public void Match(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ int length = Options.Length;
+ for (int i = 0; i < length; i++) {
+ if (input[index] == Options[i]) {
+ enqueue(Next, index + 1, index + 1);
+ return;
+ }
+ }
+ }
+
+ public byte[] Options;
+ }
+
+ class WildPattern : Pattern
+ {
+ public WildPattern(int lower, int upper)
+ {
+ Lower = lower;
+ Upper = upper;
+ }
+
+ override public void Match(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ // Make sure upper doesn't overflow.
+ int lower = index + Lower;
+ int upper = index <= Int32.MaxValue - Upper ? index + Upper : Int32.MaxValue;
+ enqueue(Next, lower, upper);
+
+ // If the lower bound is zero, we need to try matching with the next pattern, too.
+ if (Lower == 0) {
+ Next.Match(input, index, enqueue);
+ }
+ }
+
+ public int Lower;
+ public int Upper;
+ }
+
+ class NibblePattern : Pattern
+ {
+ public NibblePattern(int mask, int val)
+ {
+ Mask = mask;
+ Value = val;
+ }
+
+ override public void Match(byte[]! input, int index, EnqueueDelegate! enqueue)
+ {
+ if ((input[index] & Mask) == Value) {
+ enqueue(Next, index + 1, index + 1);
+ }
+ }
+
+ public int Mask;
+ public int Value;
+ }
+
+ // PatternParser
+ //
+ // Given the name of a virus and an input pattern, construct a Pattern
+ // object as described above.
+
+ class PatternParser
+ {
+ public Pattern Parse(string name, string! input)
+ {
+ Debug.Assert(curPattern == null);
+
+ int index = 0;
+
+ while (index < input.Length) {
+ char cur = input[index];
+ if (cur == '*') {
+ Add(new WildPattern(0, Int32.MaxValue));
+ index += 1;
+ } else if (cur == '?') {
+ char next = input[index + 1]; // TODO: exists?
+ if (next == '?') {
+ Add(new WildPattern(1, 1));
+ } else if (IsHex(next)) {
+ Add(new NibblePattern(0xf, ToByte(next)));
+ } else {
+ throw new PatternError("Invalid byte: {0}{1}", cur, next);
+ }
+ index += 2;
+ } else if (IsHex(cur)) {
+ char next = input[index + 1]; // TODO: exists?
+ if (next == '?') {
+ Add(new NibblePattern(0xf0, ToByte(cur)));
+ } else if (IsHex(next)) {
+ AddByte(ToByte(cur, next));
+ } else {
+ throw new PatternError("Invalid byte: {0}{1}", cur, next);
+ }
+ index += 2;
+ } else if (cur == '(') {
+ Debug.Assert(byteOptions.Count == 0);
+
+ do {
+ index += 1;
+ char first = input[index];
+ char second = input[index + 1];
+ if (IsHex(first) && IsHex(second)) {
+ AddOption(ToByte(first, second));
+ } else {
+ throw new PatternError("Alternation does not contain literal byte: {0}{1}", first, second);
+ }
+ index += 2;
+ } while (input[index] == '|');
+
+ if (input[index] != ')') {
+ throw new PatternError("Alternation not terminated by paren: {0}", input[index]);
+ }
+ index += 1;
+
+ FinishOptions();
+ } else if (cur == '{') {
+ index += 1;
+
+ int lower = ParseNum(input, ref index);
+
+ int upper;
+ if (input[index] == '-') {
+ index += 1;
+ int num = ParseNum(input, ref index);
+ upper = num >= 0 ? num : Int32.MaxValue;
+ } else {
+ upper = lower;
+ }
+
+ if (input[index] != '}') {
+ throw new PatternError("Wildcard not terminated by brace: {0}", input[index]);
+ }
+ index += 1;
+
+ Add(new WildPattern(lower, upper));
+ } else {
+ throw new PatternError("Unrecognized character: {0}", cur);
+ }
+ }
+
+ FinishSequence();
+
+ Add(new EmptyPattern(name));
+
+ Debug.Assert(byteBuffer.Count == 0);
+ Debug.Assert(byteOptions.Count == 0);
+
+ Pattern result = curPattern;
+ curPattern = null;
+
+ return Reverse(result);
+ }
+
+ private int ParseNum(string! input, ref int index)
+ {
+ int endIndex = input.IndexOfAny(new char[] { '-', '}' }, index);
+ string numStr = input.Substring(index, endIndex - index);
+ index = endIndex;
+ return numStr.Length > 0 ? Int32.Parse(numStr) : -1;
+ }
+
+ private void Add(Pattern! pattern)
+ {
+ FinishSequence();
+ AddCore(pattern);
+ }
+
+ private void AddCore(Pattern! pattern)
+ {
+ Debug.Assert(pattern.Next == null);
+ pattern.Next = curPattern;
+ curPattern = pattern;
+ }
+
+ private void AddByte(byte val)
+ {
+ byteBuffer.Add(val);
+ }
+
+ private void AddOption(byte val)
+ {
+ byteOptions.Add(val);
+ }
+
+ private void FinishOptions()
+ {
+ Add(new AltPattern((byte[])byteOptions.ToArray(typeof(byte))));
+ byteOptions.Clear();
+ }
+
+ private void FinishSequence()
+ {
+ if (byteBuffer.Count > 0) {
+ AddCore(new SeqPattern((byte[])byteBuffer.ToArray(typeof(byte))));
+ byteBuffer.Clear();
+ }
+ }
+
+ private Pattern Reverse(Pattern pattern)
+ {
+ Pattern reversed = null;
+
+ while (pattern != null) {
+ Pattern next = pattern.Next;
+ pattern.Next = reversed;
+ reversed = pattern;
+ pattern = next;
+ }
+
+ return reversed;
+ }
+
+ private bool IsHex(char c)
+ {
+ return ('0' <= c && c <= '9') ||
+ ('a' <= c && c <= 'f') ||
+ ('A' <= c && c <= 'F');
+ }
+
+ private byte ToByte(char c)
+ {
+ if ('0' <= c && c <= '9') {
+ return (byte)(c - '0');
+ } else if ('a' <= c && c <= 'f') {
+ return (byte)(c - 'a' + 10);
+ } else if ('A' <= c && c <= 'F') {
+ return (byte)(c - 'A' + 10);
+ } else {
+ throw new PatternError("Invalid hex digit: {0}", c);
+ }
+ }
+
+ private byte ToByte(char c1, char c2)
+ {
+ return (byte)((ToByte(c1) << 4) | ToByte(c2));
+ }
+
+ private ArrayList byteOptions = new ArrayList();
+ private ArrayList byteBuffer = new ArrayList();
+ private Pattern curPattern = null;
+ }
+}
diff --git a/base/Applications/EmailServer/EmailServer.proj b/base/Applications/EmailServer/EmailServer.proj
new file mode 100644
index 0000000..bda5c86
--- /dev/null
+++ b/base/Applications/EmailServer/EmailServer.proj
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/MailStore/MailStore.csproj b/base/Applications/EmailServer/MailStore/MailStore.csproj
new file mode 100644
index 0000000..2afe275
--- /dev/null
+++ b/base/Applications/EmailServer/MailStore/MailStore.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ Exe
+ MailStore
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/MailStore/MailStore.sg b/base/Applications/EmailServer/MailStore/MailStore.sg
new file mode 100644
index 0000000..d222ac7
--- /dev/null
+++ b/base/Applications/EmailServer/MailStore/MailStore.sg
@@ -0,0 +1,387 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Mail storage server.
+//
+
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Threading;
+
+using Microsoft.SingSharp;
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Email.Contracts;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Security;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+[assembly: ApplicationPublisherAttribute("singularity.microsoft.com")]
+[assembly: AssertPrivilegeAttribute("$register-privilege.localhost")]
+
+namespace Microsoft.Singularity.Email
+{
+ [ConsoleCategory(HelpMessage="Mail Store Service", DefaultAction=true)]
+ internal class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [Endpoint]
+ public readonly TRef avRef;
+
+ [StringParameter("accounts", Mandatory=false, Default="/init/accounts",
+ HelpMessage="File with email accounts.")]
+ internal string accountPath;
+
+ [StringParameter("files", Mandatory=false, Default="/fs/email",
+ HelpMessage="Directory for email files.")]
+ internal string fileRoot;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return Store.AppMain(this);
+ }
+ }
+
+ public class Account
+ {
+ public string address;
+ public string path;
+ public int file;
+
+ public static SortedList accounts;
+
+ public Account(string address, string path)
+ {
+ this.address = address;
+ this.path = path;
+ this.file = 0;
+ }
+
+ public string NextFile()
+ {
+ return this.path + "/" + (this.file++).ToString();
+ }
+
+ public static void ReadAllFromFile(string path)
+ {
+ SortedList list = new SortedList(256);
+ // Open file RO for now
+ FileStream fsInput = new FileStream(path, FileMode.Open, FileAccess.Read);
+ StreamReader srInput = new StreamReader(fsInput);
+ String line;
+
+ while ((line = srInput.ReadLine()) != null) {
+ int colon = line.IndexOf(':');
+ if (colon > 0) {
+ string address = line.Substring(colon + 1);
+ string storage = line.Substring(0, colon);
+
+ if (!list.ContainsKey(address)) {
+ list.Add(address, new Account(address, storage));
+ }
+ }
+ }
+ //closing a stream reader will close the file stream under the covers
+ //if you close the file stream afterwards, you will deadlock.
+ srInput.Close();
+ accounts = list;
+ }
+
+ public static string AddressList()
+ {
+ string list = null;
+ foreach (Account account in accounts.Values) {
+ if (account != null) {
+ if (list != null) {
+ list = list + ";" + account.address;
+ }
+ else {
+ list = account.address;
+ }
+ }
+ }
+ return list;
+ }
+ }
+
+ public class Store
+ {
+ public static TRef avEp;
+
+ // This function initializes the store, registers with the name service and
+ // starts a new thread per SMTP agent.
+ //
+ internal static int AppMain(Parameters! config)
+ {
+ DirectoryServiceContract.Imp ds = (config.nsRef).Acquire();
+ if (ds == null) {
+ throw new Exception("Unable to acquire handle to the Directory Service root");
+ }
+ ds.RecvSuccess();
+
+ // Here is the channel we use to communicate with the NameServer
+ ServiceProviderContract.Imp! nsImp;
+ ServiceProviderContract.Exp! nsExp;
+ ServiceProviderContract.NewChannel(out nsImp, out nsExp);
+
+ try {
+ ds.SendRegister(Bitter.FromString2(MailStoreContract.ModuleName), nsImp);
+
+ switch receive {
+ case ds.AckRegister() :
+ // All is well.
+ break;
+
+ case ds.NakRegister(ServiceProviderContract.Imp:Start rejectedEP, error) :
+ // All is very much not well; abort.
+ Console.WriteLine("MailStore: Failed to register as {0}: {1}",
+ MailStoreContract.ModuleName, error);
+ delete nsExp;
+ delete rejectedEP;
+ return -1;
+
+ case ds.ChannelClosed():
+ Console.WriteLine("mailStore: ds channel closed");
+ delete nsExp;
+ return -1;
+ }
+
+ Console.WriteLine("MailStore: Reading account list.");
+ Account.ReadAllFromFile(config.accountPath);
+ // Make sure we have a directory for each account.
+ {
+ ErrorCode error;
+ // Directory.CreateDirectory(config.fileRoot);
+ if (SdsUtils.CreateDirectory(config.fileRoot, ds, out error)) {
+ Console.WriteLine("MailStore: Created {0}", config.fileRoot);
+ }
+ }
+
+ foreach (Account account in Account.accounts.Values) {
+ if (account == null || account.path == null) {
+ continue;
+ }
+ account.path = config.fileRoot + "/" + account.path;
+
+ try {
+ ErrorCode error;
+ string path = account.path;
+ if (SdsUtils.CreateDirectory(path, ds, out error)) {
+ Console.WriteLine("MailStore: Created {0}", path);
+ }
+
+ int count = 0;
+ for (;;) {
+ string file = path + "/" + count.ToString();
+ FileAttributesRecord atr;
+ if (!SdsUtils.GetAttributes(file, ds, out atr, out error)) {
+ if (count > 0) {
+ Console.WriteLine("MailStore: {0}", file);
+ }
+ break;
+ }
+ count++;
+ }
+ account.file = count;
+ }
+ catch (IOException) {
+ }
+ }
+ }
+ finally {
+ delete ds;
+ }
+
+ Console.WriteLine("MailStore: Connecting to AntiVirus.");
+ AntiVirusContract.Imp! avImp = config.avRef.Acquire();
+ avImp.RecvAntiVirusReady();
+ avEp = new TRef(avImp);
+
+ Console.WriteLine("MailStore: Ready at {0}", MailStoreContract.ModuleName);
+
+ // Here is the set of client channels we service
+
+ for (;;) {
+ switch receive {
+ // ------------------------------- Requests for new connections
+
+ case nsExp.Connect(ServiceContract.Exp:Start! newEp):
+ // We expect people top give us MailStoreContract.Exp instances
+ MailStoreContract.Exp newClient = newEp as MailStoreContract.Exp;
+
+ if (newClient == null) {
+ // Invalid contract type. Fail.
+ nsExp.SendNackConnect(newEp);
+ }
+ else {
+ // Signal ready and start servicing this contract
+ nsExp.SendAckConnect();
+
+ // Launch the thread to handle the incoming requests.
+ Store child = new Store(newClient);
+ Thread thread = new Thread(child.Run);
+ thread.Start();
+ }
+ break;
+
+ case nsExp.ChannelClosed():
+ // The namespace channel is closed so quit.
+ delete nsExp;
+ return -1;
+ }
+ }
+
+ // Close the Anti-Virus Scanner.
+ avImp = avEp.Acquire();
+ if (avImp != null) {
+ delete avImp;
+ }
+
+ return 0;
+ }
+
+ public static string PopNextAddress(ref string content)
+ {
+ if (content == null || content.Length == 0) {
+ return null;
+ }
+
+ int i = content.IndexOf(';');
+ string ret = (i > 0) ? content.Substring(0, i) : content;
+ content = (i > 0) ? content.Substring(i + 1) : "";
+ return ret;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+ //
+ public Store([Claims] MailStoreContract.Exp:Start! ep)
+ {
+ epRef = new TRef(ep);
+ }
+
+ private TRef epRef;
+
+ public void Run()
+ {
+ MailStoreContract.Exp ep = epRef.Acquire();
+
+ if (ep == null) {
+ return;
+ }
+
+ ep.SendMailStoreReady();
+ int arg;
+
+ for (;;) {
+ switch receive {
+ case ep.SaveMessage(char[]! in ExHeap boxes, byte[]! in ExHeap buffer):
+ // Do something with the message.
+ int error = 0;
+#if false
+ Console.WriteLine("MailStore: Processing Message");
+#endif
+ byte[] message = Bitter.ToByteArray(buffer);
+ string accountList = Bitter.ToString(boxes);
+ delete boxes;
+
+ AntiVirusContract.Imp avImp = avEp.Acquire();
+ avImp.SendCheckFile(buffer);
+ string virus = null;
+ switch receive
+ {
+ case avImp.FileClean():
+ break;
+
+ case avImp.FileContaminated(virusVector):
+ virus = Bitter.ToString(virusVector);
+ delete virusVector;
+ break;
+
+ case avImp.ChannelClosed():
+ virus = "**Scanner Failed**";
+ break;
+ }
+ avEp.Release(avImp);
+
+ if (virus != null) {
+ // save the message to each of the boxes.
+ Console.WriteLine("MailStore: "+
+ "Discarding message contaminated with {0}.",
+ virus);
+ error = 666;
+ }
+ else {
+ error = 0;
+ string address;
+ while ((address = PopNextAddress(ref accountList)) != null) {
+#if false
+ Console.WriteLine("MailStore: Receive for {0} of {1} bytes",
+ address, message.Length);
+#endif
+ int key = Account.accounts.IndexOfKey(address);
+ if (key >= 0) {
+ Account! account = (Account!)Account.accounts.GetByIndex(key);
+ string path = account.NextFile();
+
+ try {
+ FileStream! sw = (!)File.Create(path);
+ sw.Write(message, 0, message.Length);
+ sw.Flush();
+ sw.Close();
+ }
+ catch (IOException) {
+ Console.WriteLine("MailStore: Write to {0} failed.", path);
+ error = 665;
+ }
+ }
+ else {
+ Console.WriteLine("MailStore: Bad address {0}", address);
+ }
+ }
+ }
+
+ if (error == 0) {
+ ep.SendSaveAck();
+ }
+ else {
+ ep.SendSaveNak(error);
+ }
+ break;
+
+
+ case ep.GetAddressList():
+ Console.WriteLine("MailStore: Providing list of email addresses.");
+ string list = Account.AddressList();
+ char[]! in ExHeap buffer = (!)Bitter.FromString(list);
+ ep.SendGetAck(buffer);
+ break;
+
+ case ep.ChannelClosed():
+ delete ep;
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/base/Applications/EmailServer/MailStore/MailStoreContracts.csproj b/base/Applications/EmailServer/MailStore/MailStoreContracts.csproj
new file mode 100644
index 0000000..7e9d5a7
--- /dev/null
+++ b/base/Applications/EmailServer/MailStore/MailStoreContracts.csproj
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ Library
+ MailStoreContracts
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/MailStore/MailStoreContracts.sg b/base/Applications/EmailServer/MailStore/MailStoreContracts.sg
new file mode 100644
index 0000000..4852ea3
--- /dev/null
+++ b/base/Applications/EmailServer/MailStore/MailStoreContracts.sg
@@ -0,0 +1,38 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Contract used by SMTP Agents to talk to the mail store.
+//
+
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Endpoint;
+
+using Microsoft.Singularity.Extending;
+
+namespace Microsoft.Singularity.Email.Contracts
+{
+ public contract MailStoreContract : ExtensionContract //ServiceContract
+ {
+ public const string ModuleName = "/service/mailstore";
+
+ out message MailStoreReady();
+
+ in message GetAddressList();
+ out message GetAck(char[]! in ExHeap addresses);
+
+ in message SaveMessage(char[]! in ExHeap accounts,
+ byte[]! in ExHeap buffer);
+ out message SaveAck();
+ out message SaveNak(int error);
+
+ override state Start : MailStoreReady! -> ReadyState;
+ state ReadyState : one {
+ SaveMessage? -> (SaveAck! or SaveNak!) -> ReadyState;
+ GetAddressList? -> (GetAck!) -> ReadyState;
+ }
+ }
+}
diff --git a/base/Applications/EmailServer/MailStore/accounts b/base/Applications/EmailServer/MailStore/accounts
new file mode 100644
index 0000000..4417243
--- /dev/null
+++ b/base/Applications/EmailServer/MailStore/accounts
@@ -0,0 +1,135 @@
+alewis:andrew.lewis@enron.com
+allen:k..allen@enron.com
+arnold:john.arnold@enron.com
+arora:harry.arora@enron.com
+badeer:robert.badeer@enron.com
+bagwell:jennifer.bagwell@enron.com
+bailey:susan.bailey@enron.com
+bass:eric.bass@enron.com
+baughman:don.baughman@enron.com
+beck:sally.beck@enron.com
+benson:robert.benson@enron.com
+blair:lynn.blair@enron.com
+brawner:f..brawner@enron.com
+brawners:sandra.brawner@enron.com
+buy:rick.buy@enron.com
+campbell:f..campbell@enron.com
+carson:mike.carson@enron.com
+cash:michelle.cash@enron.com
+causholli:monika.causholli@enron.com
+corman:shelley.corman@enron.com
+crandall:sean.crandall@enron.com
+cuilla:martin.cuilla@enron.com
+dasovich:jeff.dasovich@enron.com
+davis:dana.davis@enron.com
+dean:craig.dean@enron.com
+delainey:w..delainey@enron.com
+derrick:james.derrick@enron.com
+donoho:lindy.donoho@enron.com
+donohoe:tom.donohoe@enron.com
+dorland:chris.dorland@enron.com
+ermis:frank.ermis@enron.com
+evans:casey.evans@enron.com
+farmer:j..farmer@enron.com
+fischer:mary.fischer@enron.com
+forney:m..forney@enron.com
+gang:lisa.gang@enron.com
+gay:l..gay@enron.com
+geaccone:tracy.geaccone@enron.com
+germany:chris.germany@enron.com
+gilbertsmith:doug.gilbert-smith@enron.com
+giron:c..giron@enron.com
+griffith:john.griffith@enron.com
+grigsby:mike.grigsby@enron.com
+haedicke:e..haedicke@enron.com
+hayslett:rod.hayslett@enron.com
+heard:marie.heard@enron.com
+hendrickson:scott.hendrickson@enron.com
+hernandez:juan.hernandez@enron.com
+hlewis:h..lewis@enron.com
+hodge:john.hodge@enron.com
+holst:keith.holst@enron.com
+horton:stanley.horton@enron.com
+hyatt:kevin.hyatt@enron.com
+jones:tana.jones@enron.com
+kaminski:j.kaminski@enron.com
+kean:j..kean@enron.com
+keavey:peter.keavey@enron.com
+keaveyf:f..keavey@enron.com
+keiser:kam.keiser@enron.com
+king:jeff.king@enron.com
+kitchen:louise.kitchen@enron.com
+kuykendall:tori.kuykendall@enron.com
+lavorato:lavorato@enron.com
+lay:kenneth.lay@enron.com
+lenhart:matthew.lenhart@enron.com
+lokay:michelle.lokay@enron.com
+lokey:teb.lokey@enron.com
+love:m..love@enron.com
+lucci:t..lucci@enron.com
+maggi:mike.maggi@enron.com
+mann:kay.mann@enron.com
+martin:a..martin@enron.com
+may:larry.may@enron.com
+mccarty:danny.mccarty@enron.com
+mcconnell:mark.mcconnell@enron.com
+mckayb:brad.mckay@enron.com
+mckayj:jonathan.mckay@enron.com
+mclaughlin:errol.mclaughlin@enron.com
+meyers:albert.meyers@enron.com
+mims:l..mims@enron.com
+motley:matt.motley@enron.com
+neal:scott.neal@enron.com
+nemec:gerald.nemec@enron.com
+panus:stephanie.panus@enron.com
+parks:joe.parks@enron.com
+pereira:w..pereira@enron.com
+perlingiere:debra.perlingiere@enron.com
+pimenov:vladi.pimenov@enron.com
+platter:phillip.platter@enron.com
+presto:m..presto@enron.com
+quenet:joe.quenet@enron.com
+quigley:dutch.quigley@enron.com
+rapp:bill.rapp@enron.com
+reitmeyer:jay.reitmeyer@enron.com
+richey:cooper.richey@enron.com
+ringa:andrea.ring@enron.com
+ringr:richard.ring@enron.com
+rogers:benjamin.rogers@enron.com
+ruscitti:kevin.ruscitti@enron.com
+sager:elizabeth.sager@enron.com
+saibi:eric.saibi@enron.com
+salisbury:holden.salisbury@enron.com
+sanchez:monique.sanchez@enron.com
+sanders:b..sanders@enron.com
+scholtes:diana.scholtes@enron.com
+schoolcraft:darrell.schoolcraft@enron.com
+schwieger:jim.schwieger@enron.com
+scott:susan.scott@enron.com
+semperger:cara.semperger@enron.com
+shackleton:sara.shackleton@enron.com
+shankman:a..shankman@enron.com
+shankmanj:jeffrey.a.shankman@enron.com
+shapiro:richard.shapiro@enron.com
+shively:s..shively@enron.com
+skilling:jeff.skilling@enron.com
+slinger:ryan.slinger@enron.com
+smith:matt.smith@enron.com
+solberg:geir.solberg@enron.com
+staab:theresa.staab@enron.com
+steffes:d..steffes@enron.com
+stepenovitch:joe.stepenovitch@enron.com
+storey:geoff.storey@enron.com
+sturm:j..sturm@enron.com
+swerzbin:mike.swerzbin@enron.com
+tholt:jane.tholt@enron.com
+thomas:d..thomas@enron.com
+townsend:judy.townsend@enron.com
+tycholiz:barry.tycholiz@enron.com
+ward:kim.ward@enron.com
+watson:kimberly.watson@enron.com
+weldon:charles.weldon@enron.com
+whalley:greg.whalley@enron.com
+white:w..white@enron.com
+whitt:mark.whitt@enron.com
+williams:jason.williams@enron.com
diff --git a/base/Applications/EmailServer/SmtpAgent/Session.sg b/base/Applications/EmailServer/SmtpAgent/Session.sg
new file mode 100644
index 0000000..67af244
--- /dev/null
+++ b/base/Applications/EmailServer/SmtpAgent/Session.sg
@@ -0,0 +1,258 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: SMTP Session.
+//
+
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+
+namespace Microsoft.Singularity.Email
+{
+ public class SmtpSession
+ {
+ private Socket socket;
+ private byte[] ibuf;
+ private int iend;
+ private int ibeg;
+ private byte[] obuf;
+ private int odata;
+ private int result;
+ private bool verbose;
+
+ public SmtpSession(Socket socket)
+ {
+ this.socket = socket;
+ this.ibuf = new byte [4096];
+ this.ibeg = 0;
+ this.iend = 0;
+ this.obuf = new byte [4096];
+ this.odata = 0;
+ this.result = 0;
+ this.verbose = false;
+ }
+
+ private int HaveLine()
+ {
+ int left = iend - ibeg;
+ for (int i = 0; i + 1< left; i++) {
+ if (ibuf[ibeg + i] == '\r' && ibuf[ibeg + i + 1] == '\n') {
+ // return the # of character (not \r\n) in line.
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private int ReadLine()
+ {
+ for (;;) {
+ if (ibeg < iend) {
+
+ // See if there is a line already in the buffer.
+ int line = HaveLine();
+ if (line >= 0) {
+ return line;
+ }
+
+ // Make sure the remaining data is at the start of buffer.
+ if (ibeg > 0) {
+ Array.Copy(ibuf, ibeg, ibuf, 0, iend - ibeg);
+ iend -= ibeg;
+ ibeg = 0;
+ }
+ }
+ else {
+ ibeg = 0;
+ iend = 0;
+ }
+
+ int read = socket.Receive(ibuf, iend, ibuf.Length - iend, SocketFlags.None);
+ if (read == 0) {
+ // Should probably throw an exception.
+ return -1;
+ }
+ iend += read;
+ }
+ }
+
+ public int Result
+ {
+ get { return result; }
+ }
+
+ public bool Verbose
+ {
+ get { return verbose; }
+ set { verbose = value; }
+ }
+
+ public string ReadLine7()
+ {
+ result = 0;
+ int line = ReadLine();
+ if (line >= 0) {
+ string data = Encoding.ASCII.GetString(ibuf, ibeg, line);
+ for (int i = 0; i < line && ibuf[ibeg + i] >= '0' && ibuf[ibeg + i] <= '9'; i++) {
+ result = result * 10 + (ibuf[ibeg + i] - '0');
+ }
+ ibeg += line + 2;
+ if (verbose) {
+ Console.WriteLine("S: {0}", data);
+ }
+ return data;
+ }
+ if (verbose) {
+ Console.WriteLine("S: ");
+ }
+ return null;
+ }
+
+ public int ReadLine8(byte[] buffer, int offset)
+ {
+ result = 0;
+ int line = ReadLine();
+ if (line >= 0) {
+ Array.Copy(ibuf, ibeg, buffer, offset, line);
+ ibeg += line + 2;
+ if (verbose) {
+ Console.WriteLine("S: <8bit>");
+ }
+ return line;
+ }
+ if (verbose) {
+ Console.WriteLine("S: ");
+ }
+ return -1;
+ }
+
+ public void WritePrefix(byte prefix)
+ {
+ obuf[odata++] = prefix;
+ }
+
+ public void WriteLine7(string line)
+ {
+ WriteLine7(line, null, null, null);
+ }
+
+ public void WriteLine7(string a, string b)
+ {
+ WriteLine7(a, b, null, null);
+ }
+
+ public void WriteLine7(string a, string b, string c)
+ {
+ WriteLine7(a, b, c, null);
+ }
+
+ public void WriteLine7(string a, string b, string c, string d)
+ {
+ if (verbose) {
+ Console.WriteLine("C: {0}", a + b + c + d);
+ }
+ if (a != null) {
+ odata += Encoding.ASCII.GetBytes(a, 0, a.Length, obuf, odata);
+ }
+ if (b != null) {
+ odata += Encoding.ASCII.GetBytes(b, 0, b.Length, obuf, odata);
+ }
+ if (c != null) {
+ odata += Encoding.ASCII.GetBytes(c, 0, c.Length, obuf, odata);
+ }
+ if (d != null) {
+ odata += Encoding.ASCII.GetBytes(d, 0, d.Length, obuf, odata);
+ }
+ obuf[odata++] = (byte)'\r';
+ obuf[odata++] = (byte)'\n';
+ socket.Send(obuf, 0, odata, SocketFlags.None);
+ odata = 0;
+ }
+
+ public void WriteLine8(byte[] line)
+ {
+ if (verbose) {
+ Console.WriteLine("C: <8bit>");
+ }
+ if (odata > 0) {
+ socket.Send(obuf, 0, odata, SocketFlags.None);
+ odata = 0;
+ }
+ socket.Send(line);
+ obuf[odata++] = (byte)'\r';
+ obuf[odata++] = (byte)'\n';
+ socket.Send(obuf, 0, odata, SocketFlags.None);
+ odata = 0;
+ }
+
+ public int Quit()
+ {
+ int save = result;
+ WriteLine7("QUIT");
+ ReadLine7();
+ socket.Shutdown(SocketShutdown.Both);
+
+ if (save == 0) {
+ return 999;
+ }
+ return save;
+ }
+
+ public int Close()
+ {
+ int save = result;
+ socket.Shutdown(SocketShutdown.Both);
+
+ if (save == 0) {
+ return 999;
+ }
+ return save;
+ }
+
+ private void Dump(byte[] array, int beg, int end)
+ {
+ for (int i = beg; i < end; i += 16) {
+ Console.Write(" :: ");
+ for (int j = i; j < i + 16; j++) {
+ if (j < end) {
+ Console.Write("{0:x2}", array[j]);
+ }
+ else {
+ Console.Write(" ");
+ }
+ }
+ Console.Write(" :: ");
+ for (int j = i; j < i + 16; j++) {
+ if (j < end) {
+ if (array[j] >= 32 && array[j] < 127) {
+ Console.Write("{0}", (char)array[j]);
+ }
+ else {
+ Console.Write(".");
+ }
+ }
+ else {
+ Console.Write(" ");
+ }
+ }
+ Console.WriteLine();
+ }
+ }
+
+ public void Dump()
+ {
+ Console.WriteLine(":::: Input {0}..{1}", ibeg, iend);
+ Dump(ibuf, ibeg, iend);
+ Console.WriteLine(":::: Output {0}..{1}", 0, odata);
+ Dump(obuf, 0, odata);
+ Console.WriteLine(":::: Result {0}", result);
+ }
+ }
+}
diff --git a/base/Applications/EmailServer/SmtpAgent/SmtpAgent.csproj b/base/Applications/EmailServer/SmtpAgent/SmtpAgent.csproj
new file mode 100644
index 0000000..bd90e06
--- /dev/null
+++ b/base/Applications/EmailServer/SmtpAgent/SmtpAgent.csproj
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+ Exe
+ SmtpAgent
+ 2614,2637,2638,2613,2639
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/SmtpAgent/SmtpAgent.sg b/base/Applications/EmailServer/SmtpAgent/SmtpAgent.sg
new file mode 100644
index 0000000..cf29c64
--- /dev/null
+++ b/base/Applications/EmailServer/SmtpAgent/SmtpAgent.sg
@@ -0,0 +1,507 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: SMTP Server.
+//
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Diagnostics.Contracts;
+using Microsoft.Singularity.Endpoint;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+
+using System;
+using System.Collections;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading;
+using System.Diagnostics;
+
+using Microsoft.Singularity.Email.Contracts;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Email
+{
+ [ConsoleCategory(HelpMessage="SMTP Mail Transfer Agent", DefaultAction=true)]
+ internal class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+#if false
+ [Endpoint]
+ public readonly TRef msRef;
+#endif
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [StringParameter("mailstore service", Mandatory=false, Default="/service/mailstore",
+ HelpMessage="Location of mail store service.")]
+ internal string mailstorePath;
+
+ [StringParameter("server", Mandatory=false, Default="0.0.0.0",
+ HelpMessage="Service IP Address to give to clients.")]
+ internal string server;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return SmtpServer.AppMain(this);
+ }
+ }
+
+ public class Buffer
+ {
+ private byte[] data;
+ private int size;
+
+ public static Buffer Allocate(int bytes)
+ {
+ Buffer buffer = new Buffer(bytes);
+ return buffer;
+ }
+
+ private Buffer(int bytes)
+ {
+ this.data = new byte[bytes];
+ this.size = 0;
+ }
+
+ public byte[] Data
+ {
+ get { return data; }
+ }
+
+ public int Size
+ {
+ get { return size; }
+ }
+
+ public int Prepare(int bytes)
+ {
+ if (size + bytes > data.Length) {
+ byte[] dst = new byte[data.Length * 2];
+ Array.Copy(data, dst, size);
+ data = dst;
+ }
+ return size;
+ }
+
+ public void Save(int bytes)
+ {
+ if (size + bytes + 2 <= data.Length) {
+ size += bytes;
+ data[size++] = (byte)'\r';
+ data[size++] = (byte)'\n';
+ }
+ else {
+ throw new Exception("Overflow");
+ }
+ }
+
+ public void Release()
+ {
+ data = null;
+ size = 0;
+ }
+ }
+
+ public class ServerSession : SmtpSession
+ {
+ private static int idCount = 0;
+ private int id;
+ private string command;
+ private string server;
+
+ public ServerSession(Socket socket, String server)
+ : base(socket)
+ {
+ this.id = idCount++;
+ this.server = server;
+ }
+
+ public string GetCommand(String line)
+ {
+ int i = line.IndexOf(' ');
+ if (i < 0) {
+ command = line;
+ return null;
+ }
+ command = line.Substring(0, i).ToUpper();
+ return command;
+ }
+
+ private enum CurrentState {
+ HAD_NONE = 0,
+ HAD_HELO = 1,
+ HAD_MAIL = 2,
+ HAD_RCPT = 3,
+ };
+
+ public void Loop()
+ {
+ String client;
+ String line;
+ CurrentState cstate = CurrentState.HAD_NONE;
+ String from = null;
+ String to = null;
+
+ //Open a new connection to the mailstore for each smtp connection.
+ //Each client connection stays allive until all emails are sent.
+
+ DirectoryServiceContract.Imp! dsImp = SmtpServer.dsEp.Acquire();
+
+ MailStoreContract.Imp! msImp;
+ MailStoreContract.Exp! msExp;
+ MailStoreContract.NewChannel(out msImp, out msExp);
+
+ ErrorCode errorCode;
+ if (!SdsUtils.Bind(SmtpServer.mailstorePath, dsImp, msExp, out errorCode)) {
+ DebugStub.WriteLine("Failed to bind to mail store...error {0}\n",
+ __arglist(SdsUtils.ErrorCodeToString(errorCode)));
+ Console.WriteLine("Failed to bind to mail store...error {0}\n",
+ SdsUtils.ErrorCodeToString(errorCode));
+
+ DebugStub.Break();
+ SmtpServer.dsEp.Release(dsImp);
+ delete msImp;
+ return;
+ }
+ SmtpServer.dsEp.Release(dsImp);
+
+ // MailStoreContract.Imp! msImp = config.msRef.Acquire();
+ msImp.RecvMailStoreReady();
+
+ WriteLine7("220 ", server, " Singularity Simple SMTP Service Ready");
+
+ bool abort = false;
+ while (!abort) {
+ line = ReadLine7();
+ if (line == null) {
+ break;
+ }
+
+ GetCommand(line);
+
+ switch (command) {
+ case "EHLO":
+ client = line.Split(new Char[] {' '})[1];
+ Console.WriteLine(":{0}: EHLO {1}", id, client);
+ WriteLine7("250-", server, " greets ", client);
+ WriteLine7("250-8BITMIME");
+ WriteLine7("250 HELP");
+ from = null;
+ to = null;
+ cstate = CurrentState.HAD_HELO;
+ // DebugStub.WriteLine("Got EHLO\n");
+ break;
+
+ case "HELO":
+ client = line.Split(new Char[] {' '})[1];
+ Console.WriteLine(":{0}: HELO {1}", id, client);
+ WriteLine7("250 ", server, " greets ", client);
+ from = null;
+ to = null;
+ cstate = CurrentState.HAD_HELO;
+ // DebugStub.WriteLine("Got HELO\n");
+ break;
+
+ case "MAIL":
+ if (cstate != CurrentState.HAD_HELO) {
+ goto default;
+ }
+
+ if (line.StartsWith("MAIL FROM:")) {
+ int pos = line.IndexOf("<") + 1;
+ int beg = line.LastIndexOf(':');
+ if (beg < pos) {
+ beg = pos;
+ }
+ int end = line.IndexOf('>');
+ from = line.Substring(beg, end - beg).ToLower();
+ WriteLine7("250 OK");
+ cstate = CurrentState.HAD_MAIL;
+ // DebugStub.WriteLine("Got MAIL\n");
+ }
+ else {
+ WriteLine7("501 Syntax error in parameters");
+ }
+ break;
+
+ case "RCPT":
+ if (cstate != CurrentState.HAD_MAIL && cstate != CurrentState.HAD_RCPT) {
+ goto default;
+ }
+ // DebugStub.WriteLine("Got RCPT\n");
+ if (line.StartsWith("RCPT TO:")) {
+ int pos = line.IndexOf("<") + 1;
+ int beg = line.LastIndexOf(':');
+ if (beg < pos) {
+ beg = pos;
+ }
+ int end = line.IndexOf('>');
+ string address = line.Substring(beg, end - beg).ToLower();
+
+ if (SmtpServer.addresses.ContainsKey(address)) {
+ WriteLine7("250 OK");
+ if (to != null) {
+ to = to + ";" + address;
+ }
+ else {
+ to = address;
+ }
+ cstate = CurrentState.HAD_RCPT;
+ }
+ else {
+ WriteLine7("250 Accepting for forwarding.");
+ cstate = CurrentState.HAD_RCPT;
+ if (to != null) {
+ to = to + ";" + "mail_forward@enron.com";
+ }
+ else {
+ to = "mail_forward@enron.com";
+ }
+ }
+ }
+ else {
+ WriteLine7("501 Syntax error in parameters");
+ }
+ break;
+
+ case "DATA":
+ if (cstate != CurrentState.HAD_RCPT) {
+ goto default;
+ }
+ // DebugStub.WriteLine("Got DATA\n");
+ WriteLine7("354 Start mail input; end with .");
+
+ bool old = Verbose;
+ Verbose = false;
+ Buffer buffer = Buffer.Allocate(65536);
+ bool good = false;
+
+ for (;;) {
+ int off = buffer.Prepare(1024);
+ int len = ReadLine8(buffer.Data, off);
+
+ if (len < 0) {
+ break;
+ }
+
+ if (len == 1 && buffer.Data[off] == '.') {
+ good = true;
+ break;
+ }
+ else {
+#if false
+ Console.WriteLine("S: {0}",
+ Encoding.ASCII.GetString(buffer.Data, off, len));
+#endif
+ buffer.Save(len);
+ }
+ }
+ Verbose = old;
+
+ if (good) {
+ bool succeeded = false;
+ char[] in ExHeap! addresses = Bitter.FromString(to);
+ byte[] in ExHeap! data
+ = Bitter.FromByteArray(buffer.Data, 0, buffer.Size);
+
+ // MailStoreContract.Imp msImp = SmtpServer.msEp.Acquire();
+ // DebugStub.WriteLine("Saving data\n");
+ Console.WriteLine("SmtpAgaint: Email from {0} to {1}", from, to);
+ msImp.SendSaveMessage(addresses, data);
+ switch receive
+ {
+ case msImp.SaveAck():
+ succeeded = true;
+ break;
+
+ case msImp.SaveNak(error):
+ Console.WriteLine("SmtpAgent: Server dropped email, "+
+ "error={0}", error);
+ break;
+
+ case msImp.ChannelClosed():
+ break;
+ }
+ // SmtpServer.msEp.Release(msImp);
+ if (succeeded) {
+ WriteLine7("250 OK");
+ }
+ else {
+ WriteLine7("554 Transaction failed");
+ }
+ }
+ else {
+ WriteLine7("554 Transaction failed");
+ Dump();
+ throw new Exception("554 Transaction failed");
+ }
+
+ buffer.Release();
+ cstate = CurrentState.HAD_HELO;
+ from = null;
+ to = null;
+ break;
+
+ case "NOOP":
+ WriteLine7("250 OK");
+ break;
+
+ case "HELP":
+ WriteLine7("250 OK");
+ break;
+
+ case "RSET":
+ WriteLine7("250 OK");
+ from = null;
+ to = null;
+ cstate = CurrentState.HAD_HELO;
+ break;
+
+ case "QUIT":
+ WriteLine7("221 ", server, " Service closing transmission channel");
+ abort = true;
+ break;
+
+ default:
+ WriteLine7("503 Unrecognized command [", command, "]");
+ abort = true;
+ break;
+ }
+ }
+ Console.WriteLine(":{0}: Session closed", id);
+ delete msImp;
+ Close();
+ }
+ }
+
+ public class SmtpServer
+ {
+ public const int _port = 25;
+ public static bool verbose;
+
+ // public static TRef msEp;
+ public static TRef dsEp;
+
+ public static SortedList addresses;
+ public static string mailstorePath;
+
+ internal static int AppMain(Parameters! config)
+ {
+ string server = config.server;
+ if (server[0] >= '0' && server[0] <= '9') {
+ server = "[" + server + "]";
+ }
+
+ // Connect to the MailStore.
+ Console.WriteLine("SmtpAgent: Connecting to MailStore.");
+ DirectoryServiceContract.Imp! dsImp = config.nsRef.Acquire();
+ dsImp.RecvSuccess();
+
+ MailStoreContract.Imp! msImp;
+ MailStoreContract.Exp! msExp;
+ MailStoreContract.NewChannel(out msImp, out msExp);
+
+ mailstorePath = config.mailstorePath;
+
+ ErrorCode error;
+ if (!SdsUtils.Bind(config.mailstorePath, dsImp, msExp, out error)) {
+ DebugStub.WriteLine("Failed to bind to mail store...error {0}\n",
+ __arglist(SdsUtils.ErrorCodeToString(error)));
+ Console.WriteLine("Failed to bind to mail store...error {0}\n",
+ SdsUtils.ErrorCodeToString(error));
+
+ delete dsImp;
+ delete msImp;
+ return -1;
+ }
+
+
+ // MailStoreContract.Imp! msImp = config.msRef.Acquire();
+ msImp.RecvMailStoreReady();
+
+ // Retrieve vaild address list.
+ char[] in ExHeap! buffer;
+ msImp.SendGetAddressList();
+ msImp.RecvGetAck(out buffer);
+ addresses = ReadUniqueList(Bitter.ToString(buffer));
+ delete buffer;
+
+ delete msImp;
+ // Save the endpoint.
+ // msEp = new TRef(msImp);
+ dsEp = new TRef(dsImp);
+
+ // Connect to the network.
+ Console.WriteLine("SmtpAgent: Opening TCP port {0}", _port);
+ Socket target = new Socket(AddressFamily.InterNetwork,
+ SocketType.Stream, ProtocolType.Tcp);
+ target.Bind(new IPEndPoint(IPAddress.Any, _port));
+ target.Listen((int)SocketOptionName.MaxConnections);
+
+ for (bool stop = false; !stop;) {
+ Console.WriteLine(":: {0} waiting for accept.", server);
+ Socket socket = target.Accept();
+
+ // Create the Session and kick it off in its own thread.
+ ServerSession conn = new ServerSession(socket, server);
+
+ conn.Verbose = verbose;
+ Thread thread = new Thread(conn.Loop);
+ thread.Start();
+ }
+ target.Close();
+
+ // Close the Store engine.
+ dsImp = dsEp.Acquire();
+ if (dsImp != null) {
+ delete dsImp;
+ }
+
+ return 0;
+ }
+
+ public static string PopNextAddress(ref string content)
+ {
+ if (content.Length == 0) {
+ return null;
+ }
+
+ int i = content.IndexOf(';');
+ string ret = (i > 0) ? content.Substring(0, i) : content;
+ content = (i > 0) ? content.Substring(i + 1) : "";
+ return ret;
+ }
+
+ public static SortedList ReadUniqueList(string content)
+ {
+ SortedList list = new SortedList();
+ string address;
+
+ while ((address = PopNextAddress(ref content)) != null) {
+ if (!list.ContainsKey(address)) {
+ list.Add(address, address);
+ }
+ }
+ return list;
+ }
+ }
+}
+
+
diff --git a/base/Applications/EmailServer/SmtpAgent/accounts b/base/Applications/EmailServer/SmtpAgent/accounts
new file mode 100644
index 0000000..c070f27
--- /dev/null
+++ b/base/Applications/EmailServer/SmtpAgent/accounts
@@ -0,0 +1,136 @@
+alewis:andrew.lewis@enron.com
+allen:k..allen@enron.com
+arnold:john.arnold@enron.com
+arora:harry.arora@enron.com
+badeer:robert.badeer@enron.com
+bagwell:jennifer.bagwell@enron.com
+bailey:susan.bailey@enron.com
+bass:eric.bass@enron.com
+baughman:don.baughman@enron.com
+beck:sally.beck@enron.com
+benson:robert.benson@enron.com
+blair:lynn.blair@enron.com
+brawner:f..brawner@enron.com
+brawners:sandra.brawner@enron.com
+buy:rick.buy@enron.com
+campbell:f..campbell@enron.com
+carson:mike.carson@enron.com
+cash:michelle.cash@enron.com
+causholli:monika.causholli@enron.com
+corman:shelley.corman@enron.com
+crandall:sean.crandall@enron.com
+cuilla:martin.cuilla@enron.com
+dasovich:jeff.dasovich@enron.com
+davis:dana.davis@enron.com
+dean:craig.dean@enron.com
+delainey:w..delainey@enron.com
+derrick:james.derrick@enron.com
+donoho:lindy.donoho@enron.com
+donohoe:tom.donohoe@enron.com
+dorland:chris.dorland@enron.com
+ermis:frank.ermis@enron.com
+evans:casey.evans@enron.com
+farmer:j..farmer@enron.com
+fischer:mary.fischer@enron.com
+forney:m..forney@enron.com
+gang:lisa.gang@enron.com
+gay:l..gay@enron.com
+geaccone:tracy.geaccone@enron.com
+germany:chris.germany@enron.com
+gilbertsmith:doug.gilbert-smith@enron.com
+giron:c..giron@enron.com
+griffith:john.griffith@enron.com
+grigsby:mike.grigsby@enron.com
+haedicke:e..haedicke@enron.com
+hayslett:rod.hayslett@enron.com
+heard:marie.heard@enron.com
+hendrickson:scott.hendrickson@enron.com
+hernandez:juan.hernandez@enron.com
+hlewis:h..lewis@enron.com
+hodge:john.hodge@enron.com
+holst:keith.holst@enron.com
+horton:stanley.horton@enron.com
+hyatt:kevin.hyatt@enron.com
+jones:tana.jones@enron.com
+kaminski:j.kaminski@enron.com
+kean:j..kean@enron.com
+keavey:peter.keavey@enron.com
+keaveyf:f..keavey@enron.com
+keiser:kam.keiser@enron.com
+king:jeff.king@enron.com
+kitchen:louise.kitchen@enron.com
+kuykendall:tori.kuykendall@enron.com
+lavorato:lavorato@enron.com
+lay:kenneth.lay@enron.com
+lenhart:matthew.lenhart@enron.com
+lokay:michelle.lokay@enron.com
+lokey:teb.lokey@enron.com
+love:m..love@enron.com
+lucci:t..lucci@enron.com
+maggi:mike.maggi@enron.com
+mann:kay.mann@enron.com
+martin:a..martin@enron.com
+may:larry.may@enron.com
+mccarty:danny.mccarty@enron.com
+mcconnell:mark.mcconnell@enron.com
+mckayb:brad.mckay@enron.com
+mckayj:jonathan.mckay@enron.com
+mclaughlin:errol.mclaughlin@enron.com
+meyers:albert.meyers@enron.com
+mims:l..mims@enron.com
+motley:matt.motley@enron.com
+neal:scott.neal@enron.com
+nemec:gerald.nemec@enron.com
+panus:stephanie.panus@enron.com
+parks:joe.parks@enron.com
+pereira:w..pereira@enron.com
+perlingiere:debra.perlingiere@enron.com
+pimenov:vladi.pimenov@enron.com
+platter:phillip.platter@enron.com
+presto:m..presto@enron.com
+quenet:joe.quenet@enron.com
+quigley:dutch.quigley@enron.com
+rapp:bill.rapp@enron.com
+reitmeyer:jay.reitmeyer@enron.com
+richey:cooper.richey@enron.com
+ringa:andrea.ring@enron.com
+ringr:richard.ring@enron.com
+rogers:benjamin.rogers@enron.com
+ruscitti:kevin.ruscitti@enron.com
+sager:elizabeth.sager@enron.com
+saibi:eric.saibi@enron.com
+salisbury:holden.salisbury@enron.com
+sanchez:monique.sanchez@enron.com
+sanders:b..sanders@enron.com
+scholtes:diana.scholtes@enron.com
+schoolcraft:darrell.schoolcraft@enron.com
+schwieger:jim.schwieger@enron.com
+scott:susan.scott@enron.com
+semperger:cara.semperger@enron.com
+shackleton:sara.shackleton@enron.com
+shankman:a..shankman@enron.com
+shankmanj:jeffrey.a.shankman@enron.com
+shapiro:richard.shapiro@enron.com
+shively:s..shively@enron.com
+skilling:jeff.skilling@enron.com
+slinger:ryan.slinger@enron.com
+smith:matt.smith@enron.com
+solberg:geir.solberg@enron.com
+staab:theresa.staab@enron.com
+steffes:d..steffes@enron.com
+stepenovitch:joe.stepenovitch@enron.com
+storey:geoff.storey@enron.com
+sturm:j..sturm@enron.com
+swerzbin:mike.swerzbin@enron.com
+tholt:jane.tholt@enron.com
+thomas:d..thomas@enron.com
+townsend:judy.townsend@enron.com
+tycholiz:barry.tycholiz@enron.com
+ward:kim.ward@enron.com
+watson:kimberly.watson@enron.com
+weldon:charles.weldon@enron.com
+whalley:greg.whalley@enron.com
+white:w..white@enron.com
+whitt:mark.whitt@enron.com
+williams:jason.williams@enron.com
+forwarding:mail_forward@enron.com
diff --git a/base/Applications/EmailServer/SmtpAgentNoNet/SmtpAgentNoNet.csproj b/base/Applications/EmailServer/SmtpAgentNoNet/SmtpAgentNoNet.csproj
new file mode 100644
index 0000000..a81389f
--- /dev/null
+++ b/base/Applications/EmailServer/SmtpAgentNoNet/SmtpAgentNoNet.csproj
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+ Exe
+ SmtpAgentNoNet
+ 2614,2637,2638,2613,2639
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/EmailServer/SmtpAgentNoNet/SmtpAgentNoNet.sg b/base/Applications/EmailServer/SmtpAgentNoNet/SmtpAgentNoNet.sg
new file mode 100644
index 0000000..c70b1e8
--- /dev/null
+++ b/base/Applications/EmailServer/SmtpAgentNoNet/SmtpAgentNoNet.sg
@@ -0,0 +1,1004 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: SMTP Server.
+//
+//#define SMTPAGENT_VERBOSE
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Diagnostics.Contracts;
+using Microsoft.Singularity.Endpoint;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+
+using System;
+using System.IO;
+using System.Collections;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading;
+using System.Diagnostics;
+
+using Microsoft.Singularity.Email.Contracts;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Email_NoNet
+{
+ [ConsoleCategory(HelpMessage="SMTP Mail Transfer Agent", DefaultAction=true)]
+ internal class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("cnts", Mandatory=false, Default="/init/contents.txt",
+ HelpMessage="Contents of emails to be sent.")]
+ internal string emailCorpus;
+
+ [StringParameter("stl", Mandatory=false, Default="/init/stl.txt",
+ HelpMessage="file containing starting loc in corpus for each conn")]
+ internal string startPositionsFile;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [StringParameter("mailstore service", Mandatory=false, Default="/service/mailstore",
+ HelpMessage="Location of mail store service.")]
+ internal string mailstorePath;
+
+ [LongParameter("nts", Mandatory=false, Default= 1,
+ HelpMessage="Number of emails to send.")]
+ internal long numToSend;
+
+ [LongParameter("nc", Mandatory=false, Default=1,
+ HelpMessage="Number of concurrent connections.")]
+ internal long numConn;
+
+ [StringParameter("server", Mandatory=false, Default="0.0.0.0",
+ HelpMessage="Service IP Address to give to clients.")]
+ internal string server;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return SmtpServer.AppMain(this);
+ }
+ }
+
+
+ public class Buffer
+ {
+ private byte[] data;
+ private int size;
+
+ public static Buffer Allocate(int bytes)
+ {
+ Buffer buffer = new Buffer(bytes);
+ return buffer;
+ }
+
+ private Buffer(int bytes)
+ {
+ this.data = new byte[bytes];
+ this.size = 0;
+ }
+
+ public byte[] Data
+ {
+ get { return data; }
+ }
+
+ public int Size
+ {
+ get { return size; }
+ }
+
+ public int Prepare(int bytes)
+ {
+ if (size + bytes > data.Length) {
+ byte[] dst = new byte[data.Length * 2];
+ Array.Copy(data, dst, size);
+ data = dst;
+ }
+ return size;
+ }
+
+ public void Save(int bytes)
+ {
+ if (size + bytes + 2 <= data.Length) {
+ size += bytes;
+ data[size++] = (byte)'\r';
+ data[size++] = (byte)'\n';
+ }
+ else {
+ throw new Exception("Overflow");
+ }
+ }
+
+ public void Release()
+ {
+ data = null;
+ size = 0;
+ }
+ }
+
+
+
+ public class EmailClientError : ApplicationException {}
+
+ //Baically, instantiating this class
+ //goes through the state machine with the server
+ public class EmailClient
+ {
+ [Conditional("SMTPAGENT_VERBOSE")]
+ public static void DebugWriteLine(string format)
+ {
+ DebugStub.WriteLine(format);
+ }
+
+ [Conditional("SMTPAGENT_VERBOSE")]
+ public static void DebugWriteLine(string format, __arglist)
+ {
+ DebugStub.WriteLine(format, new ArgIterator(__arglist));
+ }
+
+ private static void DumpEmail(string[] email)
+ {
+ DebugStub.WriteLine("Dumping email...\n");
+ foreach(string line in email) {
+ DebugStub.WriteLine("{0}", __arglist(line));
+ }
+ }
+
+ //client side state machine
+ private enum ReceivedState {
+ RECEIVED_NONE = 0,
+ RECEIVED_220 = 1,
+ RECEIVED_250 = 2,
+ RECEIVED_354 = 3,
+ }
+
+ private enum SentState {
+ SENT_NONE = 0,
+ SENT_EHLO = 1,
+ SENT_NOOP = 2,
+ SENT_MAIL = 3,
+ BEGAN_RCPT = 4,
+ FINISHED_RCPT = 5,
+ BEGAN_DATA = 6,
+ FINISHED_DATA = 7,
+ };
+
+
+ private string[][] corpus;
+ private int nxtEmail;
+ private string[] emailContents;
+ private int dataIndex;
+ private ReceivedState rcvState;
+ private SentState sentState;
+ private int rcptIndex;
+ private string[] rcpts;
+
+ private static string GetCommand(String line)
+ {
+ int len = line.Length;
+ int i;
+ for (i = 0; i < len && line[i] >= '0' && line[i] <= '9'; i++);
+
+ return line.Substring(0, i);
+ }
+
+ [NotDelayed]
+ public EmailClient(String[][] corpus, int startIndex)
+ {
+
+ this.corpus = corpus;
+ this.nxtEmail = startIndex;
+ DebugStub.WriteLine("Email client starting up startindex {0}\n", __arglist(startIndex));
+ DebugStub.WriteLine("corpus length is {0}\n", __arglist(corpus.Length));
+
+ rcvState = ReceivedState.RECEIVED_NONE;
+ sentState = SentState.SENT_NONE;
+
+ emailContents = corpus[nxtEmail];
+ nxtEmail++;
+ if (nxtEmail == corpus.Length) {
+ nxtEmail = 0;
+ }
+ }
+
+ //Command from SMTP server to client
+ //Advances state machine
+ public void SendLine(string line)
+ {
+ DebugWriteLine("EmailClient.SendLine received {0}\n", __arglist(line));
+ String command = GetCommand(line);
+
+ switch(command) {
+ case "220":
+ if (rcvState == ReceivedState.RECEIVED_NONE) {
+ DebugWriteLine("EmailClient received 220 in correct state\n");
+ rcvState = ReceivedState.RECEIVED_220;
+ return;
+ }
+ DebugStub.WriteLine("EmailClient recieved 220 while in state {0}\n",
+ __arglist(rcvState));
+ DebugStub.Break();
+ throw new EmailClientError();
+ break;
+ case "250":
+ DebugWriteLine("EmailClient received 250\n");
+ rcvState = ReceivedState.RECEIVED_250;
+ break;
+ case "354":
+ DebugWriteLine("EmailClient received 354\n");
+ rcvState = ReceivedState.RECEIVED_354;
+ break;
+ case "501":
+ DebugWriteLine("Uhoh! received 501\n");
+ DebugStub.Break();
+ break;
+ default:
+ DebugStub.WriteLine("Got unexpected command {0}\n", __arglist(command));
+ DebugStub.Break();
+ break;
+ }
+ }
+
+ //Get line from client to server
+ public string GetLine()
+ {
+ switch(sentState) {
+ case SentState.SENT_NONE:
+ DebugWriteLine("EmailClient GetLine while in state SENT_NONE\n");
+ string result = "EHLO Nobody\r\n";
+ sentState = SentState.SENT_EHLO;
+ rcvState = 0;
+ return result;
+ break;
+
+ case SentState.SENT_EHLO:
+ if (rcvState != ReceivedState.RECEIVED_250) {
+ break;
+ }
+ DebugWriteLine("GetLine while in state SENT_EHLO...sending MAIL\n");
+
+ sentState = SentState.SENT_MAIL;
+ rcvState = 0;
+ rcptIndex = 0;
+ string from = FindFrom(emailContents).ToLower();
+ return "MAIL FROM: <" + from + ">\r\n";
+ break;
+
+ case SentState.SENT_MAIL:
+ DebugWriteLine("GetLine while in state SENT_MAIL...sending RCPT\n");
+ if (rcvState != ReceivedState.RECEIVED_250) {
+ break;
+ }
+ string to = FindTo("To: ", emailContents);
+ string cc = FindTo("Cc: ", emailContents);
+ string bcc = FindTo("Bcc: ", emailContents);
+ if (to == null) {
+ to = cc;
+ cc = null;
+ }
+ if (to == null) {
+ to = bcc;
+ bcc = null;
+ }
+
+ if (cc != null) {
+ to = to + "," + cc;
+ }
+ if (bcc != null) {
+ to = to + "," + bcc;
+ }
+
+
+ if (to == null || to.Length == 0) {
+ //Sometimes the "to" is blank with no cc or bcc because of
+ //an interoffice dl?
+ to = "mail_forward@enron.com";
+#if false
+ DebugStub.WriteLine(":: Couldn't find receipients.");
+ DumpEmail(emailContents);
+ DebugStub.Break();
+ throw new EmailClientError();
+#endif
+ }
+
+ rcpts = to.Split(new Char[]{','});
+ for (int i = 0; i < rcpts.Length; i++) {
+ rcpts[i] = rcpts[i].Trim().ToLower();
+ if (rcpts[i].Length == 0) {
+ rcpts[i] = null;
+ }
+ }
+
+ for (int i = 0; i < rcpts.Length; i++) {
+ for (int j = i + 1; j < rcpts.Length; j++) {
+ if (rcpts[i] == rcpts[j]) {
+ rcpts[j] = null;
+ }
+ }
+ }
+ rcvState = 0;
+
+ string rcpt = "RCPT TO: <" + rcpts[rcptIndex] + ">\r\n";
+ rcptIndex++;
+ if (rcptIndex == rcpts.Length) {
+ sentState = SentState.FINISHED_RCPT;
+ }
+ else {
+ sentState = SentState.BEGAN_RCPT;
+ }
+ return rcpt;
+ break;
+
+ case SentState.BEGAN_RCPT:
+ DebugWriteLine("GetLine while in state BEGAN_RCPT...sending RCPT\n");
+ if (rcvState != ReceivedState.RECEIVED_250) {
+ break;
+ }
+ rcpt = "RCPT TO: <" + rcpts[rcptIndex] + ">\r\n";
+ rcptIndex++;
+ rcvState = 0;
+ if (rcptIndex == rcpts.Length) {
+ sentState = SentState.FINISHED_RCPT;
+ }
+ else {
+ sentState = SentState.BEGAN_RCPT;
+ }
+ return rcpt;
+ break;
+
+ case SentState.FINISHED_RCPT:
+ DebugWriteLine("GetLine while in state FINISHED_RCPT...sending DATA\n");
+ if (rcvState != ReceivedState.RECEIVED_250) {
+ break;
+ }
+ string dataCommand = "DATA \r\n";
+ dataIndex = 0;
+ rcvState = 0;
+ sentState = SentState.BEGAN_DATA;
+ return dataCommand;
+ break;
+
+ case SentState.BEGAN_DATA:
+ DebugWriteLine("GetLine while in state BEGAN_DATA...sending DATA\n");
+ if (rcvState != ReceivedState.RECEIVED_354) {
+ break;
+ }
+ string data;
+ if (dataIndex == emailContents.Length) {
+ DebugWriteLine("Completed reading email...sending .\n");
+ data = ".";
+ sentState = SentState.SENT_EHLO;
+ rcvState = 0;
+
+ emailContents = corpus[nxtEmail];
+ if(emailContents == null) {
+ DebugStub.WriteLine("null email! nxtEmail {0}\n", __arglist(nxtEmail));
+ DebugStub.Break();
+ }
+ nxtEmail++;
+ if (nxtEmail == corpus.Length) {
+ nxtEmail = 0;
+ }
+
+ }
+ else {
+ data = emailContents[dataIndex];
+ if ((data.Length == 1) && data[0] == '.') {
+ //prepend another . to avoid false positives that this is the last line
+ data = "." + data;
+ }
+ dataIndex++;
+ //DebugWriteLine("Got {0}\n", __arglist(data));
+ }
+ return data;
+ break;
+ default:
+ DebugStub.WriteLine("In unexpected state {0}\n", __arglist(sentState));
+ DebugStub.Break();
+ break;
+ }
+ DebugStub.WriteLine("EmailClient GetLine in state {0} never got 250\n", __arglist(sentState));
+ DumpEmail(emailContents);
+ throw new EmailClientError();
+ }
+
+
+ public static String FindFrom(String[] lines)
+ {
+ foreach (string line in lines) {
+ if (line.Length == 0) {
+ return null; // Header ended.
+ }
+ if (line.StartsWith("From: ")) {
+ return line.Substring(6);
+ }
+ }
+ return null;
+ }
+
+ public static string FindTo(String prefix, String[] lines)
+ {
+ for (int i = 0; i < lines.Length; i++) {
+ if (lines[i].Length == 0) {
+ return null; // Header ended.
+ }
+ if (lines[i].StartsWith(prefix)) {
+ string to = lines[i++].Substring(prefix.Length);
+ while (lines[i].Length > 0 && (lines[i][0] == ' ' || lines[i][0] == '\t')) {
+ to = to + lines[i++];
+ }
+ return to;
+ }
+ }
+ return null;
+ }
+ }
+
+ public class ServerSession
+ {
+ private static int idCount = 0;
+ private int id;
+ private string command;
+ private string server;
+ private EmailClient emailClient;
+ private long emailLimit;
+
+ [Conditional("SMTPAGENT_VERBOSE")]
+ public static void DebugWriteLine(string format)
+ {
+ DebugStub.WriteLine(format);
+ }
+
+ [Conditional("SMTPAGENT_VERBOSE")]
+ public static void DebugWriteLine(string format, __arglist)
+ {
+ DebugStub.WriteLine(format, new ArgIterator(__arglist));
+ }
+
+ public ServerSession(string[][] corpus, long limit, int startIndex)
+ {
+ this.emailClient = new EmailClient(corpus, startIndex);
+ this.id = idCount++;
+ this.server = "0.0.0.0";
+ this.emailLimit = limit;
+ }
+
+ public string GetCommand(String line)
+ {
+ int i = line.IndexOf(' ');
+ if (i < 0) {
+ command = line;
+ return null;
+ }
+ command = line.Substring(0, i).ToUpper();
+ return command;
+ }
+
+ private enum CurrentState {
+ HAD_NONE = 0,
+ HAD_HELO = 1,
+ HAD_MAIL = 2,
+ HAD_RCPT = 3,
+ };
+
+ public void Loop()
+ {
+ String client;
+ String line;
+ CurrentState cstate = CurrentState.HAD_NONE;
+ String from = null;
+ String to = null;
+
+ //Open a new connection to the mailstore for each smtp connection.
+ //Each client connection stays allive until all emails are sent.
+
+ DirectoryServiceContract.Imp! dsImp = SmtpServer.dsEp.Acquire();
+
+ MailStoreContract.Imp! msImp;
+ MailStoreContract.Exp! msExp;
+ MailStoreContract.NewChannel(out msImp, out msExp);
+
+ ErrorCode errorCode;
+ if (!SdsUtils.Bind(SmtpServer.mailstorePath, dsImp, msExp, out errorCode)) {
+ DebugWriteLine("Failed to bind to mail store...error {0}\n",
+ __arglist(SdsUtils.ErrorCodeToString(errorCode)));
+ Console.WriteLine("Failed to bind to mail store...error {0}\n",
+ SdsUtils.ErrorCodeToString(errorCode));
+
+ DebugStub.Break();
+ SmtpServer.dsEp.Release(dsImp);
+ delete msImp;
+ return;
+ }
+ SmtpServer.dsEp.Release(dsImp);
+
+ msImp.RecvMailStoreReady();
+
+ emailClient.SendLine("220 " + server + " Singularity Simple SMTP Service Ready");
+
+ long numReceived = 0;
+ bool abort = false;
+ DateTime beginEpoch = DateTime.Now;
+ DateTime endEpoch;
+
+ while (!abort) {
+ line = emailClient.GetLine();
+ if (line == null) {
+ break;
+ }
+
+ GetCommand(line);
+
+ switch (command) {
+ case "EHLO":
+ client = line.Split(new Char[] {' '})[1];
+ Console.WriteLine(":{0}: EHLO {1}", id, client);
+
+ emailClient.SendLine("250-" + server + " greets " + client);
+ emailClient.SendLine("250-8BITMIME");
+ emailClient.SendLine("250 HELP");
+ from = null;
+ to = null;
+ cstate = CurrentState.HAD_HELO;
+ DebugWriteLine("SMTPServer: Got EHLO\n");
+ break;
+
+ case "HELO":
+ client = line.Split(new Char[] {' '})[1];
+ Console.WriteLine(":{0}: HELO {1}", id, client);
+ emailClient.SendLine("250 " + server + " greets " + client);
+ from = null;
+ to = null;
+ cstate = CurrentState.HAD_HELO;
+ DebugWriteLine("SMTPServer: Got HELO\n");
+ break;
+
+ case "MAIL":
+ if (cstate != CurrentState.HAD_HELO) {
+ goto default;
+ }
+
+ if (line.StartsWith("MAIL FROM:")) {
+ int pos = line.IndexOf("<") + 1;
+ int beg = line.LastIndexOf(':');
+ if (beg < pos) {
+ beg = pos;
+ }
+ int end = line.IndexOf('>');
+ from = line.Substring(beg, end - beg).ToLower();
+ emailClient.SendLine("250 OK");
+ cstate = CurrentState.HAD_MAIL;
+ DebugWriteLine("SMTPServer: Got MAIL from: {0}\n", __arglist(from));
+ }
+ else {
+ emailClient.SendLine("501 Syntax error in parameters");
+ }
+ break;
+
+ case "RCPT":
+ if (cstate != CurrentState.HAD_MAIL && cstate != CurrentState.HAD_RCPT) {
+ goto default;
+ }
+ DebugWriteLine("Got RCPT\n");
+ if (line.StartsWith("RCPT TO:")) {
+ int pos = line.IndexOf("<") + 1;
+ int beg = line.LastIndexOf(':');
+ if (beg < pos) {
+ beg = pos;
+ }
+ int end = line.IndexOf('>');
+ string address = line.Substring(beg, end - beg).ToLower();
+
+ if (SmtpServer.addresses.ContainsKey(address)) {
+ emailClient.SendLine("250 OK");
+ if (to != null) {
+ to = to + ";" + address;
+ }
+ else {
+ to = address;
+ }
+ cstate = CurrentState.HAD_RCPT;
+ }
+ else {
+ emailClient.SendLine("250 Accepting for forwarding.");
+ cstate = CurrentState.HAD_RCPT;
+ if (to != null) {
+ to = to + ";" + "mail_forward@enron.com";
+ }
+ else {
+ to = "mail_forward@enron.com";
+ }
+ }
+ DebugWriteLine("Got address to: {0}\n", __arglist(to));
+ }
+ else {
+ emailClient.SendLine("501 Syntax error in parameters");
+ }
+ break;
+
+ case "DATA":
+ if (cstate != CurrentState.HAD_RCPT) {
+ goto default;
+ }
+ DebugWriteLine("Got DATA\n");
+ emailClient.SendLine("354 Start mail input; end with .");
+
+ Buffer buffer = Buffer.Allocate(65536);
+ bool good = false;
+
+ for (;;) {
+ int off = buffer.Prepare(1024);
+ string buffLine = emailClient.GetLine();
+ int len = buffLine.Length;
+ Encoding.ASCII.GetBytes(buffLine, 0, len, buffer.Data, off);
+
+ if (len < 0) {
+ break;
+ }
+
+ if (len == 1 && buffer.Data[off] == '.') {
+ DebugWriteLine("Got final . char\n");
+ good = true;
+ break;
+ }
+ else {
+ DebugWriteLine("S: {0}",
+ __arglist(Encoding.ASCII.GetString(buffer.Data, off, len)));
+ buffer.Save(len);
+ }
+ }
+
+ if (good) {
+ bool succeeded = false;
+ char[] in ExHeap! addresses = Bitter.FromString(to);
+ byte[] in ExHeap! data
+ = Bitter.FromByteArray(buffer.Data, 0, buffer.Size);
+
+ // Console.WriteLine("SmtpAgaint: Email from {0} to {1}", from, to);
+ msImp.SendSaveMessage(addresses, data);
+ switch receive
+ {
+ case msImp.SaveAck():
+ succeeded = true;
+ break;
+
+ case msImp.SaveNak(error):
+ Console.WriteLine("SmtpAgent: Server dropped email, "+
+ "error={0}", error);
+ break;
+
+ case msImp.ChannelClosed():
+ break;
+ }
+ if (succeeded) {
+ numReceived++;
+ if ((numReceived % 100) == 0) {
+ Console.Write(".");
+ }
+ emailClient.SendLine("250 OK");
+ }
+ else {
+ emailClient.SendLine("554 Transaction failed");
+ }
+ }
+ else {
+ emailClient.SendLine("554 Transaction failed");
+ // Dump();
+ throw new Exception("554 Transaction failed");
+ }
+
+ buffer.Release();
+ cstate = CurrentState.HAD_HELO;
+ from = null;
+ to = null;
+ if (numReceived == emailLimit) {
+ abort = true;
+ }
+
+ break;
+
+ case "NOOP":
+ emailClient.SendLine("250 OK");
+ break;
+
+ case "HELP":
+ emailClient.SendLine("250 OK");
+ break;
+
+ case "RSET":
+ emailClient.SendLine("250 OK");
+ from = null;
+ to = null;
+ cstate = CurrentState.HAD_HELO;
+ break;
+
+ case "QUIT":
+ emailClient.SendLine("221 " + server + " Service closing transmission channel");
+ abort = true;
+ break;
+
+ default:
+ emailClient.SendLine("503 Unrecognized command [" + command + "]");
+ abort = true;
+ break;
+ }
+ }
+ endEpoch = DateTime.Now;
+ Console.WriteLine(":{0}: Session closed", id);
+ TimeSpan delta = endEpoch - beginEpoch;
+ if (delta.TotalSeconds > 0) {
+ Console.WriteLine(
+ "\nDuration(s:ms) {0:f2} emails {1} rate() {2:e3} eps",
+ delta.TotalSeconds,
+ emailLimit,
+ emailLimit/ delta.TotalSeconds
+ );
+ }
+ if (delta.TotalMilliseconds == 0) {
+ Console.WriteLine("Too fast! < 1 milliseconds to run\n");
+ }
+ else {
+ Console.WriteLine("Duration ms {0:f2} rate {1:f2} epms {2:e3} eps\n",
+ delta.TotalMilliseconds,
+ (float) ((float)emailLimit / delta.TotalMilliseconds),
+ emailLimit / (delta.TotalMilliseconds / 1000)
+ );
+ }
+ delete msImp;
+ }
+ }
+
+ public class SmtpServer
+ {
+ public static String[][] corpus;
+ public static int numCorpusEmails = 12754;
+ public static int[] startPos;
+ public const int _port = 25;
+ public static bool verbose;
+
+ public static TRef dsEp;
+
+ public static SortedList addresses;
+ public static string mailstorePath;
+
+ [Conditional("SMTPAGENT_VERBOSE")]
+ public static void DebugWriteLine(string format)
+ {
+ DebugStub.WriteLine(format);
+ }
+
+ [Conditional("SMTPAGENT_VERBOSE")]
+ public static void DebugWriteLine(string format, __arglist)
+ {
+ DebugStub.WriteLine(format, new ArgIterator(__arglist));
+ }
+
+
+ //replicating c# Array.Resize that does not appear to be available
+ //in singularity.
+ private static void Resize(ref string[] oldString, int newSize)
+ {
+ if(newSize < 0) {
+ DebugStub.WriteLine("Resize size < 0!!\n");
+ DebugStub.Break();
+ throw new EmailClientError();
+ }
+
+ string[] newString = new string[newSize];
+ int length;
+ if (oldString.Length < newSize) {
+ length = oldString.Length;
+ }
+ else {
+ length = newSize;
+ }
+
+ for(int i = 0; i < length; i++) {
+ newString[i] = oldString[i];
+ }
+
+ oldString = newString;
+ }
+
+ public static void GenerateCorpus(string path, long numberEmails)
+ {
+ DebugWriteLine("Reading test corpus at path {0}\n", __arglist(path));
+ FileStream fsInput = new FileStream(path, FileMode.Open, FileAccess.Read);
+ StreamReader reader = new StreamReader(fsInput);
+
+ corpus = new string[numCorpusEmails][];
+
+ int arrSize;
+ int numLines;
+ string line;
+ string[] emailContents;
+ //XXX currently we hard code the size of the corpus into the app
+ //we do this because we have generated a list of random
+ //starting positions for each connection that is built against
+ //the corpus...
+ for(int i = 0; i < numCorpusEmails; i++) {
+ arrSize = 1024;
+ emailContents = new string[arrSize];
+ numLines = 0;
+ while((line = reader.ReadLine()) != null) {
+ if (line.Equals("DEADBEEFDEADBEEFDEADBEEF")) {
+ break;
+ }
+ if (numLines == arrSize) {
+ arrSize = arrSize * 2;
+ Resize(ref emailContents, arrSize);
+ }
+ emailContents[numLines] = line;
+ numLines++;
+ }
+ if(line == null) {
+ DebugStub.WriteLine("line null!\n");
+ if (numLines == 0 || numLines == 1) {
+ DebugStub.WriteLine("numlines {0}\n", __arglist(numLines));
+ DebugStub.Break();
+ }
+ }
+ Resize(ref emailContents, numLines);
+ corpus[i] = emailContents;
+#if false
+ DebugStub.WriteLine("Parsed email {0} contents:\n", __arglist(i));
+ foreach (string newline in emailContents) {
+ DebugStub.WriteLine("line {0}\n", __arglist(newline));
+ }
+#endif
+ }
+ reader.Close();
+ DebugStub.WriteLine("Generate corpus complete\n");
+ }
+
+ private static int StringToInt(string line)
+ {
+ int result = 0;
+ for (int i = 0; i < line.Length && line[i] >= '0' && line[i] <= '9'; i++) {
+ result = result * 10 + (line[i] - '0');
+ }
+
+ return result;
+ }
+
+
+ public static void GenerateStartPositions(string path, long numConn)
+ {
+ DebugWriteLine("Reading test corpus at path {0}\n", __arglist(path));
+ startPos = new int[100];
+
+ FileStream fsInput = new FileStream(path, FileMode.Open, FileAccess.Read);
+ StreamReader reader = new StreamReader(fsInput);
+
+ int cnt = 0;
+ string line;
+ while((line = reader.ReadLine()) != null) {
+ startPos[cnt] = StringToInt(line);
+ if (startPos[cnt] < 0) {
+ DebugStub.Break();
+ }
+ cnt++;
+ }
+ }
+
+ internal static int AppMain(Parameters! config)
+ {
+ string server = config.server;
+ if (server[0] >= '0' && server[0] <= '9') {
+ server = "[" + server + "]";
+ }
+ if (config.numConn < 1 || config.numConn > 100) {
+ Console.WriteLine("numConn must be between [1...100]\n");
+ return -1;
+ }
+
+ // Connect to the MailStore.
+ Console.WriteLine("SmtpAgent: Connecting to MailStore.");
+ DirectoryServiceContract.Imp! dsImp = config.nsRef.Acquire();
+ dsImp.RecvSuccess();
+
+ MailStoreContract.Imp! msImp;
+ MailStoreContract.Exp! msExp;
+ MailStoreContract.NewChannel(out msImp, out msExp);
+
+ mailstorePath = config.mailstorePath;
+
+ ErrorCode error;
+ if (!SdsUtils.Bind(config.mailstorePath, dsImp, msExp, out error)) {
+ DebugStub.WriteLine("Failed to bind to mail store...error {0}\n",
+ __arglist(SdsUtils.ErrorCodeToString(error)));
+ Console.WriteLine("Failed to bind to mail store...error {0}\n",
+ SdsUtils.ErrorCodeToString(error));
+
+ delete dsImp;
+ delete msImp;
+ return -1;
+ }
+
+ msImp.RecvMailStoreReady();
+
+ // Retrieve vaild address list.
+ char[] in ExHeap! buffer;
+ msImp.SendGetAddressList();
+ msImp.RecvGetAck(out buffer);
+ addresses = ReadUniqueList(Bitter.ToString(buffer));
+ delete buffer;
+
+ delete msImp;
+ // Save the endpoint.
+ dsEp = new TRef(dsImp);
+
+ GenerateCorpus(config.emailCorpus, config.numToSend);
+ GenerateStartPositions(config.startPositionsFile, config.numConn);
+ Console.WriteLine("SmtpAgent: Spawning {0} threads sending {1} emails per connection",
+ config.numConn, config.numToSend);
+
+ Thread[] workers = new Thread[config.numConn];
+ ServerSession[] conns = new ServerSession[config.numConn];
+
+ for(int i = 0; i < config.numConn; i++) {
+ conns[i] = new ServerSession(corpus, config.numToSend, startPos[i]);
+ workers[i] = new Thread(conns[i].Loop);
+ workers[i].Start();
+ }
+
+ for(int i = 0; i < config.numConn; i++) {
+ workers[i].Join();
+ }
+
+ // Close the Store engine.
+ dsImp = dsEp.Acquire();
+ if (dsImp != null) {
+ delete dsImp;
+ }
+
+ return 0;
+ }
+
+ public static string PopNextAddress(ref string content)
+ {
+ if (content.Length == 0) {
+ return null;
+ }
+
+ int i = content.IndexOf(';');
+ string ret = (i > 0) ? content.Substring(0, i) : content;
+ content = (i > 0) ? content.Substring(i + 1) : "";
+ return ret;
+ }
+
+ public static SortedList ReadUniqueList(string content)
+ {
+ SortedList list = new SortedList();
+ string address;
+
+ while ((address = PopNextAddress(ref content)) != null) {
+ if (!list.ContainsKey(address)) {
+ list.Add(address, address);
+ }
+ }
+ return list;
+ }
+ }
+}
+
+
diff --git a/base/Applications/Eventing/EvStress/EvStress.csproj b/base/Applications/Eventing/EvStress/EvStress.csproj
new file mode 100644
index 0000000..5a5b914
--- /dev/null
+++ b/base/Applications/Eventing/EvStress/EvStress.csproj
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+ EvStress
+ true
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Eventing/EvStress/EvStress.sg b/base/Applications/Eventing/EvStress/EvStress.sg
new file mode 100644
index 0000000..579df75
--- /dev/null
+++ b/base/Applications/Eventing/EvStress/EvStress.sg
@@ -0,0 +1,272 @@
+
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.V1.Services;
+
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.UnitTest;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Test.Contracts;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Eventing;
+using Microsoft.Singularity.TestEvent;
+
+namespace Microsoft.Singularity
+{
+
+ [TestClass]
+ public class EvStress : TestClass
+ {
+
+ internal class StressLauncher
+ {
+ static EvStress1 Log;
+ static uint Loops;
+ static int Threads;
+ static AutoResetEvent WaitEvent;
+
+ public StressLauncher( string testName,
+ uint storageSize,
+ uint storageOptions,
+ uint sourceOptions,
+ uint iterations)
+ {
+ Console.WriteLine("Launching stress {0}: StorageSize={1} bytes, StorageOptions={2:x}, SourceOptions={3:x}",
+ testName,
+ storageSize,
+ storageOptions,
+ sourceOptions);
+
+ Loops = iterations;
+
+ WaitEvent = new AutoResetEvent(false);
+
+ Log = EvStress1.Create(testName, storageSize, storageOptions, sourceOptions);
+ }
+
+ public static void ChildThread()
+ {
+ if (WaitEvent == null || Log == null) {
+
+ return;
+ }
+
+ for (int i = 0; i < Loops; i++) {
+
+ Log.Log(100);
+ }
+
+ if (Interlocked.Decrement(ref Threads) == 0) {
+
+ WaitEvent.Set();
+ }
+ }
+
+ public static void StartStress(int threads)
+ {
+ if (WaitEvent == null || Log == null) {
+
+ Console.WriteLine("Failed to allocate resources");
+ return;
+ }
+
+ Threads = threads;
+ Console.WriteLine("Stress started with {0} threads", Threads);
+
+ DateTime startTime = DateTime.Now;
+ for (uint i = 0; i < threads; i++) {
+
+ Thread peer = new Thread(new ThreadStart(ChildThread));
+
+ if (peer!= null) {
+
+ peer.Start();
+ } else {
+
+ WaitEvent.Set();
+ break;
+ }
+ }
+
+ WaitEvent.WaitOne();
+
+ DateTime endTime = DateTime.Now;
+ TimeSpan t = endTime-startTime;
+ Console.WriteLine("Test completed in {0} msec", t.TotalMilliseconds);
+ }
+
+ }
+
+
+
+ [ClassInitialize]
+ public void Init()
+ {
+ }
+
+ [TestMethod]
+ public void StressNoStacks4k()
+ {
+ StressLauncher stress1 = new StressLauncher("StressNoStacks4k",
+ 4096,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void StressNoStacks1M()
+ {
+ StressLauncher stress1 = new StressLauncher("StressNoStacks1M",
+ 1024*1024,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void StressStacks4k()
+ {
+ StressLauncher stress1 = new StressLauncher("StressStacks4k",
+ 4096,
+ QualityOfService.RecyclableEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void StressStacks1M()
+ {
+ StressLauncher stress1 = new StressLauncher("StressStacks1M",
+ 1024*1024,
+ QualityOfService.RecyclableEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void StressPermNoStacks4k()
+ {
+ StressLauncher stress1 = new StressLauncher("StressPermNoStacks4k",
+ 4096,
+ QualityOfService.PermanentEvents,
+ EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void StressPermNoStacks1M()
+ {
+ StressLauncher stress1 = new StressLauncher("StressPermNoStacks1M",
+ 1024*1024,
+ QualityOfService.PermanentEvents,
+ EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void StressPermStacks4k()
+ {
+ StressLauncher stress1 = new StressLauncher("StressPermStacks4k",
+ 4096,
+ QualityOfService.PermanentEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void StressPermStacks1M()
+ {
+ StressLauncher stress1 = new StressLauncher("StressPermStacks1M",
+ 1024*1024,
+ QualityOfService.PermanentEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK,
+ 1000000);
+ if (stress1 != null) {
+
+ for (int i = 1; i <= 16; i <<= 1) {
+
+ StressLauncher.StartStress(i);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void TestAll()
+ {
+ StressNoStacks4k();
+ StressNoStacks1M();
+ StressStacks4k();
+ StressStacks1M();
+
+ StressPermNoStacks4k();
+ StressPermNoStacks1M();
+ StressPermStacks4k();
+ StressPermStacks1M();
+ }
+ }
+}
+
+
diff --git a/base/Applications/Eventing/EvStress/EvStress.tst b/base/Applications/Eventing/EvStress/EvStress.tst
new file mode 100644
index 0000000..abb5b61
--- /dev/null
+++ b/base/Applications/Eventing/EvStress/EvStress.tst
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Eventing/EventActive/EventActive.csproj b/base/Applications/Eventing/EventActive/EventActive.csproj
new file mode 100644
index 0000000..30a000c
--- /dev/null
+++ b/base/Applications/Eventing/EventActive/EventActive.csproj
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ EventActive
+ true
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Eventing/EventActive/EventActive.sg b/base/Applications/Eventing/EventActive/EventActive.sg
new file mode 100644
index 0000000..1bbc367
--- /dev/null
+++ b/base/Applications/Eventing/EventActive/EventActive.sg
@@ -0,0 +1,142 @@
+
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Io;
+
+using Microsoft.Singularity.V1.Services;
+
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.UnitTest;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Test.Contracts;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Eventing;
+
+namespace Microsoft.Singularity
+{
+
+ [CLSCompliant(false)]
+ public class TestActiveCounter : ActiveSource
+ {
+
+ //[ActiveCounter=InterruptCounter, ArraySize=256]
+ public struct ActiveCounter
+ {
+
+ public int Hits;
+ public int Count;
+ }
+
+ // ???? CODEGEN from here
+
+ public static TestActiveCounter Create(string sourceName, int size)
+ {
+ TestActiveCounter Logger = new TestActiveCounter(sourceName, size, ENABLE_ALL_MASK);
+
+ if (Logger != null) {
+ Logger.Register();
+ }
+
+ return Logger;
+ }
+
+ internal ActiveCounter[] Buffer;
+
+ public override bool Register()
+ {
+ Buffer = new ActiveCounter[Count];
+
+ if (Buffer == null) {
+ return false;
+ }
+
+ assert HostController != null;
+
+ if (HostController.RegisterEvent("ActiveCounter",
+ "ActiveCounter: Hits={0}, Count={1}",
+ ref EventTypeHandle)) {
+
+ HostController.RegisterEventField(EventTypeHandle, "Hits", 0, DataType.__int);
+ HostController.RegisterEventField(EventTypeHandle, "Count", 0, DataType.__int);
+
+ } else {
+
+ // The event might have been registered already
+ // Check whether we foundit already in the table or not
+
+ if (EventTypeHandle == 0) {
+ return false;
+ }
+ }
+
+ unsafe {
+
+ fixed (void * ptr = &Buffer[0]) {
+
+ DebugBufferAddress = (UIntPtr)ptr;
+ }
+ }
+
+ // After all internal fields are setup, we can go ahead and register with the controller
+
+ if (!base.Register()) {
+
+ return false;
+ }
+
+ return true;
+ }
+
+ TestActiveCounter(string sourceName, int size, uint controlFlags)
+ :base(sourceName, size, controlFlags)
+ {
+ unsafe {
+ EntrySize = (ushort)sizeof(ActiveCounter);
+ }
+ }
+ }
+
+ [TestClass]
+ public class EventActive : TestClass
+ {
+
+ [ClassInitialize]
+ public void Init()
+ {
+ }
+
+ [TestMethod]
+ public void SimpleActiveCounterTest()
+ {
+ TestActiveCounter activeCounter = TestActiveCounter.Create("TestActiveCounter1", 256);
+
+ if (activeCounter != null) {
+ assert activeCounter.Buffer != null;
+ for (int i = 0; i < 256; i++) {
+ activeCounter.Buffer[i].Hits += 1;
+ activeCounter.Buffer[i].Count = i;
+ }
+ }
+ }
+
+ [TestMethod]
+ public void TestAll()
+ {
+ SimpleActiveCounterTest();
+ }
+ }
+}
+
+
diff --git a/base/Applications/Eventing/EventActive/EventActive.tst b/base/Applications/Eventing/EventActive/EventActive.tst
new file mode 100644
index 0000000..9ce564e
--- /dev/null
+++ b/base/Applications/Eventing/EventActive/EventActive.tst
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Eventing/EventTest/Event.tst b/base/Applications/Eventing/EventTest/Event.tst
new file mode 100644
index 0000000..0f0caf4
--- /dev/null
+++ b/base/Applications/Eventing/EventTest/Event.tst
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/base/Applications/Eventing/EventTest/EventTest.csproj b/base/Applications/Eventing/EventTest/EventTest.csproj
new file mode 100644
index 0000000..25a61ea
--- /dev/null
+++ b/base/Applications/Eventing/EventTest/EventTest.csproj
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ EventTest
+ true
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Eventing/EventTest/EventTest.sg b/base/Applications/Eventing/EventTest/EventTest.sg
new file mode 100644
index 0000000..d806f57
--- /dev/null
+++ b/base/Applications/Eventing/EventTest/EventTest.sg
@@ -0,0 +1,926 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.V1.Services;
+
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.UnitTest;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Test.Contracts;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Eventing;
+using Microsoft.Singularity.TestEvent;
+
+namespace Microsoft.Singularity
+{
+
+ [TestClass]
+ public class EventTest : TestClass
+ {
+ uint Loops = 1000;
+
+ // needed to workaround Phoenix MSIL/PDB reader bug
+ public EventTest()
+ {
+ }
+
+ [ClassInitialize]
+ public void Init()
+ {
+ DetermineLoopCount();
+ }
+
+
+ internal TimeSpan LogEntryLoop(TestEv Log, ref uint succeeded)
+ {
+ succeeded = 0;
+ DateTime startTime = DateTime.Now;
+ //DebugStub.Break();
+ if (Log != null) {
+
+ for (int i = 0; i < Loops; i++) {
+ if (Log.Log(i)) {
+ succeeded += 1;
+ }
+ }
+ }
+ DateTime endTime = DateTime.Now;
+ TimeSpan t = endTime-startTime;
+ return t;
+ }
+
+ internal void DetermineLoopCount()
+ {
+
+ TestEv Log;
+ uint succeeded = 0;
+
+ Console.WriteLine("Determining the number of iterations");
+
+ Log = TestEv.Create("Test calibration",
+ 64*1024,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK);
+
+ if (Log == null) {
+
+ Console.WriteLine("Failure to create test", DateTime.Now);
+ return;
+ }
+
+ TimeSpan t;
+ do {
+
+ Loops *= 10;
+ t = LogEntryLoop(Log, ref succeeded);
+ Console.WriteLine("Loop of {0} completed in {1} msec", Loops, t.TotalMilliseconds);
+
+ } while (t.TotalMilliseconds < 1000);
+
+ Console.WriteLine("Calibration completed. Tests will perform {0} operations",Loops);
+
+ }
+
+ internal class QueryContext : EnumerationContext{
+
+ public Int32 PreviousValue = -1;
+ public int Count = 0;
+ public bool Forward;
+
+ public QueryContext(bool forward)
+ {
+ Forward = forward;
+ }
+ }
+
+ static internal bool fieldDelegate(FieldDescriptor fieldDescriptor,
+ object obj,
+ ref EnumerationContext context)
+ {
+ if ((fieldDescriptor != null) && (obj != null)) {
+
+ Console.WriteLine(" {0}:{1}:{2} = {3}",
+ fieldDescriptor.Offset,
+ fieldDescriptor.GetTypeName(),
+ fieldDescriptor.Name,
+ obj.ToString());
+ }
+
+ return true;
+ }
+
+
+ static internal bool EntryDelegate(EventDescriptor currentEntry,
+ QueryBuffer buffer,
+ ref EnumerationContext context)
+ {
+
+ QueryContext ctx = context as QueryContext;
+
+ if (ctx == null) {
+
+ Console.WriteLine("Invalid context received");
+ DebugStub.Break();
+ return true;
+ }
+
+
+ object o = null;
+
+ if ((currentEntry != null) && (buffer != null)) {
+
+ o = currentEntry.GetProperty(buffer, "EventId");
+ }
+
+ if (o == null) {
+
+ Console.WriteLine("Invalid property read");
+ DebugStub.Break();
+ return true;
+ }
+
+ Int32 value = (Int32)o;
+
+ ctx.Count += 1;
+
+ if (ctx.PreviousValue != -1) {
+
+ if (ctx.Forward) {
+
+ if (ctx.PreviousValue != (value - 1)) {
+
+ Console.WriteLine("Invalid sequence {0} != {1}", ctx.PreviousValue, (value - 1));
+ DebugStub.Break();
+ }
+
+ } else {
+
+ if (ctx.PreviousValue != (value + 1)) {
+
+ Console.WriteLine("Invalid sequence {0} != {1}", ctx.PreviousValue, (value + 1));
+ DebugStub.Break();
+ }
+ }
+ }
+
+ ctx.PreviousValue = value;
+ return true;
+ }
+
+ internal void TestQuery(TestEv Log, bool forward)
+ {
+ if ((Log != null) && (Log.Storage != null)) {
+
+ QuerySession query = new QuerySession();
+
+ QueryContext context = new QueryContext(forward);
+ EnumerationContext enumContext = context;
+
+
+ if ((query != null) && (context != null) &&
+ query.Initialize(Log.Storage, forward)) {
+
+ query.EnumerateEntries(new QueryEntryDelegate(EntryDelegate),
+ ref enumContext);
+ }
+ Console.WriteLine("Enumeration returned {0} entries. Last value = {1}",
+ context.Count,
+ context.PreviousValue);
+ }
+
+ }
+
+ internal bool TestQueryLimit(TestEv Log, UIntPtr queryHandle, bool forward, int limit)
+ {
+ if ((Log != null) && (Log.Storage != null)) {
+#if TEST_QUERY
+ QuerySession query = new QuerySession();
+
+ if ((query != null) && query.Initialize(Log.Storage, forward)) {
+
+ query.EnumerateEntries(new QueryEntryDelegate(EntryDelegate));
+ }
+
+
+ int value = 0;
+ unsafe {
+
+ UIntPtr type;
+ ulong timeStamp;
+ ushort size;
+ byte [] memoryBuffer = new byte[256];
+
+ UIntPtr entryHandle;
+
+ fixed(byte * buffer = &memoryBuffer[0]) {
+
+ entryHandle = Log.Storage.QueryNextEntry(queryHandle,
+ &type,
+ &timeStamp,
+ &size,
+ buffer,
+ 256);
+
+ value = *((int *)buffer);
+ }
+
+ if (entryHandle != 0) {
+
+ if (forward) {
+
+ } else {
+
+ // Check for the invariant on walking the entries
+ // backward. We should not see any of the new entries
+ // after we started the query
+
+ if (value > limit) {
+
+ Console.WriteLine("Invalid entry {0} != {1}", value, limit);
+ DebugStub.Break();
+ }
+
+ }
+
+ return true;
+
+ } else {
+
+ return false;
+ }
+ }
+#endif // TEST_QUERY
+ }
+
+ return false;
+ }
+
+ internal TimeSpan LogQueryEntryLoop(TestEv Log,
+ uint loops,
+ uint queryStep,
+ bool forward,
+ ref uint succeeded, ref uint queried)
+ {
+ succeeded = 0;
+ DateTime startTime = DateTime.Now;
+ UIntPtr queryHandle = 0;
+ queried = 0;
+ if (Log != null) {
+
+ for (int i = 0; i < loops; i++) {
+
+ if (Log.Log(i)) {
+
+ succeeded += 1;
+ }
+
+ if (i == queryStep) {
+
+ // Start query at this point in log. Verify the consistency of entries
+ // as we add more items to the log
+
+ if (Log.Storage != null) {
+
+ queryHandle = Log.Storage.CreateQueryView(forward);
+ }
+ }
+
+ if (queryHandle != 0) {
+
+ if (TestQueryLimit(Log, queryHandle, forward, (int)queryStep)) {
+
+ queried += 1;
+ }
+ }
+ }
+ }
+ DateTime endTime = DateTime.Now;
+ TimeSpan t = endTime-startTime;
+
+ if (queryHandle != 0) {
+
+ if ((Log != null) && (Log.Storage != null)) {
+ Log.Storage.DeleteQueryView(queryHandle);
+ }
+ }
+
+ return t;
+ }
+
+
+ internal TimeSpan TestQueryPermutations(string testName,
+ uint storageSize,
+ uint storageOptions,
+ uint sourceOptions,
+ uint loopCount,
+ uint queryStep,
+ bool forward,
+ uint wrapThreshold)
+ {
+
+ TestEv Log;
+ uint succeeded = 0;
+ uint queried = 0;
+ bool errorOccured;
+ TimeSpan t;
+
+ do {
+
+ errorOccured = false;
+
+ Log = TestEv.Create(testName, storageSize, storageOptions, sourceOptions);
+
+ if (Log == null) {
+
+ Console.WriteLine("Failure to create test");
+ return TimeSpan.Zero;
+ }
+
+ t = LogQueryEntryLoop(Log,
+ loopCount,
+ queryStep,
+ forward,
+ ref succeeded,
+ ref queried);
+
+ if (succeeded != loopCount) {
+
+ Console.WriteLine("Failure to log entries. {0} succeeded instead of {1}",
+ succeeded,
+ loopCount);
+ errorOccured = true;
+ DebugStub.Break();
+ }
+
+ if (forward) {
+
+ if ((queried == 0) && (queryStep != loopCount)) {
+
+ Console.WriteLine("Invalid test invariant: Step = {0}, Queried = {1}, Loops = {2}",
+ queryStep,
+ queried,
+ loopCount);
+ errorOccured = true;
+ DebugStub.Break();
+
+ }
+
+ } else {
+
+ if (((queryStep + queried) != loopCount)
+ &&
+ ((queryStep + 1) != queried)
+ &&
+ (loopCount < wrapThreshold)) {
+
+ Console.WriteLine("Invalid test invariant: Step = {0}, Queried = {1}, Loops = {2}",
+ queryStep,
+ queried,
+ loopCount);
+ errorOccured = true;
+ DebugStub.Break();
+ }
+ }
+
+ if (errorOccured) {
+
+ if (t.TotalMilliseconds != 0) {
+
+ Console.WriteLine("Succeeded = {0}. Queried = {1}. Elapsed time {2} msec. Rate = {3} KOps/sec\n",
+ succeeded,
+ queried,
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+ } else {
+
+ Console.WriteLine("Succeeded = {0}. Queried = {1}. Elapsed time {2} msec\n",
+ succeeded,
+ queried,
+ t.TotalMilliseconds);
+ }
+ }
+
+ } while (errorOccured);
+
+ return t;
+
+ }
+
+
+
+ internal TimeSpan TestLoop(string testName, uint storageSize, uint storageOptions, uint sourceOptions)
+ {
+
+ TestEv Log;
+ uint succeeded = 0;
+
+ Console.WriteLine("Test {0}: StorageSize={1} bytes, StorageOptions={2:x}, SourceOptions={3:x}",
+ testName,
+ storageSize,
+ storageOptions,
+ sourceOptions);
+
+ Log = TestEv.Create(testName, storageSize, storageOptions, sourceOptions);
+
+ if (Log == null) {
+
+ Console.WriteLine("Failure to create test");
+ return TimeSpan.Zero;
+ }
+
+ TimeSpan t = LogEntryLoop(Log, ref succeeded);
+
+ if (t.TotalMilliseconds != 0) {
+
+ Console.WriteLine("Succeeded = {0}. Elapsed time {1} msec. Rate = {2} KOps/sec\n",
+ succeeded,
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+ } else {
+
+ Console.WriteLine("Succeeded = {0}. Elapsed time {1} msec\n",
+ succeeded,
+ t.TotalMilliseconds);
+ }
+
+ TestQuery(Log, false);
+ TestQuery(Log, true);
+
+ return t;
+
+ }
+
+ [TestMethod]
+ public void TestMonitoring()
+ {
+ TestEv Log;
+
+ Console.WriteLine("Test Monitoring.Log(Monitoring.Provider.Processor...)");
+
+ DateTime startTime = DateTime.Now;
+
+ for (int i = 0; i < Loops; i++) {
+
+ Monitoring.Log(Monitoring.Provider.Processor,
+ (ushort)2, 0,
+ (uint)0, 0, 0, 0, 0);
+
+ }
+
+ DateTime endTime = DateTime.Now;
+ TimeSpan t = endTime-startTime;
+
+ Console.WriteLine("Elapsed time {0} msec. Rate = {1} KOps/sec\n",
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+ }
+
+ [TestMethod]
+ public void TestTracing()
+ {
+ TestEv Log;
+
+ Console.WriteLine("Test Tracing.Log(Tracing.Debug,string[100])");
+
+ DateTime startTime = DateTime.Now;
+
+ for (int i = 0; i < Loops; i++) {
+
+ Tracing.Log(Tracing.Debug, //100 chars
+ "____________________________________________________________________________________________________");
+ }
+
+ DateTime endTime = DateTime.Now;
+ TimeSpan t = endTime-startTime;
+
+ Console.WriteLine("Elapsed time {0} msec. Rate = {1} KOps/sec\n",
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+
+ Console.WriteLine("Test Tracing.Log(Tracing.Debug,string[1])");
+
+ startTime = DateTime.Now;
+
+ for (int i = 0; i < Loops; i++) {
+
+ Tracing.Log(Tracing.Debug,"1");
+ }
+
+ endTime = DateTime.Now;
+ t = endTime-startTime;
+
+ Console.WriteLine("Elapsed time {0} msec. Rate = {1} KOps/sec\n",
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+
+ // one argument
+
+ Console.WriteLine("Test Tracing.Log(Tracing.Debug,Event={0})");
+
+ startTime = DateTime.Now;
+
+ for (int i = 0; i < Loops; i++) {
+
+ Tracing.Log(Tracing.Debug,"Event={0}", 100);
+ }
+
+ endTime = DateTime.Now;
+ t = endTime-startTime;
+
+ Console.WriteLine("Elapsed time {0} msec. Rate = {1} KOps/sec\n",
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+
+ // two arguments
+
+ Console.WriteLine("Test Tracing.Log(Tracing.Debug,Event1={0}, Event2={1})");
+
+ startTime = DateTime.Now;
+
+ for (int i = 0; i < Loops; i++) {
+
+ Tracing.Log(Tracing.Debug,"Event1={0}, Event2={1}", 100, 200);
+ }
+
+ endTime = DateTime.Now;
+ t = endTime-startTime;
+
+ Console.WriteLine("Elapsed time {0} msec. Rate = {1} KOps/sec\n",
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+ // three arguments
+
+ Console.WriteLine("Test Tracing.Log(Tracing.Debug,Event1={0}, Event2={1}, Event3={2})");
+
+ startTime = DateTime.Now;
+
+ for (int i = 0; i < Loops; i++) {
+
+ Tracing.Log(Tracing.Debug,"Event1={0}, Event2={1}, Event3={2}", 100, 200, 300);
+ }
+
+ endTime = DateTime.Now;
+ t = endTime-startTime;
+
+ Console.WriteLine("Elapsed time {0} msec. Rate = {1} KOps/sec\n",
+ t.TotalMilliseconds,
+ Loops/t.TotalMilliseconds);
+
+ }
+
+ [TestMethod]
+ public void TestRecNoStack4()
+ {
+ TestLoop("TestLogger:TestRecyclable-NoStacks-4k",
+ 4096,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestRecNoStack64()
+ {
+ TestLoop("TestLogger:TestRecyclable-NoStacks-64k",
+ 4096 * 16,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestRecNoStack1M()
+ {
+ TestLoop("TestLogger:TestRecyclable-NoStacks-1M",
+ 1024*1024,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestRecNoStack10M()
+ {
+ TestLoop("TestLogger:TestRecyclable-NoStacks-10M",
+ 10*1024*1024,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestRecStack4()
+ {
+ TestLoop("TestLogger:TestRecyclable-Stacks-4k",
+ 4096,
+ QualityOfService.RecyclableEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestRecStack64()
+ {
+ TestLoop("TestLogger:TestRecyclable-Stacks-64k",
+ 4096 * 16,
+ QualityOfService.RecyclableEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestRecStack1M()
+ {
+ TestLoop("TestLogger:TestRecyclable-Stacks-1M",
+ 1024*1024,
+ QualityOfService.RecyclableEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestRecStack10M()
+ {
+ TestLoop("TestLogger:TestRecyclable-Stacks-10M",
+ 10*1024*1024,
+ QualityOfService.RecyclableEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestPermNoStack4()
+ {
+ TestLoop("TestLogger:TestPermanent-NoStacks-4k",
+ 4096,
+ QualityOfService.PermanentEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestPermNoStack64()
+ {
+ TestLoop("TestLogger:TestPermanent-NoStacks-64k",
+ 4096 * 16,
+ QualityOfService.PermanentEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+
+ [TestMethod]
+ public void TestPermNoStack1M()
+ {
+ TestLoop("TestLogger:TestPermanent-NoStacks-1M",
+ 1024*1024 ,
+ QualityOfService.PermanentEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+
+ [TestMethod]
+ public void TestPermNoStack10M()
+ {
+ TestLoop("TestLogger:TestPermanent-NoStacks-10M",
+ 1024*1024 * 10,
+ QualityOfService.PermanentEvents,
+ EventSource.ENABLE_ALL_MASK);
+ }
+
+
+ [TestMethod]
+ public void TestPermStack4()
+ {
+ TestLoop("TestLogger:TestPermanent-Stacks-4k",
+ 4096,
+ QualityOfService.PermanentEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+ [TestMethod]
+ public void TestPermStack64()
+ {
+ TestLoop("TestLogger:TestPermanent-Stacks-64k",
+ 4096 * 16,
+ QualityOfService.PermanentEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+
+ [TestMethod]
+ public void TestPermStack1M()
+ {
+ TestLoop("TestLogger:TestPermanent-Stacks-1M",
+ 1024*1024 ,
+ QualityOfService.PermanentEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+
+ [TestMethod]
+ public void TestPermStack10M()
+ {
+ TestLoop("TestLogger:TestPermanent-Stacks-10M",
+ 1024*1024 * 10,
+ QualityOfService.PermanentEvents,
+ EventSource.CAPTURE_STACK_TRACE | EventSource.ENABLE_ALL_MASK);
+ }
+
+
+ [TestMethod]
+ public void TestRecDisabled()
+ {
+ TestLoop("TestLogger:TestRecyclable-Disabled-4k",
+ 4096,
+ QualityOfService.RecyclableEvents,
+ 0);
+ }
+
+ [TestMethod]
+ public void ExhaustiveQueryTest()
+ {
+ TimeSpan t;
+
+ for (uint i = 1; i < 150; i += 1) {
+
+ Console.WriteLine("Iteration {0}", i);
+
+ for (uint j = 0; j <= i; j += 1) {
+
+ t = TestQueryPermutations("TestLogger:BackQueryPermutations:"+i+":"+j,
+ 4096,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK,
+ i,
+ j,
+ false,
+ 100);
+
+ if (t.TotalMilliseconds > 1000) {
+
+ Console.WriteLine("Test stopped at iteration {0}", i);
+ return;
+ }
+
+ t = TestQueryPermutations("TestLogger:ForwardQueryPermutations:"+i+":"+j,
+ 4096,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK,
+ i,
+ j,
+ true,
+ 100);
+
+ if (t.TotalMilliseconds > 1000) {
+
+ Console.WriteLine("Test stopped at iteration {0}", i);
+ return;
+ }
+ }
+ }
+ }
+
+ //
+ // Source query routines
+ //
+
+ void TestSourceQuery()
+ {
+ Controller hostController = Controller.GetLocalController();
+
+ if (hostController == null) {
+ return;
+ }
+
+ QueryBuffer entryBuffer = new QueryBuffer(256);
+
+ if (entryBuffer == null) {
+ return;
+ }
+
+ int currentSize = 100;
+ UIntPtr [] sourceArray = new UIntPtr[currentSize];
+
+ if (sourceArray != null) {
+
+ int sourceCount = hostController.QuerySourcesList(sourceArray, currentSize);
+
+ if (sourceCount > currentSize) {
+
+ sourceCount = currentSize;
+ }
+
+ for (int i = 0; i < sourceCount; i++) {
+ UIntPtr sourceHandle = sourceArray[i];
+ UIntPtr storageHandle = 0;
+ UIntPtr eventType = 0;
+ UInt16 count = 0;
+ string bufferName = "";
+
+ if (hostController.GetSourceInformation(sourceHandle, ref storageHandle, ref eventType, ref count, ref bufferName)) {
+
+ Console.WriteLine("Source Handle={0}, Storage={1}, type={2}, name={3}, count={4}",
+ sourceHandle, storageHandle, eventType, count, bufferName);
+
+ int index = 0;
+
+ if (storageHandle == 0) {
+
+ EventDescriptor descriptor = new EventDescriptor(hostController, eventType);
+
+ if ((descriptor != null) && descriptor.Initialize()) {
+ for (;;) {
+
+ if (!hostController.QueryActiveEntry(sourceHandle, index++, ref entryBuffer)) {
+ break;
+ }
+ }
+
+
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ void TestEnums()
+ {
+
+ EvTest2 log2 = EvTest2.Create("AutoEnumTest2",
+ 4096,
+ QualityOfService.RecyclableEvents,
+ EventSource.ENABLE_ALL_MASK | EventSource.CAPTURE_DEBUG_PRINT);
+
+ if (log2 == null) {
+
+ Console.WriteLine("Failure to create test");
+ return ;
+ }
+
+ log2.SaveEvent(2, EvTest2.MyEnum.Val1);
+ log2.SaveEvent(8, EvTest2.MyEnum.Val2);
+
+ log2.SaveEventFlags(4, 1, EvTest2.MyFlagsEnum.Flag0001);
+ log2.SaveEventFlags(5, 2, EvTest2.MyFlagsEnum.Flag0008);
+ log2.SaveEventFlags(6, 3, EvTest2.MyFlagsEnum.FlagdifferentSize);
+
+ log2.SaveEventCombination(256, 22, EvTest2.MyEnum.Val1, EvTest2.MyFlagsEnum.Flag0001);
+
+
+ }
+
+ [TestMethod]
+ public void TestAll()
+ {
+
+ // Legacy mechanisms
+
+ TestEnums();
+
+ TestMonitoring();
+ TestTracing();
+
+// DiagnosisService.TestKernelStorage();
+
+ // Recyclable events (ring buffers)
+
+ TestRecNoStack4();
+ TestRecNoStack64();
+ TestRecNoStack1M();
+ TestRecNoStack10M();
+
+ // Recyclable events (ring buffers) + stacks
+
+ TestRecStack4();
+ TestRecStack64();
+ TestRecStack1M();
+ TestRecStack10M();
+
+ // Permanent events (drop new events at OOM)
+
+ TestPermNoStack4();
+ TestPermNoStack64();
+ TestPermNoStack1M();
+ TestPermNoStack10M();
+
+ // Permanent events (drop new events at OOM) + stacks
+
+ TestPermStack4();
+ TestPermStack64();
+ TestPermStack1M();
+ TestPermStack10M();
+
+ // Overhead for test condition and functio call in tracing
+
+ TestRecDisabled();
+
+// ExhaustiveQueryTest();
+ }
+ }
+}
+
diff --git a/base/Applications/Eventing/testdef/testdef.cs b/base/Applications/Eventing/testdef/testdef.cs
new file mode 100644
index 0000000..89cc077
--- /dev/null
+++ b/base/Applications/Eventing/testdef/testdef.cs
@@ -0,0 +1,93 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Runtime.CompilerServices;
+using Microsoft.Singularity.Transform;
+using Microsoft.Singularity.Eventing;
+
+namespace Microsoft.Singularity
+{
+
+ public class EventEnumAttribute : Attribute
+ {
+ // mark classes & methods for eventing
+ }
+
+ [Event]
+ public abstract class TestEv : EventSource
+ {
+ [Event]
+ public abstract bool Log(int EventId);
+ public static string Log_Format = "EventLogger: EventId={0}";
+
+ }
+
+ [Event]
+ public abstract class EvStress1 : EventSource
+ {
+ [Event]
+ public abstract bool Log(int Arg1);
+ public static string Log_Format = "EvStress: seq value={0}";
+ }
+
+ //
+ // Test source that includes enums, and multiple event functions per same source
+ // The declaration of the schema for enum is still manual, but the rest of the code can leverage
+ // the existing codegen support
+ //
+
+ [Event]
+ public abstract class EvTest2 : EventSource
+ {
+ [Event]
+ public abstract bool SaveEvent(int Arg1, MyEnum en);
+ public static string SaveEvent_Format = "testenum: arg={0}, enum=[{1}]";
+
+ [Event]
+ public abstract bool SaveEventFlags(int Arg1, int Arg2, MyFlagsEnum flag );
+ public static string SaveEventFlags_Format = "FlagsEnum: arg={0}, {1}; enum=[{2}]";
+
+ [Event]
+ public abstract bool SaveEventCombination(int Arg1, int Arg2, MyEnum en, MyFlagsEnum flag);
+ public static string SaveEventCombination_Format = "Combinations: arg={0},{1}; enum=[{2}], Flags = [{3}]";
+
+ [EventEnum]
+ public enum MyEnum{
+ Val1,
+ Val2
+ };
+
+ public static UIntPtr MyEnum_Handle;
+
+ [EventEnum]
+ public enum MyFlagsEnum{
+ Flag0001 = 0x0001,
+ Flag0008 = 0x0008,
+ FlagdifferentSize = 16,
+ };
+
+ public static UIntPtr MyFlagsEnum_Handle;
+
+ public override void RegisterEnumSymbols()
+ {
+ base.RegisterEnumSymbols();
+
+ if (HostController.RegisterEnum("MyEnum", DataType.__int32, ref MyEnum_Handle)) {
+
+ HostController.RegisterEnumValue(MyEnum_Handle, "Val1", (UInt64)MyEnum.Val1, 0);
+ HostController.RegisterEnumValue(MyEnum_Handle, "Val2", (UInt64)MyEnum.Val2, 0);
+ }
+
+ if (HostController.RegisterEnum("MyFlagsEnum", DataType.__int32, ref MyFlagsEnum_Handle)) {
+
+ HostController.RegisterEnumValue(MyFlagsEnum_Handle, "Flag0001", (UInt64)MyFlagsEnum.Flag0001, (byte)'A');
+ HostController.RegisterEnumValue(MyFlagsEnum_Handle, "Flag0008", (UInt64)MyFlagsEnum.Flag0008, (byte)'B');
+ HostController.RegisterEnumValue(MyFlagsEnum_Handle, "FlagdifferentSize", (UInt64)MyFlagsEnum.FlagdifferentSize, (byte)'Z');
+ }
+ }
+ }
+}
diff --git a/base/Applications/Eventing/testdef/testdef.csproj b/base/Applications/Eventing/testdef/testdef.csproj
new file mode 100644
index 0000000..17a3566
--- /dev/null
+++ b/base/Applications/Eventing/testdef/testdef.csproj
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+ Library
+ TestEvent
+ C#
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Godot/GOdot.csproj b/base/Applications/Godot/GOdot.csproj
index 0b7b3d1..40bd623 100644
--- a/base/Applications/Godot/GOdot.csproj
+++ b/base/Applications/Godot/GOdot.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ Hello2
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/HelloMp/HelloMp.cs b/base/Applications/HelloMp/HelloMp.cs
index 6ced2be..0ddab3c 100644
--- a/base/Applications/HelloMp/HelloMp.cs
+++ b/base/Applications/HelloMp/HelloMp.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: HelloMp.cs
-//
// Note: Simple Singularity test program.
//
using System;
diff --git a/base/Applications/HelloMp/HelloMp.csproj b/base/Applications/HelloMp/HelloMp.csproj
index 8867b2a..3fceff9 100644
--- a/base/Applications/HelloMp/HelloMp.csproj
+++ b/base/Applications/HelloMp/HelloMp.csproj
@@ -1,5 +1,12 @@
-
-
+
+
+
diff --git a/base/Applications/HelloMpAsm/HelloMpAsm.cpp b/base/Applications/HelloMpAsm/HelloMpAsm.cpp
index f4cb8ba..04dd523 100644
--- a/base/Applications/HelloMpAsm/HelloMpAsm.cpp
+++ b/base/Applications/HelloMpAsm/HelloMpAsm.cpp
@@ -1,8 +1,8 @@
-///////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-
+// ----------------------------------------------------------------------------
int main ()
{
diff --git a/base/Applications/Iltest/ilstart.cpp b/base/Applications/Iltest/ilstart.cpp
new file mode 100644
index 0000000..f4472b8
--- /dev/null
+++ b/base/Applications/Iltest/ilstart.cpp
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// ilstart.cpp - Singularity Hardware Abstraction Layer
+//
+// Copyright Microsoft Corporation.
+//
+
+typedef unsigned short bartok_char;
+typedef signed short int16;
+typedef signed int int32;
+typedef __int64 int64;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned __int64 uint64;
+
+struct Struct_System_ObjectHeader
+{
+ int32 syncBlockValue;
+};
+
+struct Class_System_Object
+{
+ void * f_vtable;
+};
+
+struct Class_System_VTable : Class_System_Object
+{
+};
+
+struct Struct_Microsoft_Singularity_V1_Services_DebugService
+{
+ static void g_Break();
+ static void g_Print(bool);
+ static void g_Print(bartok_char);
+ static void g_Print(int32);
+ static void g_Print(int64);
+ static void g_Print(uint32);
+ static void g_Print(uint64);
+ static void g_Print(uint8);
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+struct Class_Microsoft_Singularity_Iltest
+{
+ static int g_Main();
+ static int g_ThreadMain(int threadIndex);
+};
+
+extern "C" void __cdecl _throwDispatcherExplicitAddrAfter()
+{
+ // ecx = exception
+ // dex = throw addr
+ Struct_Microsoft_Singularity_V1_Services_DebugService::g_Print('E');
+}
+
+extern "C" int32 __fastcall IlStart(int32 threadIndex)
+{
+ Struct_Microsoft_Singularity_V1_Services_DebugService::g_Print('-');
+ Struct_Microsoft_Singularity_V1_Services_DebugService::g_Print('I');
+ Struct_Microsoft_Singularity_V1_Services_DebugService::g_Print('\n');
+ if (threadIndex == -1) {
+ return Class_Microsoft_Singularity_Iltest::g_Main();
+ }
+ else {
+ return Class_Microsoft_Singularity_Iltest::g_ThreadMain(threadIndex);
+ }
+}
+
+extern "C" void __cdecl _pushStackMark()
+{
+}
+
+extern "C" void __cdecl _popStackMark()
+{
+}
diff --git a/base/Applications/Iltest/iltest.cs b/base/Applications/Iltest/iltest.cs
new file mode 100644
index 0000000..a0b51a0
--- /dev/null
+++ b/base/Applications/Iltest/iltest.cs
@@ -0,0 +1,195 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: This file contains the main entry point for the C#
+// portion of Singularity.
+//
+
+using Microsoft.Singularity.V1.Services;
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace Microsoft.Singularity
+{
+ [CCtorIsRunDuringStartup]
+ public class Iltest
+ {
+#if TEST_MEMORY_ABI
+ public static uint Probe(uint addr)
+ {
+ uint begin;
+ uint bytes;
+ bool used = PageTableService.Query(addr, out begin, out bytes);
+ DebugService.Print(' ');
+ DebugService.Print((ulong)begin);
+ DebugService.Print('.');
+ DebugService.Print((ulong)begin + bytes);
+ DebugService.Print(' ');
+ if (used) {
+ DebugService.Print('u');
+ }
+ DebugService.Print('\n');
+ return begin + bytes;
+ }
+#endif // TEST_MEMORY_ABI
+
+ public static int ThreadMain(int threadIndex)
+ {
+ DebugService.Print('t');
+ DebugService.Print(threadIndex);
+ DebugService.Print('\n');
+#if TEST_STACK_ABI
+ Test1(1);
+#endif // TEST_STACK_ABI
+ DebugService.Print('.');
+ return 998;
+ }
+
+ public static int Main()
+ {
+ int i = 10;
+ long l = 100;
+ byte b = 1;
+ bool o = true;
+
+ DebugService.Print('H');
+ DebugService.Print(b);
+ DebugService.Print(',');
+ DebugService.Print(i);
+ DebugService.Print(',');
+ DebugService.Print(l);
+ DebugService.Print(',');
+ DebugService.Print(o);
+ DebugService.Print('\n');
+
+#if TEST_MEMORY_ABI
+ uint tag = PageTableService.GetProcessTag();
+ DebugService.Print('p');
+ DebugService.Print((ulong)tag);
+ DebugService.Print('\n');
+
+ uint pages = PageTableService.GetPageCount();
+ DebugService.Print('n');
+ DebugService.Print(pages);
+ DebugService.Print('\n');
+
+ uint addr = PageTableService.Allocate(0x1000);
+ DebugService.Print('a');
+ DebugService.Print((ulong)addr);
+ DebugService.Print('\n');
+
+ Probe(addr);
+
+ addr = 1;
+ for (i = 0; i < 20 && addr != 0 && addr < 0xc0000000; i++) {
+ addr = Probe(addr);
+ }
+#endif // TEST_MEMORY_ABI
+#if TEST_STACK_ABI
+ Test1(1);
+#endif // TEST_STACK_ABI
+
+ return 999;
+ }
+
+#if TEST_STACK_ABI
+ [NoInline]
+ internal static int Test1(int a)
+ {
+ DebugService.Print('1');
+ DebugService.Print('('); DebugService.Print(a);
+ DebugService.Print(')');
+ a = Test2(a, a + 1) + 1;
+ DebugService.Print('=');
+ DebugService.Print(a);
+ DebugService.Print('\n');
+ return a;
+ }
+
+ [NoInline]
+ internal static int Test2(int a, int b)
+ {
+ DebugService.Print('2');
+ DebugService.Print('('); DebugService.Print(a);
+ DebugService.Print(','); DebugService.Print(b);
+ DebugService.Print(')');
+ a = Test3(a, a + 1, a + 2) + 1;
+ DebugService.Print('=');
+ DebugService.Print(a);
+ DebugService.Print('\n');
+ return a;
+ }
+
+ [NoInline]
+ internal static int Test3(int a, int b, int c)
+ {
+ DebugService.Print('3');
+ DebugService.Print('('); DebugService.Print(a);
+ DebugService.Print(','); DebugService.Print(b);
+ DebugService.Print(','); DebugService.Print(c);
+ DebugService.Print(')');
+ a = Test4(a, a + 1, a + 2, a + 3) + 1;
+ DebugService.Print('=');
+ DebugService.Print(a);
+ DebugService.Print('\n');
+ return a;
+ }
+
+ [NoInline]
+ internal static int Test4(int a, int b, int c, int d)
+ {
+ DebugService.Print('4');
+ DebugService.Print('('); DebugService.Print(a);
+ DebugService.Print(','); DebugService.Print(b);
+ DebugService.Print(','); DebugService.Print(c);
+ DebugService.Print(','); DebugService.Print(d);
+ DebugService.Print(')');
+ a = Test5(a, a + 1, a + 2, a + 3, a + 4) + 1;
+ DebugService.Print('=');
+ DebugService.Print(a);
+ DebugService.Print('\n');
+ return a;
+ }
+
+ [NoInline]
+ internal static int Test5(int a, int b, int c, int d, int e)
+ {
+ DebugService.Print('5');
+ DebugService.Print('('); DebugService.Print(a);
+ DebugService.Print(','); DebugService.Print(b);
+ DebugService.Print(','); DebugService.Print(c);
+ DebugService.Print(','); DebugService.Print(d);
+ DebugService.Print(','); DebugService.Print(e);
+ DebugService.Print(')');
+ a = Test6(a, a + 1, a + 2, a + 3, a + 4, a + 5) + 1;
+ DebugService.Print('=');
+ DebugService.Print(a);
+ DebugService.Print('\n');
+ return a;
+ }
+
+ [NoInline]
+ internal static int Test6(int a, int b, int c, int d, int e, int f)
+ {
+ DebugService.Print('6');
+ DebugService.Print('('); DebugService.Print(a);
+ DebugService.Print(','); DebugService.Print(b);
+ DebugService.Print(','); DebugService.Print(c);
+ DebugService.Print(','); DebugService.Print(d);
+ DebugService.Print(','); DebugService.Print(e);
+ DebugService.Print(','); DebugService.Print(f);
+ DebugService.Print(')');
+ a = a + 100;
+ DebugService.WalkStack();
+ DebugService.Print('=');
+ DebugService.Print(a);
+ DebugService.Print('\n');
+ return a;
+ }
+#endif // TEST_STACK_ABI
+ }
+}
diff --git a/base/Applications/IoLibtest/IoLibTest.csproj b/base/Applications/IoLibtest/IoLibTest.csproj
index decf47a..166fbcb 100644
--- a/base/Applications/IoLibtest/IoLibTest.csproj
+++ b/base/Applications/IoLibtest/IoLibTest.csproj
@@ -1,8 +1,6 @@

+
diff --git a/base/Applications/NameSpace/SDSTest/SDSTest.csproj b/base/Applications/NameSpace/SDSTest/SDSTest.csproj
new file mode 100644
index 0000000..d886890
--- /dev/null
+++ b/base/Applications/NameSpace/SDSTest/SDSTest.csproj
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ Exe
+ SDSTest
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/NameSpace/SDSTest/SDSTest.sg b/base/Applications/NameSpace/SDSTest/SDSTest.sg
new file mode 100644
index 0000000..0cf551d
--- /dev/null
+++ b/base/Applications/NameSpace/SDSTest/SDSTest.sg
@@ -0,0 +1,565 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+
+using System;
+using System.Threading;
+using Microsoft.Singularity;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Security;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.SingSharp;
+using Microsoft.SingSharp.Runtime;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Configuration;
+
+using Microsoft.Contracts;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Io;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+[assembly: ApplicationPublisherAttribute("singularity.microsoft.com")]
+[assembly: AssertPrivilegeAttribute("$register-privilege.localhost")]
+
+namespace Microsoft.Singularity.Applications
+{
+ [ConsoleCategory(HelpMessage="Test SIP-based Directory Service", DefaultAction=true)]
+ internal class Parameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [StringParameter( "mountPoint", Mandatory=true, Position=0, HelpMessage="Location of dsp to test")]
+ internal string mountPoint;
+
+ [BoolParameter( "debug", Default=false, HelpMessage="Send results to debugger")]
+ internal bool printDebug;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return DirectoryMain.AppMain(this);
+ }
+ }
+
+
+ public contract Dummy : ServiceContract
+ {
+ out message Garbage();
+
+ override state Start: one
+ {
+ Garbage! -> End;
+ }
+ state End: one {}
+ }
+
+ public class DirectoryServiceTests
+ {
+ public int passCount;
+ public int failCount;
+ private bool nakLoaded;
+ private bool dspLoaded;
+ private bool doDebug;
+
+ public DirectoryServiceTests (bool nakLoaded, bool dspLoaded, bool doDebug)
+ {
+ failCount = 0;
+ passCount = 0;
+ this.nakLoaded = nakLoaded;
+ this.dspLoaded= dspLoaded;
+ this.doDebug = doDebug;
+ }
+
+ public void CheckError( string! verb, string path, ErrorCode expected, ErrorCode actual, bool ok)
+ { if (ok){
+ //Console.WriteLine("{0} on {1} was successful.", verb, path);
+ }
+ if (expected != actual) {
+ failCount++;
+ string s = String.Format("FAIL: {0} on {1}. expected={2}, actual={3}. ok={4}",
+ verb,
+ path,
+ SdsUtils.ErrorCodeToString(expected),
+ SdsUtils.ErrorCodeToString(actual),
+ ok ? "true" : "false"
+ );
+ Console.WriteLine(s);
+ if (doDebug) DebugStub.WriteLine(s);
+ //DebugStub.Break();
+ }
+ else {
+ passCount++;
+ string s = String.Format("PASS: {0} on {1} ({2}) ok={3}.",
+ verb,
+ path,
+ SdsUtils.ErrorCodeToString(expected),
+ ok ? "true" : "false"
+ );
+ Console.WriteLine(s);
+ if (doDebug) DebugStub.WriteLine(s);
+ }
+ }
+
+ public void CheckError( string! verb, string path, NodeType expected, NodeType actual, bool ok)
+ { if (ok){
+ //Console.WriteLine("{0} on {1} was successful.", verb, path);
+ }
+ if (expected != actual) {
+ failCount++;
+ Console.WriteLine("FAIL: {0} on {1}. expected={2}, actual={3}. ok={4}",
+ verb,
+ path,
+ SdsUtils.NodeTypeToString(expected),
+ SdsUtils.NodeTypeToString(actual),
+ ok ? "true" : "false"
+ );
+ }
+ else {
+ passCount++;
+ Console.WriteLine("PASS: {0} on {1} ({2}) ok={3}.",
+ verb,
+ path,
+ SdsUtils.NodeTypeToString(expected),
+ ok ? "true" : "false"
+ );
+ }
+ }
+
+ public bool DoCreateDirectory(DirectoryServiceContract.Imp! ds, string! path, ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ bool ok = SdsUtils.CreateDirectory(path, ds, out errorOut);
+ CheckError("CreateDirectory", path, expected, errorOut, ok);
+ return ok;
+ }
+
+ public void DoDeleteDirectory(DirectoryServiceContract.Imp! ds, string! path, ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ bool ok = SdsUtils.DeleteDirectory(path, ds, out errorOut);
+ CheckError("DeleteDirectory", path, expected, errorOut, ok);
+ }
+
+ public void DoCreateLink(DirectoryServiceContract.Imp! ds, string! path, string! value, ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ bool ok = SdsUtils.CreateLink(path, value, ds, out errorOut);
+ CheckError("CreateLink", path, expected, errorOut, ok);
+ }
+
+ public void DoGetLink(DirectoryServiceContract.Imp! ds, string! path, string expectedValue, ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ string linkValue;
+ bool ok = SdsUtils.GetLinkValue(path, ds, out linkValue, out errorOut);
+ CheckError("GetLinkValue", path, expected, errorOut, ok);
+ if (ok) {
+ if (expectedValue != linkValue) {
+ Console.WriteLine(" expected({0}) got({1})", expectedValue, linkValue);
+ }
+ }
+ }
+
+ public bool DoBind(DirectoryServiceContract.Imp! ds, string! path,
+ [Claims]ServiceContract.Exp! exp, ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ string linkValue;
+ bool ok = SdsUtils.Bind(path, ds, exp, out errorOut);
+ CheckError("Bind", path, expected, errorOut, ok);
+ return ok;
+ }
+
+ //simulate FileOpen in FsUtils
+ public bool DoBind(string! path,
+ [Claims]ServiceContract.Exp! exp, ErrorCode expected)
+ {
+
+ DirectoryServiceContract.Imp! ds = DirectoryService.NewClientEndpoint();
+ ErrorCode errorOut;
+ string linkValue;
+ bool ok = SdsUtils.Bind(path, ds, exp, out errorOut);
+ CheckError("Bind", path, expected, errorOut, ok);
+ delete ds;
+ return ok;
+ }
+
+ public void DoDeleteLink(DirectoryServiceContract.Imp! ds, string! path, ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ bool ok = SdsUtils.DeleteLink(path, ds, out errorOut);
+ CheckError("DeleteLink", path, expected, errorOut, ok);
+ }
+
+ public void DoRegister(DirectoryServiceContract.Imp! ds,
+ string! path,
+ [Claims] ServiceProviderContract.Imp! service,
+ ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ bool ok = SdsUtils.Register(path, ds, service, out errorOut);
+ CheckError("Register", path, expected, errorOut, ok);
+ }
+
+ public void DoDeregister(DirectoryServiceContract.Imp! ds, string! path, ErrorCode expected)
+ {
+ ErrorCode errorOut;
+ ServiceProviderContract.Imp:Start service;
+
+ bool ok = SdsUtils.Deregister(path, ds, out service, out errorOut);
+ CheckError("Deregister", path, expected, errorOut, ok);
+ delete service;
+ }
+
+ public void DoGetAttributes(DirectoryServiceContract.Imp! ds,
+ string! path,
+ ErrorCode expected,
+ NodeType expectedNodeType)
+ {
+ ErrorCode errorOut;
+ long length;
+ NodeType nodeType;
+ FileAttributesRecord fileAttributes;
+
+ bool ok = SdsUtils.GetAttributes(path, ds, out fileAttributes, out errorOut);
+ CheckError("GetAttributes", path, expectedNodeType, fileAttributes.Type, ok);
+ CheckError("GetAttributes", path, expected, errorOut, ok);
+ }
+
+ public void AttributesTests(DirectoryServiceContract.Imp! ds)
+ {
+ DoCreateDirectory(ds, "/d1", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/d2", ErrorCode.NoError);
+ DoCreateLink(ds, "/d1/Link1", "/d2", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/d1/Link1/d2", ErrorCode.NoError);
+
+ DoGetAttributes(ds, "/d1", ErrorCode.NoError, NodeType.Directory);
+ DoGetAttributes(ds, "/d1/Link1", ErrorCode.NoError, NodeType.SymLink);
+ DoGetAttributes(ds, "/init/testpe/testpe", ErrorCode.NoError, NodeType.IoMemory);
+ DoGetAttributes(ds, "/stress", ErrorCode.NoError, NodeType.ServiceProvider);
+ DoGetAttributes(ds, "/d1/Link1/d2", ErrorCode.NoError, NodeType.Directory);
+ DoGetAttributes(ds, "/d1/garbage", ErrorCode.NotFound, NodeType.BadNode);
+
+ DoDeleteLink(ds, "/d1/Link1",ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d1", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d2/d2", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d2", ErrorCode.NoError);
+ }
+
+ public void ProviderTests(DirectoryServiceContract.Imp! ds)
+ {
+
+ ServiceProviderContract.Imp! c1;
+ ServiceProviderContract.Exp! s1;
+ ServiceProviderContract.NewChannel(out c1, out s1);
+
+ ServiceProviderContract.Imp! c2;
+ ServiceProviderContract.Exp! s2;
+ ServiceProviderContract.NewChannel(out c2, out s2);
+
+ ServiceProviderContract.Imp! c3;
+ ServiceProviderContract.Exp! s3;
+ ServiceProviderContract.NewChannel(out c3, out s3);
+
+ DoRegister(ds, "/dev/sp1", c1, ErrorCode.NoError);
+ DoRegister(ds, "/dev/sp1", c2, ErrorCode.AlreadyExists);
+ DoRegister(ds, "/notFound/sp1", c3, ErrorCode.NotFound);
+ DoDeregister(ds, "/dev/sp1", ErrorCode.NoError);
+
+ // manipulate providers within an SDS provider (DSP)
+ if (dspLoaded) {
+ ServiceProviderContract.Imp! c4;
+ ServiceProviderContract.Exp! s4;
+ ServiceProviderContract.NewChannel(out c4, out s4);
+
+ ServiceProviderContract.Imp! c5;
+ ServiceProviderContract.Exp! s5;
+ ServiceProviderContract.NewChannel(out c5, out s5);
+
+ ServiceProviderContract.Imp! c6;
+ ServiceProviderContract.Exp! s6;
+ ServiceProviderContract.NewChannel(out c6, out s6);
+
+ DoRegister(ds, "/dsp/sp1", c4, ErrorCode.NoError);
+ DoRegister(ds, "/dsp/sp1", c5, ErrorCode.AlreadyExists);
+ DoDeregister(ds, "/dsp/sp1", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/dsp/dir1", ErrorCode.NoError);
+ DoRegister(ds, "/dsp/dir1/sp1", c6, ErrorCode.NoError);
+ DoDeregister(ds, "/dsp/dir1/sp1", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/dsp/dir1", ErrorCode.NoError);
+ delete s4;
+ delete s5;
+ delete s6;
+ }
+ delete s1;
+ delete s2;
+ delete s3;
+ }
+
+ public int DirectoryTests(DirectoryServiceContract.Imp! ds)
+ {
+ // create and delete directories with and without symbolic links
+
+ //create and delete some directiores
+ DoCreateDirectory(ds, "/d1", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/d1", ErrorCode.AlreadyExists);
+ DoCreateDirectory(ds, "/d2", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/d1/d1", ErrorCode.NoError);
+
+
+ // add a symbolic link to the mix
+ DoCreateLink(ds, "/d1/Link1", "/d2", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/d1/Link1/d2", ErrorCode.NoError);
+
+ DoDeleteDirectory(ds, "/d1/Link1/d2", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d1/Link1/d2", ErrorCode.NotFound);
+
+ // create a link to a link
+ DoCreateLink(ds, "/d1/LinkToLink", "/d2/Link1", ErrorCode.NoError);
+ DoCreateLink(ds, "/d2/Link1", "/d3", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/d3", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/d1/LinkToLink/d3", ErrorCode.NoError);
+
+ // try and delete a non-empty directory
+ DoDeleteDirectory(ds, "/d1", ErrorCode.DirectoryNotEmpty);
+
+ // Attempt to delete non directories
+
+ //service provider
+ DoDeleteDirectory(ds, "/stress", ErrorCode.NotDirectory);
+ //link
+ DoDeleteDirectory(ds, "/d2/Link1", ErrorCode.NotDirectory);
+ //IoMemory
+ DoDeleteDirectory(ds, "/init/testpe/manifest", ErrorCode.NotDirectory);
+
+
+ // clean up residule files
+ DoDeleteDirectory(ds, "/d1/d1", ErrorCode.NoError);
+ DoDeleteLink(ds, "/d1/Link1",ErrorCode.NoError);
+ DoDeleteLink(ds, "/d1/LinkToLink",ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d1", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d1", ErrorCode.NotFound);
+
+ DoDeleteLink(ds, "/d2/Link1",ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d2", ErrorCode.NoError);
+
+ DoDeleteDirectory(ds, "/d3/d3", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/d3", ErrorCode.NoError);
+
+ return 0;
+ }
+
+ public void LinkTests(DirectoryServiceContract.Imp! ds)
+ {
+ DoCreateLink(ds, "/d2/Link1", "/d3", ErrorCode.NotFound); // no /dir1
+ DoCreateDirectory(ds, "/d2", ErrorCode.NoError);
+ DoCreateLink(ds, "/d2/Link1", "/d3", ErrorCode.NoError);
+ DoCreateLink(ds, "/d2/Link1", "/d3", ErrorCode.AlreadyExists);
+
+ DoGetLink(ds, "/d2/Link1", "/d3", ErrorCode.NoError);
+ DoGetLink(ds, "/d2", "", ErrorCode.NotLink);
+ DoDeleteLink(ds, "/d2/Link1",ErrorCode.NoError);
+ DoDeleteLink(ds, "/d2/Link1",ErrorCode.NotFound);
+
+ DoDeleteDirectory(ds, "/d2", ErrorCode.NoError);
+
+ if (dspLoaded) {
+ DoCreateLink(ds, "/dsp/rootlink", "/d2", ErrorCode.NoError);
+ DoCreateLink(ds, "/dsp/rootlink", "/d2", ErrorCode.AlreadyExists);
+ DoCreateDirectory(ds, "/dsp/d1", ErrorCode.NoError);
+ DoCreateLink(ds, "/dsp/d1/Link1", "/d2", ErrorCode.NoError);
+ DoDeleteLink(ds, "/dsp/d1/Link1",ErrorCode.NoError);
+ DoDeleteLink(ds, "/dsp/rootlink",ErrorCode.NoError);
+ DoDeleteDirectory(ds, "dsp/d1", ErrorCode.NoError);
+ }
+ }
+
+ public void BindTests(DirectoryServiceContract.Imp! ds)
+ {
+ // try to bind to the various node types within the root dsp
+
+ FileContract.Imp! fc;
+ FileContract.Exp! fs;
+
+ ServiceProviderContract.Imp! sc;
+ ServiceProviderContract.Exp! ss;
+
+ DirectoryServiceContract.Imp! imp;
+ DirectoryServiceContract.Exp! exp;
+
+ Dummy.Imp! dC;
+ Dummy.Exp! dS;
+
+ FileContract.NewChannel(out fc, out fs);
+ DoBind(ds,"/init/testpe/testpe",fs,ErrorCode.NoError);
+ delete fc;
+
+ Dummy.NewChannel(out dC, out dS);
+ DoBind(ds,"/init/testpe/testpe",dS,ErrorCode.ContractNotSupported);
+ delete dC;
+
+ DirectoryServiceContract.NewChannel(out imp , out exp);
+ DoBind(ds,"/init/testpe/testpe",exp,ErrorCode.ContractNotSupported);
+ delete imp;
+
+ DoCreateLink(ds, "/link", "/init", ErrorCode.NoError);
+ FileContract.NewChannel(out fc, out fs);
+ DoBind(ds,"/link/testpe/testpe",fs,ErrorCode.NoError);
+ delete fc;
+ DoDeleteLink(ds, "/link", ErrorCode.NoError);
+
+ FileContract.NewChannel(out fc, out fs);
+ // bind to dir with File
+ DoBind(ds,"/init",fs,ErrorCode.ContractNotSupported);
+ delete fc;
+
+ FileContract.NewChannel(out fc, out fs);
+ //bind to ServiceProvider with File
+ DoBind(ds,"/FsCtrl",fs,ErrorCode.ContractNotSupported);
+ delete fc;
+
+ FileContract.NewChannel(out fc, out fs);
+
+ delete fc;
+ delete fs;
+
+ //ServiceProvider.NewChannel(out sc, out ss);
+ // try binding to a dir with all the other types
+ // bind through links
+ if (dspLoaded) {
+ DoCreateDirectory(ds, "/dsp/BindTest", ErrorCode.NoError);
+ DoCreateLink(ds, "/dsp/BindTest/link", "/BindTest/d2", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/dsp/BindTest/d1", ErrorCode.NoError);
+ DoCreateDirectory(ds, "/dsp/BindTest/d2", ErrorCode.NoError);
+
+ DirectoryServiceContract.NewChannel(out imp, out exp);
+ DoBind(ds,"/dsp/BindTest/d1",exp,ErrorCode.NoError);
+ delete imp;
+
+ DirectoryServiceContract.NewChannel(out imp, out exp);
+ DoBind(ds,"/dsp/BindTest/link",exp,ErrorCode.NoError);
+ delete imp;
+
+ //DoCreateLink(ds, "/dsp/d1/link", "/d2", ErrorCode.NoError);
+
+
+ DoDeleteLink(ds, "/dsp/BindTest/link",ErrorCode.NoError);
+ //DoDeleteLink(ds, "/dsp/d1/link",ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/dsp/BindTest/d1", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/dsp/BindTest/d2", ErrorCode.NoError);
+ DoDeleteDirectory(ds, "/dsp/BindTest",ErrorCode.NoError);
+ }
+ if (nakLoaded) {
+ // attempt to bind to nak service
+ // attempt to bind to a closed channel
+ }
+ }
+ }
+
+ public class DirectoryMain
+ {
+ private static Process LoadProcess(string[]! arguments)
+ {
+ try {
+ Process process = new Process(arguments);
+ if (process == null) {
+ Console.WriteLine("Unable to create process {0}",arguments[0]);
+ return null;
+ }
+ else {
+ process.Start();
+ return process;
+ }
+ }
+ catch (ProcessCreateException) {
+ Console.WriteLine("Unable to create process {0}",arguments[0]);
+ }
+ return null;
+ }
+
+ internal static int AppMain(Parameters! config)
+ {
+ Process dsp = null;
+ ErrorCode errorOut;
+
+ DirectoryServiceContract.Imp ds = config.nsRef.Acquire();
+ if (ds == null) {
+ throw new Exception("Unable to acquire handle to the Directory Service root");
+ }
+
+ ds.RecvSuccess();
+
+ // see if the test DSP is loaded by attempting to bind to it
+ // if not present load it
+
+ bool ok;
+ ///
+ /// TODO: Fix. SdsUtils FlushCache needs to be re-implemented
+ /// in order for us to be able to wait for NakService termination
+ ///
+
+ DirectoryServiceContract.Imp! dspImp;
+ DirectoryServiceContract.Exp! dspExp;
+ DirectoryServiceContract.NewChannel(out dspImp, out dspExp);
+
+ string dspMountPoint = config.mountPoint;
+ ok = SdsUtils.Bind(dspMountPoint, ds, dspExp, out errorOut);
+ delete dspImp;
+
+ bool dspLoaded = false;
+ if (!ok) {
+ Console.WriteLine(" unable to bind to {0}. Reason={1}",
+ dspMountPoint, SdsUtils.ErrorCodeToString(errorOut));
+ delete ds;
+ return 1;
+ }
+ else dspLoaded = true;
+
+ DirectoryServiceTests t = new DirectoryServiceTests(false ,dspLoaded, config.printDebug);
+
+ try {
+ t.DirectoryTests(ds);
+ t.AttributesTests(ds);
+ t.ProviderTests(ds);
+ t.LinkTests(ds);
+ t.BindTests(ds);
+
+ Console.WriteLine(" pass={0}, fail={1}", t.passCount, t.failCount);
+
+
+ //Thread.Sleep(TimeSpan.FromMilliseconds(1000));
+
+ if (dsp != null) {
+ t.DoDeregister(ds,dspMountPoint, ErrorCode.NoError);
+ }
+ delete ds;
+
+ //Thread.Sleep(TimeSpan.FromMilliseconds(1000));
+
+ if (dsp != null) {
+ dsp.Join();
+ }
+ }
+ finally {
+ }
+ return 0;
+ }
+
+ private static void Usage(string name)
+ {
+ Console.WriteLine("{0} creates a directory.",name);
+ }
+ } // class Test
+}
diff --git a/base/Applications/NameSpace/TestDSP/DirectoryService.sg b/base/Applications/NameSpace/TestDSP/DirectoryService.sg
index 197c858..d509677 100644
--- a/base/Applications/NameSpace/TestDSP/DirectoryService.sg
+++ b/base/Applications/NameSpace/TestDSP/DirectoryService.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Directory.sg
-//
// Note:
//
@@ -29,7 +27,8 @@ using Microsoft.Singularity.Configuration;
[assembly: ApplicationPublisherAttribute("singularity.microsoft.com")]
[assembly: AssertPrivilegeAttribute("$register-privilege.localhost")]
-namespace Microsoft.Application.DSP {
+namespace Microsoft.Application.DSP
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -145,30 +144,30 @@ namespace Microsoft.Application.DSP {
// for now, we will just add a rule to allow **any** access
private static void InstallAcls(ISdsAcl! aclT)
{
- /*
- // read the rules section from the config
- XmlNode node = config.GetChild(PolicyListXmlTag);
- if (node == null) {
- return;
- }
-
- foreach (XmlNode! rule in node.Children) {
- if (rule.Name != "rule") {
- continue;
- }
-
- string! resource = (!)rule.GetAttribute("resource", "");
- if (resource.Equals("")) {
- continue;
- }
- string! aclstr = (!)rule.GetAttribute("acl", "");
- if (aclstr.Equals("")) {
- continue;
- }
-
- policy.AddRule(resource, aclstr);
- }
- */
+ //
+ //// read the rules section from the config
+ //XmlNode node = config.GetChild(PolicyListXmlTag);
+ //if (node == null) {
+ // return;
+ //}
+//
+ //foreach (XmlNode! rule in node.Children) {
+ // if (rule.Name != "rule") {
+ // continue;
+ // }
+//
+ // string! resource = (!)rule.GetAttribute("resource", "");
+ // if (resource.Equals("")) {
+ // continue;
+ // }
+ // string! aclstr = (!)rule.GetAttribute("acl", "");
+ // if (aclstr.Equals("")) {
+ // continue;
+ // }
+//
+ // policy.AddRule(resource, aclstr);
+ //}
+ //
//policy.AddRule("/", "{/groups/anyall}");
aclT.Set("/", new Acl("{$dsanyrw}|{$dsregister}"));
}
@@ -188,7 +187,7 @@ namespace Microsoft.Application.DSP {
ServiceProviderContract.Imp! imp;
ServiceProviderContract.Exp! s;
ServiceProviderContract.NewChannel(out imp, out s);
- status = Register(config.mountPoint, imp);
+ status = Register((!)config.mountPoint, imp);
if (status != 0) {
delete s;
diff --git a/base/Applications/NameSpace/TestDSP/TestDSP.csproj b/base/Applications/NameSpace/TestDSP/TestDSP.csproj
index 12d5d6e..b09169e 100644
--- a/base/Applications/NameSpace/TestDSP/TestDSP.csproj
+++ b/base/Applications/NameSpace/TestDSP/TestDSP.csproj
@@ -1,8 +1,6 @@

+
@@ -10,6 +18,7 @@
+
diff --git a/base/Applications/Network/NetworkCommand.targets b/base/Applications/Network/NetworkCommand.targets
index 8e2f29e..39eff62 100644
--- a/base/Applications/Network/NetworkCommand.targets
+++ b/base/Applications/Network/NetworkCommand.targets
@@ -1,6 +1,13 @@
+
+
-
Exe
diff --git a/base/Applications/Network/Route/Route.cs b/base/Applications/Network/Route/Route.cs
index 6785575..2e99040 100644
--- a/base/Applications/Network/Route/Route.cs
+++ b/base/Applications/Network/Route/Route.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Route.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -26,7 +24,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications.Network {
+namespace Microsoft.Singularity.Applications.Network
+{
[ConsoleCategory(Action="show", HelpMessage="Show network routing information")]
internal class ShowConfig {
@@ -77,7 +76,7 @@ namespace Microsoft.Singularity.Applications.Network {
}
}
- [ConsoleCategory(Action="delete", HelpMessage="Show network routing information")]
+ [ConsoleCategory(Action="delete", HelpMessage="Remove network routing information")]
internal class DeleteConfig {
[Endpoint]
public readonly TRef Stdin;
@@ -88,10 +87,10 @@ namespace Microsoft.Singularity.Applications.Network {
[Endpoint]
public readonly TRef routingRef;
- [StringParameter( "address", Mandatory=true, Position=0, HelpMessage="Address to be deleted")]
+ [StringParameter( "address", Mandatory=true, Position=0, HelpMessage="Address to be removed")]
internal string address;
- [StringParameter( "destination", Mandatory=true, Position=0, HelpMessage="Address to be added")]
+ [StringParameter( "destination", Mandatory=true, Position=0, HelpMessage="destination to be removed")]
internal string destination;
reflective internal DeleteConfig();
@@ -110,7 +109,7 @@ namespace Microsoft.Singularity.Applications.Network {
{
RouteEntry[] in ExHeap routes;
- RoutingContract.Imp routeConn = (config.routingRef).Acquire();
+ RoutingContract.Imp routeConn = ((!)config.routingRef).Acquire();
if (routeConn == null) {
Console.WriteLine("Could not initialize routing endpoint.");
return 1;
@@ -123,8 +122,7 @@ namespace Microsoft.Singularity.Applications.Network {
if (routes == null)
throw new Exception("routes is null");
- for (int i = 0; i < routes.Length; i++)
- {
+ for (int i = 0; i < routes.Length; i++) {
Console.WriteLine("Network : " + ChannelUtils.NetworkToString(routes[i].network));
Console.WriteLine("Gateway : " + ChannelUtils.AddressToString(routes[i].gateway));
Console.WriteLine("Interface address : " + ChannelUtils.AddressToString(routes[i].ifaddr));
@@ -141,34 +139,30 @@ namespace Microsoft.Singularity.Applications.Network {
{
IPv4 gateway;
- RoutingContract.Imp routeConn = (config.routingRef).Acquire();
+ RoutingContract.Imp routeConn = ((!)config.routingRef).Acquire();
if (routeConn == null) {
Console.WriteLine("Could not initialize routing endpoint.");
return 1;
}
routeConn.RecvReady();
- if (IPv4.Parse(config.gateway, out gateway) == false)
- {
+ if (IPv4.Parse(config.gateway, out gateway) == false) {
Console.WriteLine("Could not parse gateway address.");
delete routeConn;
return -1;
}
- try
- {
- // note for some reason the compiler doesn't
+ try {
+ // NOTE: for some reason the compiler doesn't
// realize that ifaddr will definitely be assigned if
// we survive the if/switch-receive sequence. Work
// around that by initializing.
IPv4 ifaddr = new IPv4(0);
- if (config.ifAddress == null)
- {
+ if (config.ifAddress == null) {
routeConn.SendFindHostRoute((uint)gateway);
- switch receive
- {
+ switch receive {
case routeConn.Route(RouteEntry r) :
ifaddr = new IPv4(r.ifaddr);
break;
@@ -184,43 +178,37 @@ namespace Microsoft.Singularity.Applications.Network {
throw new Exception("routeConn channel closed.");
}
}
- else if (IPv4.Parse(config.ifAddress, out ifaddr) == false)
- {
+ else if (IPv4.Parse(config.ifAddress, out ifaddr) == false) {
Console.WriteLine("Could not parse interface address.");
delete routeConn;
return -1;
}
- IPContract.Imp ipConn = (config.ipRef).Acquire();
- if (ipConn == null)
- {
+ IPContract.Imp ipConn = ((!)config.ipRef).Acquire();
+ if (ipConn == null) {
Console.WriteLine("Could not initialize IP endpoint.");
delete routeConn;
return -1;
}
- try
- {
+ try {
bool isLocal;
ipConn.SendIsLocalAddress((uint)ifaddr);
ipConn.RecvIsLocal(out isLocal);
- if (!isLocal)
- {
+ if (!isLocal) {
Console.WriteLine("Proposed interface address is not bound to an interface.");
delete routeConn;
return -1;
}
}
- finally
- {
+ finally {
delete ipConn;
ipConn = null;
}
IPv4Network destination;
- if (IPv4Network.Parse(config.destination, out destination) == false)
- {
+ if (IPv4Network.Parse(config.destination, out destination) == false) {
Console.WriteLine("Could not parse destination address.");
delete routeConn;
return -1;
@@ -231,8 +219,7 @@ namespace Microsoft.Singularity.Applications.Network {
nwrk.netmask = (uint)destination.NetMask;
routeConn.SendAddRoute(nwrk, (uint)gateway, (uint)ifaddr);
- switch receive
- {
+ switch receive {
case routeConn.Err() :
Console.WriteLine("Route could not be added -- it may already exist.");
break;
@@ -245,8 +232,7 @@ namespace Microsoft.Singularity.Applications.Network {
throw new Exception("routeConn channel closed");
}
}
- catch (Exception e)
- {
+ catch (Exception e) {
Console.WriteLine("Exception: {0}", e);
}
delete routeConn;
@@ -255,25 +241,22 @@ namespace Microsoft.Singularity.Applications.Network {
internal static int Delete(DeleteConfig! config)
{
- RoutingContract.Imp routeConn = (config.routingRef).Acquire();
- if (routeConn == null)
- {
+ RoutingContract.Imp routeConn = ((!)config.routingRef).Acquire();
+ if (routeConn == null) {
Console.WriteLine("Could not initialize routing endpoint.");
return 1;
}
routeConn.RecvReady();
IPv4Network destination;
- if (IPv4Network.Parse(config.destination, out destination) == false)
- {
+ if (IPv4Network.Parse(config.destination, out destination) == false) {
Console.WriteLine("Could not parse destination address.");
}
Network destNet = ChannelUtils.NetworkToChannelNetwork(destination);
routeConn.SendFindSpecificNetRoute(destNet);
- switch receive
- {
+ switch receive {
case routeConn.NoRouteFound() :
Console.WriteLine("No route for destination.");
delete routeConn;
@@ -290,8 +273,7 @@ namespace Microsoft.Singularity.Applications.Network {
routeConn.SendDeleteRoute(destNet);
- switch receive
- {
+ switch receive {
case routeConn.NoRouteFound() :
Console.WriteLine("Unexpected error attempting to delete the route");
break;
diff --git a/base/Applications/Network/Route/Route.csproj b/base/Applications/Network/Route/Route.csproj
index acf4023..6d1a213 100644
--- a/base/Applications/Network/Route/Route.csproj
+++ b/base/Applications/Network/Route/Route.csproj
@@ -1,8 +1,6 @@

-
+
Exe
UdpBlast
-
+
diff --git a/base/Applications/Network/UdpGulp/UdpGulp.cs b/base/Applications/Network/UdpGulp/UdpGulp.cs
index e533446..a9a2199 100644
--- a/base/Applications/Network/UdpGulp/UdpGulp.cs
+++ b/base/Applications/Network/UdpGulp/UdpGulp.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: UdpGulp.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -69,7 +67,8 @@ namespace Microsoft.Singularity.Applications.Network
long totalSeconds
)
{
- int bytesThisRound = 0;
+ int bytesThisRound = 0;
+ int packetsThisRound = 0;
DateTime now = DateTime.Now;
DateTime epochEnd = now + TimeSpan.FromSeconds(1);
@@ -84,24 +83,32 @@ namespace Microsoft.Singularity.Applications.Network
// necessarily mean the connection
// is closed.
Thread.Yield();
- break;
- case udpConn.Data(uint addr, ushort port2,
- byte[]! in ExHeap data):
- bytesThisRound += data.Length + FixedHeaderBytes;
- delete data;
- break;
- case udpConn.ChannelClosed():
- throw new Exception("udpConn channel closed");
+ break;
+ case udpConn.Data(uint addr, ushort port2, byte[]! in ExHeap data):
+ bytesThisRound += data.Length + FixedHeaderBytes;
+ packetsThisRound++;
+ delete data;
+ break;
+ case udpConn.ChannelClosed():
+ throw new Exception("udpConn channel closed");
}
now = DateTime.Now;
}
TimeSpan delta = now - epochStart;
- Console.WriteLine(
- "Duration(s) {0:f2} rate(bps) {1:e3} bps",
+ string msg = String.Format(
+ "Duration(s) {0:f2} rate {1:e3} bps, {2:e3} bytes/sec, {3:e3} pps",
delta.TotalSeconds,
- 8.0 * bytesThisRound / delta.TotalSeconds);
+ 8.0 * bytesThisRound / delta.TotalSeconds,
+ 8.0 * bytesThisRound / delta.TotalSeconds,
+ 1.0 * packetsThisRound / delta.TotalSeconds
+ );
+
+ Console.WriteLine(msg);
+ DebugStub.WriteLine(msg);
+
bytesThisRound = 0;
+ packetsThisRound = 0;
epochStart = DateTime.Now;
epochEnd = epochStart + TimeSpan.FromSeconds(1);
}
@@ -137,8 +144,7 @@ namespace Microsoft.Singularity.Applications.Network
Console.WriteLine("Closing connection");
udpConn.SendClose();
}
- catch (Exception e)
- {
+ catch (Exception e) {
Console.WriteLine("Unexpected exception: {0}", e);
}
finally {
@@ -165,7 +171,7 @@ namespace Microsoft.Singularity.Applications.Network
}
ushort port = (ushort) config.port;
- UdpContract.Imp udpConn = (config.udpRef).Acquire();
+ UdpContract.Imp udpConn = ((!)config.udpRef).Acquire();
if (udpConn == null) {
Console.WriteLine("Could not initialize TCP endpoint.");
return 1;
diff --git a/base/Applications/Network/UdpGulp/UdpGulp.csproj b/base/Applications/Network/UdpGulp/UdpGulp.csproj
index 1613eb9..dc40cec 100644
--- a/base/Applications/Network/UdpGulp/UdpGulp.csproj
+++ b/base/Applications/Network/UdpGulp/UdpGulp.csproj
@@ -1,8 +1,6 @@

-
-
-
-
-
- Exe
- PingPongIntTest
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/PingPongIntTest/PingPongIntTest.sg b/base/Applications/PingPongIntTest/PingPongIntTest.sg
deleted file mode 100644
index f937d2d..0000000
--- a/base/Applications/PingPongIntTest/PingPongIntTest.sg
+++ /dev/null
@@ -1,38 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: PingPongIntTest.cs
-//
-// Note: Simple Singularity test program.
-//
-using System;
-using Microsoft.Singularity.V1.Services;
-using Microsoft.Singularity.Processor;
-
-
-namespace Microsoft.Singularity.Applications
-{
- public class PingPongIntTest
- {
- public static int Main(String[] args)
- {
- Console.WriteLine("PingPongIntTest World!");
-
- //uint a, b, c, d;
- //Processor.ReadCpuid(0, out a, out b, out c, out d);
-
- int retval = ProcessService.RunPingPongInt(7);
- if (retval == 0) {
- Console.WriteLine(" Retval: {0} -- successful", retval);
- }
- else {
- Console.WriteLine(" Retval: {0} -- fail", retval);
- }
-
- return 0;
- }
- }
-}
diff --git a/base/Applications/Play/Play.csproj b/base/Applications/Play/Play.csproj
index 79b6801..7db73b6 100644
--- a/base/Applications/Play/Play.csproj
+++ b/base/Applications/Play/Play.csproj
@@ -1,8 +1,6 @@

+
+
+
diff --git a/base/Applications/Pong/Pong.sg b/base/Applications/Pong/Pong.sg
index f4ea4d8..6619c75 100644
--- a/base/Applications/Pong/Pong.sg
+++ b/base/Applications/Pong/Pong.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Pong.cs
-//
// Note:
//
@@ -108,28 +106,27 @@ namespace Microsoft.Singularity.Applications
ErrorCode errorOut;
bool ok = SdsUtils.Bind(devName, ns, exp, out errorOut);
if (!ok) {
- if (errorOut == ErrorCode.ChannelClosed)
- {
+ if (errorOut == ErrorCode.ChannelClosed) {
throw new Exception("Encountered a ChannelClosed while opening Keyboard");
}
}
else {
success = true;
}
- /*
- // ns.SendBind(Bitter.FromString2(devName),exp);
- switch receive {
- case ns.AckBind():
- success = true;
- break;
- case ns.NakBind(rejected,error):
- delete rejected;
- break;
- case ns.ChannelClosed():
- delete ns;
- throw new Exception("ns unexpectedly closed");
- }
- */
+ //
+ //// ns.SendBind(Bitter.FromString2(devName),exp);
+ //switch receive {
+ //case ns.AckBind():
+ //success = true;
+ //break;
+ //case ns.NakBind(rejected,error):
+ //delete rejected;
+ //break;
+ //case ns.ChannelClosed():
+ //delete ns;
+ //throw new Exception("ns unexpectedly closed");
+ //}
+ //
if (!success) {
DebugStub.WriteLine("OpenKeyboard lookup of {0} failed\n",
__arglist(devName));
@@ -446,8 +443,7 @@ namespace Microsoft.Singularity.Applications
while (!done) {
uint key = 0;
keyboard.SendPollKey();
- switch receive
- {
+ switch receive {
case keyboard.AckKey(ikey):
key = ikey;
break;
diff --git a/base/Applications/Runtime/AppRuntime.proj b/base/Applications/Runtime/AppRuntime.proj
deleted file mode 100644
index 9baac18..0000000
--- a/base/Applications/Runtime/AppRuntime.proj
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Runtime/Corlib.Native.proj b/base/Applications/Runtime/Corlib.Native.proj
deleted file mode 100644
index adea05c..0000000
--- a/base/Applications/Runtime/Corlib.Native.proj
+++ /dev/null
@@ -1,337 +0,0 @@
-
-
-
-
-
- $(APPRUNTIMENATIVEDIR)\Corlib.obj
- $(OBJROOT)\$(OBJRELRUNTIMEDIR)
- $(CFLAGS) /Gr /I$(BINDIR) /I$(SINGULARITY_ROOT)\boot\include /DSINGULARITY_PROCESS=1
- $(AFLAGS) /DSINGULARITY_PROCESS
- $(APPRUNTIMEDIR)\Corlib.dll
- $(SINGULARITY_ROOT)\Kernel
- $(APPRUNTIMENATIVEDIR)\native.lib
- $(COLLECTOR_APP)
-
-
-
-
-
-
-
-
-
-
- $(BARTOK_FLAGS) /Singularity
- $(BARTOK_FLAGS) /UnnameTracedPtrs=true
- $(BARTOK_FLAGS) /OmitFramePointer=false
- $(BARTOK_FLAGS) /GCInlineAllocations=false
- $(BARTOK_FLAGS) /GCInlineWriteBarrier=false
- $(BARTOK_FLAGS) /GenCoffLineNumber=false
- $(BARTOK_FLAGS) /WholeProgram=true
- $(BARTOK_FLAGS) /Warnings=true
- $(BARTOK_FLAGS) /DisablePInvoke=true
- $(BARTOK_FLAGS) /BackEndComments=true
- $(BARTOK_FLAGS) $(BARTOK_COLLECTOR)
-
-
- $(CORLIB_BARTOK_FLAGS)
- $(CORLIB_BARTOK_FLAGS) /CompileOnly=true
- $(CORLIB_BARTOK_FLAGS) /Warnings=true
- $(CORLIB_BARTOK_FLAGS) $(BARTOK_COLLECTOR)
- $(CORLIB_BARTOK_FLAGS) /r:$(LIBSDIR)\Singularity.V1.dll
- $(CORLIB_BARTOK_FLAGS) /r:$(ILLSDIR)\Console.ill
- $(CORLIB_BARTOK_FLAGS) /r:$(APPRUNTIMEDIR)\ILHelpers.dll
- $(CORLIB_BARTOK_FLAGS) /out: $(APPRUNTIMENATIVEDIR)\CorLib.obj
- $(CORLIB_BARTOK_FLAGS) /outdir: $(APPRUNTIMENATIVEDIR)
- $(CORLIB_BARTOK_FLAGS) $(APPRUNTIMEDIR)\Corlib.dll
-
-
- /verbosity:silence
- $(TESTAPP_BARTOK_FLAGS) /GenAsmHeader="$(APPRUNTIMENATIVEDIR)\halclass.inc"
- $(TESTAPP_BARTOK_FLAGS) /GenCppHeader="$(APPRUNTIMENATIVEDIR)\halclass.h"
- $(TESTAPP_BARTOK_FLAGS) /IrTreeShake=false
- $(TESTAPP_BARTOK_FLAGS) /IrTreeShakeLate=false
- $(TESTAPP_BARTOK_FLAGS) /out:$(APPRUNTIMENATIVEDIR)\testapp.obj
- $(TESTAPP_BARTOK_FLAGS) /outdir:$(APPRUNTIMENATIVEDIR)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- $(BARTOK_FLAGS) /IrSimpleInliner=false
-
-
-
-
-
-
-
-
- $(BARTOK_FLAGS) /LinkedStacks=true
- $(BARTOK_FLAGS) /SymbolicDebug=true
- $(MASTER)\Native
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Runtime/Full/App.Corlib.csproj b/base/Applications/Runtime/Full/App.Corlib.csproj
new file mode 100644
index 0000000..0417e09
--- /dev/null
+++ b/base/Applications/Runtime/Full/App.Corlib.csproj
@@ -0,0 +1,362 @@
+
+
+
+
+
+
+ true
+ true
+ true
+ false
+ SINGULARITY_PROCESS;ENDPOINT_STRUCT
+ $(DefineConstants);PTR_SIZE_64
+ 169,649
+ Corlib
+ Library
+ none
+ $(SINGULARITY_ROOT)\Kernel
+ ..\..\..\Libraries
+ C#
+ true
+ {F4C22616-B154-496C-A4CF-C49401E52C87}
+
+
+
+
+
+ $(DefineConstants);PAGING
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(COLLECTOR_APP)
+ true
+
+
+
+
+
diff --git a/base/Applications/Runtime/Full/AppRuntime.proj b/base/Applications/Runtime/Full/AppRuntime.proj
new file mode 100644
index 0000000..f966b4d
--- /dev/null
+++ b/base/Applications/Runtime/Full/AppRuntime.proj
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Runtime/Full/Corlib.Contracts.csproj b/base/Applications/Runtime/Full/Corlib.Contracts.csproj
new file mode 100644
index 0000000..9ea25bc
--- /dev/null
+++ b/base/Applications/Runtime/Full/Corlib.Contracts.csproj
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+ Corlib.Contracts
+ Library
+ true
+ ENDPOINT_STRUCT;SINGULARITY;PTR_SIZE_32;_NEW_CLASSLOADER;NODEFAULTLIB;NOOWNERSHIPCHECK
+ $(APPRUNTIMEDIR)\Corlib.dll
+ false
+ true
+ $(APPRUNTIMEDIR)
+ true
+ $(SINGULARITY_ROOT)\Kernel\SpecSharp.Contracts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Runtime/Full/Corlib.Native.proj b/base/Applications/Runtime/Full/Corlib.Native.proj
new file mode 100644
index 0000000..5b34ee9
--- /dev/null
+++ b/base/Applications/Runtime/Full/Corlib.Native.proj
@@ -0,0 +1,500 @@
+
+
+
+
+
+
+
+
+
+ $(APPRUNTIMENATIVEDIR)
+ $(APPRUNTIMENATIVEDIR)\Corlib.obj
+ $(OBJROOT)\$(OBJRELRUNTIMEDIR)
+ $(CFLAGS) /I"$(BINDIR)" /DSINGULARITY_PROCESS=1
+ $(AFLAGS) /DSINGULARITY_PROCESS
+ $(APPRUNTIMEDIR)\Corlib.dll
+ $(SINGULARITY_ROOT)\Kernel
+ $(APPRUNTIMENATIVEDIR)\native.$(Runtime).lib
+ $(COLLECTOR_APP)
+
+
+
+ $(CFLAGS) /Gr /DISA_X86=1 /DPTR_SIZE_32=1
+ $(ACFLAGS) /DISA_X86=1 /DPTR_SIZE_32=1
+
+
+
+ $(CFLAGS) /Gr /DISA_X64=1 /DPTR_SIZE_64=1
+ $(ACFLAGS) /DISA_X64=1 /DPTR_SIZE_64=1
+
+
+
+ $(CFLAGS) /QRarch5 /QRimplicit-import- /DISA_ARM=1 /DPTR_SIZE_32=1
+ $(ACFLAGS) /DISA_ARM=1 /DPTR_SIZE_32=1
+
+
+
+
+
+
+
+ $(BARTOK_FLAGS) /Singularity
+ $(BARTOK_FLAGS) /UnnameTracedPtrs=true
+ $(BARTOK_FLAGS) /OmitFramePointer=false
+ $(BARTOK_FLAGS) /GCInlineArrayAllocations=false
+ $(BARTOK_FLAGS) /GCInlineFixedAllocations=false
+ $(BARTOK_FLAGS) /GCIntrinsicFixedAllocations=false
+ $(BARTOK_FLAGS) /GCInlineWriteBarrier=false
+ $(BARTOK_FLAGS) /GenCoffLineNumber=false
+ $(BARTOK_FLAGS) /WholeProgram=true
+ $(BARTOK_FLAGS) /Warnings=true
+ $(BARTOK_FLAGS) /DisablePInvoke=true
+ $(BARTOK_FLAGS) $(BARTOK_COLLECTOR)
+
+
+ $(CORLIB_BARTOK_FLAGS)
+ $(CORLIB_BARTOK_FLAGS) /CompileOnly=true
+ $(CORLIB_BARTOK_FLAGS) /Warnings=true
+ $(CORLIB_BARTOK_FLAGS) $(BARTOK_COLLECTOR)
+ $(CORLIB_BARTOK_FLAGS) /r:"$(LIBSDIR)\Singularity.V1.App.dll"
+ $(CORLIB_BARTOK_FLAGS) /r:"$(APPILLSDIR)\Console.App.ill"
+ $(CORLIB_BARTOK_FLAGS) /out: "$(APPRUNTIMENATIVEDIR)\CorLib.obj"
+ $(CORLIB_BARTOK_FLAGS) /outdir: "$(APPRUNTIMENATIVEDIR)"
+ $(CORLIB_BARTOK_FLAGS) "$(APPRUNTIMEDIR)\Corlib.dll"
+
+
+ /verbosity:silence
+ $(TESTAPP_BARTOK_FLAGS) /GenAsmHeader="$(APPRUNTIMENATIVEDIR)\halclass.inc"
+ $(TESTAPP_BARTOK_FLAGS) /GenCppHeader="$(APPRUNTIMENATIVEDIR)\halclass.h"
+ $(TESTAPP_BARTOK_FLAGS) /IrTreeShake=false
+ $(TESTAPP_BARTOK_FLAGS) /IrTreeShakeLate=false
+ $(TESTAPP_BARTOK_FLAGS) /out:"$(APPRUNTIMENATIVEDIR)\testapp.obj"
+ $(TESTAPP_BARTOK_FLAGS) /outdir:"$(APPRUNTIMENATIVEDIR)"
+
+
+
+
+
+
+
+
+
+
+
+
+ $(BARTOK_FLAGS) /IrSimpleInliner=false
+ $(BARTOK_FLAGS) /CoalesceExceptionThrow=false
+
+
+
+
+ $(BARTOK_FLAGS) /LinkedStacks=true
+ $(BARTOK_FLAGS) /StackOverflowChecks=true
+ $(BARTOK_FLAGS) /SymbolicDebug=true
+ $(AFLAGS) /I"$(SINGULARITY_ROOT)\kernel\native\ix"
+ $(AFLAGS) /I"$(SINGULARITY_ROOT)\kernel\native\ix86"
+
+
+
+ $(BARTOK_FLAGS) /PhoenixMirOpts=false
+ $(BARTOK_FLAGS) /TargetArch=ARM
+ $(BARTOK_FLAGS) /EnableIrExposeAllocationCall=true
+ $(AFLAGS) /I"$(SINGULARITY_ROOT)\kernel\native\arm"
+
+
+
+ $(BARTOK_FLAGS) /x64
+ $(BARTOK_FLAGS) /LinkedStacks=true
+ $(BARTOK_FLAGS) /StackOverflowChecks=true
+ $(AFLAGS) /I"$(SINGULARITY_ROOT)\kernel\native\ix"
+ $(AFLAGS) /I"$(SINGULARITY_ROOT)\kernel\native\ix64"
+
+
+
+
+
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\
+ Kernel\Native\ix64\
+ Kernel\Native\ix86\
+ Kernel\Singularity\Isal\
+
+ Bartok\runtime\shared\native\arch\$(BARTOK_MACHINE)\
+ Bartok\runtime\singularity\native\arch\$(BARTOK_MACHINE)\
+ Bartok\runtime\singularity\native\arch\$(BARTOK_MACHINE)\
+
+
+
+
+ Kernel\Native\ix\
+ Kernel\Native\ix\
+ Kernel\Native\ix\
+ Kernel\Singularity\Isal\ix\
+
+
+
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+ Kernel\Native\ix86\
+
+
+
+ Kernel\Native\ix64\
+ Kernel\Native\ix64\
+ Kernel\Native\ix64\
+ Kernel\Native\ix64\
+ Kernel\Native\ix64\
+
+
+
+ Native\arm\
+ Kernel\Native\arm\
+ Kernel\Native\arm\
+ Kernel\Native\arm\
+ Kernel\Native\arm\
+ Kernel\Singularity\Isal\Arm\
+ Kernel\Singularity\Isal\Arm\
+
+
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+ Kernel\Native\Arm\Crt\
+
+
+
+ Kernel\Native\arm\
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Runtime/Corlibsg.csproj b/base/Applications/Runtime/Full/Corlibsg.csproj
similarity index 83%
rename from base/Applications/Runtime/Corlibsg.csproj
rename to base/Applications/Runtime/Full/Corlibsg.csproj
index e8a90b5..33b0c79 100644
--- a/base/Applications/Runtime/Corlibsg.csproj
+++ b/base/Applications/Runtime/Full/Corlibsg.csproj
@@ -1,15 +1,13 @@
-
+
Corlibsg
@@ -19,8 +17,7 @@
-
-
+
@@ -31,7 +28,7 @@
-
+
true
diff --git a/base/Applications/Runtime/Full/Microsoft.SingSharp.Runtime.App.csproj b/base/Applications/Runtime/Full/Microsoft.SingSharp.Runtime.App.csproj
new file mode 100644
index 0000000..efa0adf
--- /dev/null
+++ b/base/Applications/Runtime/Full/Microsoft.SingSharp.Runtime.App.csproj
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+ Microsoft.SingSharp.Runtime
+ Library
+ true
+ NOOWNERSHIPCHECK;NODEFAULTLIB
+ true
+ $(SINGULARITY_ROOT)\Kernel\SingSharp.Runtime
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Runtime/Full/Native/arm/liesapp.asm b/base/Applications/Runtime/Full/Native/arm/liesapp.asm
new file mode 100644
index 0000000..41a1233
--- /dev/null
+++ b/base/Applications/Runtime/Full/Native/arm/liesapp.asm
@@ -0,0 +1,66 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Microsoft Research Singularity ARM Bootstrap
+;;;
+;;;
+
+ IMPORT |?brtmain@@3P6AHPAUClassVector_Class_System_String@@@ZA|
+
+|defining ?g_CallMain@Class_Microsoft_Singularity_AppRuntime@@SAHPAUClassVector_Class_System_String@@@Z| EQU 1
+
+ include hal.inc
+
+ MACRO
+ BREAKPOINT
+ ;; bkpt 0xffff
+ swi 0xffff03
+ MEND
+
+
+ TEXTAREA
+
+;;;
+;;; "void __cdecl Draw(unsigned char)"
+;;;
+ EXPORT |?Draw@@YAXE@Z|
+|?Draw@@YAXE@Z| PROC
+ mov pc, lr
+ ENDP
+
+;;;
+;;; "public: static int Class_Microsoft_Singularity_AppRuntime::g_CallMain(struct ClassVector_Class_System_String *)"
+;;;
+ LEAF_ENTRY ?g_CallMain@Class_Microsoft_Singularity_AppRuntime@@SAHPAUClassVector_Class_System_String@@@Z
+
+ ldr r1, brtmain
+ ldr r1, [r1]
+ mov pc, r1
+
+brtmain DCD |?brtmain@@3P6AHPAUClassVector_Class_System_String@@@ZA|
+ NESTED_END
+
+;;;
+;;;
+;;;
+ LEAF_ENTRY fmod
+ BREAKPOINT
+ bx lr
+ LEAF_END
+
+;;;
+;;;
+;;;
+ LEAF_ENTRY fmodf
+ BREAKPOINT
+ bx lr
+ LEAF_END
+
+;;;
+;;;
+;;;
+ LEAF_ENTRY ?Halt@@YAXXZ
+ DCD 0xe320f003 ;; WFI Note: ARMv7 Specific.
+ bx lr
+ LEAF_END
+
+ END
diff --git a/base/Applications/Runtime/Full/Singularity.V1.App.csproj b/base/Applications/Runtime/Full/Singularity.V1.App.csproj
new file mode 100644
index 0000000..e1c049d
--- /dev/null
+++ b/base/Applications/Runtime/Full/Singularity.V1.App.csproj
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+ Singularity.V1.App
+ Library
+ 2
+ true
+ true
+ true
+ C#
+ $(LIBSDIR)
+ $(SINGULARITY_ROOT)\Libraries\Singularity.V1
+
+
+
+ $(DefineConstants);
+ $(DefineConstants)CE_PC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Runtime/Full/Singularity/AppRuntime.cs b/base/Applications/Runtime/Full/Singularity/AppRuntime.cs
new file mode 100644
index 0000000..fc6a662
--- /dev/null
+++ b/base/Applications/Runtime/Full/Singularity/AppRuntime.cs
@@ -0,0 +1,303 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Threading;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+using Microsoft.Bartok.Runtime;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.V1.Services;
+
+using Microsoft.Singularity.Eventing;
+
+[assembly: AssemblyTitle("Microsoft.Singularity")]
+[assembly: AssemblyProduct("Microsoft Research Singularity Runtime")]
+[assembly: AssemblyCompany("Microsoft Corporation")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyKeyFile("public.snk")]
+[assembly: AssemblyDelaySign(true)]
+
+namespace Microsoft.Singularity
+{
+
+ [NoCCtor]
+ [CLSCompliant(false)]
+ [AccessedByRuntime("referenced from hal.cpp")]
+ public class AppRuntime
+ {
+ // Note: This function is called by Hal.cpp.
+ [AccessedByRuntime("referenced from hal.cpp")]
+ public static unsafe int AppStart(Type userClass)
+ {
+ System.GCs.Transitions.ThreadStart();
+
+ int result = 0;
+
+ string arg0 = "(unknown)";
+
+ try {
+ Tracing.Log(Tracing.Audit, "Runtime.Main()");
+
+ // Initialize the primitive runtime, which calls the
+ // class constructor for Runtime().
+ VTable.Initialize((RuntimeType)typeof(AppRuntime));
+ //VTable.ParseArgs(args);
+
+ Tracing.Log(Tracing.Audit, "Enabling GC Heap");
+ GC.EnableHeap();
+ Controller.InitializeSystem();
+ GCProfilerLogger.StartProfiling();
+
+ InitializeConsole();
+
+ SetDebuggerPresence(DebugService.IsDebuggerPresent());
+
+ int argCount = 0;
+ int argMaxLen = 0;
+ for (;; argCount++) {
+ int len = ProcessService.GetStartupArg(argCount, null, 0);
+ if (len == 0) {
+ break;
+ }
+ if (argMaxLen < len) {
+ argMaxLen = len;
+ }
+ }
+ char[] argArray = new char [argMaxLen];
+ string[] args = new string[argCount];
+ for (int arg = 0; arg < argCount; arg++) {
+ fixed (char *argptr = &argArray[0]) {
+ int len = ProcessService.GetStartupArg(arg,
+ argptr,
+ argArray.Length);
+ args[arg] = String.StringCTOR(argptr, 0, len);
+ if (arg == 0)
+ arg0 = args[arg];
+ }
+ }
+
+#if DEBUG || true
+ // Record the first argument passed to this program, under the assumption that
+ // this is the application name. We use this string in DebugStub.WriteLine.
+ // Also, if the name has an extension, such as ".x86", chop it off.
+ // Also chop off any path prefix, such as "/init/".
+ appName = arg0;
+ int index = appName.LastIndexOf('.');
+ if (index != -1)
+ appName = appName.Substring(0, index);
+ index = appName.LastIndexOf('/');
+ if (index != -1)
+ appName = appName.Substring(index + 1);
+
+ // The default DebugName value for the main thread is "main";
+ // apps can override this by setting Thread.CurrentThread.DebugName.
+ Thread mainThread = Thread.CurrentThread;
+ if (mainThread != null) {
+ mainThread.DebugName = "main";
+ }
+#endif
+
+ if (userClass != null) {
+ VTable.initType((RuntimeType)userClass);
+ }
+
+ result = CallMain(args);
+ if (!MainReturnsInt()) result = 0;
+
+ Tracing.Log(Tracing.Audit, "Main thread exited [{0}]",
+ (UIntPtr)unchecked((uint)result));
+ }
+ catch (Exception e) {
+ Tracing.Log(Tracing.Fatal, "Failed with exception {0}.{1}",
+ e.GetType().Namespace, e.GetType().Name);
+ Tracing.Log(Tracing.Trace, "Exception message was {0}",
+ e.ToString());
+ TopLevelException(e);
+ result = -1;
+ }
+
+ Thread.RemoveThread(Thread.CurrentThread.threadIndex);
+ Thread.JoinAll();
+
+ try {
+ FinalizeConsole();
+ }
+ catch (Exception e) {
+ Tracing.Log(Tracing.Fatal, "An exception occurred while shutting down the console: {0}",
+ e.ToString());
+ }
+
+ Controller.Finalize();
+ Tracing.Log(Tracing.Audit, "Runtime shutdown started.");
+ VTable.Shutdown(result);
+ Tracing.Log(Tracing.Audit, "Runtime exiting [{0}]",
+ (UIntPtr)unchecked((uint)result));
+ return result;
+ }
+
+
+ ///
+ /// This method runs when the "main" thread terminates by throwing an exception.
+ /// It is a separate method, rather than simply code within the AppStart method,
+ /// in order to make life easier during debugging.
+ ///
+ ///
+ private static void TopLevelException(Exception/*!*/ ex)
+ {
+ DebugStub.WriteLine("AppRuntime: Main app thread terminated with exception:");
+ for (Exception focus = ex; focus != null; focus = focus.InnerException) {
+ DebugStub.WriteLine("{0}: {1}", __arglist(focus.GetType().FullName, focus.Message));
+ }
+ }
+
+#if DEBUG || true
+ ///
+ /// Returns the name of the application, as determined by the first parameter
+ /// passed in the argv block. This property is only present on DEBUG builds
+ /// (Debug and Prototype). It is provided for DebugStub.WriteLine, to provide
+ /// useful debugging spew.
+ ///
+ public static string AppName
+ {
+ [NoHeapAllocation]
+ get
+ {
+ return appName;
+ }
+ }
+
+ private static string appName;
+#endif
+
+ [AccessedByRuntime("output to header : defined in hal.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(256)]
+ private static extern int CallMain(String[] args);
+
+ [AccessedByRuntime("output to header: defined in hal.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(256)]
+ private static extern bool MainReturnsInt();
+
+ [AccessedByRuntime("output to header: defined in hal.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(256)]
+ private static extern void SetDebuggerPresence(bool debuggerPresent);
+
+ internal static void Shutdown(int exitCode)
+ {
+ //
+ // Gracefully close down the process.
+ //
+ Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0})",
+ (UIntPtr)unchecked((uint)exitCode));
+
+ DebugStub.WriteLine("Runtime.Shutdown({0})", __arglist(exitCode));
+
+ VTable.Shutdown(exitCode);
+ Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0}) terminating",
+ (UIntPtr)unchecked((uint)exitCode));
+ ProcessService.Stop(exitCode);
+ }
+
+ internal static void Stop(int exitCode)
+ {
+ //
+ // Halt the process immediately.
+ //
+ Tracing.Log(Tracing.Audit, "Runtime.Stop({0})",
+ (UIntPtr)unchecked((uint)exitCode));
+
+ DebugStub.WriteLine("Runtime.Stop({0})", __arglist(exitCode));
+
+ ProcessService.Stop(exitCode);
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ [NoHeapAllocation]
+ public static UIntPtr AddressOf(Object o)
+ {
+ return Magic.addressOf(o);
+ }
+
+ [NoHeapAllocation]
+ public static UIntPtr SizeOf(Object o)
+ {
+ return System.GCs.ObjectLayout.Sizeof(o);
+ }
+
+ public static void InitType(Type ty)
+ {
+ VTable.initType((RuntimeType) ty);
+ }
+
+ public static void DumpPageTable()
+ {
+ System.GCs.PageTable.Dump("PageTable");
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ public static bool EnableGCVerify
+ {
+ get {
+ return VTable.enableGCVerify;
+ }
+ set {
+ VTable.enableGCVerify = value;
+ }
+ }
+
+ public static bool EnableGCAccounting
+ {
+ get {
+ return VTable.enableGCAccounting;
+ }
+ set {
+ VTable.enableGCAccounting = value;
+ if (value == true) {
+ System.GCs.MemoryAccounting.Initialize(GC.gcType);
+ }
+ }
+ }
+
+ public static uint GCPerfCounter
+ {
+ get {
+ return System.GC.perfCounter;
+ }
+ set {
+ System.GC.perfCounter = value;
+ }
+ }
+
+ ///
+ /// This stub method is provided for so that System.Console.dll can override it for those
+ /// apps that want a console. This is necessary, in order to initialize and shutdown the
+ /// console at the right time.
+ ///
+ private static void InitializeConsole()
+ {
+ }
+
+ ///
+ /// This stub method is provided for so that System.Console.dll can override it for those
+ /// apps that want a console. This is necessary, in order to initialize and shutdown the
+ /// console at the right time.
+ ///
+ private static void FinalizeConsole()
+ {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/Singularity/CorlibSgAssemblyInfo.sg b/base/Applications/Runtime/Full/Singularity/CorlibSgAssemblyInfo.sg
new file mode 100644
index 0000000..f707cbf
--- /dev/null
+++ b/base/Applications/Runtime/Full/Singularity/CorlibSgAssemblyInfo.sg
@@ -0,0 +1,8 @@
+using System.Reflection;
+
+[assembly: AssemblyTitle("Corlibsg")]
+[assembly: AssemblyProduct("Microsoft Research Singularity Operating System")]
+[assembly: AssemblyCompany("Microsoft Corporation")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyKeyFile("public.snk")]
+[assembly: AssemblyDelaySign(true)]
diff --git a/base/Applications/Runtime/Full/Singularity/DebugStub.cs b/base/Applications/Runtime/Full/Singularity/DebugStub.cs
new file mode 100644
index 0000000..2e282d8
--- /dev/null
+++ b/base/Applications/Runtime/Full/Singularity/DebugStub.cs
@@ -0,0 +1,364 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+using Microsoft.Singularity.V1.Services;
+
+namespace Microsoft.Singularity
+{
+ [NoCCtor]
+ [CLSCompliant(false)]
+ [AccessedByRuntime("referenced in halkd.cpp")]
+ public class DebugStub
+ {
+ /////////////////////////////////////////////////////// Print Methods.
+ //
+ [NoHeapAllocation]
+ public static void Print(byte value)
+ {
+ Print("{0:x2}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(ushort value)
+ {
+ Print("{0:x4}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(uint value)
+ {
+ Print("{0:x8}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(ulong value)
+ {
+ Print("{0:x}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(UIntPtr value)
+ {
+ Print("{0:x8}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(sbyte value)
+ {
+ Print("{0}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(short value)
+ {
+ Print("{0}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(int value)
+ {
+ Print("{0}", __arglist(value));
+ }
+
+ [NoHeapAllocation]
+ public static void Print(long value)
+ {
+ Print("{0}", __arglist(value));
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+
+ [NoHeapAllocation]
+ public static void Print(String value)
+ {
+ if (value != null) {
+ Print(value, new ArgIterator());
+ }
+ }
+
+ [NoHeapAllocation]
+ public static void Print(String format, __arglist)
+ {
+ Print(format, new ArgIterator(__arglist));
+ }
+
+ [NoHeapAllocation]
+ public static unsafe void Print(String format, ArgIterator args)
+ {
+ WriteLine(format, args);
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+
+ [NoHeapAllocation]
+ public static void Write(String value)
+ {
+ if (value != null) {
+ WriteLine(value, new ArgIterator());
+ }
+ }
+
+ [NoHeapAllocation]
+ public static void Write(String format, __arglist)
+ {
+ Write(format, new ArgIterator(__arglist));
+ }
+
+ [NoHeapAllocation]
+ public static unsafe void Write(String format, ArgIterator args)
+ {
+ WriteLine(format, args);
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ [NoHeapAllocation]
+ public static void WriteLine()
+ {
+ WriteLine("", new ArgIterator());
+ }
+
+ [NoHeapAllocation]
+ public static void WriteLine(String value)
+ {
+ if (value != null) {
+ WriteLine(value, new ArgIterator());
+ }
+ }
+
+ [NoHeapAllocation]
+ public static void WriteLine(String format, __arglist)
+ {
+ WriteLine(format, new ArgIterator(__arglist));
+ }
+
+ [NoHeapAllocation]
+ public static unsafe void WriteLine(String format, ArgIterator args)
+ {
+ char *buffer;
+ int length;
+ int used = 0;
+
+ DebugService.PrintBegin(out buffer, out length);
+ try {
+ if (buffer != null) {
+ AddLineHeader(buffer, ref used, length);
+ int format_used = String.LimitedFormatTo(format, args, buffer+used, length-used);
+ used += format_used;
+
+ // If the line had \r or \n at the start, replace with spaces.
+ for (int i = 0; i < used; i++) {
+ char c = buffer[i];
+ if (c == '\r' || c == '\n') {
+ buffer[i] = ' ';
+ }
+ else {
+ break;
+ }
+ }
+
+ // Remove whitespace (including \r\n) from the end.
+ while (used > 0) {
+ char c = buffer[used - 1];
+ if (c == ' ' || c == '\r' || c == '\n' || c == '\t') {
+ used--;
+ }
+ else {
+ break;
+ }
+ }
+
+ // Add our own \r\n
+ if (used < length) {
+ buffer[used++] = '\n';
+ }
+ }
+ }
+ finally {
+ DebugService.PrintComplete(buffer, used);
+ }
+ }
+
+ ///
+ /// This method adds prefix to each line sent to the debugger, containing the app name,
+ /// process id, thread id, and thread name. The thread name can be changed by setting
+ /// the DebugName property of a thread.
+ ///
+ [NoHeapAllocation]
+ private static unsafe void AddLineHeader(char* buffer, ref int length, int maxLength)
+ {
+ uint processId = ProcessService.GetCurrentProcessId();
+ uint threadId = unchecked((uint)Thread.GetCurrentThreadIndex());
+
+ string appName;
+ string threadName;
+#if DEBUG
+ appName = AppRuntime.AppName;
+ if (appName == null)
+ appName = "?";
+
+ Thread currentThread = Thread.CurrentThread;
+ if (currentThread != null) {
+ threadName = currentThread.DebugName;
+ if (threadName == null) {
+ threadName = "";
+ }
+ }
+ else {
+ threadName = "";
+ }
+#else
+ appName = "?";
+ threadName = "";
+#endif
+
+ InsertFormat(buffer, ref length, maxLength, "[{0,10} p{1,2} t{2,2} {3,6}] ", __arglist(appName, processId, threadId, threadName));
+ }
+
+ [NoHeapAllocation]
+ private static unsafe void InsertFormat(char* buffer, ref int length, int maxLength, String format, __arglist)
+ {
+ int count = String.LimitedFormatTo(format, new ArgIterator(__arglist), &buffer[length], maxLength - length);
+ length += count;
+ }
+
+ ////////////////////////////////////////////////////// Assert Methods.
+ //
+ [NoHeapAllocation]
+ public static void NotImplemented()
+ {
+ failAssert("Not implemented.");
+ }
+
+ [NoHeapAllocation]
+ public static void NotImplemented(String msg)
+ {
+ failAssert(/*"Not implemented: "+*/msg);
+ }
+
+ [Conditional("DEBUG")]
+ [NoInline]
+ [NoHeapAllocation]
+ public static void NotReached()
+ {
+ failAssert("Unreachable code reached.");
+ }
+
+ [Conditional("DEBUG")]
+ [NoInline]
+ [NoHeapAllocation]
+ public static void NotReached(String msg)
+ {
+ failAssert(/*"Unreachable code reached: "+*/msg);
+ }
+
+ [Conditional("DEBUG")]
+ [NoInline]
+ [ManualRefCounts]
+ [NoHeapAllocation]
+ public static void Assert(bool expr)
+ {
+ if (!expr) {
+ failAssert(null);
+ }
+ }
+
+ [Conditional("DEBUG")]
+ [NoInline]
+ [ManualRefCounts]
+ [NoHeapAllocation]
+ public static void Deny(bool expr)
+ {
+ if (expr) {
+ failAssert(null);
+ }
+ }
+
+ [Conditional("DEBUG")]
+ [NoInline]
+ [ManualRefCounts]
+ [NoHeapAllocation]
+ public static void Assert(bool expr, String s)
+ {
+ if (!expr) {
+ failAssert(s);
+ }
+ }
+
+ [Conditional("DEBUG")]
+ [NoInline]
+ [NoHeapAllocation]
+ public static void Deny(bool expr, String s)
+ {
+ if (expr) {
+ failAssert(s);
+ }
+ }
+
+ [ManualRefCounts]
+ [NoHeapAllocation]
+ private static void failAssert(String s)
+ {
+ if (s != null) {
+ Print("Assertion failed: {0}", __arglist(s));
+ }
+ else {
+ Print("Assertion failed.");
+ }
+ Break();
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ [NoHeapAllocation]
+ public static ulong ReadPerfCounter(uint which)
+ {
+ return DebugService.ReadPerfCounter(which);
+ }
+
+
+ [NoHeapAllocation]
+ public static bool WritePerfCounter(uint which, ulong value)
+ {
+ return DebugService.WritePerfCounter(which, value);
+ }
+
+ [NoHeapAllocation]
+ public static bool AddToPerfCounter(uint which, ulong value)
+ {
+ return DebugService.AddToPerfCounter(which, value);
+ }
+
+ /////////////////////////////////////////////////////// State Methods.
+ //
+#if true
+ [AccessedByRuntime("output to header : defined in halkd.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(638)]
+ [NoHeapAllocation]
+ public static extern void Break();
+#else
+ [NoHeapAllocation]
+ public static void Break()
+ {
+ DebugService.Break();
+ }
+#endif
+ }
+}
diff --git a/base/Applications/Runtime/Full/Singularity/Directory/NameService.sg b/base/Applications/Runtime/Full/Singularity/Directory/NameService.sg
new file mode 100644
index 0000000..760f53f
--- /dev/null
+++ b/base/Applications/Runtime/Full/Singularity/Directory/NameService.sg
@@ -0,0 +1,28 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+// This file provides an implementation of Naming.DirectoryService.NewClientEndpoint
+// that calls through the ABI to retrieve the name-service channel endpoint.
+// This is for use by applications; kernel components can call the "real"
+// DirectoryService class directly.
+//
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Naming;
+using Microsoft.Singularity.V1.Services;
+
+namespace Microsoft.Singularity.Directory
+{
+ public class DirectoryService
+ {
+ public static unsafe DirectoryServiceContract.Imp!:Ready NewClientEndpoint()
+ {
+ return (DirectoryServiceContract.Imp!)ProcessService.GetNamespaceEndpoint();
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Singularity/Io/IoIrq.cs b/base/Applications/Runtime/Full/Singularity/Io/IoIrq.cs
similarity index 82%
rename from base/Applications/Runtime/Singularity/Io/IoIrq.cs
rename to base/Applications/Runtime/Full/Singularity/Io/IoIrq.cs
index 326c90e..147e979 100644
--- a/base/Applications/Runtime/Singularity/Io/IoIrq.cs
+++ b/base/Applications/Runtime/Full/Singularity/Io/IoIrq.cs
@@ -4,7 +4,7 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: IoIrq.cs - Process Code
+// Note: Process Code
//
using System;
@@ -27,8 +27,7 @@ namespace Microsoft.Singularity.Io
~IoIrq()
{
- if (handle.id != UIntPtr.Zero)
- {
+ if (handle.id != UIntPtr.Zero) {
ReleaseInterrupt();
}
}
@@ -55,8 +54,7 @@ namespace Microsoft.Singularity.Io
public bool WaitForInterrupt()
{
- if (handle.id != UIntPtr.Zero)
- {
+ if (handle.id != UIntPtr.Zero) {
return InterruptHandle.Wait(handle);
}
return false;
@@ -64,16 +62,14 @@ namespace Microsoft.Singularity.Io
public void Pulse()
{
- if (handle.id != UIntPtr.Zero)
- {
+ if (handle.id != UIntPtr.Zero) {
InterruptHandle.Pulse(handle);
}
}
public bool AckInterrupt()
{
- if (handle.id != UIntPtr.Zero)
- {
+ if (handle.id != UIntPtr.Zero) {
return InterruptHandle.Ack(handle);
}
return false;
diff --git a/base/Applications/Runtime/Full/Singularity/Io/PciPort.cs b/base/Applications/Runtime/Full/Singularity/Io/PciPort.cs
new file mode 100644
index 0000000..5a6b075
--- /dev/null
+++ b/base/Applications/Runtime/Full/Singularity/Io/PciPort.cs
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+
+using Microsoft.Singularity.V1.Services;
+
+namespace Microsoft.Singularity.Io
+{
+ [CLSCompliant(false)]
+ public sealed class PciPort
+ {
+ private PciPortHandle handle;
+
+ internal PciPort(PciPortHandle pciPortHandle)
+ {
+ this.handle = pciPortHandle;
+ }
+
+ ~PciPort()
+ {
+ }
+
+ public void Write8(int offset, byte value)
+ {
+ if (!PciPortHandle.Write8(handle, offset, value)) {
+ DebugStub.Break();
+ }
+ }
+
+ public void Write16(int offset, ushort value)
+ {
+ if (!PciPortHandle.Write16(handle, offset, value)) {
+ DebugStub.Break();
+ }
+ }
+
+ public void Write32(int offset, uint value)
+ {
+ if (!PciPortHandle.Write32(handle, offset, value)) {
+ DebugStub.Break();
+ }
+ }
+
+ public byte Read8(int offset)
+ {
+ return Read8Impl(offset);
+ }
+
+ public ushort Read16(int offset)
+ {
+ return Read16Impl(offset);
+ }
+
+ public uint Read32(int offset)
+ {
+ return Read32Impl(offset);
+ }
+
+ private unsafe byte Read8Impl(int offset)
+ {
+ byte v;
+
+ if (PciPortHandle.Read8Impl(handle, offset, &v)) {
+ return v;
+ }
+ else {
+ DebugStub.Break();
+ return 0;
+ }
+ }
+
+ private unsafe ushort Read16Impl(int offset)
+ {
+ ushort v;
+
+ if (PciPortHandle.Read16Impl(handle, offset, &v)) {
+ return v;
+ }
+ else {
+ DebugStub.Break();
+ return 0;
+ }
+ }
+
+ private unsafe uint Read32Impl(int offset)
+ {
+ uint v;
+
+ if (PciPortHandle.Read32Impl(handle, offset, &v)) {
+ return v;
+ }
+ else {
+ DebugStub.Break();
+ return 0;
+ }
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Singularity/Io/PipeLookAhead.sg b/base/Applications/Runtime/Full/Singularity/Io/PipeLookAhead.sg
similarity index 84%
rename from base/Applications/Runtime/Singularity/Io/PipeLookAhead.sg
rename to base/Applications/Runtime/Full/Singularity/Io/PipeLookAhead.sg
index e73c2da..54557fb 100644
--- a/base/Applications/Runtime/Singularity/Io/PipeLookAhead.sg
+++ b/base/Applications/Runtime/Full/Singularity/Io/PipeLookAhead.sg
@@ -4,21 +4,21 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: PipeLookAhead.sg
-//
// Note: Implements a selectable abstraction that looks ahead on a pipe channels
// for control-C and exports separate logical receivable messages for
-// non-control-C characters and control-C, effectively allowing one to
-// consume Ctrl-C's out of order.
+// non-control-C characters and control-C, effectively allowing one to
+// consume Ctrl-C's out of order.
//
+
using System;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.V1.Threads;
-using Tty = Microsoft.Singularity.Io.Tty2006;
+using Tty = Microsoft.Singularity.Io.Tty;
-namespace Microsoft.Singularity.Io {
+namespace Microsoft.Singularity.Io
+{
public sealed class PipeLookAhead : ITracked, ISelectable {
@@ -60,7 +60,7 @@ namespace Microsoft.Singularity.Io {
}
}
-
+
public CircularBuffer(int lookAhead) {
this.buffer = new[ExHeap] char[lookAhead+256];
this.nextReadIndex = 0;
@@ -82,7 +82,7 @@ namespace Microsoft.Singularity.Io {
}
public void Add(char[]! in ExHeap buffer, int index, int count) {
EnsureCapacity(count);
- for (int i=0; ithread;
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // These methods are currently marked external because they are used
+ // by device drivers. We need a tool to verify that device drivers
+ // are in fact using them correctly!
+ //
+
+ [NoHeapAllocation]
+ [AccessedByRuntime("referenced from c++")]
+ public static bool DisableLocalPreemption()
+ {
+ // BUGBUG: this is a placeholder until the new scheduler work
+ // gets implemented, and we'll be able to control the local scheduling
+
+ // The current usage in SIPs seem only to rely on disabling preemption for
+ // performance reasons, not for corectness.
+ // return PlatformService.DisableInterrupts();
+
+ return false;
+ }
+
+ [NoHeapAllocation]
+ [AccessedByRuntime("referenced from c++")]
+ public static void RestoreLocalPreemption(bool enabled)
+ {
+ // Same as above, use the interrupts disabled temporary, until the scheduller
+ // changes with a SIP hierarcy get integrated.
+
+ // The current usage in SIPs seem only to rely on disabling preemption for
+ // performance reasons, not for corectness.
+ // PlatformService.RestoreInterrupts(enabled);
+ }
+
+ }
+}
diff --git a/base/Kernel/System.Compiler.Runtime/System.Compiler.Runtime.App.csproj b/base/Applications/Runtime/Full/System.Compiler.Runtime.App.csproj
similarity index 81%
rename from base/Kernel/System.Compiler.Runtime/System.Compiler.Runtime.App.csproj
rename to base/Applications/Runtime/Full/System.Compiler.Runtime.App.csproj
index 3e57277..edf704a 100644
--- a/base/Kernel/System.Compiler.Runtime/System.Compiler.Runtime.App.csproj
+++ b/base/Applications/Runtime/Full/System.Compiler.Runtime.App.csproj
@@ -5,8 +5,6 @@
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
-# File: Kernel\System.Compiler.Runtime\System.Compiler.Runtime.App.csproj
-#
# Note: This project builds the copy of System.Runtime.Compiler.dll
# that applications use (executables outside of the kernel).
#
@@ -25,12 +23,12 @@
-
-
+
+
-
+
diff --git a/base/Kernel/System/ApplicationException.cs b/base/Applications/Runtime/Full/System/ApplicationException.cs
similarity index 81%
rename from base/Kernel/System/ApplicationException.cs
rename to base/Applications/Runtime/Full/System/ApplicationException.cs
index 3f01af0..696d2f0 100644
--- a/base/Kernel/System/ApplicationException.cs
+++ b/base/Applications/Runtime/Full/System/ApplicationException.cs
@@ -3,19 +3,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** Class: ApplicationException
-**
-**
-** Purpose: The base class for all "less serious" exceptions that must be
-** declared or caught.
-**
-** Date: March 11, 1998
-**
-=============================================================================*/
+//=============================================================================
+//
+// Class: ApplicationException
+//
+// Purpose: The base class for all "less serious" exceptions that must be
+// declared or caught.
+//
+//=============================================================================
-namespace System {
+namespace System
+{
// The ApplicationException is the base class for nonfatal,
// application errors that occur. These exceptions are generated
diff --git a/base/Applications/Runtime/Full/System/ArgIterator.cs b/base/Applications/Runtime/Full/System/ArgIterator.cs
new file mode 100644
index 0000000..4dac82c
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/ArgIterator.cs
@@ -0,0 +1,161 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System
+{
+
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+
+ using Microsoft.Bartok.Runtime;
+
+ [NoCCtor]
+ [StructLayout(LayoutKind.Auto)]
+ public unsafe struct ArgIterator
+ {
+ private IntPtr * nextArg;
+ private int remainingArgs;
+
+ [NoHeapAllocation]
+ public ArgIterator(RuntimeArgumentHandle arglist)
+ {
+ IntPtr* p = (IntPtr *) arglist.Pointer;
+ this.remainingArgs = (int) *p;
+ this.nextArg = p + 1;
+ }
+
+ [NoHeapAllocation]
+ public int GetRemainingCount() {
+ return remainingArgs;
+ }
+
+ public int Length {
+ [NoHeapAllocation]
+ get { return remainingArgs; }
+ }
+
+ [NoHeapAllocation]
+ internal RuntimeType GetArg(int arg, out IntPtr value)
+ {
+ if (arg < 0 || arg >= remainingArgs) {
+ value = IntPtr.Zero;
+ return null;
+ }
+#if ISA_IX86
+ value = nextArg[arg * 2];
+ return Magic.toRuntimeType(Magic.fromAddress((UIntPtr)nextArg[arg * 2 + 1]));
+#elif ISA_IX64
+ IntPtr * ptr = (IntPtr *) nextArg[arg];
+ value = *ptr;
+ return Magic.toRuntimeType(Magic.fromAddress((UIntPtr)(*(ptr+1))));
+#elif ISA_ARM
+ // TODO: Correct implementation
+ value = nextArg[arg * 2];
+ return Magic.toRuntimeType(Magic.fromAddress((UIntPtr)nextArg[arg * 2 + 1]));
+#else
+#error Undefined architecture
+#endif
+ }
+
+ [NoHeapAllocation]
+ public Object GetObjectArg(int arg)
+ {
+ IntPtr pvalue;
+ RuntimeType rt = GetArg(arg, out pvalue);
+
+ return (rt != null &&
+ pvalue != IntPtr.Zero &&
+ rt.classVtable.structuralView == StructuralType.Reference)
+ ? Magic.fromAddress(*(UIntPtr *)pvalue)
+ : null;
+ }
+
+ [NoHeapAllocation]
+ internal RuntimeType PopNextArg(out IntPtr value)
+ {
+ if (remainingArgs == 0) {
+ value = IntPtr.Zero;
+ return null;
+ }
+ else {
+ RuntimeType type;
+#if ISA_IX86
+ value = *nextArg++;
+ type = Magic.toRuntimeType(Magic.fromAddress((UIntPtr)(*nextArg++)));
+#elif ISA_IX64
+ IntPtr * ptr = (IntPtr *) *nextArg++;
+ value = *ptr;
+ type = Magic.toRuntimeType(Magic.fromAddress((UIntPtr)(*(ptr+1))));
+#elif ISA_ARM
+ // TODO: Correct implementation
+ value = *nextArg++;
+ type = Magic.toRuntimeType(Magic.fromAddress((UIntPtr)(*nextArg++)));
+#else
+#error Undefined architecture
+#endif
+
+ remainingArgs--;
+
+ return type;
+ }
+ }
+
+ [CLSCompliant(false)]
+ public TypedReference GetNextArg()
+ {
+ if (remainingArgs == 0) {
+ throw new InvalidOperationException
+ ("GetNextArg: No more arguments");
+ }
+
+#if ISA_IX86
+ IntPtr value = *nextArg++;
+ RuntimeType type = Magic.toRuntimeType(
+ Magic.fromAddress((UIntPtr)(*nextArg++)));
+#elif ISA_IX64
+ IntPtr * ptr = (IntPtr *) *nextArg++;
+ IntPtr value = *ptr;
+ RuntimeType type = Magic.toRuntimeType(
+ Magic.fromAddress((UIntPtr)(*(ptr+1))));
+#elif ISA_ARM
+ // TODO: Correct implementation
+ IntPtr value = *nextArg++;
+ RuntimeType type = Magic.toRuntimeType(
+ Magic.fromAddress((UIntPtr)(*nextArg++)));
+#else
+#error Undefined architecture
+#endif
+ remainingArgs--;
+
+ return new TypedReference(value, type);
+ }
+
+ [CLSCompliant(false)]
+ public RuntimeTypeHandle GetNextArgType()
+ {
+ if (remainingArgs == 0) {
+ throw new InvalidOperationException
+ ("GetNextArgType: No more arguments");
+ }
+#if ISA_IX86
+ return new RuntimeTypeHandle(Magic.toRuntimeType(
+ Magic.fromAddress(
+ (UIntPtr)(nextArg[1]))));
+#elif ISA_IX64
+ IntPtr * ptr = (IntPtr *) *nextArg;
+ return new RuntimeTypeHandle(Magic.toRuntimeType(
+ Magic.fromAddress(
+ (UIntPtr)(*(ptr+1)))));
+#elif ISA_ARM
+ // TODO: Correct implementation
+ return new RuntimeTypeHandle(Magic.toRuntimeType(
+ Magic.fromAddress(
+ (UIntPtr)(nextArg[1]))));
+#else
+#error Undefined architecture
+#endif
+ }
+ }
+}
diff --git a/base/Kernel/System/ArgumentException.cs b/base/Applications/Runtime/Full/System/ArgumentException.cs
similarity index 78%
rename from base/Kernel/System/ArgumentException.cs
rename to base/Applications/Runtime/Full/System/ArgumentException.cs
index 22ae860..e04aba2 100644
--- a/base/Kernel/System/ArgumentException.cs
+++ b/base/Applications/Runtime/Full/System/ArgumentException.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** Class: ArgumentException
-**
-**
-** Purpose: Exception class for invalid arguments to a method.
-**
-** Date: March 24, 1998
-**
-=============================================================================*/
+//=============================================================================
+//
+// Class: ArgumentException
+//
+// Purpose: Exception class for invalid arguments to a method.
+//
+//=============================================================================
-namespace System {
+namespace System
+{
using System;
@@ -64,7 +62,7 @@ namespace System {
{
get {
String s = base.Message;
- if (! ((m_paramName == null) ||
+ if (!((m_paramName == null) ||
(m_paramName.Length == 0)) )
return s + Environment.NewLine + String.Format("{0}", m_paramName);
else
@@ -72,16 +70,16 @@ namespace System {
}
}
- /*
- public String ToString()
- {
- String s = super.ToString();
- if (m_paramName != null)
- return s + "Parameter name: "+m_paramName+"\tActual value: "+(m_actualValue==null ? "" : m_actualValue.ToString());
- else
- return s;
- }
- */
+ //
+ //public String ToString()
+ //{
+ // String s = super.ToString();
+ // if (m_paramName != null)
+ // return s + "Parameter name: "+m_paramName+"\tActual value: "+(m_actualValue==null ? "" : m_actualValue.ToString());
+ // else
+ // return s;
+ //}
+ //
//|
public virtual String ParamName {
diff --git a/base/Kernel/System/ArgumentNullException.cs b/base/Applications/Runtime/Full/System/ArgumentNullException.cs
similarity index 82%
rename from base/Kernel/System/ArgumentNullException.cs
rename to base/Applications/Runtime/Full/System/ArgumentNullException.cs
index dfdec41..ecbeaeb 100644
--- a/base/Kernel/System/ArgumentNullException.cs
+++ b/base/Applications/Runtime/Full/System/ArgumentNullException.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** Class: ArgumentNullException
-**
-**
-** Purpose: Exception class for null arguments to a method.
-**
-** Date: April 28, 1999
-**
-=============================================================================*/
+//=============================================================================
+//
+// Class: ArgumentNullException
+//
+// Purpose: Exception class for null arguments to a method.
+//
+//=============================================================================
-namespace System {
+namespace System
+{
using System;
diff --git a/base/Applications/Runtime/Full/System/ArgumentOutOfRangeException.cs b/base/Applications/Runtime/Full/System/ArgumentOutOfRangeException.cs
new file mode 100644
index 0000000..a3db41f
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/ArgumentOutOfRangeException.cs
@@ -0,0 +1,88 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: ArgumentOutOfRangeException
+//
+// Purpose: Exception class for method arguments outside of the legal range.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ // The ArgumentOutOfRangeException is thrown when an argument
+ // is outside the legal range for that argument. This may often be caused
+ // by
+ //
+ //|
+ public partial class ArgumentOutOfRangeException : ArgumentException {
+
+ private static String _rangeMessage;
+ private Object m_actualValue;
+
+ private static String RangeMessage {
+ get {
+ if (_rangeMessage == null)
+ _rangeMessage = "Arg_ArgumentOutOfRangeException";
+ return _rangeMessage;
+ }
+ }
+
+ // Creates a new ArgumentOutOfRangeException with its message
+ // string set to a default message explaining an argument was out of range.
+ //|
+ public ArgumentOutOfRangeException()
+ : base(RangeMessage) {
+ }
+
+ //|
+ public ArgumentOutOfRangeException(String paramName)
+ : base(RangeMessage, paramName) {
+ }
+
+ //|
+ public ArgumentOutOfRangeException(String paramName, String message)
+ : base(message, paramName) {
+ }
+
+ // We will not use this in the classlibs, but we'll provide it for
+ // anyone that's really interested so they don't have to stick a bunch
+ // of printf's in their code.
+ //|
+ public ArgumentOutOfRangeException(String paramName, Object actualValue, String message)
+ : base(message, paramName) {
+ m_actualValue = actualValue;
+ }
+
+ //|
+ public override String Message
+ {
+ get {
+ String s = base.Message;
+ if (m_actualValue != null) {
+ String valueMessage = String.Format("ArgumentOutOfRange_ActualValue", m_actualValue.ToString());
+ if (s == null)
+ return valueMessage;
+ return s + Environment.NewLine + valueMessage;
+ }
+ return s;
+ }
+ }
+
+ // Gets the value of the argument that caused the exception.
+ // Note - we don't set this anywhere in the class libraries in
+ // version 1, but it might come in handy for other developers who
+ // want to avoid sticking printf's in their code.
+ //|
+ public virtual Object ActualValue {
+ get { return m_actualValue; }
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/ArithmeticException.cs b/base/Applications/Runtime/Full/System/ArithmeticException.cs
new file mode 100644
index 0000000..d4bf46c
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/ArithmeticException.cs
@@ -0,0 +1,48 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: ArithmeticException
+//
+// Purpose: Exception class for bad arithmetic conditions!
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ // The ArithmeticException is thrown when overflow or underflow
+ // occurs.
+ //
+ //|
+ public partial class ArithmeticException : SystemException
+ {
+ // Creates a new ArithmeticException with its message string set to
+ // the empty string, its HRESULT set to COR_E_ARITHMETIC,
+ // and its ExceptionInfo reference set to null.
+ //|
+ public ArithmeticException()
+ : base("Arg_ArithmeticException") {
+ }
+
+ // Creates a new ArithmeticException with its message string set to
+ // message, its HRESULT set to COR_E_ARITHMETIC,
+ // and its ExceptionInfo reference set to null.
+ //
+ //|
+ public ArithmeticException(String message)
+ : base(message) {
+ }
+
+ //|
+ public ArithmeticException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Array.cs b/base/Applications/Runtime/Full/System/Array.cs
new file mode 100644
index 0000000..e841c47
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Array.cs
@@ -0,0 +1,2759 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: Array
+//
+// Purpose: Base class which can be used to access any array
+//
+//===========================================================
+namespace System
+{
+
+ using Microsoft.Bartok.Runtime;
+ using System;
+ using System.Collections;
+ using System.GCs;
+ using System.Diagnostics;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+ using System.Threading;
+
+ // REVIEW: to be moved/integrated elsewhere
+ // REVIEW: see System.Variant::ClassTypes
+ internal class TypeInfo {
+ internal static VTable[] arrayOfBox = {
+ null, // not array
+ null, // reference
+ null, // untraced pointer
+ null, // struct
+ ((RuntimeType)typeof(Boolean)).classVtable,
+ ((RuntimeType)typeof(Char)).classVtable,
+ ((RuntimeType)typeof(SByte)).classVtable,
+ ((RuntimeType)typeof(Int16)).classVtable,
+ ((RuntimeType)typeof(Int32)).classVtable,
+ ((RuntimeType)typeof(Int64)).classVtable,
+ ((RuntimeType)typeof(Byte)).classVtable,
+ ((RuntimeType)typeof(UInt16)).classVtable,
+ ((RuntimeType)typeof(UInt32)).classVtable,
+ ((RuntimeType)typeof(UInt64)).classVtable,
+ ((RuntimeType)typeof(Single)).classVtable,
+ ((RuntimeType)typeof(Double)).classVtable,
+ ((RuntimeType)typeof(IntPtr)).classVtable,
+ ((RuntimeType)typeof(UIntPtr)).classVtable
+ };
+ }
+
+ //|
+ [StructLayout(LayoutKind.Sequential)]
+ public abstract class Array : ICloneable, IList
+ {
+ // [spacer] means 4 byte insertion if elements are 8-aligned
+
+ // Vector layout:
+ // length, [spacer], elem0, ...
+
+ // Rect layout:
+ // rank, total_length, base0, length0, ..., basen, lengthn, elem0, ...
+
+ // VTable vtable is inherited from Object
+
+ internal int field1;
+ private int field2;
+ private int field3;
+ private int field4;
+
+ ///
+ private Array() {}
+
+ // Create instance will create an array
+ //|
+ public static Array CreateInstance(Type elementType, int length)
+ {
+ if (elementType == null)
+ throw new ArgumentNullException("elementType");
+ RuntimeType t = elementType.UnderlyingSystemType as RuntimeType;
+ if (t == null)
+ throw new ArgumentException("Arg_MustBeType","elementType");
+ if (length < 0)
+ throw new ArgumentOutOfRangeException("length", "ArgumentOutOfRange_NeedNonNegNum");
+ VTable v = t.classVtable.vectorClass;
+ if (v == null) {
+ throw new InvalidCastException("Arg_VectorClassNotFound");
+ }
+ return GC.AllocateVector(v, length);
+ }
+
+ private static void VectorCopy(Object srcObject, int srcOffset,
+ Object dstObject, int dstOffset,
+ int length) {
+ StructuralType srcArrayOf = srcObject.vtable.arrayOf;
+ StructuralType dstArrayOf = dstObject.vtable.arrayOf;
+ if ((srcArrayOf == StructuralType.None)
+ || (srcArrayOf != dstArrayOf) ) {
+ throw new ArrayTypeMismatchException();
+ }
+ if ((srcOffset < 0)
+ || (dstOffset < 0)
+ || (length < 0) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ switch (srcArrayOf) {
+ case StructuralType.None:
+ throw new ArrayTypeMismatchException();
+
+ case StructuralType.Bool: {
+ bool[] srcArray = (bool[])srcObject;
+ bool[] dstArray = (bool[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Char: {
+ char[] srcArray = (char[])srcObject;
+ char[] dstArray = (char[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Int8: {
+ sbyte[] srcArray = (sbyte[])srcObject;
+ sbyte[] dstArray = (sbyte[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Int16: {
+ short[] srcArray = (short[])srcObject;
+ short[] dstArray = (short[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Int32: {
+ int[] srcArray = (int[])srcObject;
+ int[] dstArray = (int[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Int64: {
+ long[] srcArray = (long[])srcObject;
+ long[] dstArray = (long[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.UInt8: {
+ byte[] srcArray = (byte[])srcObject;
+ byte[] dstArray = (byte[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.UInt16: {
+ ushort[] srcArray = (ushort[])srcObject;
+ ushort[] dstArray = (ushort[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.UInt32: {
+ uint[] srcArray = (uint[])srcObject;
+ uint[] dstArray = (uint[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.UInt64: {
+ ulong[] srcArray = (ulong[])srcObject;
+ ulong[] dstArray = (ulong[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Float32: {
+ float[] srcArray = (float[])srcObject;
+ float[] dstArray = (float[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Float64: {
+ double[] srcArray = (double[])srcObject;
+ double[] dstArray = (double[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ case StructuralType.Reference: {
+ Object[] srcArray = (Object[])srcObject;
+ Object[] dstArray = (Object[])dstObject;
+ Copy(srcArray,srcOffset,dstArray,dstOffset,length);
+ return;
+ }
+ default:
+ VTable.DebugBreak();
+ return;
+ }
+ }
+
+#if DEBUG_ARRAY
+ private void debug(Object srcArray,int srcOffset,Object dstArray,int dstOffset,
+ int length)
+ {
+#if TODO
+ DebugPrint("System.Copy(");
+ DebugPrint(srcArray.getClass().getName());
+ DebugPrint(",");
+ DebugPrint(srcOffset);
+ DebugPrint(",");
+ DebugPrint(dstArray.getClass().getName());
+ DebugPrint(",");
+ DebugPrint(dstOffset);
+ DebugPrint(",");
+ DebugPrint(length);
+ DebugPrintln(")");
+#endif
+ }
+#endif
+
+ public static void Copy(bool[] srcArray, int srcOffset, bool[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfBool);
+ }
+#endif
+
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyBoolDown(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyBoolDown(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyBoolUp(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyBoolUp(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ public static void Copy(char[] srcArray, int srcOffset, char[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfChar);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyCharDown(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyCharDown(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyCharUp(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyCharUp(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ [CLSCompliant(false)]
+ public static void Copy(sbyte[] srcArray, int srcOffset, sbyte[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfByte);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyInt8Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt8Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyInt8Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt8Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ }
+
+ public static void Copy(short[] srcArray, int srcOffset, short[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfShort);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyInt16Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt16Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyInt16Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt16Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ public static void Copy(int[] srcArray, int srcOffset, int[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfInt);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyInt32Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt32Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.CopyInt32Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt32Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ public static void Copy(long[] srcArray, int srcOffset, long[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfLong);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyInt64Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt64Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyInt64Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyInt64Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ public static void Copy(byte[] srcArray, int srcOffset, byte[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfByte);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyUInt8Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt8Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyUInt8Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt8Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ }
+
+ [CLSCompliant(false)]
+ public static void Copy(ushort[] srcArray, int srcOffset, ushort[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfShort);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyUInt16Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt16Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyUInt16Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt16Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ [CLSCompliant(false)]
+ public static void Copy(uint[] srcArray, int srcOffset, uint[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfInt);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyUInt32Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt32Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.CopyUInt32Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt32Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ [CLSCompliant(false)]
+ public static void Copy(ulong[] srcArray, int srcOffset, ulong[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfLong);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyUInt64Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt64Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyUInt64Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyUInt64Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ public static void Copy(float[] srcArray, int srcOffset, float[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfFloat);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyFloat32Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyFloat32Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyFloat32Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyFloat32Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ public static void Copy(double[] srcArray, int srcOffset, double[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfDouble);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyFloat64Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyFloat64Down(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ else {
+ if ((srcOffset + length <= srcLength)
+ && (dstOffset+length <= dstLength) ) {
+ ArrayHelper.UncheckedCopyFloat64Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ else {
+ ArrayHelper.CopyFloat64Up(srcArray, srcOffset, dstArray, dstOffset, length);
+ }
+ }
+ return;
+ }
+
+ public static void Copy(Object[] srcArray, int srcOffset, Object[] dstArray, int dstOffset, int length)
+ {
+#if DEBUG_ARRAY
+ debug(srcArray,srcOffset,dstArray,dstOffset,length);
+#endif
+ int srcLength = srcArray.Length;
+ int dstLength = dstArray.Length;
+#if TODO
+ if (VTable.enableLibraryOptions) {
+ Assert(VTable.enableLibraryOptions && EnableLibraryAsserts() &&
+ srcArray.vtable.arrayOf == Array.OfReference);
+ }
+#endif
+ if ((length < 0)
+ || (srcOffset < 0)
+ || (dstOffset < 0)
+ || (srcOffset+length > srcLength)
+ || (dstOffset+length > dstLength) ) {
+ VTable.throwNewArgumentOutOfRangeException();
+ }
+ if ((srcArray == dstArray)
+ && (srcOffset < dstOffset)
+ && (dstOffset < srcOffset+length) ) {
+ int dx = dstOffset+length-1;
+ int sx = srcOffset+length-1;
+ for (int i = length - 1; i >= 0; i--) {
+ dstArray[dx] = srcArray[sx];
+ sx--;
+ dx--;
+ }
+ // for (int i=0; i= 0; i--) {
+ dstArray[dx] = srcArray[sx];
+ sx++;
+ dx++;
+ }
+ // for (int i=0; i= 0 &&
+ destArray != null && destIndex >= 0 && len >= 0);
+ VTable destVT = destArray.vtable.arrayElementClass;
+ VTable.Assert(destVT != null);
+ // Cache last cast test to speed up cast checks.
+ VTable lastVT = null;
+
+ //const BOOL destIsArray = destTH.IsArray();
+ fixed (int *srcField = &sourceArray.field1) {
+ fixed (int *dstField = &destArray.field1) {
+ UIntPtr* sourceArrayPtr =(UIntPtr*)
+ sourceArray.GetFirstElementAddress(srcField);
+ UIntPtr* destArrayPtr = (UIntPtr*)
+ destArray.GetFirstElementAddress(dstField);
+ Object obj;
+ for (int i = srcIndex; i < srcIndex + len; ++i) {
+ UIntPtr objAddress = sourceArrayPtr[i];
+ obj = Magic.fromAddress(objAddress);
+ // Now that we have grabbed obj, we are no longer
+ // subject to races from another mutator thread.
+ if (obj != null) {
+ VTable objVT = obj.vtable;
+ if (objVT != lastVT && objVT != destVT) {
+ lastVT = objVT;
+ // do cast check
+ if(!VTable.isValidAssignment
+ (destVT.vtableType, objVT.vtableType)) {
+ throw new InvalidCastException("InvalidCast_DownCastArrayElement");
+ }
+ }
+ }
+ VTable.Assert(destArray.vtable.arrayOf !=
+ StructuralType.Struct);
+ if (destArray.vtable.arrayOf ==
+ StructuralType.Reference) {
+#if REFERENCE_COUNTING_GC
+ GCs.ReferenceCountingCollector.
+ IncrementRefCount(obj);
+ UIntPtr dstAddr =
+ destArrayPtr[i-srcIndex+destIndex];
+ Object dst = Magic.fromAddress(dstAddr);
+ GCs.ReferenceCountingCollector.
+ DecrementRefCount(dst);
+ destArrayPtr[i - srcIndex + destIndex] = objAddress;
+#elif DEFERRED_REFERENCE_COUNTING_GC
+ GCs.DeferredReferenceCountingCollector.
+ IncrementRefCount(obj);
+ UIntPtr dstAddr =
+ destArrayPtr[i-srcIndex+destIndex];
+ Object dst = Magic.fromAddress(dstAddr);
+ GCs.DeferredReferenceCountingCollector.
+ DecrementRefCount(dst);
+ destArrayPtr[i - srcIndex + destIndex] = objAddress;
+#else
+ UIntPtr *elementPtr =
+ destArrayPtr + i - srcIndex + destIndex;
+ Barrier.StoreIndirect(elementPtr, obj, 0);
+#endif // REFERENCE_COUNTING_GC
+ }
+ else {
+ destArrayPtr[i - srcIndex + destIndex] = objAddress;
+ }
+ // N.B. CLR uses layers of #defines/methods to do this
+ // assignment, starting with SetObjectReference
+ }
+ }
+ }
+ }
+
+ private static void BoxEachElement(Array sourceArray, int srcIndex,
+ Array destArray, int destIndex,
+ int len) {
+ // For now, use this silly implementation that leans on
+ // SetValue to do the right thing.
+ for (int i = 0; i < len; ++i) {
+ destArray.SetValue(sourceArray.GetValue(srcIndex + i), destIndex + i);
+ }
+ }
+
+ private unsafe static void UnBoxEachElement(Array sourceArray,
+ int srcIndex,
+ Array destArray,
+ int destIndex,
+ int len,
+ bool castEachElement)
+ {
+ VTable.Assert(sourceArray != null && srcIndex >= 0 &&
+ destArray != null && destIndex >= 0 && len >= 0);
+ VTable destVT = destArray.vtable.arrayElementClass;
+ VTable.Assert(destVT != null);
+ int elementSize = destArray.vtable.arrayElementSize;
+ // Cache last cast test to speed up cast checks.
+ VTable lastVT = null;
+
+ //const BOOL destIsArray = destTH.IsArray();
+ fixed (int *srcField = &sourceArray.field1) {
+ fixed (int *dstField = &destArray.field1) {
+ UIntPtr* sourceArrayPtr =(UIntPtr*)
+ sourceArray.GetFirstElementAddress(srcField);
+ byte* destArrayPtr = (byte*)
+ destArray.GetFirstElementAddress(dstField);
+ Object obj;
+ for (int i = srcIndex; i < srcIndex + len; ++i) {
+ UIntPtr objAddr = sourceArrayPtr[i];
+ obj = Magic.fromAddress(objAddr);
+ if (castEachElement) {
+ //obj = Magic.fromAddress(objAddr);
+ // Now that we have grabbed obj, we are no longer
+ // subject to races from another mutator thread.
+ if (obj != null) {
+ VTable objVT = obj.vtable;
+ if (objVT != lastVT && objVT != destVT) {
+ lastVT = objVT;
+ // do cast check
+ if(!VTable.isValidAssignment
+ (destVT.vtableType, objVT.vtableType)) {
+ throw new InvalidCastException
+ ("InvalidCast_DownCastArrayElement");
+ }
+ }
+ }
+ }
+ int postHeaderSize = PostHeader.Size;
+ UIntPtr src = objAddr + postHeaderSize;
+ int offset = (i-srcIndex + destIndex) * elementSize;
+ UIntPtr dst = (UIntPtr) destArrayPtr + offset;
+ VTable.Assert(destArray.vtable.arrayOf !=
+ StructuralType.Reference);
+ if (destArray.vtable.arrayOf ==
+ StructuralType.Struct) {
+ UIntPtr dstAddr = dst - postHeaderSize;
+#if REFERENCE_COUNTING_GC
+ GCs.ReferenceCountingCollector.
+ IncrementReferentRefCounts(objAddr, obj.vtable);
+ GCs.ReferenceCountingCollector.
+ DecrementReferentRefCounts(dstAddr, destVT);
+ Buffer.MoveMemory(dst, src, elementSize);
+#elif DEFERRED_REFERENCE_COUNTING_GC
+ GCs.DeferredReferenceCountingCollector.
+ IncrementReferentRefCounts(objAddr, obj.vtable);
+ GCs.DeferredReferenceCountingCollector.
+ DecrementReferentRefCounts(dstAddr, destVT);
+ Buffer.MoveMemory(dst, src, elementSize);
+#else
+ Barrier.CopyStruct(obj, destArray, destVT, src, dst);
+#endif // REFERENCE_COUNTING_GC
+ }
+ else {
+ Buffer.MoveMemory((byte *) dst, (byte *) src,
+ (UIntPtr) elementSize);
+ }
+ }
+ }
+ }
+ }
+
+ private static void PrimitiveWiden(Array sourceArray, int srcIndex,
+ Array destArray, int destIndex,
+ int len) {
+ throw new Exception("System.Array.PrimitiveWiden not implemented in Bartok!");
+ }
+
+ // Copies length elements from sourceArray, starting at index 0, to
+ // destinationArray, starting at index 0.
+ //
+ //|
+ public static void Copy(Array sourceArray, Array destinationArray, int length)
+ {
+ if (sourceArray == null)
+ throw new ArgumentNullException("sourceArray");
+ if (destinationArray == null)
+ throw new ArgumentNullException("destinationArray");
+ Copy(sourceArray, sourceArray.GetLowerBound(0), destinationArray, destinationArray.GetLowerBound(0), length);
+ }
+
+ // Copies length elements from sourceArray, starting at sourceIndex, to
+ // destinationArray, starting at destinationIndex.
+ //
+ //|
+
+
+ //|
+ public static void Copy(Array sourceArray, Array destinationArray, long length)
+ {
+ if (length > Int32.MaxValue || length < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("length", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ Array.Copy(sourceArray, destinationArray, (int) length);
+ }
+
+ //|
+ public unsafe static void Copy(Array sourceArray, int sourceIndex,
+ Array destinationArray,
+ int destinationIndex, int length) {
+ if (sourceArray == null) {
+ throw new ArgumentNullException("sourceArray");
+ }
+ if (destinationArray == null) {
+ throw new ArgumentNullException("destinationArray");
+ }
+ if (sourceArray.Rank != destinationArray.Rank) {
+ throw new RankException("Ranks must match");
+ }
+
+ bool castEachElement = false;
+ bool boxEachElement = false;
+ bool unboxEachElement = false;
+ bool primitiveWiden = false;
+
+ AssignArray r;
+
+ // Small perf optimization - we copy from one portion of an array
+ // back to itself a lot when resizing collections, etc. The cost of
+ // doing the type checking is significant for copying small numbers
+ // of bytes (~half of the time for copying 1 byte within one array
+ // from element 0 to element 1).
+ if (sourceArray == destinationArray) {
+ r = AssignArray.WillWork;
+ }
+ else {
+ r = CanAssignArrayType(sourceArray, destinationArray);
+ }
+
+ // Specialized vector copy
+
+ // Undo support adds logging to array copies which can trigger GCs
+ // at inopportune times so for now we use the specialized copy
+ // routine when possible for correctness.
+ // BUGBUG: arraycopy of struct + logging may lose GC information
+
+ if (r == AssignArray.WillWork
+ && sourceArray.IsVector
+ && (sourceArray.vtable.arrayOf != StructuralType.Struct)) {
+ VectorCopy(sourceArray,sourceIndex,destinationArray,
+ destinationIndex,length);
+ return;
+ }
+ else {
+ switch (r) {
+ case AssignArray.WrongType:
+ throw new ArrayTypeMismatchException("ArrayTypeMismatch_CantAssignType");
+ case AssignArray.MustCast:
+ castEachElement = true;
+ break;
+ case AssignArray.WillWork:
+ break;
+ case AssignArray.BoxValueClassOrPrimitive:
+ boxEachElement = true;
+ break;
+ case AssignArray.UnboxValueClassOrPrimitive:
+ castEachElement = true;
+ unboxEachElement = true;
+ break;
+ case AssignArray.PrimitiveWiden:
+ primitiveWiden = true;
+ break;
+ default:
+ VTable.NotReached("Fell through switch in Array.Copy!");
+ break;
+ }
+ }
+ if (length < 0) {
+ throw new ArgumentOutOfRangeException("length", "ArgumentOutOfRange_NeedNonNegNum");
+ }
+
+ int sourceLower = sourceArray.GetLowerBound(0);
+ int destinationLower = destinationArray.GetLowerBound(0);
+ if (sourceIndex < sourceLower ||
+ sourceIndex + length > sourceLower + sourceArray.Length) {
+ throw new ArgumentException("Illegal range from sourceArray");
+ }
+ if (destinationIndex < destinationLower ||
+ destinationIndex + length > destinationLower + destinationArray.Length) {
+ throw new ArgumentException("Illegal range from destinationArray");
+ }
+
+ if (length > 0) {
+ VTable.Assert(!boxEachElement || !castEachElement);
+ if (unboxEachElement) {
+ UnBoxEachElement(sourceArray, sourceIndex - sourceLower,
+ destinationArray,
+ destinationIndex - destinationLower,
+ length, castEachElement);
+ }
+ else if (boxEachElement) {
+ BoxEachElement(sourceArray, sourceIndex - sourceLower,
+ destinationArray,
+ destinationIndex - destinationLower, length);
+ }
+ else if (castEachElement) {
+ VTable.Assert(!unboxEachElement); // handled above
+ CastCheckEachElement(sourceArray, sourceIndex - sourceLower,
+ destinationArray,
+ destinationIndex - destinationLower,
+ length);
+ }
+ else if (primitiveWiden) {
+ PrimitiveWiden(sourceArray, sourceIndex - sourceLower,
+ destinationArray,
+ destinationIndex - destinationLower, length);
+ }
+ else {
+#if !REFERENCE_COUNTING_GC && !DEFERRED_REFERENCE_COUNTING_GC
+ Barrier.ArrayCopy(sourceArray,
+ sourceIndex - sourceLower,
+ destinationArray,
+ destinationIndex - destinationLower,
+ length);
+#else
+ fixed (int *sourceFieldPtr = &sourceArray.field1) {
+ fixed (int *dstFieldPtr = &destinationArray.field1) {
+ byte* src = (byte*) sourceArray.GetFirstElementAddress(sourceFieldPtr);
+ byte* dst = (byte*) destinationArray.GetFirstElementAddress(dstFieldPtr);
+ int size = sourceArray.vtable.arrayElementSize;
+ Buffer.MoveMemory(dst + ((destinationIndex - destinationLower)*size),
+ src + ((sourceIndex - sourceLower)*size),
+ length*size);
+ }
+ }
+#endif
+ }
+ }
+ }
+
+ // Sets length elements in array to 0 (or null for Object arrays), starting
+ // at index.
+ //
+ //|
+ public unsafe static void Clear(Array array, int index, int length) {
+ // cannot pass null for array
+ if (array == null) {
+ throw new ArgumentNullException("array", "ArgumentNull_Array");
+ }
+
+ // array bounds checking
+ int lb = array.GetLowerBound(0);
+ // are the first two redundant or is there an overflow issue?
+ if (index < lb || (index - lb) < 0 || length < 0) {
+ throw new IndexOutOfRangeException();
+ }
+ if (index - lb > array.Length - length) {
+ throw new IndexOutOfRangeException();
+ }
+
+ if (length > 0) {
+ fixed (int *fieldPtr = &array.field1) {
+ byte* arrayPtr = (byte*)
+ array.GetFirstElementAddress(fieldPtr);
+ int size = array.vtable.arrayElementSize;
+ VTable.Assert(size >= 1);
+ // REVIEW: what about structs?
+ VTable.Assert(size <= 8);
+ Buffer.ZeroMemory(arrayPtr + (index-lb) * size,
+ length * size);
+ }
+ }
+ }
+
+ // The various Get values...
+ //|
+ public Object GetValue(params int[] indices)
+ {
+ if (indices == null)
+ throw new ArgumentNullException("indices");
+ if (Rank != indices.Length)
+ throw new ArgumentException("Arg_RankIndices");
+ return InternalGetValueEx(indices);
+ }
+
+ //|
+ public Object GetValue(int index)
+ {
+ if (Rank != 1)
+ throw new ArgumentException("Arg_Need1DArray");
+ return InternalGetValue(index,0,0);
+ }
+
+ //|
+ public Object GetValue(int index1, int index2)
+ {
+ if (Rank != 2)
+ throw new ArgumentException("Arg_Need2DArray");
+ return InternalGetValue(index1,index2,0);
+ }
+
+ //|
+ public Object GetValue(int index1, int index2, int index3)
+ {
+ if (Rank != 3)
+ throw new ArgumentException("Arg_Need3DArray");
+ return InternalGetValue(index1,index2,index3);
+ }
+
+ //|
+ public Object GetValue(long index)
+ {
+ if (index > Int32.MaxValue || index < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ return this.GetValue((int) index);
+ }
+
+ //|
+ public Object GetValue(long index1, long index2)
+ {
+ if (index1 > Int32.MaxValue || index1 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index1", "ArgumentOutOfRange_HugeArrayNotSupported");
+ if (index2 > Int32.MaxValue || index2 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index2", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ return this.GetValue((int) index1, (int) index2);
+ }
+
+ //|
+ public Object GetValue(long index1, long index2, long index3)
+ {
+ if (index1 > Int32.MaxValue || index1 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index1", "ArgumentOutOfRange_HugeArrayNotSupported");
+ if (index2 > Int32.MaxValue || index2 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index2", "ArgumentOutOfRange_HugeArrayNotSupported");
+ if (index3 > Int32.MaxValue || index3 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index3", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ return this.GetValue((int) index1, (int) index2, (int) index3);
+ }
+
+ //|
+ public Object GetValue(params long[] indices)
+ {
+ int[] intIndices = new int[indices.Length];
+
+ for (int i = 0; i < indices.Length; ++i) {
+ long index = indices[i];
+ if (index > Int32.MaxValue || index < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_HugeArrayNotSupported");
+ intIndices[i] = (int) index;
+ }
+
+ return this.GetValue(intIndices);
+ }
+
+
+ //|
+ public void SetValue(Object value,int index)
+ {
+ if (Rank != 1)
+ throw new ArgumentException("Arg_Need1DArray");
+ InternalSetValue(value,index,0,0);
+ }
+
+ //|
+ public void SetValue(Object value,int index1, int index2)
+ {
+ if (Rank != 2)
+ throw new ArgumentException("Arg_Need2DArray");
+ InternalSetValue(value,index1,index2,0);
+ }
+
+ //|
+ public void SetValue(Object value,int index1, int index2, int index3)
+ {
+ if (Rank != 3)
+ throw new ArgumentException("Arg_Need3DArray");
+ InternalSetValue(value,index1,index2,index3);
+ }
+
+ //|
+ public void SetValue(Object value,params int[] indices)
+ {
+ if (indices == null)
+ throw new ArgumentNullException("indices");
+ if (Rank != indices.Length)
+ throw new ArgumentException("Arg_RankIndices");
+ InternalSetValueEx(value,indices);
+ }
+
+ //|
+ public void SetValue(Object value, long index)
+ {
+ if (index > Int32.MaxValue || index < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ this.SetValue(value, (int) index);
+ }
+
+ //|
+ public void SetValue(Object value, long index1, long index2)
+ {
+ if (index1 > Int32.MaxValue || index1 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index1", "ArgumentOutOfRange_HugeArrayNotSupported");
+ if (index2 > Int32.MaxValue || index2 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index2", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ this.SetValue(value, (int) index1, (int) index2);
+ }
+
+ //|
+ public void SetValue(Object value, long index1, long index2, long index3)
+ {
+ if (index1 > Int32.MaxValue || index1 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index1", "ArgumentOutOfRange_HugeArrayNotSupported");
+ if (index2 > Int32.MaxValue || index2 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index2", "ArgumentOutOfRange_HugeArrayNotSupported");
+ if (index3 > Int32.MaxValue || index3 < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index3", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ this.SetValue(value, (int) index1, (int) index2, (int) index3);
+ }
+
+ //|
+ public void SetValue(Object value, params long[] indices)
+ {
+ int[] intIndices = new int[indices.Length];
+
+ for (int i = 0; i < indices.Length; ++i) {
+ long index = indices[i];
+ if (index > Int32.MaxValue || index < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_HugeArrayNotSupported");
+ intIndices[i] = (int) index;
+ }
+
+ this.SetValue(value, intIndices);
+ }
+
+ // These functions are provided to help device drivers.
+ //
+ [CLSCompliant(false)]
+ [NoHeapAllocation]
+ public unsafe UIntPtr AddressOfContent()
+ {
+ if (!IsVector) {
+ return UIntPtr.Zero;
+ }
+
+ // This operation is only legal on a pinned object!
+ UIntPtr addr = UIntPtr.Zero;
+ fixed (int *fieldPtr = &field1) {
+ addr = (UIntPtr)GetFirstElementAddress(fieldPtr);
+ }
+ return addr;
+ }
+
+ [CLSCompliant(false)]
+ public UIntPtr SizeOfContent()
+ {
+ if (!IsVector) {
+ return UIntPtr.Zero;
+ }
+ return (UIntPtr)(GetLengthVector() * vtable.arrayElementSize);
+ }
+
+ // This is the set of native routines that implement the real
+ // Get/Set Value. The arguments have been verified that they exist
+ // before we get to this point.
+ //|
+ public int GetLength(int dimension) {
+ if (IsVector) {
+ return GetLengthVector();
+ }
+ else {
+ return GetLengthRectangleArray(dimension);
+ }
+ }
+
+ //|
+ public int Length {
+ get {
+ if (IsVector) {
+ return GetLengthVector();
+ }
+ else {
+ return GetLengthRectangleArray();
+ }
+ }
+ }
+
+ //|
+ public long LongLength {
+ get { return Length; }
+ }
+
+ //|
+ public long GetLongLength(int dimension) {
+ return GetLength(dimension);
+ }
+
+ //|
+ public int Rank {
+ get {
+ if (IsVector) {
+ return 1;
+ }
+ else {
+ return RankRectangleArray;
+ }
+ }
+ }
+
+ // This is to be used only when allocating a vector!
+ [Inline]
+ [NoBarriers]
+ internal void InitializeVectorLength(int numElements) {
+ this.field1 = numElements;
+ }
+
+ // This is to be used only when allocating an array!
+ [Inline]
+ [NoBarriers]
+ internal void InitializeArrayLength(int rank, int totalElements) {
+ this.field1 = rank;
+ this.field2 = totalElements;
+ }
+
+ internal bool IsVector {
+ [NoHeapAllocation]
+ get {
+ // REVIEW: information can be closer
+ return this.vtable.vtableType.IsVector;
+ }
+ }
+ private bool IsRectangleArray {
+ [NoHeapAllocation]
+ get {
+ // REVIEW: information can be closer
+ return this.vtable.vtableType.IsRectangleArray;
+ }
+ }
+
+ //|
+ public int GetUpperBound(int dimension) {
+ if (dimension >= Rank) {
+ throw new IndexOutOfRangeException("GetUpperBound dimension");
+ }
+ return GetLowerBound(dimension) + GetLength(dimension) - 1;
+ }
+
+ //|
+ public int GetLowerBound(int dimension) {
+ if (dimension >= Rank) {
+ throw new IndexOutOfRangeException("GetLowerBound dimension");
+ }
+ if (IsVector) { // zero - based
+ return 0;
+ }
+ // IsRectangleArray() == true
+ return GetLowerBoundRectangleArray(dimension);
+ }
+
+ // Number of elements in the Array.
+ //|
+ int ICollection.Count
+ { get { return Length; } }
+
+
+ // Returns an object appropriate for synchronizing access to this
+ // Array.
+ //|
+ public virtual Object SyncRoot
+ { get { return this; } }
+
+ // Is this Array read-only?
+ //|
+ public virtual bool IsReadOnly
+ { get { return false; } }
+
+ //|
+ public virtual bool IsFixedSize {
+ get { return true; }
+ }
+
+ // Is this Array synchronized (i.e., thread-safe)? If you want a synchronized
+ // collection, you can use SyncRoot as an object to synchronize your
+ // collection with. You could also call GetSynchronized()
+ // to get a synchronized wrapper around the Array.
+ //|
+ public virtual bool IsSynchronized
+ { get { return false; } }
+
+
+ //|
+ Object IList.this[int index] {
+ get { return GetValue(index); }
+ set { SetValue(value, index); }
+ }
+
+ //|
+ int IList.Add(Object value)
+ {
+ throw new NotSupportedException("NotSupported_FixedSizeCollection");
+ }
+
+ //|
+ bool IList.Contains(Object value)
+ {
+ return Array.IndexOf(this, value) >= this.GetLowerBound(0);
+ }
+
+ //|
+ void IList.Clear()
+ {
+ Array.Clear(this, 0, this.Length);
+ }
+
+ //|
+ int IList.IndexOf(Object value)
+ {
+ return Array.IndexOf(this, value);
+ }
+
+ //|
+ void IList.Insert(int index, Object value)
+ {
+ throw new NotSupportedException("NotSupported_FixedSizeCollection");
+ }
+
+ //|
+ void IList.Remove(Object value)
+ {
+ throw new NotSupportedException("NotSupported_FixedSizeCollection");
+ }
+
+ //|
+ void IList.RemoveAt(int index)
+ {
+ throw new NotSupportedException("NotSupported_FixedSizeCollection");
+ }
+
+ // Make a new array which is a deep copy of the original array.
+ //
+ //|
+ public virtual Object Clone()
+ {
+ return MemberwiseClone();
+ }
+
+ // Searches an array for a given element using a binary search algorithm.
+ // Elements of the array are compared to the search value using the
+ // IComparable interface, which must be implemented by all elements
+ // of the array and the given search value. This method assumes that the
+ // array is already sorted according to the IComparable interface;
+ // if this is not the case, the result will be incorrect.
+ //
+ // The method returns the index of the given value in the array. If the
+ // array does not contain the given value, the method returns a negative
+ // integer. The bitwise complement operator (~) can be applied to a
+ // negative result to produce the index of the first element (if any) that
+ // is larger than the given search value.
+ //
+ //|
+ public static int BinarySearch(Array array, Object value) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ int lb = array.GetLowerBound(0);
+ return BinarySearch(array, lb, array.Length, value, null);
+ }
+
+ // Searches a section of an array for a given element using a binary search
+ // algorithm. Elements of the array are compared to the search value using
+ // the IComparable interface, which must be implemented by all
+ // elements of the array and the given search value. This method assumes
+ // that the array is already sorted according to the IComparable
+ // interface; if this is not the case, the result will be incorrect.
+ //
+ // The method returns the index of the given value in the array. If the
+ // array does not contain the given value, the method returns a negative
+ // integer. The bitwise complement operator (~) can be applied to a
+ // negative result to produce the index of the first element (if any) that
+ // is larger than the given search value.
+ //
+ //|
+ public static int BinarySearch(Array array, int index, int length, Object value) {
+ return BinarySearch(array, index, length, value, null);
+ }
+
+ // Searches an array for a given element using a binary search algorithm.
+ // Elements of the array are compared to the search value using the given
+ // IComparer interface. If comparer is null, elements of the
+ // array are compared to the search value using the IComparable
+ // interface, which in that case must be implemented by all elements of the
+ // array and the given search value. This method assumes that the array is
+ // already sorted; if this is not the case, the result will be incorrect.
+ //
+ // The method returns the index of the given value in the array. If the
+ // array does not contain the given value, the method returns a negative
+ // integer. The bitwise complement operator (~) can be applied to a
+ // negative result to produce the index of the first element (if any) that
+ // is larger than the given search value.
+ //
+ //|
+ public static int BinarySearch(Array array, Object value, IComparer comparer) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ int lb = array.GetLowerBound(0);
+ return BinarySearch(array, lb, array.Length, value, comparer);
+ }
+
+ // Searches a section of an array for a given element using a binary search
+ // algorithm. Elements of the array are compared to the search value using
+ // the given IComparer interface. If comparer is null,
+ // elements of the array are compared to the search value using the
+ // IComparable interface, which in that case must be implemented by
+ // all elements of the array and the given search value. This method
+ // assumes that the array is already sorted; if this is not the case, the
+ // result will be incorrect.
+ //
+ // The method returns the index of the given value in the array. If the
+ // array does not contain the given value, the method returns a negative
+ // integer. The bitwise complement operator (~) can be applied to a
+ // negative result to produce the index of the first element (if any) that
+ // is larger than the given search value.
+ //
+ //|
+ public static int BinarySearch(Array array, int index, int length, Object value, IComparer comparer) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ int lb = array.GetLowerBound(0);
+ if (index < lb || length < 0)
+ throw new ArgumentOutOfRangeException((index> 1;
+ int c;
+ try {
+ c = comparer.Compare(objArray[i], value);
+ }
+ catch (Exception e) {
+ throw new InvalidOperationException("InvalidOperation_IComparerFailed", e);
+ }
+ if (c == 0) return i;
+ if (c < 0) {
+ lo = i + 1;
+ }
+ else {
+ hi = i - 1;
+ }
+ }
+ }
+ else {
+ while (lo <= hi) {
+ int i = (lo + hi) >> 1;
+ int c;
+ try {
+ c = comparer.Compare(array.GetValue(i), value);
+ }
+ catch (Exception e) {
+ throw new InvalidOperationException("InvalidOperation_IComparerFailed", e);
+ }
+ if (c == 0) return i;
+ if (c < 0) {
+ lo = i + 1;
+ }
+ else {
+ hi = i - 1;
+ }
+ }
+ }
+ return ~lo;
+ }
+
+ private static int TrySZBinarySearch(Array sourceArray, int sourceIndex, int count, Object value, out int retVal) {
+ // BUGBUG: was fast native primitive type method
+ // returning false (0) means we couldn't handle it
+ retVal = -1;
+ return 0;
+ }
+
+ // CopyTo copies a collection into an Array, starting at a particular
+ // index into the array.
+ //
+ // This method is to support the ICollection interface, and calls
+ // Array.Copy internally. If you aren't using ICollection explicitly,
+ // call Array.Copy to avoid an extra indirection.
+ //
+ //|
+ public virtual void CopyTo(Array array, int index)
+ {
+ if (array != null && array.Rank != 1)
+ throw new ArgumentException("Arg_RankMultiDimNotSupported");
+ // Note: Array.Copy throws a RankException and we want a consistent ArgumentException for all the IList CopyTo methods.
+ Array.Copy(this, GetLowerBound(0), array, index, Length);
+ }
+
+ //|
+ public virtual void CopyTo(Array array, long index)
+ {
+ if (index > Int32.MaxValue || index < Int32.MinValue)
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_HugeArrayNotSupported");
+
+ this.CopyTo(array, (int) index);
+ }
+
+
+ // GetEnumerator returns an IEnumerator over this Array.
+ //
+ // Currently, only one dimensional arrays are supported.
+ //
+ //|
+ public virtual IEnumerator GetEnumerator()
+ {
+ int lowerBound = GetLowerBound(0);
+ if (Rank == 1 && lowerBound == 0)
+ return new SZArrayEnumerator(this);
+ else
+ return new ArrayEnumerator(this, lowerBound, Length);
+ }
+
+ // Returns the index of the first occurrence of a given value in an array.
+ // The array is searched forwards, and the elements of the array are
+ // compared to the given value using the Object.Equals method.
+ //
+ //|
+ public static int IndexOf(Array array, Object value) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ int lb = array.GetLowerBound(0);
+ return IndexOf(array, value, lb, array.Length);
+ }
+
+ // Returns the index of the first occurrence of a given value in a range of
+ // an array. The array is searched forwards, starting at index
+ // startIndex and ending at the last element of the array. The
+ // elements of the array are compared to the given value using the
+ // Object.Equals method.
+ //
+ //|
+ public static int IndexOf(Array array, Object value, int startIndex) {
+ if (array == null)
+ throw new ArgumentNullException("array", "ArgumentNull_Array");
+ int lb = array.GetLowerBound(0);
+ return IndexOf(array, value, startIndex, array.Length - startIndex + lb);
+ }
+
+ // Returns the index of the first occurrence of a given value in a range of
+ // an array. The array is searched forwards, starting at index
+ // startIndex and up to count elements. The
+ // elements of the array are compared to the given value using the
+ // Object.Equals method.
+ //
+ //|
+ public static int IndexOf(Array array, Object value, int startIndex, int count) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ int lb = array.GetLowerBound(0);
+ if (startIndex < lb || startIndex > array.Length + lb)
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_Index");
+ if (count < 0 || count > array.Length - startIndex + lb)
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_Count");
+ if (array.Rank != 1)
+ throw new RankException("Rank_MultiDimNotSupported");
+
+ // Try calling a quick native method to handle primitive types.
+ int retVal;
+ int r = TrySZIndexOf(array, startIndex, count, value, out retVal);
+ if (r != 0)
+ return retVal;
+
+ Object[] objArray = array as Object[];
+ int endIndex = startIndex + count;
+ if (objArray != null) {
+ if (value == null) {
+ for (int i = startIndex; i < endIndex; i++) {
+ if (objArray[i] == null) return i;
+ }
+ }
+ else {
+ for (int i = startIndex; i < endIndex; i++) {
+ Object obj = objArray[i];
+ if (obj != null && value.Equals(obj)) return i;
+ }
+ }
+ }
+ else {
+ // This is an array of value classes
+ Debug.Assert(array.GetType().GetElementType().IsValueType, "array.GetType().GetUnderlyingType().IsValueType");
+ if (value == null)
+ return -1;
+ for (int i = startIndex; i < endIndex; i++) {
+ Object obj = array.GetValue(i);
+ if (obj != null && value.Equals(obj)) return i;
+ }
+ }
+ // Return one less than the lower bound of the array. This way,
+ // for arrays with a lower bound of -1 we will not return -1 when the
+ // item was not found. And for SZArrays (the vast majority), -1 still
+ // works for them.
+ return lb-1;
+ }
+
+ private static int TrySZIndexOf(Array sourceArray, int sourceIndex, int count, Object value, out int retVal) {
+ // BUGBUG: was fast native primitive type method
+ // returning false (0) means we couldn't handle it
+ retVal = -1;
+ return 0;
+ }
+
+ // Returns the index of the last occurrence of a given value in an array.
+ // The array is searched backwards, and the elements of the array are
+ // compared to the given value using the Object.Equals method.
+ //
+ //|
+ public static int LastIndexOf(Array array, Object value) {
+ if (array == null)
+ throw new ArgumentNullException("array", "ArgumentNull_Array");
+ int lb = array.GetLowerBound(0);
+ return LastIndexOf(array, value, array.Length - 1 + lb, array.Length);
+ }
+
+ // Returns the index of the last occurrence of a given value in a range of
+ // an array. The array is searched backwards, starting at index
+ // startIndex and ending at index 0. The elements of the array are
+ // compared to the given value using the Object.Equals method.
+ //
+ //|
+ public static int LastIndexOf(Array array, Object value, int startIndex) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ int lb = array.GetLowerBound(0);
+ return LastIndexOf(array, value, startIndex, startIndex + 1 - lb);
+ }
+
+ // Returns the index of the last occurrence of a given value in a range of
+ // an array. The array is searched backwards, starting at index
+ // startIndex and counting uptocount elements. The elements of
+ // the array are compared to the given value using the Object.Equals
+ // method.
+ //
+ //|
+ public static int LastIndexOf(Array array, Object value, int startIndex, int count) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ if (array.Length == 0) {
+ return -1;
+ }
+ int lb = array.GetLowerBound(0);
+ if (startIndex < lb || startIndex >= array.Length + lb)
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_Index");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_Count");
+ if (count > startIndex - lb + 1)
+ throw new ArgumentOutOfRangeException("endIndex", "ArgumentOutOfRange_EndIndexStartIndex");
+ if (array.Rank != 1)
+ throw new RankException("Rank_MultiDimNotSupported");
+
+ // Try calling a quick native method to handle primitive types.
+ int retVal;
+ int r = TrySZLastIndexOf(array, startIndex, count, value, out retVal);
+ if (r != 0)
+ return retVal;
+
+ Object[] objArray = array as Object[];
+ int endIndex = startIndex - count + 1;
+ if (objArray != null) {
+ if (value == null) {
+ for (int i = startIndex; i >= endIndex; i--) {
+ if (objArray[i] == null) return i;
+ }
+ }
+ else {
+ for (int i = startIndex; i >= endIndex; i--) {
+ Object obj = objArray[i];
+ if (obj != null && value.Equals(obj)) return i;
+ }
+ }
+ }
+ else {
+ // This is an array of value classes
+ Debug.Assert(array.GetType().GetElementType().IsValueType, "array.GetType().GetUnderlyingType().IsValueType");
+ if (value == null)
+ return -1;
+ for (int i = startIndex; i >= endIndex; i--) {
+ Object obj = array.GetValue(i);
+ if (obj != null && value.Equals(obj)) return i;
+ }
+ }
+ return lb-1; // Return lb-1 for arrays with negative lower bounds.
+ }
+
+ private static int TrySZLastIndexOf(Array sourceArray, int sourceIndex, int count, Object value, out int retVal) {
+ // BUGBUG: was fast native primitive type method
+ // returning false (0) means we couldn't handle it
+ retVal = -1;
+ return 0;
+ }
+
+ // Reverses all elements of the given array. Following a call to this
+ // method, an element previously located at index i will now be
+ // located at index length - i - 1, where length is the
+ // length of the array.
+ //
+ //|
+ public static void Reverse(Array array) {
+ if (array == null)
+ throw new ArgumentNullException("array", "ArgumentNull_Array");
+ Reverse(array, array.GetLowerBound(0), array.Length);
+ }
+
+ // Reverses the elements in a range of an array. Following a call to this
+ // method, an element in the range given by index and count
+ // which was previously located at index i will now be located at
+ // index index + (index + count - i - 1).
+ //
+ //|
+ public static void Reverse(Array array, int index, int length) {
+ if (array == null)
+ throw new ArgumentNullException("array");
+ if (index < array.GetLowerBound(0) || length < 0)
+ throw new ArgumentOutOfRangeException((index<0 ? "index" : "length"), "ArgumentOutOfRange_NeedNonNegNum");
+ if (array.Length - (index - array.GetLowerBound(0)) < length)
+ throw new ArgumentException("Argument_InvalidOffLen");
+ if (array.Rank != 1)
+ throw new RankException("Rank_MultiDimNotSupported");
+
+ bool r = TrySZReverse(array, index, length);
+ if (r)
+ return;
+
+ int i = index;
+ int j = index + length - 1;
+ Object[] objArray = array as Object[];
+ if (objArray != null) {
+ while (i < j) {
+ Object temp = objArray[i];
+ objArray[i] = objArray[j];
+ objArray[j] = temp;
+ i++;
+ j--;
+ }
+ }
+ else {
+ while (i < j) {
+ Object temp = array.GetValue(i);
+ array.SetValue(array.GetValue(j), i);
+ array.SetValue(temp, j);
+ i++;
+ j--;
+ }
+ }
+ }
+
+ private static bool TrySZReverse(Array array, int index, int count) {
+ // BUGBUG: was fast native primitive type method
+ // returning false means we couldn't handle it
+ return false;
+ }
+
+ // Sorts the elements of an array. The sort compares the elements to each
+ // other using the IComparable interface, which must be implemented
+ // by all elements of the array.
+ //
+ //|
+ public static void Sort(Array array) {
+ if (array == null)
+ throw new ArgumentNullException("array", "ArgumentNull_Array");
+ Sort(array, null, array.GetLowerBound(0), array.Length, null);
+ }
+
+ // Sorts the elements of two arrays based on the keys in the first array.
+ // Elements in the keys array specify the sort keys for
+ // corresponding elements in the items array. The sort compares the
+ // keys to each other using the IComparable interface, which must be
+ // implemented by all elements of the keys array.
+ //
+ //|
+ public static void Sort(Array keys, Array items) {
+ if (keys == null)
+ throw new ArgumentNullException("keys");
+ Sort(keys, items, keys.GetLowerBound(0), keys.Length, null);
+ }
+
+ // Sorts the elements in a section of an array. The sort compares the
+ // elements to each other using the IComparable interface, which
+ // must be implemented by all elements in the given section of the array.
+ //
+ //|
+ public static void Sort(Array array, int index, int length) {
+ Sort(array, null, index, length, null);
+ }
+
+ // Sorts the elements in a section of two arrays based on the keys in the
+ // first array. Elements in the keys array specify the sort keys for
+ // corresponding elements in the items array. The sort compares the
+ // keys to each other using the IComparable interface, which must be
+ // implemented by all elements of the keys array.
+ //
+ //|
+ public static void Sort(Array keys, Array items, int index, int length) {
+ Sort(keys, items, index, length, null);
+ }
+
+ // Sorts the elements of an array. The sort compares the elements to each
+ // other using the given IComparer interface. If comparer is
+ // null, the elements are compared to each other using the
+ // IComparable interface, which in that case must be implemented by
+ // all elements of the array.
+ //
+ //|
+ public static void Sort(Array array, IComparer comparer) {
+ if (array == null)
+ throw new ArgumentNullException("array", "ArgumentNull_Array");
+ Sort(array, null, array.GetLowerBound(0), array.Length, comparer);
+ }
+
+ // Sorts the elements of two arrays based on the keys in the first array.
+ // Elements in the keys array specify the sort keys for
+ // corresponding elements in the items array. The sort compares the
+ // keys to each other using the given IComparer interface. If
+ // comparer is null, the elements are compared to each other using
+ // the IComparable interface, which in that case must be implemented
+ // by all elements of the keys array.
+ //
+ //|
+ public static void Sort(Array keys, Array items, IComparer comparer) {
+ if (keys == null)
+ throw new ArgumentNullException("keys");
+ Sort(keys, items, keys.GetLowerBound(0), keys.Length, comparer);
+ }
+
+ // Sorts the elements in a section of an array. The sort compares the
+ // elements to each other using the given IComparer interface. If
+ // comparer is null, the elements are compared to each other using
+ // the IComparable interface, which in that case must be implemented
+ // by all elements in the given section of the array.
+ //
+ //|
+ public static void Sort(Array array, int index, int length, IComparer comparer) {
+ Sort(array, null, index, length, comparer);
+ }
+
+ // Sorts the elements in a section of two arrays based on the keys in the
+ // first array. Elements in the keys array specify the sort keys for
+ // corresponding elements in the items array. The sort compares the
+ // keys to each other using the given IComparer interface. If
+ // comparer is null, the elements are compared to each other using
+ // the IComparable interface, which in that case must be implemented
+ // by all elements of the given section of the keys array.
+ //
+ //|
+ public static void Sort(Array keys, Array items, int index, int length, IComparer comparer) {
+ if (keys == null)
+ throw new ArgumentNullException("keys");
+ if (keys.Rank != 1 || (items != null && items.Rank != 1))
+ throw new RankException("Rank_MultiDimNotSupported");
+ if (items != null && keys.GetLowerBound(0) != items.GetLowerBound(0))
+ throw new ArgumentException("Arg_LowerBoundsMustMatch");
+ if (index < keys.GetLowerBound(0) || length < 0)
+ throw new ArgumentOutOfRangeException((length<0 ? "length" : "index"), "ArgumentOutOfRange_NeedNonNegNum");
+ if (keys.Length - (index + keys.GetLowerBound(0)) < length || (items != null && index > items.Length - length))
+ throw new ArgumentException("Argument_InvalidOffLen");
+
+
+
+ if (length > 1) {
+ if (comparer == Comparer.Default || comparer == null) {
+ int r = TrySZSort(keys, items, index, index + length - 1);
+ if (r != 0)
+ return;
+ }
+
+ Object[] objKeys = keys as Object[];
+ Object[] objItems = null;
+ if (objKeys != null)
+ objItems = items as Object[];
+ if (objKeys != null && (items == null || objItems != null)) {
+ SorterObjectArray sorter = new SorterObjectArray(objKeys, objItems, comparer);
+ sorter.QuickSort(index, index + length - 1);
+ }
+ else {
+ SorterGenericArray sorter = new SorterGenericArray(keys, items, comparer);
+ sorter.QuickSort(index, index + length - 1);
+ }
+ }
+ }
+
+ private static int TrySZSort(Array keys, Array items, int left, int right) {
+ // BUGBUG: was fast native primitive type method
+ // returning false (0) means we couldn't handle it
+ return 0;
+ }
+
+ // Private class used by the Sort methods.
+ private class SorterObjectArray
+ {
+ private Object[] keys;
+ private Object[] items;
+ private IComparer comparer;
+
+
+ public SorterObjectArray(Object[] keys, Object[] items, IComparer comparer) {
+ if (comparer == null) comparer = Comparer.Default;
+ this.keys = keys;
+ this.items = items;
+ this.comparer = comparer;
+ }
+
+ public virtual void QuickSort(int left, int right) {
+ // Can use the much faster jit helpers for array access.
+ do {
+ int i = left;
+ int j = right;
+ Object x = keys[(i + j) >> 1];
+ do {
+ // Add a try block here to detect IComparers (or their
+ // underlying IComparables, etc) that are bogus.
+ try {
+ while (comparer.Compare(keys[i], x) < 0) i++;
+ while (comparer.Compare(x, keys[j]) < 0) j--;
+ }
+ catch (IndexOutOfRangeException) {
+ throw new ArgumentException(String.Format("Arg_BogusIComparer", x, x.GetType().Name, comparer));
+ }
+ catch (Exception e) {
+ throw new InvalidOperationException("InvalidOperation_IComparerFailed", e);
+ }
+ Debug.Assert(i>=left && j<=right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
+ if (i > j) break;
+ if (i < j) {
+ Object key = keys[i];
+ keys[i] = keys[j];
+ keys[j] = key;
+ if (items != null) {
+ Object item = items[i];
+ items[i] = items[j];
+ items[j] = item;
+ }
+ }
+ i++;
+ j--;
+ } while (i <= j);
+ if (j - left <= right - i) {
+ if (left < j) QuickSort(left, j);
+ left = i;
+ }
+ else {
+ if (i < right) QuickSort(i, right);
+ right = j;
+ }
+ } while (left < right);
+ }
+ }
+
+ // Private class used by the Sort methods for instances of System.Array.
+ // This is slower than the one for Object[], since we can't use the JIT helpers
+ // to access the elements. We must use GetValue & SetValue.
+ private class SorterGenericArray
+ {
+ private Array keys;
+ private Array items;
+ private IComparer comparer;
+
+ public SorterGenericArray(Array keys, Array items, IComparer comparer) {
+ if (comparer == null) comparer = Comparer.Default;
+ this.keys = keys;
+ this.items = items;
+ this.comparer = comparer;
+ }
+
+ public virtual void QuickSort(int left, int right) {
+ // Must use slow Array accessors (GetValue & SetValue)
+ do {
+ int i = left;
+ int j = right;
+ Object x = keys.GetValue((i + j) >> 1);
+ do {
+ // Add a try block here to detect IComparers (or their
+ // underlying IComparables, etc) that are bogus.
+ try {
+ while (comparer.Compare(keys.GetValue(i), x) < 0) i++;
+ while (comparer.Compare(x, keys.GetValue(j)) < 0) j--;
+ }
+ catch (IndexOutOfRangeException) {
+ throw new ArgumentException(String.Format("Arg_BogusIComparer", x, x.GetType().Name, comparer));
+ }
+ catch (Exception e) {
+ throw new InvalidOperationException("InvalidOperation_IComparerFailed", e);
+ }
+ Debug.Assert(i>=left && j<=right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
+ if (i > j) break;
+ if (i < j) {
+ Object key = keys.GetValue(i);
+ keys.SetValue(keys.GetValue(j), i);
+ keys.SetValue(key, j);
+ if (items != null) {
+ Object item = items.GetValue(i);
+ items.SetValue(items.GetValue(j), i);
+ items.SetValue(item, j);
+ }
+ }
+ i++;
+ j--;
+ } while (i <= j);
+ if (j - left <= right - i) {
+ if (left < j) QuickSort(left, j);
+ left = i;
+ }
+ else {
+ if (i < right) QuickSort(i, right);
+ right = j;
+ }
+ } while (left < right);
+ }
+ }
+
+ private class SZArrayEnumerator : IEnumerator, ICloneable
+ {
+ private Array _array;
+ private int _index;
+ private int _endIndex; // cache array length, since it's a little slow.
+
+ internal SZArrayEnumerator(Array array) {
+ Debug.Assert(array.Rank == 1 && array.GetLowerBound(0) == 0, "SZArrayEnumerator only works on single dimension arrays w/ a lower bound of zero.");
+ _array = array;
+ _index = -1;
+ _endIndex = array.Length;
+ }
+
+ public virtual Object Clone()
+ {
+ return MemberwiseClone();
+ }
+
+ public virtual bool MoveNext() {
+ if (_index < _endIndex) {
+ _index++;
+ return (_index < _endIndex);
+ }
+ return false;
+ }
+
+ public virtual Object Current {
+ get {
+ if (_index < 0) throw new InvalidOperationException("InvalidOperation_EnumNotStarted");
+ if (_index >= _endIndex) throw new InvalidOperationException("InvalidOperation_EnumEnded");
+ return _array.GetValue(_index);
+ }
+ }
+
+ public virtual void Reset() {
+ _index = -1;
+ }
+ }
+
+ private class ArrayEnumerator : IEnumerator, ICloneable
+ {
+ private Array array;
+ private int index;
+ private int endIndex;
+ private int startIndex; // Save for Reset.
+ private int[] _indices; // The current position in a multidimensional array
+ private bool _complete;
+
+ internal ArrayEnumerator(Array array, int index, int count) {
+ this.array = array;
+ this.index = index - 1;
+ startIndex = index;
+ endIndex = index + count;
+ _indices = new int[array.Rank];
+ int checkForZero = 1; // Check for dimensions of size 0.
+ for (int i = 0; i < array.Rank; i++) {
+ _indices[i] = array.GetLowerBound(i);
+ checkForZero *= array.GetLength(i);
+ }
+ // To make MoveNext simpler, decrement least significant index.
+ _indices[_indices.Length-1]--;
+ _complete = (checkForZero == 0);
+ }
+
+ private void IncArray() {
+ // This method advances us to the next valid array index,
+ // handling all the multiple dimension & bounds correctly.
+ // Think of it like an odometer in your car - we start with
+ // the last digit, increment it, and check for rollover. If
+ // it rolls over, we set all digits to the right and including
+ // the current to the appropriate lower bound. Do these overflow
+ // checks for each dimension, and if the most significant digit
+ // has rolled over its upper bound, we're done.
+ //
+ // @TODO: Figure out if this slower and/or more complex than
+ // sticking a private method on Array to access it as a flat
+ // structure (ie, reference from 0 to length, ignoring bounds &
+ // dimensions).
+ int rank = array.Rank;
+ _indices[rank-1]++;
+ for (int dim = rank - 1; dim >= 0; dim--) {
+ if (_indices[dim] > array.GetUpperBound(dim)) {
+ if (dim == 0) {
+ _complete = true;
+ break;
+ }
+ for (int j = dim; j < rank; j++)
+ _indices[j] = array.GetLowerBound(j);
+ _indices[dim-1]++;
+ }
+ }
+ }
+
+ public virtual Object Clone()
+ {
+ return MemberwiseClone();
+ }
+
+ public virtual bool MoveNext() {
+ if (_complete) {
+ index = endIndex;
+ return false;
+ }
+ index++;
+ IncArray();
+ return !_complete;
+ }
+
+ public virtual Object Current {
+ get {
+ if (index < startIndex) throw new InvalidOperationException("InvalidOperation_EnumNotStarted");
+ if (_complete) throw new InvalidOperationException("InvalidOperation_EnumEnded");
+ return array.GetValue(_indices);
+ }
+ }
+
+ public virtual void Reset() {
+ index = startIndex - 1;
+ int checkForZero = 1;
+ for (int i = 0; i < array.Rank; i++) {
+ _indices[i] = array.GetLowerBound(i);
+ checkForZero *= array.GetLength(i);
+ }
+ _complete = (checkForZero == 0);
+ // To make MoveNext simpler, decrement least significant index.
+ _indices[_indices.Length-1]--;
+ }
+ }
+
+
+ // if this is an array of value classes and that value class has a default constructor
+ // then this calls this default constructor on every element in the value class array.
+ // otherwise this is a no-op. Generally this method is called automatically by the compiler
+ //|
+ public unsafe void Initialize()
+ {
+ // if it is an array of struct, we need to call the default
+ // constructor for the struct
+ if (this.vtable.arrayOf == StructuralType.Struct) {
+ RuntimeType runtimeType = this.vtable.arrayElementClass.vtableType;
+ UIntPtr fn = runtimeType.ctor;
+ if (fn == UIntPtr.Zero)
+ return;
+
+ int total = 0;
+ for (int i = 0; i < Rank; i++) {
+ total += GetLength(i);
+ }
+ fixed(int *srcField = &this.field1) {
+ UIntPtr elementAddress =
+ new UIntPtr(this.GetFirstElementAddress(srcField));
+ UIntPtr elementSize =
+ new UIntPtr(this.vtable.arrayElementSize);
+ for (int i = 0; i < total; i++) {
+ Magic.calli(runtimeType.ctor, elementAddress);
+ elementAddress = elementAddress + elementSize;
+ }
+ }
+ }
+ }
+
+ private int RankRectangleArray {
+ get {
+ return field1;
+ }
+ }
+ private int Length0RectangleArray {
+ get {
+ return field4;
+ }
+ }
+ // PRE: this fixed
+ // REVIEW: return type
+ internal unsafe void* GetFirstDimInfoRectangleArray() {
+ fixed(int* ptr = &field3) {
+ return (void*)ptr;
+ }
+ }
+
+ private unsafe int GetLowerBoundRectangleArray(int dimension) {
+ fixed(int* ptr = &field3) {
+ return ptr[2*dimension];
+ }
+ }
+
+ private int GetLengthVector() {
+ return field1;
+ }
+
+ private unsafe int GetLengthRectangleArray(int dimension) {
+ fixed(int* ptr = &field3) {
+ return ptr[2*dimension+1];
+ }
+ }
+
+ private unsafe int GetLengthRectangleArray() {
+ return field2;
+ }
+
+ // PRE: this fixed
+ // REVIEW: return type
+ [NoHeapAllocation]
+ internal unsafe void* GetFirstElementAddress(int *field1Addr) {
+ return (void*)(((byte*)field1Addr) + this.vtable.baseLength -
+ (PreHeader.Size + PostHeader.Size));
+ }
+
+ // Calculates the offset from the first element of the array to the
+ // desired element. This offset is a count -- that is, it does not take
+ // the size of the elements into account (e.g. int_array[2] would lead
+ // to 2, not 2*sizeof(int) = 8).
+ private unsafe int InternalGetOffset(int[] indices) {
+ if (IsVector) {
+ return indices[0];
+ }
+ else {
+ int rank = RankRectangleArray;
+ int dwOffset = 0;
+ int dwMultiplier = 1;
+
+ fixed(int* ptr = &field3) {
+ for (int i = rank - 1; i >= 0; i--) {
+ int dwIndex = indices[i] - ptr[2*i];
+
+ if (dwIndex >= ptr[2*i + 1]) {
+ throw new IndexOutOfRangeException();
+ }
+
+ dwOffset += dwIndex * dwMultiplier;
+ dwMultiplier *= ptr[2*i+1];
+ }
+ return dwOffset;
+ }
+ }
+ }
+
+ // See comment by the other InternalGetOffset
+ private unsafe int InternalGetOffset(int index1, int index2,
+ int index3) {
+ if (IsVector) {
+ VTable.Assert(index2 == 0);
+ VTable.Assert(index3 == 0);
+ return index1;
+ }
+ else {
+ int rank = RankRectangleArray;
+ int dwOffset = 0;
+ int dwMultiplier = 1;
+
+ VTable.Assert(rank <= 3);
+
+ fixed(int* ptr = &field3) {
+ for (int i = rank - 1; i >= 0; i--) {
+ int dwIndex;
+ if (i == 2) {
+ dwIndex = index3 - ptr[2*i];
+ }
+ else if(i == 1) {
+ dwIndex = index2 - ptr[2*i];
+ }
+ else {
+ dwIndex = index1 - ptr[2*i];
+ }
+
+ if (dwIndex >= ptr[2*i + 1]) {
+ throw new IndexOutOfRangeException();
+ }
+ dwOffset += dwIndex * dwMultiplier;
+ dwMultiplier *= ptr[2*i+1];
+ }
+ return dwOffset;
+ }
+ }
+ }
+
+ // Given an array (this), a pointer to its first element (EA), and
+ // the offset (count of elements -- see InternalGetOffset comment for
+ // what this means), compute the desired element's address, get the
+ // value, box it if necessary, and return it
+ // PRE: 'this' fixed
+ private unsafe Object InternalGetValueHelper(byte *EA, int dwOffset) {
+ int arrayElementSize = this.vtable.arrayElementSize;
+ EA += dwOffset * arrayElementSize;
+
+ // now we have the address of the array element
+ // if it's already an object, return it
+ if (this.vtable.arrayOf == StructuralType.Reference) {
+ return Magic.fromAddress(*(UIntPtr*)EA);
+ }
+
+ // BUGBUG: we won't have the enum type anywhere!
+
+ Object result;
+ switch (this.vtable.arrayOf) {
+ case StructuralType.Struct:
+ // possible GC point -- but 'this' is fixed so EA won't get
+ // invalidated
+
+ Thread thread = Thread.CurrentThread;
+ result = GC.AllocateObject(vtable.arrayElementClass);
+
+ // HACK: depends on value being at same spot in all value types
+ // REVIEW: result is not fixed
+ UIntPtr dst = Magic.addressOf(result) + PostHeader.Size;
+ VTable arrayElementClass = this.vtable.arrayElementClass;
+#if REFERENCE_COUNTING_GC
+ UIntPtr objAddr = (UIntPtr)(EA-PostHeader.Size);
+ GCs.ReferenceCountingCollector.
+ IncrementReferentRefCounts(objAddr, arrayElementClass);
+ System.IO.__UnmanagedMemoryStream.memcpyimpl(EA, (byte *) dst,
+ arrayElementSize);
+#elif DEFERRED_REFERENCE_COUNTING_GC
+ UIntPtr objAddr =
+ (UIntPtr)(EA-Object.VTABLE_OFFSET-UIntPtr.Size);
+ GCs.DeferredReferenceCountingCollector.
+ IncrementReferentRefCounts(objAddr, arrayElementClass);
+ System.IO.__UnmanagedMemoryStream.memcpyimpl(EA, (byte *) dst,
+ arrayElementSize);
+#else
+ Barrier.CopyStruct(this, result, arrayElementClass,
+ (UIntPtr) EA, dst);
+#endif // REFERENCE_COUNTING_GC
+ break;
+ case StructuralType.Bool:
+ result = *(bool*)EA;
+ break;
+ case StructuralType.Char:
+ result = *(char*)EA;
+ break;
+ case StructuralType.Int8:
+ result = *(sbyte*)EA;
+ break;
+ case StructuralType.Int16:
+ result = *(short*)EA;
+ break;
+ case StructuralType.Int32:
+ result = *(int*)EA;
+ break;
+ case StructuralType.Int64:
+ result = *(long*)EA;
+ break;
+ case StructuralType.UInt8:
+ result = *(byte*)EA;
+ break;
+ case StructuralType.UInt16:
+ result = *(ushort*)EA;
+ break;
+ case StructuralType.UInt32:
+ result = *(uint*)EA;
+ break;
+ case StructuralType.UInt64:
+ result = *(ulong*)EA;
+ break;
+ case StructuralType.Float32:
+ result = *(float*)EA;
+ break;
+ case StructuralType.Float64:
+ result = *(double*)EA;
+ break;
+ default:
+ VTable.Assert(false, "unreachable array get box");
+ return null;
+ }
+ return result;
+ }
+
+ // Given an array (this), a pointer to its first element (EA), and
+ // the offset (count of elements -- see m_InternalGetOffset comment for
+ // what this means), compute the desired element's address, typecheck
+ // the value against the actual array type, unbox it if necessary, and
+ // put it in the array
+ // PRE: 'this' fixed
+ // BUGBUG: need to support widening of primitives
+ private unsafe void InternalSetValueHelper(byte *EA, int dwOffset,
+ Object value) {
+ int arrayElementSize = this.vtable.arrayElementSize;
+ EA += dwOffset * arrayElementSize;
+
+ // have address to store at, but need to typecheck
+ if (this.vtable.arrayOf == StructuralType.Reference) {
+ VTable.checkArrayStore(this, value);
+
+#if REFERENCE_COUNTING_GC
+ GCs.ReferenceCountingCollector.IncrementRefCount(value);
+ Object old = Magic.fromAddress(*(UIntPtr*)EA);
+ GCs.ReferenceCountingCollector.DecrementRefCount(old);
+ *(UIntPtr *)EA = Magic.addressOf(value);
+#elif DEFERRED_REFERENCE_COUNTING_GC
+ GCs.DeferredReferenceCountingCollector.IncrementRefCount(value);
+ Object old = Magic.fromAddress(*(UIntPtr*)EA);
+ GCs.DeferredReferenceCountingCollector.DecrementRefCount(old);
+ *(UIntPtr *)EA = Magic.addressOf(value);
+#else
+ Barrier.StoreIndirect((UIntPtr *) EA, value, 0);
+#endif // REFERENCE_COUNTING_GC
+ return;
+ }
+
+ // BUGBUG: enum type lost
+
+ VTable vtable;
+ if (this.vtable.arrayOf == StructuralType.Struct) {
+ vtable = this.vtable.arrayElementClass;
+ }
+ else {
+ // assert primitive
+ vtable = TypeInfo.arrayOfBox[(int)this.vtable.arrayOf];
+ }
+
+ // BUGBUG: need to also widening of primitives
+ if (vtable != value.vtable) {
+ throw new InvalidCastException("InvalidCast_StoreArrayElement");
+ }
+
+ // HACK: depends on value being at same spot in all value types
+ // REVIEW: value is not fixed
+ UIntPtr src = Magic.addressOf(value) + PostHeader.Size;
+ if (this.vtable.arrayOf == StructuralType.Struct) {
+#if REFERENCE_COUNTING_GC
+ GCs.ReferenceCountingCollector.
+ IncrementReferentRefCounts(Magic.addressOf(value), vtable);
+ UIntPtr objAddr =
+ (UIntPtr)(EA-Object.VTABLE_OFFSET-UIntPtr.Size);
+ GCs.ReferenceCountingCollector.
+ DecrementReferentRefCounts(objAddr, vtable);
+#elif DEFERRED_REFERENCE_COUNTING_GC
+ GCs.DeferredReferenceCountingCollector.
+ IncrementReferentRefCounts(Magic.addressOf(value), vtable);
+ UIntPtr objAddr =
+ (UIntPtr)(EA-Object.VTABLE_OFFSET-UIntPtr.Size);
+ GCs.DeferredReferenceCountingCollector.
+ DecrementReferentRefCounts(objAddr, vtable);
+#else
+ Barrier.CopyStruct(value, this, vtable, src, (UIntPtr) EA);
+ return;
+#endif // REFERENCE_COUNTING_GC
+ }
+
+ Buffer.MoveMemory((byte *) EA, (byte *) src,
+ (UIntPtr) arrayElementSize);
+ }
+
+
+ // This is the core set routines for Get/Set Value. The arguments have
+ // been verified that they exist before we get to this point.
+
+ // PRE: rank has been checked (e.g. if rank==1, then index2==index3==0)
+ private unsafe Object InternalGetValue(int index1, int index2, int index3) {
+ fixed(int *o = &this.field1) {
+ byte *EA = (byte*) GetFirstElementAddress(o);
+ int dwOffset = InternalGetOffset(index1, index2, index3);
+ return InternalGetValueHelper(EA, dwOffset);
+ }
+ }
+
+ // PRE: rank has been checked
+ private unsafe Object InternalGetValueEx(int[] indices) {
+ fixed(int *o = &this.field1) {
+ byte *EA = (byte*) GetFirstElementAddress(o);
+ int dwOffset = InternalGetOffset(indices);
+ return InternalGetValueHelper(EA, dwOffset);
+ }
+ }
+
+
+ // PRE: rank has been checked (e.g. if rank==1, then index2==index3==0)
+ // REVIEW: check ordering of errors (e.g. if you try to store the wrong
+ // types of object in an array at an illegal offset, what should happen?)
+ private unsafe void InternalSetValue(Object value, int index1,
+ int index2, int index3) {
+ fixed(int *o = &this.field1) {
+ byte *EA = (byte*) GetFirstElementAddress(o);
+ int dwOffset = InternalGetOffset(index1, index2, index3);
+ InternalSetValueHelper(EA, dwOffset, value);
+ }
+ }
+
+ private unsafe void InternalSetValueEx(Object value,int[] indices) {
+ fixed(int *o = &this.field1) {
+ byte *EA = (byte*) GetFirstElementAddress(o);
+ int dwOffset = InternalGetOffset(indices);
+ InternalSetValueHelper(EA, dwOffset, value);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern private static void UnsafeUpdateArray(Array a,Object value,int index);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ extern private static Object UnsafeReadArray(Array arr,int index);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern Array InternalQuickCreateEx(VTable array_type,int[] lengths,int[] lowerBounds);
+
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/ArrayTypeMismatchException.cs b/base/Applications/Runtime/Full/System/ArrayTypeMismatchException.cs
new file mode 100644
index 0000000..aca4af3
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/ArrayTypeMismatchException.cs
@@ -0,0 +1,40 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: ArrayTypeMismatchException
+//
+// Purpose: The arrays are of different primitive types.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ // The ArrayMismatchException is thrown when an attempt to store
+ // an object of the wrong type within an array occurs.
+ //
+ //|
+ public partial class ArrayTypeMismatchException : SystemException {
+
+ // Creates a new ArrayMismatchException with its message string set to
+ // message, its HRESULT set to COR_E_ARRAYTYPEMISMATCH,
+ // and its ExceptionInfo reference set to null.
+ //
+ //|
+ public ArrayTypeMismatchException(String message)
+ : base(message) {
+ }
+
+ //|
+ public ArrayTypeMismatchException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Attribute.cs b/base/Applications/Runtime/Full/System/Attribute.cs
new file mode 100644
index 0000000..2dc1460
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Attribute.cs
@@ -0,0 +1,30 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: Attribute
+//
+// Purpose: The class used as an attribute to denote that
+// another class can be used as an attribute.
+//
+//===========================================================
+namespace System
+{
+
+ using System;
+ using System.Reflection;
+ using System.Collections;
+
+ // This class is a placeholder for the compiler only!
+ // Singularity and Bartok don't support runtime access to custom attributes.
+
+ //|
+ [AttributeUsageAttribute(AttributeTargets.All, Inherited = true, AllowMultiple=false)] // Base class for all attributes
+ public abstract class Attribute {
+ //|
+ protected Attribute(){}
+ }
+}
diff --git a/base/Kernel/System/AttributeTargets.cs b/base/Applications/Runtime/Full/System/AttributeTargets.cs
similarity index 96%
rename from base/Kernel/System/AttributeTargets.cs
rename to base/Applications/Runtime/Full/System/AttributeTargets.cs
index 77dc941..e294721 100644
--- a/base/Kernel/System/AttributeTargets.cs
+++ b/base/Applications/Runtime/Full/System/AttributeTargets.cs
@@ -5,7 +5,8 @@
// ==--==
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-namespace System {
+namespace System
+{
using System;
diff --git a/base/Kernel/System/AttributeUsageAttribute.cs b/base/Applications/Runtime/Full/System/AttributeUsageAttribute.cs
similarity index 78%
rename from base/Kernel/System/AttributeUsageAttribute.cs
rename to base/Applications/Runtime/Full/System/AttributeUsageAttribute.cs
index fb83974..6ecf6af 100644
--- a/base/Kernel/System/AttributeUsageAttribute.cs
+++ b/base/Applications/Runtime/Full/System/AttributeUsageAttribute.cs
@@ -3,20 +3,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: AttributeUsageAttribute
-**
-**
-** Purpose: The class denotes how to specify the usage of an attribute
-**
-** Date: December 7, 1999
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: AttributeUsageAttribute
+//
+// Purpose: The class denotes how to specify the usage of an attribute
+//
+//===========================================================
+namespace System
+{
using System.Reflection;
- /* By default, attributes are inherited and multiple attributes are not allowed */
+ // By default, attributes are inherited and multiple attributes are not allowed
//|
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public sealed class AttributeUsageAttribute : Attribute
diff --git a/base/Applications/Runtime/Full/System/BitConverter.cs b/base/Applications/Runtime/Full/System/BitConverter.cs
new file mode 100644
index 0000000..18081e7
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/BitConverter.cs
@@ -0,0 +1,544 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: BitConverter
+//
+// Purpose: Allows developers to view the base data types as
+// an arbitrary array of bits.
+//
+//===========================================================
+namespace System
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+
+ // The BitConverter class contains methods for
+ // converting an array of bytes to one of the base data
+ // types, as well as for converting a base data type to an
+ // array of bytes.
+ //
+ //|
+
+ [CCtorIsRunDuringStartup]
+ public sealed class BitConverter {
+
+ // This field indicates the "endianness" of the architecture.
+ // The value is set to true if the architecture is
+ // little endian; false if it is big endian.
+ //|
+ public static readonly bool IsLittleEndian;
+
+ static BitConverter() {
+ byte [] ba = GetBytes((short)0xF);
+ if (ba[0] == 0xF) {
+ IsLittleEndian=true;
+ }
+ else {
+ IsLittleEndian=false;
+ }
+ }
+
+ // This class only contains static methods and may not be instantiated.
+ private BitConverter() {
+ }
+
+ // ======================================================================
+ // Convert from primitive types to byte array slices. These functions
+ // do not perform memory allocation and so are suitable for use in
+ // interrupt handlers and other no-allocation-allowed contexts. -- mbj
+ // ======================================================================
+
+ // Converts a byte into an existing array slice of bytes with length one.
+ public static void GetBytes(bool value, byte[] array, int startIndex) {
+ const int bytesNeeded = 1;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ array[startIndex] = (value ? (byte)Boolean.True : (byte)Boolean.False );
+ }
+
+ // Converts a char into an existing array slice of bytes with length two.
+ public static unsafe void GetBytes(char value, byte[] array, int startIndex) {
+ const int bytesNeeded = 2;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex]) {
+ *((char *) ptr) = value;
+ }
+ }
+
+ // Converts a short into an existing array slice of bytes with length two.
+ public static unsafe void GetBytes(short value, byte[] array, int startIndex) {
+ const int bytesNeeded = 2;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex]) {
+ *((short *) ptr) = value;
+ }
+ }
+
+ // Converts an int into an existing array slice of bytes with length four.
+ public static unsafe void GetBytes(int value, byte[] array, int startIndex) {
+ const int bytesNeeded = 4;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex]) {
+ *((int *) ptr) = value;
+ }
+ }
+
+ // Converts a long into an existing array slice of bytes with length eight.
+ public static unsafe void GetBytes(long value, byte[] array, int startIndex) {
+ const int bytesNeeded = 8;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex]) {
+ *((long *) ptr) = value;
+ }
+ }
+
+ // Converts an ushort into an existing array slice of bytes with length two.
+ [CLSCompliant(false)]
+ public static unsafe void GetBytes(ushort value, byte[] array, int startIndex) {
+ const int bytesNeeded = 2;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex])
+ {
+ *((ushort *) ptr) = value;
+ }
+ }
+
+ // Converts an uint into an existing array slice of bytes with length four.
+ [CLSCompliant(false)]
+ public static unsafe void GetBytes(uint value, byte[] array, int startIndex) {
+ const int bytesNeeded = 4;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex])
+ {
+ *((uint *) ptr) = value;
+ }
+ }
+
+ // Converts an unsigned long into an existing array slice of bytes with length eight.
+ [CLSCompliant(false)]
+ public static unsafe void GetBytes(ulong value, byte[] array, int startIndex) {
+ const int bytesNeeded = 8;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex])
+ {
+ *((ulong *) ptr) = value;
+ }
+ }
+
+ // Converts a float into an existing array slice of bytes with length four.
+ public unsafe static void GetBytes(float value, byte[] array, int startIndex)
+ {
+ const int bytesNeeded = 4;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex])
+ *((float*) ptr) = value;
+ }
+
+ // Converts a double into an existing array slice of bytes with length eight.
+ public unsafe static void GetBytes(double value, byte[] array, int startIndex)
+ {
+ const int bytesNeeded = 8;
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + bytesNeeded > array.Length) {
+ throw new ArgumentException("Array is too small");
+ }
+ fixed (byte *ptr = &array[startIndex])
+ *((double*) ptr) = value;
+ }
+
+ // ======================================================================
+ // Convert from primitive types to new byte arrays. These functions
+ // perform memory allocation and so are unsuitable for use in
+ // interrupt handlers and other no-allocation-allowed contexts. -- mbj
+ // ======================================================================
+
+ // Converts a byte into an array of bytes with length one.
+ //|
+ public static byte[] GetBytes(bool value) {
+ byte[] result = new byte[1];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts a char into an array of bytes with length two.
+ //|
+ public static unsafe byte[] GetBytes(char value) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::CharToBytes
+ byte[] result = new byte[2];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts a short into an array of bytes with length
+ // two.
+ //|
+ public static unsafe byte[] GetBytes(short value) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::I2ToBytes
+ byte[] result = new byte[2];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts an int into an array of bytes with length
+ // four.
+ //|
+ public static unsafe byte[] GetBytes(int value) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::I4ToBytes
+ byte[] result = new byte[4];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts a long into an array of bytes with length
+ // eight.
+ //|
+ public static unsafe byte[] GetBytes(long value) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::I8ToBytes
+ byte[] result = new byte[8];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts an ushort into an array of bytes with
+ // length two.
+ //|
+ [CLSCompliant(false)]
+ public static unsafe byte[] GetBytes(ushort value) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::U2ToBytes
+ byte[] result = new byte[2];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts an uint into an array of bytes with
+ // length four.
+ //|
+ [CLSCompliant(false)]
+ public static unsafe byte[] GetBytes(uint value) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::U4ToBytes
+ byte[] result = new byte[4];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts an unsigned long into an array of bytes with
+ // length eight.
+ //|
+ [CLSCompliant(false)]
+ public static unsafe byte[] GetBytes(ulong value) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::U8ToBytes
+ byte[] result = new byte[8];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts a float into an array of bytes with length
+ // four.
+ //|
+ public unsafe static byte[] GetBytes(float value)
+ {
+ byte[] result = new byte[4];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // Converts a double into an array of bytes with length
+ // eight.
+ //|
+ public unsafe static byte[] GetBytes(double value)
+ {
+ byte[] result = new byte[8];
+ GetBytes(value, result, 0);
+ return result;
+ }
+
+ // ============ Convert from byte array slices to primitive types ============
+
+ // Converts an array of bytes into a char.
+ //|
+ public static unsafe char ToChar(byte[] value, int startIndex) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::BytesToChar
+ char result;
+ fixed (byte *ptr = value) {
+ result = *((char *) (ptr + startIndex));
+ }
+ return result;
+ }
+
+ // Converts an array of bytes into a short.
+ //|
+ public static unsafe short ToInt16(byte[] value, int startIndex)
+ {
+ if (value == null) {
+ throw new ArgumentNullException("value");
+ }
+ if (((uint)startIndex) >= (uint)value.Length) {
+ throw new ArgumentOutOfRangeException("startIndex");
+ }
+ if (startIndex > (value.Length - 2)) {
+ throw new ArgumentException("startIndex");
+ }
+ fixed (byte* p = &value[startIndex]) {
+ if ((startIndex % 2) == 0) {
+ return *((short*)p);
+ }
+ if (IsLittleEndian) {
+ return (short)(p[0] | (p[1] << 8));
+ }
+ else {
+ return (short)(p[1] | (p[0] << 8));
+ }
+ }
+ }
+
+ // Converts an array of bytes into an int.
+ //|
+ public static unsafe int ToInt32(byte[]value, int startIndex)
+ {
+ if (value == null) {
+ throw new ArgumentNullException("value");
+ }
+ if (((uint)startIndex) >= (uint)value.Length) {
+ throw new ArgumentOutOfRangeException("startIndex");
+ }
+ if (startIndex > (value.Length - 4)) {
+ throw new ArgumentException("startIndex");
+ }
+ fixed (byte* p = &value[startIndex]) {
+ if ((startIndex % 4) == 0) {
+ return *((int*)p);
+ }
+ if (IsLittleEndian) {
+ return (
+ ((int)p[0]) |
+ (((int)p[1]) << 8) |
+ (((int)p[2]) << 16) |
+ (((int)p[3]) << 24)
+ );
+ }
+ else {
+ return (
+ ((int)p[3]) |
+ (((int)p[2]) << 8) |
+ (((int)p[1]) << 16) |
+ (((int)p[0]) << 24)
+ );
+ }
+ }
+ }
+
+ // Converts an array of bytes into a long.
+ //|
+ public static unsafe long ToInt64(byte[] value, int startIndex)
+ {
+ if (value == null) {
+ throw new ArgumentNullException("value");
+ }
+ if (((uint)startIndex) >= (uint)value.Length) {
+ throw new ArgumentOutOfRangeException("startIndex");
+ }
+ if (startIndex > (value.Length - 8)) {
+ throw new ArgumentException("startIndex");
+ }
+ fixed (byte* p = &value[startIndex]) {
+ if ((startIndex % 8) == 0) {
+ return *((long*)p);
+ }
+ if (IsLittleEndian) {
+ int lo = (((int)p[0]) |
+ (((int)p[1]) << 8) |
+ (((int)p[2]) << 16) |
+ (((int)p[3]) << 24)
+ );
+ int hi = (((int)p[4]) |
+ (((int)p[5]) << 8) |
+ (((int)p[6]) << 16) |
+ (((int)p[7]) << 24)
+ );
+ return (long)(((ulong)lo) | ((ulong)hi) << 32);
+ }
+ else {
+ int hi = (((int)p[3]) |
+ (((int)p[2]) << 8) |
+ (((int)p[1]) << 16) |
+ (((int)p[0]) << 24)
+ );
+ int lo = (((int)p[7]) |
+ (((int)p[6]) << 8) |
+ (((int)p[5]) << 16) |
+ (((int)p[4]) << 24)
+ );
+ return (long)(((ulong)lo) | ((ulong)hi) << 32);
+ }
+ }
+ }
+
+ // Converts an array of bytes into an ushort.
+ //
+ //|
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(byte[] value, int startIndex)
+ {
+ unchecked {
+ return (ushort)ToInt16(value, startIndex);
+ }
+ }
+
+ // Converts an array of bytes into an uint.
+ //
+ //|
+ [CLSCompliant(false)]
+ public static uint ToUInt32(byte[] value, int startIndex)
+ {
+ unchecked {
+ return (uint)ToInt32(value, startIndex);
+ }
+ }
+
+ // Converts an array of bytes into an unsigned long.
+ //
+ //|
+ [CLSCompliant(false)]
+ public static unsafe ulong ToUInt64(byte[] value, int startIndex)
+ {
+ unchecked {
+ return (ulong)ToInt64(value, startIndex);
+ }
+ }
+
+ // Converts an array of bytes into a float.
+ //|
+ public static unsafe float ToSingle(byte[]value, int startIndex) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::BytesToR4
+ float result;
+ fixed (byte *ptr = value) {
+ result = *((float *) (ptr + startIndex));
+ }
+ return result;
+ }
+
+ // Converts an array of bytes into a double.
+ //|
+ public static unsafe double ToDouble(byte []value, int startIndex) {
+ // See also Lightning\Src\VM\COMUtilNative.cpp::BytesToR8
+ double result;
+ fixed (byte *ptr = value) {
+ result = *((double *) (ptr + startIndex));
+ }
+ return result;
+ }
+
+ //==================================ToBoolean===================================
+ //Action: Convert an array of bytes to a boolean value. We treat this array
+ // as if the first 4 bytes were an Int4 an operate on this value.
+ //Returns: True if the Int4 value of the first 4 bytes is non-zero.
+ //Arguments: value -- The byte array
+ // startIndex -- The position within the array.
+ //Exceptions: See ToInt4.
+ //==============================================================================
+ // Converts an array of bytes into a boolean.
+ //|
+ public static bool ToBoolean(byte[]value, int startIndex) {
+ if (value == null)
+ throw new ArgumentNullException("value");
+ if (startIndex < 0)
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_NeedNonNegNum");
+ if (startIndex > value.Length - 1)
+ throw new ArgumentOutOfRangeException("ArgumentOutOfRange_Index");
+
+ return (value[startIndex]==0)?false:true;
+ }
+
+ //|
+ [Inline]
+ public static unsafe long DoubleToInt64Bits(double value) {
+ return *((long *)&value);
+ }
+
+ //|
+ [Inline]
+ public static unsafe double Int64BitsToDouble(long value) {
+ return *((double *)&value);
+ }
+
+ //|
+ [Inline]
+ [CLSCompliant(false)]
+ public static unsafe ulong DoubleToUInt64Bits(double value) {
+ return *((ulong *)&value);
+ }
+
+ //|
+ [Inline]
+ [CLSCompliant(false)]
+ public static unsafe double UInt64BitsToDouble(ulong value) {
+ return *((double *)&value);
+ }
+
+ //|
+ [Inline]
+ [CLSCompliant(false)]
+ public static unsafe uint SingleToUInt32Bits(float value) {
+ return *((uint *)&value);
+ }
+
+ //|
+ [Inline]
+ [CLSCompliant(false)]
+ public static unsafe float UInt32BitsToSingle(uint value) {
+ return *((float *)&value);
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Boolean.cs b/base/Applications/Runtime/Full/System/Boolean.cs
new file mode 100644
index 0000000..03b954c
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Boolean.cs
@@ -0,0 +1,164 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: Boolean
+//
+// Purpose: The boolean class serves as a wrapper for the primitive
+// type boolean.
+//
+//===========================================================
+namespace System
+{
+
+ using System;
+ using System.Globalization;
+ using System.Runtime.CompilerServices;
+
+ // The Boolean class provides the
+ // object representation of the boolean primitive type.
+ //|
+ public struct Boolean : IComparable {
+
+ //
+ // Member Variables
+ //
+ private bool m_value;
+
+
+ //
+ // Public Constants
+ //
+
+ // The true value.
+ //
+ internal const int True = 1;
+
+ // The false value.
+ //
+ internal const int False = 0;
+
+ // The string representation of true.
+ //
+ //|
+ public static readonly String TrueString = "True";
+
+ // The string representation of false.
+ //
+ //|
+ public static readonly String FalseString = "False";
+
+ //
+ // Overridden Instance Methods
+ //
+ //=================================GetHashCode==================================
+ //Args: None
+ //Returns: 1 or 0 depending on whether this instance represents true or false.
+ //Exceptions: None
+ //Overridden From: Value
+ //==============================================================================
+ // Provides a hash code for this instance.
+ //|
+ public override int GetHashCode() {
+ return (m_value)?True:False;
+ }
+
+ //===================================ToString===================================
+ //Args: None
+ //Returns: "True" or "False" depending on the state of the boolean.
+ //Exceptions: None.
+ //==============================================================================
+ // Converts the boolean value of this instance to a String.
+ //|
+ public override String ToString() {
+ if (false == m_value) {
+ return FalseString;
+ }
+ return TrueString;
+ }
+
+ // Determines whether two Boolean objects are equal.
+ //|
+ public override bool Equals (Object obj) {
+ //If it's not a boolean, we're definitely not equal
+ if (!(obj is Boolean)) {
+ return false;
+ }
+
+ return (m_value==((Boolean)obj).m_value);
+ }
+
+ // Compares this object to another object, returning an integer that
+ // indicates the relationship. For booleans, false sorts before true.
+ // null is considered to be less than any instance.
+ // If object is not of type boolean, this method throws an ArgumentException.
+ //
+ // Returns a value less than zero if this object
+ //
+ //|
+ public int CompareTo(Object obj) {
+ if (obj == null) {
+ return 1;
+ }
+ if (!(obj is Boolean)) {
+ throw new ArgumentException ("Arg_MustBeBoolean");
+ }
+
+ if (m_value ==((Boolean)obj).m_value) {
+ return 0;
+ }
+ else if (m_value == false) {
+ return -1;
+ }
+ return 1;
+
+ }
+
+ //
+ // Static Methods
+ //
+
+ // Determines whether a String represents true or false.
+ //
+ //|
+ public static bool Parse(String value) {
+ if (value==null) throw new ArgumentNullException("value");
+ // For perf reasons, let's first see if they're equal, then do the
+ // trim to get rid of white space, and check again.
+ if (0 == String.Compare(value, TrueString,true))
+ return true;
+ if (0 == String.Compare(value,FalseString,true))
+ return false;
+
+ value = value.Trim(); // Remove leading & trailing white space.
+ if (0 == String.Compare(value, TrueString,true))
+ return true;
+ if (0 == String.Compare(value,FalseString,true))
+ return false;
+ throw new FormatException("Format_BadBoolean");
+ }
+
+ //
+ // IValue implementation
+ //
+
+ //|
+ [NoHeapAllocation]
+ public override TypeCode GetTypeCode() {
+ return TypeCode.Boolean;
+ }
+
+ //
+ // This is just designed to prevent compiler warnings.
+ // This field is used from native, but we need to prevent the compiler warnings.
+ //
+#if _DEBUG
+ private void DontTouchThis() {
+ m_value = m_value;
+ }
+#endif
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Buffer.cs b/base/Applications/Runtime/Full/System/Buffer.cs
new file mode 100644
index 0000000..d690b17
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Buffer.cs
@@ -0,0 +1,388 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//
+// Note: These routines assume that the processor supports
+// 32-bit aligned accesses. Migration to non-x86 platforms will
+// need to examine and tune the implementations accordingly.
+//
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+ //|
+
+ public sealed partial class Buffer
+ {
+ [NoHeapAllocation]
+ [Inline]
+ private static unsafe void WriteHelperByte(byte* dst, byte val,
+ bool vol) {
+ if (vol) {
+ System.Threading.Thread.VolatileWriteUnsafe(dst, val);
+ }
+ else {
+ *dst = val;
+ }
+ }
+
+ [NoHeapAllocation]
+ [Inline]
+ private static unsafe byte ReadHelperByte(byte* src, bool vol) {
+ if (vol) {
+ return System.Threading.Thread.VolatileReadUnsafe(src);
+ }
+ else {
+ return *src;
+ }
+ }
+
+ [NoHeapAllocation]
+ [Inline]
+ private static unsafe void WriteHelperShort(short* dst, short val,
+ bool vol) {
+ if (vol) {
+ System.Threading.Thread.VolatileWriteUnsafe(dst, val);
+ }
+ else {
+ *dst = val;
+ }
+ }
+
+ [NoHeapAllocation]
+ [Inline]
+ private static unsafe short ReadHelperShort(short* src, bool vol) {
+ if (vol) {
+ return System.Threading.Thread.VolatileReadUnsafe(src);
+ }
+ else {
+ return *src;
+ }
+ }
+
+ [NoHeapAllocation]
+ [Inline]
+ private static unsafe void WriteHelperInt(int* dst, int val, bool vol) {
+ if (vol) {
+ System.Threading.Thread.VolatileWriteUnsafe(dst, val);
+ }
+ else {
+ *dst = val;
+ }
+ }
+
+ [NoHeapAllocation]
+ [Inline]
+ private static unsafe int ReadHelperInt(int* src, bool vol) {
+ if (vol) {
+ return System.Threading.Thread.VolatileReadUnsafe(src);
+ }
+ else {
+ return *src;
+ }
+ }
+
+ [NoHeapAllocation]
+ public static unsafe void MoveMemory(byte* dmem, byte* smem,
+ UIntPtr size)
+ {
+ MoveMemory(dmem, smem, (int)size);
+ }
+
+ // This is a replacement for the memmove intrinsic.
+ // It performs better than the CRT one and the inline version
+ // originally from Lightning\Src\VM\COMSystem.cpp
+ [NoHeapAllocation]
+ [Inline]
+ private static unsafe void MoveMemoryImpl(byte* dmem, byte* smem,
+ int size, bool vol) {
+ if (dmem <= smem) {
+ // take the slow path if the source and dest and co-aligned.
+ if (((int)smem & 0x3) != ((int)dmem & 0x3)) {
+ for (; size > 0; size--) {
+ WriteHelperByte(dmem++, ReadHelperByte(smem++, vol), vol);
+ }
+ return;
+ }
+
+ // make sure the destination is dword aligned
+ while ((((int)dmem) & 0x3) != 0 && size >= 3) {
+ WriteHelperByte(dmem++, ReadHelperByte(smem++, vol), vol);
+ size -= 1;
+ }
+ // copy 16 bytes at a time
+ if (size >= 16) {
+ size -= 16;
+ do {
+ WriteHelperInt(&((int*)dmem)[0],
+ ReadHelperInt(&((int*)smem)[0], vol),
+ vol);
+ WriteHelperInt(&((int*)dmem)[1],
+ ReadHelperInt(&((int*)smem)[1], vol),
+ vol);
+ WriteHelperInt(&((int*)dmem)[2],
+ ReadHelperInt(&((int*)smem)[2], vol),
+ vol);
+ WriteHelperInt(&((int*)dmem)[3],
+ ReadHelperInt(&((int*)smem)[3], vol),
+ vol);
+ dmem += 16;
+ smem += 16;
+ }
+ while ((size -= 16) >= 0);
+ }
+
+ // still 8 bytes or more left to copy?
+ if ((size & 8) != 0) {
+ WriteHelperInt(&((int *)dmem)[0],
+ ReadHelperInt(&((int *)smem)[0], vol), vol);
+ WriteHelperInt(&((int *)dmem)[1],
+ ReadHelperInt(&((int *)smem)[1], vol), vol);
+ dmem += 8;
+ smem += 8;
+ }
+
+ // still 4 bytes or more left to copy?
+ if ((size & 4) != 0) {
+ WriteHelperInt(&((int *)dmem)[0],
+ ReadHelperInt(&((int *)smem)[0], vol), vol);
+ dmem += 4;
+ smem += 4;
+ }
+
+ // still 2 bytes or more left to copy?
+ if ((size & 2) != 0) {
+ WriteHelperShort(&((short *)dmem)[0],
+ ReadHelperShort(&((short *)smem)[0], vol),
+ vol);
+ dmem += 2;
+ smem += 2;
+ }
+
+ // still 1 byte left to copy?
+ if ((size & 1) != 0) {
+ WriteHelperByte(dmem, ReadHelperByte(smem, vol), vol);
+ dmem += 1;
+ smem += 1;
+ }
+ }
+ else {
+ smem += size;
+ dmem += size;
+
+ // take the slow path if the source and dest and co-aligned.
+ if (((int)smem & 0x3) != ((int)dmem & 0x3)) {
+ for (; size > 0; size--) {
+ WriteHelperByte(--dmem, ReadHelperByte(--smem, vol), vol);
+ }
+ return;
+ }
+
+ // make sure the destination is dword aligned
+ while ((((int)dmem) & 0x3) != 0 && size >= 3) {
+ WriteHelperByte(--dmem, ReadHelperByte(--smem, vol), vol);
+ size -= 1;
+ }
+
+ // copy 16 bytes at a time
+ if (size >= 16) {
+ size -= 16;
+ do {
+ dmem -= 16;
+ smem -= 16;
+ WriteHelperInt(&((int *)dmem)[3],
+ ReadHelperInt(&((int *)smem)[3], vol),
+ vol);
+ WriteHelperInt(&((int *)dmem)[2],
+ ReadHelperInt(&((int *)smem)[2], vol),
+ vol);
+ WriteHelperInt(&((int *)dmem)[1],
+ ReadHelperInt(&((int *)smem)[1], vol),
+ vol);
+ WriteHelperInt(&((int *)dmem)[0],
+ ReadHelperInt(&((int *)smem)[0], vol),
+ vol);
+ }
+ while ((size -= 16) >= 0);
+ }
+
+ // still 8 bytes or more left to copy?
+ if ((size & 8) != 0) {
+ dmem -= 8;
+ smem -= 8;
+ WriteHelperInt(&((int *)dmem)[1],
+ ReadHelperInt(&((int *)smem)[1], vol), vol);
+ WriteHelperInt(&((int *)dmem)[0],
+ ReadHelperInt(&((int *)smem)[0], vol), vol);
+ }
+
+ // still 4 bytes or more left to copy?
+ if ((size & 4) != 0) {
+ dmem -= 4;
+ smem -= 4;
+ WriteHelperInt(&((int *)dmem)[0],
+ ReadHelperInt(&((int *)smem)[0], vol), vol);
+ }
+
+ // still 2 bytes or more left to copy?
+ if ((size & 2) != 0) {
+ dmem -= 2;
+ smem -= 2;
+ WriteHelperShort(&((short *)dmem)[0],
+ ReadHelperShort(&((short *)smem)[0], vol),
+ vol);
+ }
+
+ // still 1 byte left to copy?
+ if ((size & 1) != 0) {
+ dmem -= 1;
+ smem -= 1;
+ WriteHelperByte(dmem,
+ ReadHelperByte(smem, vol), vol);
+ }
+ }
+ }
+
+ // Copies from one primitive array to another primitive array without
+ // respecting types. This calls memmove internally.
+ //|
+ public static void BlockCopy(Array src, int srcOffset,
+ Array dst, int dstOffset, int count) {
+ if (src == null) {
+ throw new ArgumentNullException("src");
+ }
+ if (dst == null) {
+ throw new ArgumentNullException("dst");
+ }
+ InternalBlockCopy(src, srcOffset, dst, dstOffset, count);
+ }
+
+ // A very simple and efficient array copy that assumes all of the
+ // parameter validation has already been done. All counts here are
+ // in bytes.
+ internal static unsafe void InternalBlockCopy(Array src, int srcOffset,
+ Array dst, int dstOffset,
+ int count) {
+ VTable.Assert(src != null);
+ VTable.Assert(dst != null);
+
+ // Unfortunately, we must do a check to make sure we're writing
+ // within the bounds of the array. This will ensure that we don't
+ // overwrite memory elsewhere in the system nor do we write out junk.
+ // This can happen if multiple threads screw with our IO classes
+ // simultaneously without being threadsafe. Throw here.
+ int srcLen = src.Length * src.vtable.arrayElementSize;
+ if (srcOffset < 0 || dstOffset < 0 || count < 0 ||
+ srcOffset > srcLen - count)
+ throw new IndexOutOfRangeException
+ ("IndexOutOfRange_IORaceCondition");
+ if (src == dst) {
+ if (dstOffset > srcLen - count)
+ throw new IndexOutOfRangeException
+ ("IndexOutOfRange_IORaceCondition");
+ }
+ else {
+ int dstLen = dst.Length * dst.vtable.arrayElementSize;
+ if (dstOffset > dstLen - count)
+ throw new IndexOutOfRangeException
+ ("IndexOutOfRange_IORaceCondition");
+ }
+
+ // Copy the data.
+ // Call our faster version of memmove, not the CRT one.
+ fixed (int *srcFieldPtr = &src.field1) {
+ fixed (int *dstFieldPtr = &dst.field1) {
+ byte *srcPtr = (byte *)
+ src.GetFirstElementAddress(srcFieldPtr);
+ byte *dstPtr = (byte *)
+ dst.GetFirstElementAddress(dstFieldPtr);
+ MoveMemory(dstPtr + dstOffset, srcPtr + srcOffset, count);
+ }
+ }
+ }
+
+ [NoHeapAllocation]
+ internal static unsafe void ZeroMemory(byte* dst, UIntPtr len)
+ {
+ ZeroMemory(dst, (int)len);
+ }
+
+ [Inline]
+ [NoHeapAllocation]
+ internal unsafe static void InitMemoryImpl(byte* dest, byte value,
+ int len, bool vol) {
+ int intValue = (value == 0) ? 0 :
+ (value | (value << 8) | (value << 16) | (value << 24));
+ // This is based on Peter Sollich's faster memcpy implementation,
+ // from COMString.cpp.
+ while ((((int)dest) & 0x03) != 0 && len >= 3) {
+ WriteHelperByte(dest++, value, vol);
+ len -= 1;
+ }
+
+ if (len >= 16) {
+ len -= 16;
+ do {
+ WriteHelperInt(&((int*)dest)[0], intValue, vol);
+ WriteHelperInt(&((int*)dest)[1], intValue, vol);
+ WriteHelperInt(&((int*)dest)[2], intValue, vol);
+ WriteHelperInt(&((int*)dest)[3], intValue, vol);
+ dest += 16;
+ } while ((len -= 16) >= 0);
+ }
+ if ((len & 8) > 0) {
+ WriteHelperInt(&((int*)dest)[0], intValue, vol);
+ WriteHelperInt(&((int*)dest)[1], intValue, vol);
+ dest += 8;
+ }
+ if ((len & 4) > 0) {
+ WriteHelperInt(&((int*)dest)[0], intValue, vol);
+ dest += 4;
+ }
+ if ((len & 2) != 0) {
+ short shortValue = (value == 0) ? (short) 0 :
+ (short)(value | value << 8) ;
+ dest += 2;
+ }
+ if ((len & 1) != 0)
+ WriteHelperByte(dest++, value, vol);
+ }
+
+ // Gets a particular byte out of the array. The array must be an
+ // array of primitives.
+ //
+ // This essentially does the following:
+ // return ((byte*)array) + index.
+ //
+ //|
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [NoHeapAllocation]
+ public static extern byte GetByte(Array array, int index);
+
+ // Sets a particular byte in an the array. The array must be an
+ // array of primitives.
+ //
+ // This essentially does the following:
+ // *(((byte*)array) + index) = value.
+ //
+ //|
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [NoHeapAllocation]
+ public static extern void SetByte(Array array, int index, byte value);
+
+ // Gets a particular byte out of the array. The array must be an
+ // array of primitives.
+ //
+ // This essentially does the following:
+ // return array.length * sizeof(array.UnderlyingElementType).
+ //
+ //|
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [NoHeapAllocation]
+ public static extern int ByteLength(Array array);
+ }
+}
diff --git a/base/Kernel/System/Byte.cs b/base/Applications/Runtime/Full/System/Byte.cs
similarity index 89%
rename from base/Kernel/System/Byte.cs
rename to base/Applications/Runtime/Full/System/Byte.cs
index 249e9db..424996a 100644
--- a/base/Kernel/System/Byte.cs
+++ b/base/Applications/Runtime/Full/System/Byte.cs
@@ -3,19 +3,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Byte
-**
-**
-** Purpose: This class will encapsulate a byte and provide an
-** Object representation of it.
-**
-** Date: August 3, 1998
-**
-===========================================================*/
+//============================================================
+//
+// Class: Byte
+//
+// Purpose: This class will encapsulate a byte and provide an
+// Object representation of it.
+//
+//===========================================================
-namespace System {
+namespace System
+{
using System;
using System.Globalization;
diff --git a/base/Applications/Runtime/Full/System/CLSCompliantAttribute.cs b/base/Applications/Runtime/Full/System/CLSCompliantAttribute.cs
new file mode 100644
index 0000000..f396a03
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/CLSCompliantAttribute.cs
@@ -0,0 +1,36 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: CLSCompliantAttribute
+//
+// Purpose: Container for assemblies.
+//
+//=============================================================================
+
+namespace System
+{
+ //|
+ [AttributeUsage (AttributeTargets.All, Inherited=true, AllowMultiple=false)]
+ public sealed class CLSCompliantAttribute : Attribute
+ {
+ private bool m_compliant;
+
+ //|
+ public CLSCompliantAttribute (bool isCompliant)
+ {
+ m_compliant = isCompliant;
+ }
+ //|
+ public bool IsCompliant
+ {
+ get
+ {
+ return m_compliant;
+ }
+ }
+ }
+}
diff --git a/base/Kernel/System/Char.cs b/base/Applications/Runtime/Full/System/Char.cs
similarity index 77%
rename from base/Kernel/System/Char.cs
rename to base/Applications/Runtime/Full/System/Char.cs
index 9eed763..5067d5a 100644
--- a/base/Kernel/System/Char.cs
+++ b/base/Applications/Runtime/Full/System/Char.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Char
-**
-**
-** Purpose: This is the value class representing a Unicode character
-** Char methods until we create this functionality.
-**
-** Date: August 3, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: Char
+//
+// Purpose: This is the value class representing a Unicode character
+// Char methods until we create this functionality.
+//
+//===========================================================
+namespace System
+{
using System;
using System.Globalization;
@@ -71,7 +69,7 @@ namespace System {
//
//|
public int CompareTo(Object value) {
- if (value==null) {
+ if (value == null) {
return 1;
}
if (!(value is Char)) {
@@ -91,9 +89,9 @@ namespace System {
// Formatting Methods
//
- /*===================================ToString===================================
- **This static methods takes a character and returns the String representation of it.
- ==============================================================================*/
+ //===================================ToString===================================
+ //This static methods takes a character and returns the String representation of it.
+ //==============================================================================
// Provides a string representation of a character.
//|
public unsafe static String ToString(char c) {
@@ -103,10 +101,10 @@ namespace System {
//|
public static char Parse(String s) {
- if (s==null) {
+ if (s == null) {
throw new ArgumentNullException("s");
}
- if (s.Length!=1) {
+ if (s.Length != 1) {
throw new FormatException("Format_NeedSingleChar");
}
return s[0];
@@ -115,30 +113,30 @@ namespace System {
//
// Static Methods
//
- /*=================================ISDIGIT======================================
- **A wrapper for Char. Returns a boolean indicating whether **
- **character c is considered to be a digit. **
- ==============================================================================*/
+ //=================================ISDIGIT======================================
+ //A wrapper for Char. Returns a boolean indicating whether **
+ //character c is considered to be a digit. **
+ //==============================================================================
// Determines whether a character is a digit.
//|
public static bool IsDigit(char c) {
return CharacterInfo.IsDigit(c);
}
- /*=================================ISLETTER=====================================
- **A wrapper for Char. Returns a boolean indicating whether **
- **character c is considered to be a letter. **
- ==============================================================================*/
+ //=================================ISLETTER=====================================
+ //A wrapper for Char. Returns a boolean indicating whether **
+ //character c is considered to be a letter. **
+ //==============================================================================
// Determines whether a character is a letter.
//|
public static bool IsLetter(char c) {
return CharacterInfo.IsLetter(c);
}
- /*===============================ISWHITESPACE===================================
- **A wrapper for Char. Returns a boolean indicating whether **
- **character c is considered to be a whitespace character. **
- ==============================================================================*/
+ //===============================ISWHITESPACE===================================
+ //A wrapper for Char. Returns a boolean indicating whether **
+ //character c is considered to be a whitespace character. **
+ //==============================================================================
// Determines whether a character is whitespace.
//|
public static bool IsWhiteSpace(char c) {
@@ -146,30 +144,30 @@ namespace System {
}
- /*===================================IsUpper====================================
- **Arguments: c -- the character to be checked.
- **Returns: True if c is an uppercase character.
- ==============================================================================*/
+ //===================================IsUpper====================================
+ //Arguments: c -- the character to be checked.
+ //Returns: True if c is an uppercase character.
+ //==============================================================================
// Determines whether a character is upper-case.
//|
public static bool IsUpper(char c) {
return CharacterInfo.IsUpper(c);
}
- /*===================================IsLower====================================
- **Arguments: c -- the character to be checked.
- **Returns: True if c is an lowercase character.
- ==============================================================================*/
+ //===================================IsLower====================================
+ //Arguments: c -- the character to be checked.
+ //Returns: True if c is an lowercase character.
+ //==============================================================================
// Determines whether a character is lower-case.
//|
public static bool IsLower(char c) {
return CharacterInfo.IsLower(c);
}
- /*================================IsPunctuation=================================
- **Arguments: c -- the character to be checked.
- **Returns: True if c is an punctuation mark
- ==============================================================================*/
+ //================================IsPunctuation=================================
+ //Arguments: c -- the character to be checked.
+ //Returns: True if c is an punctuation mark
+ //==============================================================================
// Determines whether a character is a punctuation mark.
//|
public static bool IsPunctuation(char c){
@@ -188,11 +186,11 @@ namespace System {
|| uc == UnicodeCategory.DecimalDigitNumber);
}
- /*=================================TOUPPER======================================
- **A wrapper for Char.toUpperCase. Converts character c to its **
- **uppercase equivalent. If c is already an uppercase character or is not an **
- **alphabetic, nothing happens. **
- ==============================================================================*/
+ //=================================TOUPPER======================================
+ //A wrapper for Char.toUpperCase. Converts character c to its **
+ //uppercase equivalent. If c is already an uppercase character or is not an **
+ //alphabetic, nothing happens. **
+ //==============================================================================
// Converts a character to upper-case for the default culture.
//
//|
@@ -201,11 +199,11 @@ namespace System {
}
- /*=================================TOLOWER======================================
- **A wrapper for Char.toLowerCase. Converts character c to its **
- **lowercase equivalent. If c is already a lowercase character or is not an **
- **alphabetic, nothing happens. **
- ==============================================================================*/
+ //=================================TOLOWER======================================
+ //A wrapper for Char.toLowerCase. Converts character c to its **
+ //lowercase equivalent. If c is already a lowercase character or is not an **
+ //alphabetic, nothing happens. **
+ //==============================================================================
// Converts a character to lower-case for the default culture.
//|
public static char ToLower(char c) {
@@ -230,7 +228,7 @@ namespace System {
//|
public static bool IsControl(String s, int index) {
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -241,7 +239,7 @@ namespace System {
//|
public static bool IsDigit(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -252,7 +250,7 @@ namespace System {
//|
public static bool IsLetter(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -263,7 +261,7 @@ namespace System {
//|
public static bool IsLetterOrDigit(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -274,7 +272,7 @@ namespace System {
//|
public static bool IsLower(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -291,7 +289,7 @@ namespace System {
//|
public static bool IsNumber(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -302,7 +300,7 @@ namespace System {
//|
public static bool IsPunctuation (String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -319,7 +317,7 @@ namespace System {
//|
public static bool IsSeparator(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -336,7 +334,7 @@ namespace System {
//|
public static bool IsSurrogate(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -353,7 +351,7 @@ namespace System {
//|
public static bool IsSymbol(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -365,7 +363,7 @@ namespace System {
//|
public static bool IsUpper(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -376,7 +374,7 @@ namespace System {
//|
public static bool IsWhiteSpace(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
@@ -393,7 +391,7 @@ namespace System {
//|
public static UnicodeCategory GetUnicodeCategory(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
if (((uint)index)>=((uint)s.Length)) {
throw new ArgumentOutOfRangeException("index");
diff --git a/base/Kernel/System/CharEnumerator.cs b/base/Applications/Runtime/Full/System/CharEnumerator.cs
similarity index 82%
rename from base/Kernel/System/CharEnumerator.cs
rename to base/Applications/Runtime/Full/System/CharEnumerator.cs
index 32615f1..373cdc9 100644
--- a/base/Kernel/System/CharEnumerator.cs
+++ b/base/Applications/Runtime/Full/System/CharEnumerator.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: CharEnumerator
-**
-**
-** Purpose: Enumerates the characters on a string. skips range
-** checks.
-**
-** Date: January 3, 2001
-**
-============================================================*/
-namespace System {
+//============================================================
+//
+// Class: CharEnumerator
+//
+// Purpose: Enumerates the characters on a string. skips range
+// checks.
+//
+//============================================================
+namespace System
+{
using System.Collections;
@@ -36,7 +34,7 @@ namespace System {
//|
public bool MoveNext() {
- if (index < (str.Length-1)) {
+ if (index < (str.Length - 1)) {
index++;
currentElement = str[index];
return true;
diff --git a/base/Kernel/System/Collections/ArrayList.cs b/base/Applications/Runtime/Full/System/Collections/ArrayList.cs
similarity index 95%
rename from base/Kernel/System/Collections/ArrayList.cs
rename to base/Applications/Runtime/Full/System/Collections/ArrayList.cs
index 6b3c49e..8db591e 100644
--- a/base/Kernel/System/Collections/ArrayList.cs
+++ b/base/Applications/Runtime/Full/System/Collections/ArrayList.cs
@@ -3,19 +3,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: ArrayList
-**
-**
-** Purpose: Implements a dynamically sized List as an array,
-** and provides many convenience methods for treating
-** an array as an IList.
-**
-** Date: October, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Class: ArrayList
+//
+// Purpose: Implements a dynamically sized List as an array,
+// and provides many convenience methods for treating
+// an array as an IList.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
// Implements a variable-size List that uses an array of objects to store the
@@ -24,8 +22,7 @@ namespace System.Collections {
// of the ArrayList is automatically increased as required by reallocating the
// internal array.
//
- // By Anders Hejlsberg
- // version 1.00 8/13/98
+ // version 1.00
//|
public class ArrayList : IList, ICloneable
{
@@ -65,7 +62,7 @@ namespace System.Collections {
//
//|
public ArrayList(ICollection c) {
- if (c==null)
+ if (c == null)
throw new ArgumentNullException("c", "ArgumentNull_Collection");
_items = new Object[c.Count];
AddRange(c);
@@ -148,7 +145,7 @@ namespace System.Collections {
//
//|
public static ArrayList Adapter(IList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new IListWrapper(list);
}
@@ -245,14 +242,14 @@ namespace System.Collections {
//
//|
public virtual bool Contains(Object item) {
- if (item==null) {
- for(int i=0; i<_size; i++)
+ if (item == null) {
+ for (int i = 0; i < _size; i++)
if (_items[i]==null)
return true;
return false;
}
else {
- for(int i=0; i<_size; i++)
+ for (int i = 0; i < _size; i++)
if (item.Equals(_items[i]))
return true;
return false;
@@ -309,7 +306,7 @@ namespace System.Collections {
//
//|
public static IList FixedSize(IList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new FixedSizeList(list);
}
@@ -319,7 +316,7 @@ namespace System.Collections {
//
//|
public static ArrayList FixedSize(ArrayList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new FixedSizeArrayList(list);
}
@@ -417,7 +414,7 @@ namespace System.Collections {
//
//|
public virtual void InsertRange(int index, ICollection c) {
- if (c==null)
+ if (c == null)
throw new ArgumentNullException("c", "ArgumentNull_Collection");
if (index < 0 || index > _size) throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_Index");
int count = c.Count;
@@ -496,7 +493,7 @@ namespace System.Collections {
//
//|
public static IList ReadOnly(IList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new ReadOnlyList(list);
}
@@ -505,7 +502,7 @@ namespace System.Collections {
//
//|
public static ArrayList ReadOnly(ArrayList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new ReadOnlyArrayList(list);
}
@@ -516,7 +513,7 @@ namespace System.Collections {
//|
public virtual void Remove(Object obj) {
int index = IndexOf(obj);
- if (index >=0)
+ if (index >= 0)
RemoveAt(index);
}
@@ -568,7 +565,7 @@ namespace System.Collections {
throw new ArgumentOutOfRangeException("count","ArgumentOutOfRange_NeedNonNegNum");
ArrayList list = new ArrayList((count>_defaultCapacity)?count:_defaultCapacity);
- for(int i=0; i
public static IList Synchronized(IList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new SyncIList(list);
}
@@ -669,7 +666,7 @@ namespace System.Collections {
//
//|
public static ArrayList Synchronized(ArrayList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new SyncArrayList(list);
}
@@ -690,7 +687,7 @@ namespace System.Collections {
//
//|
public virtual Array ToArray(Type type) {
- if (type==null)
+ if (type == null)
throw new ArgumentNullException("type");
Array array = Array.CreateInstance(type, _size);
Array.Copy(_items, 0, array, 0, _size);
@@ -815,7 +812,7 @@ namespace System.Collections {
}
public override void CopyTo(int index, Array array, int arrayIndex, int count) {
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (index < 0 || arrayIndex < 0)
throw new ArgumentOutOfRangeException((index < 0) ? "index" : "arrayIndex", "ArgumentOutOfRange_NeedNonNegNum");
@@ -826,7 +823,7 @@ namespace System.Collections {
if (array.Rank != 1)
throw new ArgumentException("Arg_RankMultiDimNotSupported");
- for(int i=index; i _list.Count) throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_Index");
IEnumerator en = c.GetEnumerator();
- while(en.MoveNext()) {
+ while (en.MoveNext()) {
_list.Insert(index++, en.Current);
}
}
@@ -901,12 +899,13 @@ namespace System.Collections {
int endIndex = startIndex - count + 1;
if (value == null) {
- for(int i=startIndex; i >= endIndex; i--)
+ for (int i = startIndex; i >= endIndex; i--)
if (_list[i] == null)
return i;
return -1;
- } else {
- for(int i=startIndex; i >= endIndex; i--)
+ }
+ else {
+ for (int i = startIndex; i >= endIndex; i--)
if (value.Equals(_list[i]))
return i;
return -1;
@@ -927,7 +926,7 @@ namespace System.Collections {
if (_list.Count - index < count)
throw new ArgumentException("Argument_InvalidOffLen");
- while(count > 0) {
+ while (count > 0) {
_list.RemoveAt(index);
count--;
}
@@ -941,8 +940,7 @@ namespace System.Collections {
int i = index;
int j = index + count - 1;
- while (i < j)
- {
+ while (i < j) {
Object tmp = _list[i];
_list[i++] = _list[j];
_list[j--] = tmp;
@@ -950,14 +948,14 @@ namespace System.Collections {
}
public override void SetRange(int index, ICollection c) {
- if (c==null)
+ if (c == null)
throw new ArgumentNullException("c", "ArgumentNull_Collection");
if (index < 0 || index >= _list.Count) throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_Index");
if (_list.Count - index < c.Count)
throw new ArgumentException("Argument_InvalidOffLen");
IEnumerator en = c.GetEnumerator();
- while(en.MoveNext()) {
+ while (en.MoveNext()) {
_list[index++] = en.Current;
}
}
@@ -979,7 +977,7 @@ namespace System.Collections {
Object [] array = new Object[count];
CopyTo(index, array, 0, count);
Array.Sort(array, 0, count, comparer);
- for(int i=0; i 0 && _en.MoveNext());
+ while (startIndex-- > 0 && _en.MoveNext());
_remaining = count;
_firstCall = true;
}
@@ -1063,7 +1061,7 @@ namespace System.Collections {
public virtual void Reset() {
_en.Reset();
int startIndex = _initialStartIndex;
- while(startIndex-- > 0 && _en.MoveNext());
+ while (startIndex-- > 0 && _en.MoveNext());
_remaining = _initialCount;
_firstCall = true;
}
@@ -1903,8 +1901,7 @@ namespace System.Collections {
index++;
return true;
}
- else
- {
+ else {
index = endIndex + 1;
currentElement = list;
}
@@ -1995,8 +1992,7 @@ namespace System.Collections {
public override void Clear() {
InternalUpdateRange();
- if (_baseSize != 0)
- {
+ if (_baseSize != 0) {
_baseList.RemoveRange(_baseIndex, _baseSize);
_baseVersion++;
_baseSize = 0;
@@ -2012,14 +2008,14 @@ namespace System.Collections {
public override bool Contains(Object item) {
InternalUpdateRange();
- if (item==null) {
- for(int i=0; i<_baseSize; i++)
+ if (item == null) {
+ for (int i = 0; i < _baseSize; i++)
if (_baseList[_baseIndex + i]==null)
return true;
return false;
}
else {
- for(int i=0; i<_baseSize; i++)
+ for (int i = 0; i < _baseSize; i++)
if (item.Equals(_baseList[_baseIndex + i]))
return true;
return false;
@@ -2028,7 +2024,7 @@ namespace System.Collections {
public override void CopyTo(Array array, int index) {
InternalUpdateRange();
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (array.Rank != 1)
throw new ArgumentException("Arg_RankMultiDimNotSupported");
@@ -2041,7 +2037,7 @@ namespace System.Collections {
public override void CopyTo(int index, Array array, int arrayIndex, int count) {
InternalUpdateRange();
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (array.Rank != 1)
throw new ArgumentException("Arg_RankMultiDimNotSupported");
@@ -2248,7 +2244,7 @@ namespace System.Collections {
public override Array ToArray(Type type) {
InternalUpdateRange();
- if (type==null)
+ if (type == null)
throw new ArgumentNullException("type");
Array array = Array.CreateInstance(type, _baseSize);
Array.Copy(_baseList._items, _baseIndex, array, 0, _baseSize);
@@ -2283,7 +2279,7 @@ namespace System.Collections {
public virtual bool MoveNext() {
if (version != list._version) throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
- if (index < (list.Count-1)) {
+ if (index < (list.Count - 1)) {
index++;
currentElement = list[index];
return true;
diff --git a/base/Applications/Runtime/Full/System/Collections/BitArray.cs b/base/Applications/Runtime/Full/System/Collections/BitArray.cs
new file mode 100644
index 0000000..85c44e6
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Collections/BitArray.cs
@@ -0,0 +1,488 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: BitArray
+//
+// Purpose: The BitArray class manages a compact array of bit values.
+//
+//=============================================================================
+namespace System.Collections
+{
+ // @Consider: is _ShrinkThreshold (256) ints the correct threshold for shrinking?
+ using System;
+ using System.Diagnostics;
+
+ // A vector of bits. Use this to store bits efficiently, without having to do bit
+ // shifting yourself.
+ //|
+ public sealed class BitArray : ICollection, ICloneable {
+ private BitArray() {
+ }
+
+ //=========================================================================
+ // Allocates space to hold length bit values. All of the values in the bit
+ // array are set to false.
+ //
+ // Exceptions: ArgumentException if length < 0.
+ //=========================================================================
+ //|
+ public BitArray(int length)
+ : this(length, false) {
+ }
+
+ //=========================================================================
+ // Allocates space to hold length bit values. All of the values in the bit
+ // array are set to defaultValue.
+ //
+ // Exceptions: ArgumentOutOfRangeException if length < 0.
+ //=========================================================================
+ //|
+ public BitArray(int length, bool defaultValue) {
+ if (length < 0) {
+ throw new ArgumentOutOfRangeException("ArgumentOutOfRange_NeedNonNegNum");
+ }
+
+ m_array = new int[(length + 31) / 32];
+ m_length = length;
+
+ int fillValue = defaultValue ? unchecked(((int)0xffffffff)) : 0;
+ for (int i = 0; i < m_array.Length; i++) {
+ m_array[i] = fillValue;
+ }
+
+ _version = 0;
+ }
+
+ //=========================================================================
+ // Allocates space to hold the bit values in bytes. bytes[0] represents
+ // bits 0 - 7, bytes[1] represents bits 8 - 15, etc. The LSB of each byte
+ // represents the lowest index value; bytes[0] & 1 represents bit 0,
+ // bytes[0] & 2 represents bit 1, bytes[0] & 4 represents bit 2, etc.
+ //
+ // Exceptions: ArgumentException if bytes == null.
+ //=========================================================================
+ //|
+ public BitArray(byte[] bytes) {
+ if (bytes == null) {
+ throw new ArgumentNullException("bytes");
+ }
+
+ m_array = new int[(bytes.Length + 3) / 4];
+ m_length = bytes.Length * 8;
+
+ int i = 0;
+ int j = 0;
+ while (bytes.Length - j >= 4) {
+ m_array[i++] = (bytes[j] & 0xff) |
+ ((bytes[j + 1] & 0xff) << 8) |
+ ((bytes[j + 2] & 0xff) << 16) |
+ ((bytes[j + 3] & 0xff) << 24);
+ j += 4;
+ }
+
+ Debug.Assert(bytes.Length - j >= 0, "BitArray byteLength problem");
+ Debug.Assert(bytes.Length - j < 4, "BitArray byteLength problem #2");
+
+ switch (bytes.Length - j) {
+ case 3:
+ m_array[i] = ((bytes[j + 2] & 0xff) << 16);
+ goto case 2;
+ // fall through
+ case 2:
+ m_array[i] |= ((bytes[j + 1] & 0xff) << 8);
+ goto case 1;
+ // fall through
+ case 1:
+ m_array[i] |= (bytes[j] & 0xff);
+ break;
+ }
+
+ _version = 0;
+ }
+
+ //|
+ public BitArray(bool[] values) {
+ if (values == null) {
+ throw new ArgumentNullException("values");
+ }
+
+ m_array = new int[(values.Length + 31) / 32];
+ m_length = values.Length;
+
+ for (int i = 0; i < values.Length; i++) {
+ if (values[i])
+ m_array[i/32] |= (1 << (i%32));
+ }
+
+ _version = 0;
+
+ }
+
+ //=========================================================================
+ // Allocates space to hold the bit values in values. values[0] represents
+ // bits 0 - 31, values[1] represents bits 32 - 63, etc. The LSB of each
+ // integer represents the lowest index value; values[0] & 1 represents bit
+ // 0, values[0] & 2 represents bit 1, values[0] & 4 represents bit 2, etc.
+ //
+ // Exceptions: ArgumentException if values == null.
+ //=========================================================================
+ //|
+ public BitArray(int[] values) {
+ if (values == null) {
+ throw new ArgumentNullException("values");
+ }
+
+ m_array = new int[values.Length];
+ m_length = values.Length * 32;
+
+ Array.Copy(values, m_array, values.Length);
+
+ _version = 0;
+ }
+
+ //=========================================================================
+ // Allocates a new BitArray with the same length and bit values as bits.
+ //
+ // Exceptions: ArgumentException if bits == null.
+ //=========================================================================
+ //|
+ public BitArray(BitArray bits) {
+ if (bits == null) {
+ throw new ArgumentNullException("bits");
+ }
+
+ m_array = new int[(bits.m_length + 31) / 32];
+ m_length = bits.m_length;
+
+ Array.Copy(bits.m_array, m_array, (bits.m_length + 31) / 32);
+
+ _version = bits._version;
+ }
+
+ //|
+ public bool this[int index] {
+ get {
+ return Get(index);
+ }
+ set {
+ Set(index,value);
+ }
+ }
+
+ //=========================================================================
+ // Returns the bit value at position index.
+ //
+ // Exceptions: ArgumentOutOfRangeException if index < 0 or
+ // index >= GetLength().
+ //=========================================================================
+ //|
+ public bool Get(int index) {
+ if (index < 0 || index >= m_length) {
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_Index");
+ }
+
+ return (m_array[index / 32] & (1 << (index % 32))) != 0;
+ }
+
+ //=========================================================================
+ // Sets the bit value at position index to value.
+ //
+ // Exceptions: ArgumentOutOfRangeException if index < 0 or
+ // index >= GetLength().
+ //=========================================================================
+ //|
+ public void Set(int index, bool value) {
+ if (index < 0 || index >= m_length) {
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_Index");
+ }
+
+ if (value) {
+ m_array[index / 32] |= (1 << (index % 32));
+ }
+ else {
+ m_array[index / 32] &= ~(1 << (index % 32));
+ }
+
+ _version++;
+ }
+
+ //=========================================================================
+ // Sets all the bit values to value.
+ //=========================================================================
+ //|
+ public void SetAll(bool value) {
+ int fillValue = value ? unchecked(((int)0xffffffff)) : 0;
+ int ints = (m_length + 31) / 32;
+ for (int i = 0; i < ints; i++) {
+ m_array[i] = fillValue;
+ }
+
+ _version++;
+ }
+
+ //=========================================================================
+ // Returns a reference to the current instance ANDed with value.
+ //
+ // Exceptions: ArgumentException if value == null or
+ // value.Length != this.Length.
+ //=========================================================================
+ //|
+ public BitArray And(BitArray value) {
+ if (value == null)
+ throw new ArgumentNullException("value");
+ if (m_length != value.m_length)
+ throw new ArgumentException("Arg_ArrayLengthsDiffer");
+
+ int ints = (m_length + 31) / 32;
+ for (int i = 0; i < ints; i++) {
+ m_array[i] &= value.m_array[i];
+ }
+
+ _version++;
+ return this;
+ }
+
+ //=========================================================================
+ // Returns a reference to the current instance ORed with value.
+ //
+ // Exceptions: ArgumentException if value == null or
+ // value.Length != this.Length.
+ //=========================================================================
+ //|
+ public BitArray Or(BitArray value) {
+ if (value == null)
+ throw new ArgumentNullException("value");
+ if (m_length != value.m_length)
+ throw new ArgumentException("Arg_ArrayLengthsDiffer");
+
+ int ints = (m_length + 31) / 32;
+ for (int i = 0; i < ints; i++) {
+ m_array[i] |= value.m_array[i];
+ }
+
+ _version++;
+ return this;
+ }
+
+ //=========================================================================
+ // Returns a reference to the current instance XORed with value.
+ //
+ // Exceptions: ArgumentException if value == null or
+ // value.Length != this.Length.
+ //=========================================================================
+ //|
+ public BitArray Xor(BitArray value) {
+ if (value == null)
+ throw new ArgumentNullException("value");
+ if (m_length != value.m_length)
+ throw new ArgumentException("Arg_ArrayLengthsDiffer");
+
+ int ints = (m_length + 31) / 32;
+ for (int i = 0; i < ints; i++) {
+ m_array[i] ^= value.m_array[i];
+ }
+
+ _version++;
+ return this;
+ }
+
+ //=========================================================================
+ // Inverts all the bit values. On/true bit values are converted to
+ // off/false. Off/false bit values are turned on/true. The current instance
+ // is updated and returned.
+ //=========================================================================
+ //|
+ public BitArray Not() {
+ int ints = (m_length + 31) / 32;
+ for (int i = 0; i < ints; i++) {
+ m_array[i] = ~m_array[i];
+ }
+
+ _version++;
+ return this;
+ }
+
+
+ //|
+ public int Length {
+ get { return m_length; }
+ set {
+ if (value < 0) {
+ throw new ArgumentOutOfRangeException("ArgumentOutOfRange_NeedNonNegNum");
+ }
+
+ int newints = (value + 31) / 32;
+ if (newints > m_array.Length || newints + _ShrinkThreshold < m_array.Length) {
+ // grow or shrink (if wasting more than _ShrinkThreshold ints)
+ int[] newarray = new int[newints];
+ Array.Copy(m_array, newarray, newints > m_array.Length ? m_array.Length : newints);
+ m_array = newarray;
+ }
+
+ if (value > m_length) {
+ // clear high bit values in the last int
+ int last = ((m_length + 31) / 32) - 1;
+ int bits = m_length % 32;
+ if (bits > 0) {
+ m_array[last] &= (1 << bits) - 1;
+ }
+
+ // clear remaining int values
+ Array.Clear(m_array, last + 1, newints - last - 1);
+ }
+
+ m_length = value;
+ _version++;
+ }
+ }
+
+ // ICollection implementation
+ //|
+ public void CopyTo(Array array, int index)
+ {
+ if (array == null)
+ throw new ArgumentNullException("array");
+
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("ArgumentOutOfRange_NeedNonNegNum");
+
+ if (array.Rank != 1)
+ throw new ArgumentException("Arg_RankMultiDimNotSupported");
+
+
+ if (array is int[]) {
+ Array.Copy(m_array, 0, array, index, (m_length + 31) / 32);
+ }
+ else if (array is byte[]) {
+ if ((array.Length - index) < (m_length + 7)/8)
+ throw new ArgumentException("Argument_InvalidOffLen");
+
+ byte [] b = (byte[])array;
+ for (int i = 0; i <(m_length + 7)/8; i++)
+ b[index + i] = (byte)((m_array[i/4] >> ((i%4)*8)) & 0x000000FF); // Shift to bring the required byte to LSB, then mask
+ }
+ else if (array is bool[]) {
+ if (array.Length - index < m_length)
+ throw new ArgumentException("Argument_InvalidOffLen");
+
+ bool [] b = (bool[])array;
+ for (int i = 0; i < m_length; i++)
+ b[index + i] = ((m_array[i/32] >> (i%32)) & 0x00000001) != 0;
+ }
+ else
+ throw new ArgumentException("Arg_BitArrayTypeUnsupported");
+ }
+
+ //|
+ public int Count
+ {
+ get
+ {
+ return m_length;
+ }
+ }
+
+ //|
+ public Object Clone()
+ {
+ BitArray bitArray = new BitArray(m_array);
+ bitArray._version = _version;
+ bitArray.m_length = m_length;
+ return bitArray;
+ }
+
+ //|
+ public Object SyncRoot
+ {
+ get
+ {
+ return this;
+ }
+ }
+
+ //|
+ public bool IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+
+ //|
+ public bool IsSynchronized
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ //|
+ public IEnumerator GetEnumerator()
+ {
+ return new BitArrayEnumeratorSimple(this);
+ }
+
+ // For a straightforward enumeration of the entire ArrayList,
+ // this is faster, because it's smaller. Patrick showed
+ // this with a benchmark.
+ private class BitArrayEnumeratorSimple : IEnumerator, ICloneable
+ {
+ private BitArray bitarray;
+ private int index;
+ private int version;
+ private bool currentElement;
+
+ internal BitArrayEnumeratorSimple(BitArray bitarray) {
+ this.bitarray = bitarray;
+ this.index = -1;
+ version = bitarray._version;
+ }
+
+ public Object Clone() {
+ return MemberwiseClone();
+ }
+
+ public virtual bool MoveNext() {
+ if (version != bitarray._version) throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
+ if (index < (bitarray.Count - 1)) {
+ index++;
+ currentElement = bitarray.Get(index);
+ return true;
+ }
+ else
+ index = bitarray.Count;
+
+ return false;
+ }
+
+ public virtual Object Current {
+ get {
+ if (index == -1)
+ throw new InvalidOperationException("InvalidOperation_EnumNotStarted");
+ if (index >= bitarray.Count)
+ throw new InvalidOperationException("InvalidOperation_EnumEnded");
+ return currentElement;
+ }
+ }
+
+ public void Reset() {
+ if (version != bitarray._version) throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
+ index = -1;
+ }
+ }
+
+ private int[] m_array;
+ private int m_length;
+ private int _version;
+
+ private const int _ShrinkThreshold = 256;
+ }
+
+}
diff --git a/base/Kernel/System/Collections/CaseInsensitiveComparer.cs b/base/Applications/Runtime/Full/System/Collections/CaseInsensitiveComparer.cs
similarity index 85%
rename from base/Kernel/System/Collections/CaseInsensitiveComparer.cs
rename to base/Applications/Runtime/Full/System/Collections/CaseInsensitiveComparer.cs
index 80c85a3..56cae9c 100644
--- a/base/Kernel/System/Collections/CaseInsensitiveComparer.cs
+++ b/base/Applications/Runtime/Full/System/Collections/CaseInsensitiveComparer.cs
@@ -3,15 +3,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: CaseInsensitiveComparer
-**
-**
-** Date: May 17, 2000
-**
-============================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Class: CaseInsensitiveComparer
+//
+//============================================================
+namespace System.Collections
+{
using System;
using System.Collections;
using System.Globalization;
diff --git a/base/Applications/Runtime/Full/System/Collections/CaseInsensitiveHashCodeProvider.cs b/base/Applications/Runtime/Full/System/Collections/CaseInsensitiveHashCodeProvider.cs
new file mode 100644
index 0000000..ebcd013
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Collections/CaseInsensitiveHashCodeProvider.cs
@@ -0,0 +1,55 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: CaseInsensitiveHashCodeProvider
+//
+// Purpose: Designed to support hashtables which require
+// case-insensitive behavior while still maintaining case,
+// this provides an efficient mechanism for getting the
+// hashcode of the string ignoring case.
+//
+//============================================================
+namespace System.Collections
+{
+ using System;
+ using System.Collections;
+ using System.Globalization;
+
+ //|
+ public class CaseInsensitiveHashCodeProvider : IHashCodeProvider {
+
+ public static readonly CaseInsensitiveHashCodeProvider Default
+ = new CaseInsensitiveHashCodeProvider();
+
+ //|
+ public CaseInsensitiveHashCodeProvider() {
+ }
+
+ //|
+ public static CaseInsensitiveHashCodeProvider DefaultInvariant
+ {
+ get
+ {
+ return Default;
+ }
+ }
+
+ //|
+ public int GetHashCode(Object obj) {
+ if (obj == null) {
+ throw new ArgumentNullException("obj");
+ }
+
+ String s = obj as String;
+ if (s == null) {
+ return obj.GetHashCode();
+ }
+
+ return TextInfo.GetCaseInsensitiveHashCode(s);
+ }
+ }
+}
diff --git a/base/Kernel/System/Collections/CollectionBase.cs b/base/Applications/Runtime/Full/System/Collections/CollectionBase.cs
similarity index 96%
rename from base/Kernel/System/Collections/CollectionBase.cs
rename to base/Applications/Runtime/Full/System/Collections/CollectionBase.cs
index 009f1ab..f1f4e8b 100644
--- a/base/Kernel/System/Collections/CollectionBase.cs
+++ b/base/Applications/Runtime/Full/System/Collections/CollectionBase.cs
@@ -6,7 +6,8 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-namespace System.Collections {
+namespace System.Collections
+{
using System;
// Useful base class for typed read/write collections where items derive from object
diff --git a/base/Kernel/System/Collections/Comparer.cs b/base/Applications/Runtime/Full/System/Collections/Comparer.cs
similarity index 82%
rename from base/Kernel/System/Collections/Comparer.cs
rename to base/Applications/Runtime/Full/System/Collections/Comparer.cs
index 9cc3de5..b232e32 100644
--- a/base/Kernel/System/Collections/Comparer.cs
+++ b/base/Applications/Runtime/Full/System/Collections/Comparer.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Comparer
-**
-**
-** Purpose: Default IComparer implementation.
-**
-** Date: October 9, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Class: Comparer
+//
+// Purpose: Default IComparer implementation.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
using System.Globalization;
diff --git a/base/Kernel/System/Collections/DictionaryBase.cs b/base/Applications/Runtime/Full/System/Collections/DictionaryBase.cs
similarity index 96%
rename from base/Kernel/System/Collections/DictionaryBase.cs
rename to base/Applications/Runtime/Full/System/Collections/DictionaryBase.cs
index c423aa4..02026f3 100644
--- a/base/Kernel/System/Collections/DictionaryBase.cs
+++ b/base/Applications/Runtime/Full/System/Collections/DictionaryBase.cs
@@ -6,7 +6,8 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-namespace System.Collections {
+namespace System.Collections
+{
using System;
diff --git a/base/Kernel/System/Collections/DictionaryEntry.cs b/base/Applications/Runtime/Full/System/Collections/DictionaryEntry.cs
similarity index 79%
rename from base/Kernel/System/Collections/DictionaryEntry.cs
rename to base/Applications/Runtime/Full/System/Collections/DictionaryEntry.cs
index 027cc7a..1981fc6 100644
--- a/base/Kernel/System/Collections/DictionaryEntry.cs
+++ b/base/Applications/Runtime/Full/System/Collections/DictionaryEntry.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Interface: DictionaryEntry
-**
-**
-** Purpose: Return Value for IDictionaryEnumerator::GetEntry
-**
-** Date: September 20, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Interface: DictionaryEntry
+//
+// Purpose: Return Value for IDictionaryEnumerator::GetEntry
+//
+//===========================================================
+namespace System.Collections
+{
using System;
// A DictionaryEntry holds a key and a value from a dictionary.
@@ -32,7 +30,7 @@ namespace System.Collections {
//|
public DictionaryEntry(Object key, Object value)
{
- if (key==null)
+ if (key == null)
throw new ArgumentNullException("key");
_key = key;
_value = value;
diff --git a/base/Kernel/System/Collections/Hashtable.cs b/base/Applications/Runtime/Full/System/Collections/Hashtable.cs
similarity index 89%
rename from base/Kernel/System/Collections/Hashtable.cs
rename to base/Applications/Runtime/Full/System/Collections/Hashtable.cs
index 5580f45..9898e44 100644
--- a/base/Kernel/System/Collections/Hashtable.cs
+++ b/base/Applications/Runtime/Full/System/Collections/Hashtable.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Hashtable
-**
-**
-** Purpose: Hash table implementation
-**
-** Date: September 25, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Class: Hashtable
+//
+// Purpose: Hash table implementation
+//
+//===========================================================
+namespace System.Collections
+{
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
@@ -64,69 +62,67 @@ namespace System.Collections {
// clear the hash code & collision field, then the key then value field
// (at least value should be set last).
//
- // By Brian Grunkemeyer, algorithm by Patrick Dussud.
- // Version 1.30 2/20/2000
+ // Version 1.30
//|
[CCtorIsRunDuringStartup]
public class Hashtable : IDictionary, ICloneable
{
- /*
- Implementation Notes:
-
- This Hashtable uses double hashing. There are hashsize buckets in
- the table, and each bucket can contain 0 or 1 element. We a bit to
- mark whether there's been a collision when we inserted multiple
- elements (ie, an inserted item was hashed at least a second time and
- we probed this bucket, but it was already in use). Using the
- collision bit, we can terminate lookups & removes for elements that
- aren't in the hash table more quickly. We steal the most
- significant bit from the hash code to store the collision bit.
-
- Our hash function is of the following form:
-
- h(key, n) = h1(key) + n*h2(key)
-
- where n is the number of times we've hit a collided bucket and
- rehashed (on this particular lookup). Here are our hash functions:
-
- h1(key) = GetHash(key); // default implementation calls key.GetHashCode();
- h2(key) = 1 + (((h1(key) >> 5) + 1) % (hashsize - 1));
-
- The h1 can return any number. h2 must return a number between 1 and
- hashsize - 1 that is relatively prime to hashsize (not a problem if
- hashsize is prime). (Knuth's Art of Computer Programming, Vol. 3,
- p. 528-9)
-
- If this is true, then we are guaranteed to visit every bucket in
- exactly hashsize probes, since the least common multiple of hashsize
- and h2(key) will be hashsize * h2(key). (This is the first number
- where adding h2 to h1 mod hashsize will be 0 and we will search the
- same bucket twice).
-
- We previously used a different h2(key, n) that was not constant.
- That is a horrifically bad idea, unless you can prove that series
- will never produce any identical numbers that overlap when you mod
- them by hashsize, for all subranges from i to i+hashsize, for all i.
- It's not worth investigating, since there was no clear benefit from
- using that hash function, and it was broken.
-
- For efficiency reasons, we've implemented this by storing h1 and h2
- in a temporary, and setting a variable called seed equal to h1. We
- do a probe, and if we collided, we simply add h2 to seed each time
- through the loop.
-
- A good test for h2() is to subclass Hashtable, provide your own
- implementation of GetHash() that returns a constant, then add many
- items to the hash table. Make sure Count equals the number of items
- you inserted.
-
- Note that when we remove an item from the hash table, we set the key
- equal to buckets, if there was a collision in this bucket.
- Otherwise we'd either wipe out the collision bit, or we'd still have
- an item in the hash table.
-
- -- Brian Grunkemeyer, 10/28/1999
- */
+ //
+ //Implementation Notes:
+//
+ //This Hashtable uses double hashing. There are hashsize buckets in
+ //the table, and each bucket can contain 0 or 1 element. We a bit to
+ //mark whether there's been a collision when we inserted multiple
+ //elements (ie, an inserted item was hashed at least a second time and
+ //we probed this bucket, but it was already in use). Using the
+ //collision bit, we can terminate lookups & removes for elements that
+ //aren't in the hash table more quickly. We steal the most
+ //significant bit from the hash code to store the collision bit.
+//
+ //Our hash function is of the following form:
+//
+ //h(key, n) = h1(key) + n*h2(key)
+//
+ //where n is the number of times we've hit a collided bucket and
+ //rehashed (on this particular lookup). Here are our hash functions:
+//
+ //h1(key) = GetHash(key); // default implementation calls key.GetHashCode();
+ //h2(key) = 1 + (((h1(key) >> 5) + 1) % (hashsize - 1));
+//
+ //The h1 can return any number. h2 must return a number between 1 and
+ //hashsize - 1 that is relatively prime to hashsize (not a problem if
+ //hashsize is prime). (Knuth's Art of Computer Programming, Vol. 3,
+ //p. 528-9)
+//
+ //If this is true, then we are guaranteed to visit every bucket in
+ //exactly hashsize probes, since the least common multiple of hashsize
+ //and h2(key) will be hashsize * h2(key). (This is the first number
+ //where adding h2 to h1 mod hashsize will be 0 and we will search the
+ //same bucket twice).
+//
+ //We previously used a different h2(key, n) that was not constant.
+ //That is a horrifically bad idea, unless you can prove that series
+ //will never produce any identical numbers that overlap when you mod
+ //them by hashsize, for all subranges from i to i+hashsize, for all i.
+ //It's not worth investigating, since there was no clear benefit from
+ //using that hash function, and it was broken.
+//
+ //For efficiency reasons, we've implemented this by storing h1 and h2
+ //in a temporary, and setting a variable called seed equal to h1. We
+ //do a probe, and if we collided, we simply add h2 to seed each time
+ //through the loop.
+//
+ //A good test for h2() is to subclass Hashtable, provide your own
+ //implementation of GetHash() that returns a constant, then add many
+ //items to the hash table. Make sure Count equals the number of items
+ //you inserted.
+//
+ //Note that when we remove an item from the hash table, we set the key
+ //equal to buckets, if there was a collision in this bucket.
+ //Otherwise we'd either wipe out the collision bit, or we'd still have
+ //an item in the hash table.
+//
+ //
// Table of prime numbers to use as hash table sizes. Each entry is the
// smallest prime number larger than twice the previous entry.
@@ -230,13 +226,13 @@ namespace System.Collections {
public Hashtable(int capacity) : this(capacity, 100) {
}
- //
+ // [Bartok]:
public Hashtable(int capacity, float loadFactor)
: this(capacity, (int)(loadFactor * 100), null, null)
{
}
- //
+ // [Bartok]:
public Hashtable(int capacity, float loadFactor, IHashCodeProvider hcp, IComparer comparer)
: this(capacity, (int)(loadFactor * 100), hcp, comparer)
{
@@ -337,7 +333,7 @@ namespace System.Collections {
//|
public Hashtable(IDictionary d, int loadFactorPerc, IHashCodeProvider hcp, IComparer comparer)
: this((d != null ? d.Count : 0), loadFactorPerc, hcp, comparer) {
- if (d==null)
+ if (d == null)
throw new ArgumentNullException("d", "ArgumentNull_Dictionary");
IDictionaryEnumerator e = d.GetEnumerator();
@@ -377,7 +373,7 @@ namespace System.Collections {
if (count == 0)
return;
- for (int i = 0; i < buckets.Length; i++){
+ for (int i = 0; i < buckets.Length; i++) {
buckets[i].hash_coll = 0;
buckets[i].key = null;
buckets[i].val = null;
@@ -403,7 +399,7 @@ namespace System.Collections {
while (bucket > 0) {
bucket--;
Object keyv = lbuckets[bucket].key;
- if ((keyv!= null) && (keyv != lbuckets)) {
+ if ((keyv != null) && (keyv != lbuckets)) {
ht[keyv] = lbuckets[bucket].val;
}
}
@@ -440,7 +436,7 @@ namespace System.Collections {
if (b.key == null) {
return false;
}
- if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
+ if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
KeyEquals (b.key, key))
return true;
seed += incr;
@@ -467,7 +463,7 @@ namespace System.Collections {
else {
for (int i = buckets.Length; --i >= 0;) {
Object val = buckets[i].val;
- if (val!=null && value.Equals(val)) return true;
+ if (val != null && value.Equals(val)) return true;
}
}
return false;
@@ -480,7 +476,7 @@ namespace System.Collections {
bucket[] lbuckets = buckets;
for (int i = lbuckets.Length; --i >= 0;) {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
+ if ((keyv != null) && (keyv != buckets)) {
array.SetValue(keyv, arrayIndex++);
}
}
@@ -493,7 +489,7 @@ namespace System.Collections {
bucket[] lbuckets = buckets;
for (int i = lbuckets.Length; --i >= 0;) {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
+ if ((keyv != null) && (keyv != buckets)) {
DictionaryEntry entry = new DictionaryEntry(keyv,lbuckets[i].val);
array.SetValue(entry, arrayIndex++);
}
@@ -523,7 +519,7 @@ namespace System.Collections {
bucket[] lbuckets = buckets;
for (int i = lbuckets.Length; --i >= 0;) {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
+ if ((keyv != null) && (keyv != buckets)) {
array.SetValue(lbuckets[i].val, arrayIndex++);
}
}
@@ -557,7 +553,7 @@ namespace System.Collections {
KeyEquals (key, b.key))
return b.val;
seed += incr;
- }while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
+ } while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
return null;
}
set {
@@ -596,9 +592,9 @@ namespace System.Collections {
// rehash table into new buckets
int nb;
- for (nb = 0; nb < buckets.Length; nb++){
+ for (nb = 0; nb < buckets.Length; nb++) {
bucket oldb = buckets[nb];
- if ((oldb.key != null) && (oldb.key != buckets)){
+ if ((oldb.key != null) && (oldb.key != buckets)) {
putEntry(newBuckets, oldb.key, oldb.val, oldb.hash_coll & 0x7FFFFFFF);
}
}
@@ -641,7 +637,7 @@ namespace System.Collections {
//|
protected virtual int GetHash(Object key)
{
- if (hcp!=null)
+ if (hcp != null)
return hcp.GetHashCode(key);
return key.GetHashCode();
}
@@ -670,7 +666,7 @@ namespace System.Collections {
//|
protected virtual bool KeyEquals(Object item, Object key)
{
- if (comparer!=null)
+ if (comparer != null)
return comparer.Compare(item, key)==0;
return item.Equals(key);
}
@@ -740,7 +736,7 @@ namespace System.Collections {
// that once contained an entry and also has had a collision.
// We need to search this entire collision chain because we have to ensure that there are no
// duplicate entries in the table.
- if (emptySlotNumber == -1 && (buckets[bucketNumber].key == buckets) && (buckets[bucketNumber].hash_coll < 0))//(((buckets[bucketNumber].hash_coll & unchecked(0x80000000))!=0)))
+ if (emptySlotNumber == -1 && (buckets[bucketNumber].key == buckets) && (buckets[bucketNumber].hash_coll < 0))//(((buckets[bucketNumber].hash_coll & unchecked(0x80000000)) != 0)))
emptySlotNumber = bucketNumber;
// Insert the key/value pair into this bucket if this bucket is empty and has never contained an entry
@@ -781,7 +777,7 @@ namespace System.Collections {
// UNLESS
// we have remembered an available slot previously.
if (emptySlotNumber == -1) {// We don't need to set the collision bit here since we already have an empty slot
- if( buckets[bucketNumber].hash_coll >= 0 ) {
+ if (buckets[bucketNumber].hash_coll >= 0) {
buckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
occupancy++;
}
@@ -790,8 +786,7 @@ namespace System.Collections {
} while (++ntry < buckets.Length);
// This code is here if and only if there were no buckets without a collision bit set in the entire table
- if (emptySlotNumber != -1)
- {
+ if (emptySlotNumber != -1) {
// We pretty much have to insert in this order. Don't set hash
// code until the value & key are set appropriately.
buckets[emptySlotNumber].val = nvalue;
@@ -827,12 +822,12 @@ namespace System.Collections {
return;
}
- if( newBuckets[bucketNumber].hash_coll >= 0 ) {
+ if (newBuckets[bucketNumber].hash_coll >= 0) {
newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
occupancy++;
}
seed += incr;
- } while( true );
+ } while (true);
}
// Removes an entry from this hashtable. If an entry with the specified
@@ -893,7 +888,7 @@ namespace System.Collections {
//
//|
public static Hashtable Synchronized(Hashtable table) {
- if (table==null)
+ if (table == null)
throw new ArgumentNullException("table");
return new SyncHashtable(table);
}
@@ -909,7 +904,7 @@ namespace System.Collections {
}
public virtual void CopyTo(Array array, int arrayIndex) {
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (array.Rank != 1)
throw new ArgumentException("Arg_RankMultiDimNotSupported");
@@ -952,7 +947,7 @@ namespace System.Collections {
}
public virtual void CopyTo(Array array, int arrayIndex) {
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (array.Rank != 1)
throw new ArgumentException("Arg_RankMultiDimNotSupported");
@@ -1136,7 +1131,7 @@ namespace System.Collections {
while (bucket > 0) {
bucket--;
Object keyv = hashtable.buckets[bucket].key;
- if ((keyv!= null) && (keyv != hashtable.buckets)) {
+ if ((keyv != null) && (keyv != hashtable.buckets)) {
currentKey = keyv;
currentValue = hashtable.buckets[bucket].val;
current = true;
@@ -1159,9 +1154,9 @@ namespace System.Collections {
get {
if (current == false) throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen");
- if (getObjectRetType==Keys)
+ if (getObjectRetType == Keys)
return currentKey;
- else if (getObjectRetType==Values)
+ else if (getObjectRetType == Values)
return currentValue;
else
return new DictionaryEntry(currentKey, currentValue);
diff --git a/base/Kernel/System/Collections/ICollection.cs b/base/Applications/Runtime/Full/System/Collections/ICollection.cs
similarity index 87%
rename from base/Kernel/System/Collections/ICollection.cs
rename to base/Applications/Runtime/Full/System/Collections/ICollection.cs
index 22f1531..d69251d 100644
--- a/base/Kernel/System/Collections/ICollection.cs
+++ b/base/Applications/Runtime/Full/System/Collections/ICollection.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Interface: ICollection
-**
-**
-** Purpose: Base interface for all collections.
-**
-** Date: June 11, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Interface: ICollection
+//
+// Purpose: Base interface for all collections.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
// Base interface for all collections, defining enumerators, size, and
diff --git a/base/Applications/Runtime/Full/System/Collections/IComparer.cs b/base/Applications/Runtime/Full/System/Collections/IComparer.cs
new file mode 100644
index 0000000..f7a3ee7
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Collections/IComparer.cs
@@ -0,0 +1,30 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Interface: IComparer
+//
+// Purpose: Interface for comparing two Objects.
+//
+//===========================================================
+namespace System.Collections
+{
+
+ using System;
+ // The IComparer interface implements a method that compares two objects. It is
+ // used in conjunction with the Sort and BinarySearch methods on
+ // the Array and List classes.
+ //
+ //|
+ public interface IComparer {
+ // Compares two objects. An implementation of this method must return a
+ // value less than zero if x is less than y, zero if x is equal to y, or a
+ // value greater than zero if x is greater than y.
+ //
+ //|
+ int Compare(Object x, Object y);
+ }
+}
diff --git a/base/Kernel/System/Collections/IDictionary.cs b/base/Applications/Runtime/Full/System/Collections/IDictionary.cs
similarity index 86%
rename from base/Kernel/System/Collections/IDictionary.cs
rename to base/Applications/Runtime/Full/System/Collections/IDictionary.cs
index ad48f50..f26d13c 100644
--- a/base/Kernel/System/Collections/IDictionary.cs
+++ b/base/Applications/Runtime/Full/System/Collections/IDictionary.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Interface: IDictionary
-**
-**
-** Purpose: Base interface for all dictionarys.
-**
-** Date: September 21, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Interface: IDictionary
+//
+// Purpose: Base interface for all dictionarys.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
// An IDictionary is a possibly unordered set of key-value pairs.
diff --git a/base/Kernel/System/Collections/IDictionaryEnumerator.cs b/base/Applications/Runtime/Full/System/Collections/IDictionaryEnumerator.cs
similarity index 89%
rename from base/Kernel/System/Collections/IDictionaryEnumerator.cs
rename to base/Applications/Runtime/Full/System/Collections/IDictionaryEnumerator.cs
index f549476..4e253c4 100644
--- a/base/Kernel/System/Collections/IDictionaryEnumerator.cs
+++ b/base/Applications/Runtime/Full/System/Collections/IDictionaryEnumerator.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Interface: IDictionaryEnumerator
-**
-**
-** Purpose: Base interface for dictionary enumerators.
-**
-** Date: September 20, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Interface: IDictionaryEnumerator
+//
+// Purpose: Base interface for dictionary enumerators.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
// This interface represents an enumerator that allows sequential access to the
diff --git a/base/Applications/Runtime/Full/System/Collections/IEnumerable.cs b/base/Applications/Runtime/Full/System/Collections/IEnumerable.cs
new file mode 100644
index 0000000..72a2bd0
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Collections/IEnumerable.cs
@@ -0,0 +1,27 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Interface: IEnumerable
+//
+// Purpose: Interface for classes providing IEnumerators
+//
+//===========================================================
+namespace System.Collections
+{
+ using System;
+ using System.Runtime.InteropServices;
+ // Implement this interface if you need to support VB's foreach semantics.
+ // Also, COM classes that support an enumerator will also implement this interface.
+ //|
+ public interface IEnumerable
+ {
+ // Returns an IEnumerator for this enumerable Object. The enumerator provides
+ // a simple way to access all the contents of a collection.
+ //|
+ IEnumerator GetEnumerator();
+ }
+}
diff --git a/base/Kernel/System/Collections/IEnumerator.cs b/base/Applications/Runtime/Full/System/Collections/IEnumerator.cs
similarity index 84%
rename from base/Kernel/System/Collections/IEnumerator.cs
rename to base/Applications/Runtime/Full/System/Collections/IEnumerator.cs
index f1a2f77..c05e00e 100644
--- a/base/Kernel/System/Collections/IEnumerator.cs
+++ b/base/Applications/Runtime/Full/System/Collections/IEnumerator.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Interface: IEnumerator
-**
-**
-** Purpose: Base interface for all enumerators.
-**
-** Date: June 14, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Interface: IEnumerator
+//
+// Purpose: Base interface for all enumerators.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
using System.Runtime.InteropServices;
diff --git a/base/Applications/Runtime/Full/System/Collections/IHashCodeProvider.cs b/base/Applications/Runtime/Full/System/Collections/IHashCodeProvider.cs
new file mode 100644
index 0000000..650ae7b
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Collections/IHashCodeProvider.cs
@@ -0,0 +1,27 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Interface: IHashCodeProvider
+//
+// Purpose: A bunch of strings.
+//
+//===========================================================
+namespace System.Collections
+{
+
+ using System;
+ // Provides a mechanism for a hash table user to override the default
+ // GetHashCode() function on Objects, providing their own hash function.
+ //|
+ public interface IHashCodeProvider
+ {
+ // Returns a hash code for the given object.
+ //
+ //|
+ int GetHashCode (Object obj);
+ }
+}
diff --git a/base/Kernel/System/Collections/IList.cs b/base/Applications/Runtime/Full/System/Collections/IList.cs
similarity index 87%
rename from base/Kernel/System/Collections/IList.cs
rename to base/Applications/Runtime/Full/System/Collections/IList.cs
index d76243d..82bcbc0 100644
--- a/base/Kernel/System/Collections/IList.cs
+++ b/base/Applications/Runtime/Full/System/Collections/IList.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Interface: IList
-**
-**
-** Purpose: Base interface for all Lists.
-**
-** Date: September 21, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Interface: IList
+//
+// Purpose: Base interface for all Lists.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
// An IList is an ordered collection of objects. The exact ordering
diff --git a/base/Kernel/System/Collections/Queue.cs b/base/Applications/Runtime/Full/System/Collections/Queue.cs
similarity index 91%
rename from base/Kernel/System/Collections/Queue.cs
rename to base/Applications/Runtime/Full/System/Collections/Queue.cs
index 5e6887d..e6c6b8a 100644
--- a/base/Kernel/System/Collections/Queue.cs
+++ b/base/Applications/Runtime/Full/System/Collections/Queue.cs
@@ -3,18 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** Class: Queue
-**
-** Original implementation by Derek Yenser
-**
-** Purpose: A circular-array implementation of a queue.
-**
-** Date: October 4, 1999
-**
-=============================================================================*/
-namespace System.Collections {
+//=============================================================================
+//
+// Class: Queue
+//
+// Purpose: A circular-array implementation of a queue.
+//
+//=============================================================================
+namespace System.Collections
+{
using System;
// A simple Queue of objects. Internally it is implemented as a circular
@@ -70,10 +67,10 @@ namespace System.Collections {
//|
public Queue(ICollection col) : this((col==null ? 32 : col.Count))
{
- if (col==null)
+ if (col == null)
throw new ArgumentNullException("col");
IEnumerator en = col.GetEnumerator();
- while(en.MoveNext())
+ while (en.MoveNext())
Enqueue(en.Current);
}
@@ -124,7 +121,7 @@ namespace System.Collections {
//|
public virtual void CopyTo(Array array, int index)
{
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (array.Rank != 1)
throw new ArgumentException("Arg_RankMultiDimNotSupported");
@@ -135,11 +132,12 @@ namespace System.Collections {
throw new ArgumentException("Argument_InvalidOffLen");
int numToCopy = (arrayLen-index < _size) ? arrayLen-index : _size;
- if (numToCopy==0)
+ if (numToCopy == 0)
return;
if (_head < _tail) {
Array.Copy(_array, _head, array, index, numToCopy);
- } else {
+ }
+ else {
int firstPart = (_array.Length - _head < numToCopy) ? _array.Length - _head : numToCopy;
Array.Copy(_array, _head, array, index, firstPart);
numToCopy -= firstPart;
@@ -200,6 +198,14 @@ namespace System.Collections {
return _array[_head];
}
+ public virtual Object PeekAt(int index)
+ {
+ if (index < 0 || index >= _size) {
+ throw new ArgumentOutOfRangeException("index");
+ }
+ return GetElement(index);
+ }
+
// Returns a synchronized Queue. Returns a synchronized wrapper
// class around the queue - the caller must not use references to the
// original queue.
@@ -207,7 +213,7 @@ namespace System.Collections {
//|
public static Queue Synchronized(Queue queue)
{
- if (queue==null)
+ if (queue == null)
throw new ArgumentNullException("queue");
return new SynchronizedQueue(queue);
}
@@ -225,7 +231,8 @@ namespace System.Collections {
if (obj == null) {
if (_array[index] == null)
return true;
- } else if (obj.Equals(_array[index])) {
+ }
+ else if (obj.Equals(_array[index])) {
return true;
}
index = (index + 1) % _array.Length;
@@ -247,12 +254,13 @@ namespace System.Collections {
public virtual Object[] ToArray()
{
Object[] arr = new Object[_size];
- if (_size==0)
+ if (_size == 0)
return arr;
if (_head < _tail) {
Array.Copy(_array, _head, arr, 0, _size);
- } else {
+ }
+ else {
Array.Copy(_array, _head, arr, 0, _array.Length - _head);
Array.Copy(_array, 0, arr, _array.Length - _head, _tail);
}
@@ -268,7 +276,8 @@ namespace System.Collections {
if (_size > 0) {
if (_head < _tail) {
Array.Copy(_array, _head, newarray, 0, _size);
- } else {
+ }
+ else {
Array.Copy(_array, _head, newarray, 0, _array.Length - _head);
Array.Copy(_array, 0, newarray, _array.Length - _head, _tail);
}
@@ -420,8 +429,7 @@ namespace System.Collections {
public virtual Object Current {
get {
- if (currentElement == _q._array)
- {
+ if (currentElement == _q._array) {
if (_index == 0)
throw new InvalidOperationException("InvalidOperation_EnumNotStarted");
else
diff --git a/base/Kernel/System/Collections/ReadOnlyCollectionBase.cs b/base/Applications/Runtime/Full/System/Collections/ReadOnlyCollectionBase.cs
similarity index 95%
rename from base/Kernel/System/Collections/ReadOnlyCollectionBase.cs
rename to base/Applications/Runtime/Full/System/Collections/ReadOnlyCollectionBase.cs
index 909900b..620c045 100644
--- a/base/Kernel/System/Collections/ReadOnlyCollectionBase.cs
+++ b/base/Applications/Runtime/Full/System/Collections/ReadOnlyCollectionBase.cs
@@ -6,7 +6,8 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
-namespace System.Collections {
+namespace System.Collections
+{
using System;
diff --git a/base/Kernel/System/Collections/SortedList.cs b/base/Applications/Runtime/Full/System/Collections/SortedList.cs
similarity index 95%
rename from base/Kernel/System/Collections/SortedList.cs
rename to base/Applications/Runtime/Full/System/Collections/SortedList.cs
index c9a4106..3ccb2de 100644
--- a/base/Kernel/System/Collections/SortedList.cs
+++ b/base/Applications/Runtime/Full/System/Collections/SortedList.cs
@@ -3,18 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: SortedList
-**
-** Original implementation by Anders Hejlsberg
-**
-** Purpose: A sorted dictionary.
-**
-** Date: September 21, 1999
-**
-===========================================================*/
-namespace System.Collections {
+//============================================================
+//
+// Class: SortedList
+//
+// Purpose: A sorted dictionary.
+//
+//===========================================================
+namespace System.Collections
+{
using System;
// The SortedList class implements a sorted list of keys and values. Entries in
@@ -56,8 +53,7 @@ namespace System.Collections {
// has a constructor that allows a specific IComparer implementation to
// be specified.
//
- // By Anders Hejlsberg, further work by Brian Grunkemeyer
- // version 1.10 9/10/98
+ // version 1.10
//|
public class SortedList : IDictionary, ICloneable
{
@@ -153,7 +149,7 @@ namespace System.Collections {
//|
public SortedList(IDictionary d, IComparer comparer)
: this(comparer, (d != null ? d.Count : 0)) {
- if (d==null)
+ if (d == null)
throw new ArgumentNullException("d", "ArgumentNull_Dictionary");
d.Keys.CopyTo(keys, 0);
d.Values.CopyTo(values, 0);
@@ -322,7 +318,7 @@ namespace System.Collections {
throw new ArgumentOutOfRangeException("arrayIndex", "ArgumentOutOfRange_NeedNonNegNum");
if (array.Length - arrayIndex < Count)
throw new ArgumentException("Arg_ArrayPlusOffTooSmall");
- for (int i = 0; i
public static SortedList Synchronized(SortedList list) {
- if (list==null)
+ if (list == null)
throw new ArgumentNullException("list");
return new SyncSortedList(list);
}
@@ -756,9 +752,9 @@ namespace System.Collections {
get {
if (current == false) throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen");
- if (getObjectRetType==Keys)
+ if (getObjectRetType == Keys)
return key;
- else if (getObjectRetType==Values)
+ else if (getObjectRetType == Values)
return value;
else
return new DictionaryEntry(key, value);
@@ -849,7 +845,7 @@ namespace System.Collections {
}
public virtual int IndexOf(Object key) {
- if (key==null)
+ if (key == null)
throw new ArgumentNullException("key", "ArgumentNull_Key");
int i = Array.BinarySearch(sortedList.keys, 0,
diff --git a/base/Kernel/System/Collections/Specialized/ListDictionary.cs b/base/Applications/Runtime/Full/System/Collections/Specialized/ListDictionary.cs
similarity index 95%
rename from base/Kernel/System/Collections/Specialized/ListDictionary.cs
rename to base/Applications/Runtime/Full/System/Collections/Specialized/ListDictionary.cs
index 0912d24..bede4b6 100644
--- a/base/Kernel/System/Collections/Specialized/ListDictionary.cs
+++ b/base/Applications/Runtime/Full/System/Collections/Specialized/ListDictionary.cs
@@ -4,7 +4,8 @@
//
//------------------------------------------------------------------------------
-namespace System.Collections.Specialized {
+namespace System.Collections.Specialized
+{
using System.Collections;
@@ -213,7 +214,7 @@ namespace System.Collections.Specialized {
/// [To be supplied.]
///
public void CopyTo(Array array, int index) {
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (index < 0)
throw new ArgumentOutOfRangeException("index");
@@ -259,7 +260,8 @@ namespace System.Collections.Specialized {
}
if (node == head) {
head = node.next;
- } else {
+ }
+ else {
last.next = node.next;
}
count--;
@@ -347,7 +349,7 @@ namespace System.Collections.Specialized {
}
void ICollection.CopyTo(Array array, int index) {
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (index < 0)
throw new ArgumentOutOfRangeException("index");
diff --git a/base/Kernel/System/Collections/Specialized/StringDictionary.cs b/base/Applications/Runtime/Full/System/Collections/Specialized/StringDictionary.cs
similarity index 92%
rename from base/Kernel/System/Collections/Specialized/StringDictionary.cs
rename to base/Applications/Runtime/Full/System/Collections/Specialized/StringDictionary.cs
index a3a3083..4607497 100644
--- a/base/Kernel/System/Collections/Specialized/StringDictionary.cs
+++ b/base/Applications/Runtime/Full/System/Collections/Specialized/StringDictionary.cs
@@ -4,9 +4,10 @@
//
//------------------------------------------------------------------------------
-/*
- */
-namespace System.Collections.Specialized {
+//
+//
+namespace System.Collections.Specialized
+{
using System.Runtime.InteropServices;
using System.Diagnostics;
using System;
@@ -53,14 +54,14 @@ namespace System.Collections.Specialized {
///
public virtual string this[string key] {
get {
- if( key == null ) {
+ if (key == null) {
throw new ArgumentNullException("key");
}
return (string) contents[key.ToLower()];
}
set {
- if( key == null ) {
+ if (key == null) {
throw new ArgumentNullException("key");
}
@@ -100,7 +101,7 @@ namespace System.Collections.Specialized {
/// Adds an entry with the specified key and value into the System.Windows.Forms.StringDictionary.
///
public virtual void Add(string key, string value) {
- if( key == null ) {
+ if (key == null) {
throw new ArgumentNullException("key");
}
@@ -118,7 +119,7 @@ namespace System.Collections.Specialized {
/// Determines if the string dictionary contains a specific key
///
public virtual bool ContainsKey(string key) {
- if( key == null ) {
+ if (key == null) {
throw new ArgumentNullException("key");
}
@@ -151,7 +152,7 @@ namespace System.Collections.Specialized {
/// Removes the entry with the specified key from the string dictionary.
///
public virtual void Remove(string key) {
- if( key == null ) {
+ if (key == null) {
throw new ArgumentNullException("key");
}
diff --git a/base/Kernel/System/Collections/Stack.cs b/base/Applications/Runtime/Full/System/Collections/Stack.cs
similarity index 91%
rename from base/Kernel/System/Collections/Stack.cs
rename to base/Applications/Runtime/Full/System/Collections/Stack.cs
index 47c396c..643a56c 100644
--- a/base/Kernel/System/Collections/Stack.cs
+++ b/base/Applications/Runtime/Full/System/Collections/Stack.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** Class: Stack
-**
-**
-** Purpose: An array implementation of a stack.
-**
-** Date: October 7, 1999
-**
-=============================================================================*/
-namespace System.Collections {
+//=============================================================================
+//
+// Class: Stack
+//
+// Purpose: An array implementation of a stack.
+//
+//=============================================================================
+namespace System.Collections
+{
using System;
// A simple stack of objects. Internally it is implemented as an array,
@@ -52,10 +50,10 @@ namespace System.Collections {
//|
public Stack(ICollection col) : this((col==null ? 32 : col.Count))
{
- if (col==null)
+ if (col == null)
throw new ArgumentNullException("col");
IEnumerator en = col.GetEnumerator();
- while(en.MoveNext())
+ while (en.MoveNext())
Push(en.Current);
}
@@ -110,7 +108,7 @@ namespace System.Collections {
// Copies the stack into an array.
//|
public virtual void CopyTo(Array array, int index) {
- if (array==null)
+ if (array == null)
throw new ArgumentNullException("array");
if (array.Rank != 1)
throw new ArgumentException("Arg_RankMultiDimNotSupported");
@@ -122,13 +120,13 @@ namespace System.Collections {
int i = 0;
if (array is Object[]) {
Object[] objArray = (Object[]) array;
- while(i < _size) {
+ while (i < _size) {
objArray[i+index] = _array[_size-i-1];
i++;
}
}
else {
- while(i < _size) {
+ while (i < _size) {
array.SetValue(_array[_size-i-1], i+index);
i++;
}
@@ -145,7 +143,7 @@ namespace System.Collections {
// is empty, Peek throws an InvalidOperationException.
//|
public virtual Object Peek() {
- if (_size==0)
+ if (_size == 0)
throw new InvalidOperationException("InvalidOperation_EmptyStack");
return _array[_size-1];
}
@@ -179,7 +177,7 @@ namespace System.Collections {
//
//|
public static Stack Synchronized(Stack stack) {
- if (stack==null)
+ if (stack == null)
throw new ArgumentNullException("stack");
return new SyncStack(stack);
}
@@ -191,7 +189,7 @@ namespace System.Collections {
{
Object[] objArray = new Object[_size];
int i = 0;
- while(i < _size) {
+ while (i < _size) {
objArray[i] = _array[_size-i-1];
i++;
}
@@ -304,14 +302,14 @@ namespace System.Collections {
public virtual bool MoveNext() {
bool retval;
if (_version != _stack._version) throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
- if (_index == -2) { // First call to enumerator.
+ if (_index == -2) { // First call to enumerator.
_index = _stack._size-1;
retval = ( _index >= 0);
if (retval)
currentElement = _stack._array[_index];
return retval;
}
- if (_index == -1) { // End of enumeration.
+ if (_index == -1) { // End of enumeration.
return false;
}
diff --git a/base/Applications/Runtime/Full/System/Console.cs b/base/Applications/Runtime/Full/System/Console.cs
new file mode 100644
index 0000000..2372e72
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Console.cs
@@ -0,0 +1,320 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+
+namespace System
+{
+ using Microsoft.Singularity;
+#if !MINRUNTIME
+ using Microsoft.Singularity.Io;
+#endif
+ using System;
+ using System.Text;
+ using System.Globalization;
+ using System.Runtime.CompilerServices;
+
+ using System.Runtime.InteropServices;
+
+ // Provides static fields for console input and output. Use
+ // Console.In for input from the standard input stream (stdin),
+ // Console.Out for output to stdout, and Console.Error
+ // for output to stderr. If any of those console streams are
+ // redirected from the command line, these streams will be redirected.
+ // A program can also redirect its own output or input with the
+ // SetIn, SetOut, and SetError methods.
+ //
+ // The distinction between Console.Out and Console.Error is useful
+ // for programs that redirect output to a file or a pipe. Note that
+ // stdout and stderr can be output to different files at the same
+ // time from the DOS command line:
+ //
+ // someProgram 1> out 2> err
+ //
+ //|
+ public sealed class Console
+ {
+ private Console()
+ {
+ throw new NotSupportedException("NotSupported_Constructor");
+ }
+
+ static Console() {
+ }
+
+
+ private static void WriteInternal(char[] buffer, int index, int count)
+ {
+#if !MINRUNTIME
+ ConsoleOutput.Write(buffer, index, count);
+#else
+ for (int i = 0; i < count; i++) {
+ DebugStub.Print(buffer[index + i]);
+ }
+#endif
+ }
+
+ private static void WriteInternal(String value)
+ {
+#if !MINRUNTIME
+ ConsoleOutput.Write(value);
+#else
+ DebugStub.Print(value);
+#endif
+ }
+
+ private static void WriteNewLine()
+ {
+ WriteInternal(Environment.NewLine);
+ }
+
+ //|
+ public static void WriteLine()
+ {
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(String value)
+ {
+ WriteInternal(value);
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(bool value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(char value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(char[] buffer)
+ {
+ WriteInternal(buffer, 0, buffer.Length);
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(char[] buffer, int index, int count)
+ {
+ WriteInternal(buffer, index, count);
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(decimal value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(double value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(float value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(int value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ [CLSCompliant(false)]
+ public static void WriteLine(uint value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(long value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ [CLSCompliant(false)]
+ public static void WriteLine(ulong value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(Object value)
+ {
+ WriteInternal(value.ToString());
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(String format, Object arg0)
+ {
+ WriteInternal(String.Format(format, arg0));
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(String format, Object arg0, Object arg1)
+ {
+ WriteInternal(String.Format(format, arg0, arg1));
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(String format, Object arg0, Object arg1, Object arg2)
+ {
+ WriteInternal(String.Format(format, arg0, arg1, arg2));
+ WriteNewLine();
+ }
+
+ //|
+ public static void WriteLine(String format, params Object[] args)
+ {
+ WriteInternal(String.Format(format, args));
+ WriteNewLine();
+ }
+
+ //|
+ public static void Write(String format, Object arg0)
+ {
+ WriteInternal(String.Format(format, arg0));
+ }
+
+ //|
+ public static void Write(String format, Object arg0, Object arg1)
+ {
+ WriteInternal(String.Format(format, arg0, arg1));
+ }
+
+ //|
+ public static void Write(String format, Object arg0, Object arg1, Object arg2)
+ {
+ WriteInternal(String.Format(format, arg0, arg1, arg2));
+ }
+
+ //|
+ public static void Write(String format, params Object[] args)
+ {
+ WriteInternal(String.Format(format, args));
+ }
+
+ //|
+ public static void Write(bool value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(char value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(char[] buffer)
+ {
+ WriteInternal(buffer, 0, buffer.Length);
+ }
+
+ //|
+ public static void Write(char[] buffer, int index, int count)
+ {
+ WriteInternal(buffer, index, count);
+ }
+
+ //|
+ public static void Write(double value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(decimal value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(float value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(int value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ [CLSCompliant(false)]
+ public static void Write(uint value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(long value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ [CLSCompliant(false)]
+ public static void Write(ulong value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(Object value)
+ {
+ WriteInternal(value.ToString());
+ }
+
+ //|
+ public static void Write(String value)
+ {
+ WriteInternal(value);
+ }
+
+ public static int Read()
+ {
+#if !MINRUNTIME
+ return ConsoleInput.ReadChar();
+#else
+ return -1;
+#endif
+ }
+ public static string ReadLine()
+ {
+#if !MINRUNTIME
+ return ConsoleInput.ReadLine();
+#else
+ return "";
+#endif
+ }
+ }
+}
diff --git a/base/Applications/Runtime/System/DateTime.cs b/base/Applications/Runtime/Full/System/DateTime.cs
similarity index 96%
rename from base/Applications/Runtime/System/DateTime.cs
rename to base/Applications/Runtime/Full/System/DateTime.cs
index 72ccac3..e9c6bdb 100644
--- a/base/Applications/Runtime/System/DateTime.cs
+++ b/base/Applications/Runtime/Full/System/DateTime.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
using System.Threading;
@@ -108,10 +109,11 @@ namespace System {
[NoHeapAllocation]
private DateTime(long ticksFound, int ignoreMe) {
this.ticks = ticksFound;
- if ((ulong)ticks>(ulong)MaxTicks) {
- if (ticks>MaxTicks) {
+ if ((ulong)ticks >(ulong)MaxTicks) {
+ if (ticks > MaxTicks) {
ticks = MaxTicks;
- } else {
+ }
+ else {
ticks = MinTicks;
}
}
@@ -331,8 +333,7 @@ namespace System {
{
//TimeSpan.TimeToTicks is a family access function which does no error checking, so
//we need to put some error checking out here.
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >=0 && second < 60)
- {
+ if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60) {
return (TimeSpan.TimeToTicks(hour, minute, second));
}
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_BadHourMinuteSecond");
@@ -664,7 +665,8 @@ namespace System {
return String.Format("{0:s}, {1:d02} {2:s} {3:d} {4:d02}:{5:d02}:{6:d02} GMT",
GetShortWeekday(), Day, GetShortMonth(), Year,
Hour, Minute, Second);
- } else {
+ }
+ else {
return String.Format("{0:d}/{1:d}/{2:d} {3:d}:{4:d}:{5:d}",
Month, Day, Year, Hour, Minute, Second);
}
@@ -746,7 +748,7 @@ namespace System {
private string GetShortWeekday()
{
// Hardcoded USA-English until we support globalization
- switch(DayOfWeek) {
+ switch (DayOfWeek) {
case DayOfWeek.Monday : return "Mon";
case DayOfWeek.Tuesday : return "Tue";
case DayOfWeek.Wednesday : return "Wed";
@@ -762,7 +764,7 @@ namespace System {
private string GetShortMonth()
{
// Hardcoded USA-English until we support globalization
- switch(Month) {
+ switch (Month) {
case 1 : return "Jan";
case 2 : return "Feb";
case 3 : return "Mar";
diff --git a/base/Applications/Runtime/Full/System/DayOfWeek.cs b/base/Applications/Runtime/Full/System/DayOfWeek.cs
new file mode 100644
index 0000000..4fe0008
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/DayOfWeek.cs
@@ -0,0 +1,33 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: DayOfWeek
+//
+// Purpose: Enum for the day of the week.
+//
+//============================================================
+namespace System
+{
+
+ //|
+ public enum DayOfWeek {
+ //|
+ Sunday = 0,
+ //|
+ Monday = 1,
+ //|
+ Tuesday = 2,
+ //|
+ Wednesday = 3,
+ //|
+ Thursday = 4,
+ //|
+ Friday = 5,
+ //|
+ Saturday = 6,
+ }
+}
diff --git a/base/Kernel/System/Decimal.cs b/base/Applications/Runtime/Full/System/Decimal.cs
similarity index 92%
rename from base/Kernel/System/Decimal.cs
rename to base/Applications/Runtime/Full/System/Decimal.cs
index bcb6b0b..51678d9 100644
--- a/base/Kernel/System/Decimal.cs
+++ b/base/Applications/Runtime/Full/System/Decimal.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
using System.Diagnostics;
@@ -47,6 +48,7 @@ namespace System {
// the range of the Decimal type.
//|
[StructLayout(LayoutKind.Sequential)]
+ [AccessedByRuntime("referenced in Decimal.cpp")]
public struct Decimal : IFormattable, IComparable
{
// Sign mask for the flags field. A value of zero in this bit indicates a
@@ -202,7 +204,7 @@ namespace System {
//
//|
public Decimal(float value) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::InitSingle
+ // See also Lightning\Src\VM\COMDecimal.cpp::InitSingle
if (DecimalFromFloat(value, out this) < 0) {
throw new OverflowException("Overflow_Decimal");
}
@@ -219,7 +221,7 @@ namespace System {
//
//|
public Decimal(double value) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::InitDouble
+ // See also Lightning\Src\VM\COMDecimal.cpp::InitDouble
if (DecimalFromDouble(value, out this) < 0) {
throw new OverflowException("Overflow_Decimal");
}
@@ -252,7 +254,7 @@ namespace System {
//
//|
public Decimal(int[] bits) {
- if (bits==null)
+ if (bits == null)
throw new ArgumentNullException("bits");
if (bits.Length == 4) {
int f = bits[3];
@@ -302,7 +304,7 @@ namespace System {
//
//|
public static Decimal Add(Decimal d1, Decimal d2) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Add
+ // See also Lightning\Src\VM\COMDecimal.cpp::Add
Decimal result;
if (DecimalAdd(ref d2, ref d1, out result) < 0) {
throw new OverflowException("Decimal.Add");
@@ -323,7 +325,7 @@ namespace System {
//
//|
public static int Compare(Decimal d1, Decimal d2) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Compare
+ // See also Lightning\Src\VM\COMDecimal.cpp::Compare
return (DecimalCompare(ref d2, ref d1) - 1);
}
@@ -353,7 +355,7 @@ namespace System {
//
//|
public static Decimal Divide(Decimal d1, Decimal d2) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Divide
+ // See also Lightning\Src\VM\COMDecimal.cpp::Divide
Decimal result;
if (DecimalDivide(ref d2, ref d1, out result) < 0) {
throw new OverflowException("Decimal.Divide");
@@ -385,7 +387,7 @@ namespace System {
//
//|
public override int GetHashCode() {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::GetHashCode
+ // See also Lightning\Src\VM\COMDecimal.cpp::GetHashCode
double dbl;
if (DoubleFromDecimal(ref this, out dbl) != 0) {
throw new Exception("Decimal.GetHashCode failure");
@@ -407,7 +409,7 @@ namespace System {
//
//|
public static Decimal Floor(Decimal d) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Floor
+ // See also Lightning\Src\VM\COMDecimal.cpp::Floor
Decimal result;
DecimalFloor(ref d, out result);
return result;
@@ -451,21 +453,21 @@ namespace System {
return Number.ParseDecimal(s, style);
}
- /* Returns a binary representation of a Decimal. The return value is an
- * integer array with four elements. Elements 0, 1, and 2 contain the low,
- * middle, and high 32 bits of the 96-bit integer part of the Decimal.
- * Element 3 contains the scale factor and sign of the Decimal: bits 0-15
- * (the lower word) are unused; bits 16-23 contain a value between 0 and
- * 28, indicating the power of 10 to divide the 96-bit integer part by to
- * produce the Decimal value; bits 24-30 are unused; and finally bit 31
- * indicates the sign of the Decimal value, 0 meaning positive and 1
- * meaning negative.
- *
- * @param d A Decimal value.
- * @return An integer array with four elements containing the binary
- * representation of the argument.
- * @see Decimal(int[])
- */
+ // Returns a binary representation of a Decimal. The return value is an
+ // integer array with four elements. Elements 0, 1, and 2 contain the low,
+ // middle, and high 32 bits of the 96-bit integer part of the Decimal.
+ // Element 3 contains the scale factor and sign of the Decimal: bits 0-15
+ // (the lower word) are unused; bits 16-23 contain a value between 0 and
+ // 28, indicating the power of 10 to divide the 96-bit integer part by to
+ // produce the Decimal value; bits 24-30 are unused; and finally bit 31
+ // indicates the sign of the Decimal value, 0 meaning positive and 1
+ // meaning negative.
+ //
+ // @param d A Decimal value.
+ // @return An integer array with four elements containing the binary
+ // representation of the argument.
+ // @see Decimal(int[])
+ //
//|
public static int[] GetBits(Decimal d) {
return new int[] {d.lo, d.mid, d.hi, d.flags};
@@ -526,7 +528,7 @@ namespace System {
//|
public static Decimal Remainder(Decimal d1, Decimal d2) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Remainder
+ // See also Lightning\Src\VM\COMDecimal.cpp::Remainder
Decimal tmp = Truncate(Divide(d1, d2));
return Subtract(d1, Multiply(d2, tmp));
}
@@ -535,7 +537,7 @@ namespace System {
//
//|
public static Decimal Multiply(Decimal d1, Decimal d2) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Multiply
+ // See also Lightning\Src\VM\COMDecimal.cpp::Multiply
Decimal result;
if (DecimalMultiply(ref d1, ref d2, out result) < 0) {
throw new OverflowException("Decimal.Multiply");
@@ -571,7 +573,7 @@ namespace System {
//
//|
public static Decimal Round(Decimal d1, int decimals) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Round
+ // See also Lightning\Src\VM\COMDecimal.cpp::Round
Decimal result;
if (decimals < 0 || decimals > 28) {
throw new ArgumentOutOfRangeException("decimals");
@@ -593,7 +595,7 @@ namespace System {
//
//|
public static Decimal Subtract(Decimal d1, Decimal d2) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp::Subtract
+ // See also Lightning\Src\VM\COMDecimal.cpp::Subtract
Decimal result;
if (DecimalSubtract(ref d1, ref d2, out result) < 0) {
throw new OverflowException("Decimal.Subtract");
@@ -648,7 +650,7 @@ namespace System {
//
//|
public static double ToDouble(Decimal d) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp
+ // See also Lightning\Src\VM\COMDecimal.cpp
double result;
DoubleFromDecimal(ref d, out result);
return result;
@@ -748,7 +750,7 @@ namespace System {
//
//|
public static float ToSingle(Decimal d) {
- // rusa: see also Lightning\Src\VM\COMDecimal.cpp
+ // See also Lightning\Src\VM\COMDecimal.cpp
float result;
FloatFromDecimal(ref d, out result);
return result;
@@ -939,16 +941,16 @@ namespace System {
return Remainder(d1, d2);
}
- /*private static bool operator equals(Decimal d1, Decimal d2) {
- return Compare(d1, d2) == 0;
- }
-
- private static int operator compare(Decimal d1, Decimal d2) {
- int c = Compare(d1, d2);
- if (c < 0) return -1;
- if (c > 0) return 1;
- return 0;
- }*/
+ //private static bool operator equals(Decimal d1, Decimal d2) {
+ //return Compare(d1, d2) == 0;
+ //}
+//
+ //private static int operator compare(Decimal d1, Decimal d2) {
+ //int c = Compare(d1, d2);
+ //if (c < 0) return -1;
+ //if (c > 0) return 1;
+ //return 0;
+ //}
//|
public static bool operator ==(Decimal d1, Decimal d2) {
diff --git a/base/Applications/Runtime/Full/System/Delegate.cs b/base/Applications/Runtime/Full/System/Delegate.cs
new file mode 100644
index 0000000..5c7e40c
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Delegate.cs
@@ -0,0 +1,493 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+
+// Verbose runtime tracing
+//#define ENABLE_DEBUG_PRINT
+
+// This class provides runtime support for managing delegates that may have
+// been passed in to native code.
+//
+// The problem with these delegates is that the GC may move the delegate
+// object without being aware of references from native code. Rather than
+// pinning the objects (which currently operates at a page granularity), we
+// allocate GC-stable indexes ("delegate idxs") which the native code uses in
+// place of the underlying Delegate reference.
+//
+// The entry points from compiled code are:
+//
+// GetCodePtr, which allocates a short function to enter a delegate, passing
+// in the delegate idx.
+//
+// ReleaseCodePtr, which deallocates the function and releases the delegate
+// idx.
+//
+// The NativeDelegateTable is used to map delegate idxs to Delegate references.
+// References from this table are ordinary strong references as far as the GC
+// is concerned.
+namespace System
+{
+
+ using System.Reflection;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+ using System.Threading;
+
+ //|
+ public abstract partial class Delegate : ICloneable
+ {
+ private IntPtr CodePtr;
+
+ // equals returns true IIF the delegate is not null and has the
+ // same target, method and invocation list as this object
+ //|
+ public override bool Equals(Object obj)
+ {
+ if (obj != null && obj is Delegate) {
+ Delegate d = (Delegate) obj;
+ if (IsStatic()) {
+ if (_methodPtrAux == d._methodPtrAux) {
+ return true;
+ }
+ }
+ else {
+ if (d._target == _target &&
+ d._methodPtr == _methodPtr) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ //|
+ public override int GetHashCode()
+ {
+ if (IsStatic())
+ return this._methodPtrAux.ToInt32();
+ else
+ return this._methodPtr.ToInt32();
+ }
+
+ // Combine creates a new delegate based upon the contents of the
+ // delegates passed in.
+ //|
+ public static Delegate Combine(Delegate a, Delegate b)
+ {
+ //@TODO: Should this really check to see that they are both multicast
+ // because it really is an error to try and combine non-multicasts?
+ // Spec says that it returns null and only does the check if a and b
+ // are both null.
+
+ // boundary conditions -- if either (or both) delegates is null
+ // return the other.
+ if (a == null)
+ return b;
+ if (b == null)
+ return a;
+
+ // Verify that the types are the same...
+ if (a.GetType() != b.GetType())
+ throw new ArgumentException("Arg_DlgtTypeMis");
+ return a.CombineImpl(b);
+ }
+
+ // This method creates a new delegate based upon the passed
+ // array of delegates.
+ //|
+ public static Delegate Combine(Delegate[] delegates)
+ {
+ if (delegates == null || delegates.Length == 0)
+ return null;
+
+ Delegate d = delegates[0];
+ for (int i = 1; i < delegates.Length; i++)
+ d = Combine(d,delegates[i]);
+ return d;
+ }
+
+ // Return an array of delegates that represent the invocation list.
+ // This is basically THIS for a Delegate. MulticastDelegates may
+ // have multiple members.
+ //|
+ public virtual Delegate[] GetInvocationList() {
+ Delegate[] d = new Delegate[1];
+ d[0] = this;
+ return d;
+ }
+
+ // This routine will return the target
+ //|
+ public Object Target
+ {
+ get {return IsStatic() ? null : _target;}
+ }
+
+
+
+ //A quick test to see if this is a delegate to a static method.
+ //@ToDo: Verify that this is a sufficient test.
+ private bool IsStatic() {
+ if (_target is Delegate) {
+ return true;
+ }
+ return false;
+ }
+
+ // This will remove the value delegate from the source delegate
+ // if it found.
+ //|
+ public static Delegate Remove(Delegate source, Delegate value)
+ {
+ if (source == null)
+ return null;
+ if (value == null)
+ return source;
+ return source.RemoveImpl(value);
+ }
+
+ //|
+ public static Delegate RemoveAll(Delegate source, Delegate value)
+ {
+ Delegate newDelegate = null;
+ do {
+ newDelegate = source;
+ source = Remove(source, value);
+ } while (newDelegate != source);
+ return newDelegate;
+ }
+
+ // This is an internal routine that is called to do the combine. We
+ // use this to do the combine because the Combine routines are static
+ // final methods. In Delegate, this simply throws a MulticastNotSupportedException
+ // error. Multicast delegate must implement this.
+ //|
+ protected virtual Delegate CombineImpl(Delegate d)
+ {
+ throw new MulticastNotSupportedException("Multicast_Combine");
+ }
+
+ // This is an internal routine that is called to do the remove. We use this
+ // to do the remove because Remove is a static final method. Here we simply
+ // make sure that d is equal to this and return null or this.
+ //|
+ protected virtual Delegate RemoveImpl(Delegate d)
+ {
+ if (_target == d._target && _methodPtr == d._methodPtr)
+ return null;
+ else
+ return this;
+ }
+
+ //|
+ public virtual Object Clone()
+ {
+ return MemberwiseClone();
+ }
+
+ //|
+ public static bool operator ==(Delegate d1, Delegate d2) {
+ if ((Object)d1 == null)
+ return (Object)d2 == null;
+ return d1.Equals(d2);
+ }
+
+ //|
+ public static bool operator != (Delegate d1, Delegate d2) {
+ if ((Object)d1 == null)
+ return (Object)d2 != null;
+ return !d1.Equals(d2);
+ }
+
+ // GetCodePtr should be called by the marshalling code with the
+ // delegate and the address of the call back stub for that
+ // delegate class.
+ [RequiredByBartok]
+ private static IntPtr GetCodePtr(Delegate d,IntPtr callBackStub)
+ {
+ IntPtr codePtr = d.CodePtr;
+ if (codePtr == IntPtr.Zero) {
+
+ CriticalSection.AcquireMutex();
+ try {
+ codePtr = d.CodePtr;
+ if (codePtr == IntPtr.Zero) {
+ int idx = AllocateNativeDelegateRecord(d);
+ codePtr = CreateCodePtr(idx, callBackStub);
+ d.CodePtr = codePtr;
+ }
+ }
+ finally {
+ CriticalSection.ReleaseMutex();
+ }
+ }
+ return codePtr;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ internal static IntPtr FixedAlloc(int sizetdwBytes)
+ {
+ VTable.DebugBreak();
+ return IntPtr.Zero;
+ }
+
+ internal static void FixedFree(IntPtr handle)
+ {
+ VTable.DebugBreak();
+ }
+
+ // Create a little piece of assembly code that adds idx onto the
+ // argument list (by pushing it onto the stack) and jumps to the
+ // call back stub.
+
+ // The idx is added as the first argument. The calling
+ // convention is assumed to be STDCALL.
+ //
+ // The call back stub is a function created by the Bartok code
+ // generator and:
+ // 1. Uses the idx to get to the delegate via the NativeDelegateTable
+ // 2. Calls the invoke method of the delegate
+
+ private static unsafe IntPtr CreateCodePtr(int idx,
+ IntPtr callBackStub) {
+ IntPtr buffer = FixedAlloc(32);
+ if (buffer == IntPtr.Zero) {
+ return IntPtr.Zero;
+ }
+ // The desired instructions:
+ // push [sp]
+ // mov [sp+4], idx
+ // jmp callBackStub
+ //
+ byte* codeBuffer = (byte *) buffer.ToPointer();
+ // push [sp]
+ *(codeBuffer) = 0xFF;
+ *(codeBuffer+1) = 0x34;
+ *(codeBuffer+2) = 0x24;
+ // mov [sp+4], idx
+ *(codeBuffer+3) = 0xC7;
+ *(codeBuffer+4) = 0x44;
+ *(codeBuffer+5) = 0x24;
+ *(codeBuffer+6) = 0x04;
+ *((int*) (codeBuffer+7)) = idx;
+ // jmp callBackStub
+ *(codeBuffer+11) = 0xE9;
+ IntPtr disp = callBackStub - buffer;
+ *((int *) (codeBuffer+12)) = (disp - 16).ToInt32();
+ //
+ // pad the rest of the buffer with int 3
+ //
+
+ for (int i = 16; i < 32; i++) {
+ *(codeBuffer+i) = 0xcc;
+ }
+ return buffer;
+ }
+
+ // This method accepts a code pointer and allows the NativeDelegateRecord
+ // associated with it to be collected. In order to call this method
+ // safely it must be certain that no references to the code ptr exist
+ // in native code.
+ private static unsafe void ReleaseCodePtr(IntPtr codePtr) {
+ byte* codeBuffer = (byte *)codePtr.ToPointer();
+ int idx = *(int*)(codeBuffer+7);
+ Delegate del = IdxToDelegate(idx);
+ del.CodePtr = IntPtr.Zero;
+ CriticalSection.AcquireMutex();
+ try {
+ FreeNativeDelegateRecord(idx);
+ }
+ finally {
+ CriticalSection.ReleaseMutex();
+ }
+ FixedFree(codePtr);
+ }
+
+ //
+ // The CriticalSection protects the CodePtr fields during
+ // initialization and the NativeDelegateTable arrays when claiming
+ // indexes in them.
+ //
+ private static readonly Mutex CriticalSection;
+
+ //
+ // The NativeDelegateTable is held as a triangular array, starting
+ // with small arrays of NativeDelegateRecord structures and using
+ // successively larger arrays as the table is expanded. This avoids
+ // frequent allocations in programs that pass a lot of delegates
+ // to native code, and allows an idx to map to a (table,offset) pair
+ // in O(log n) steps.
+ //
+ private static NativeDelegateRecord[][] NativeDelegateTable;
+
+ // In a debug build, start the NativeDelegateTable size very small in order to
+ // force testing of table expansion
+#if DEBUG
+ private const int FIRST_TABLE_SIZE = 1;
+#else
+ private const int FIRST_TABLE_SIZE = 16;
+#endif
+
+ //
+ // FreeListStartIdx is the idx is the head of the list of NativeDelegateTable
+ // entries that have been freed. -1 indicates that the free list is empty.
+ //
+ private static int FreeListStartIdx;
+ private const int FREE_LIST_EMPTY = -1;
+
+ //
+ // FreeExtentStartIdx is the idx of the start of the contiguous
+ // extent of NativeDelegateTable entries. These are logically
+ // considered at the end of the free list: we use entries from the free
+ // list in preference to using 'pristine' space from the free extent.
+ //
+ private static int FreeExtentStartIdx;
+
+ //
+ // Each entry in the NativeDelegateTable currently holds an ordinary
+ // reference to the Delegate and an integer used to form the free list
+ // of unused records. We could overload a single field, but note that
+ // (a) we would then need to special-case the GC visiting code and
+ // that (b) during GC we could not simply iterate through the arrays because
+ // we couldn't distinguish free-list entries for allocated ones.
+ //
+ // Of course, we could steal a bit in the object reference to distinguish
+ // the free list, using odd values for the free list to avoid needing
+ // to mask the contents in IdxToDelegate.
+ //
+ // Seems like needless complexity unless we find the table is getting
+ // large.
+ //
+ private struct NativeDelegateRecord {
+ Delegate del;
+ int nextIdx;
+
+ internal void Allocate(Delegate del) {
+ VTable.Assert(this.del == null);
+ this.del = del;
+ }
+
+ internal void DeAllocate(int nextIdx) {
+ VTable.Assert(this.del != null);
+ this.del = null;
+ this.nextIdx = nextIdx;
+ }
+
+ internal Delegate Delegate() {
+ VTable.Assert(this.del != null);
+ return this.del;
+ }
+
+ internal int NextIdx() {
+ VTable.Assert(this.del == null);
+ return this.nextIdx;
+ }
+ }
+
+ // Allocate a native delegate record for "del". The caller must hold
+ // the CriticalSection.
+ private static int AllocateNativeDelegateRecord(Delegate del) {
+ int idx;
+ int table;
+ int offset;
+
+ DebugPrint("AllocateNativeDelegateRecord (list={0}, extent {1})\n",
+ __arglist(FreeListStartIdx, FreeExtentStartIdx));
+
+ if (FreeListStartIdx != FREE_LIST_EMPTY) {
+ // There's space in the free list: use that
+ int nextFreeIdx;
+ idx = FreeListStartIdx;
+ SplitIdx (idx, out table, out offset);
+ nextFreeIdx = NativeDelegateTable[table][offset].NextIdx();
+ FreeListStartIdx = nextFreeIdx;
+ }
+ else {
+ // There's no space in the free list, use the next slot in the
+ // free extent.
+ idx = FreeExtentStartIdx;
+ SplitIdx (idx, out table, out offset);
+ FreeExtentStartIdx ++;
+ if (offset + 1 == NativeDelegateTable[table].Length) {
+ // We've used the last slot in the free extent: allocate some
+ // more.
+ int currentLength = NativeDelegateTable[table].Length;
+ int nextLength = currentLength * 2;
+ DebugPrint("AllocateNativeDelegateRecord expanding to {0} len {1}\n",
+ __arglist(table + 1, nextLength));
+ NativeDelegateTable[table + 1] = new NativeDelegateRecord[nextLength];
+ }
+ }
+
+ NativeDelegateTable[table][offset].Allocate(del);
+
+ DebugPrint("AllocateNativeDelegateRecord got {0} (list={1}, extent {2})\n",
+ __arglist(idx, FreeListStartIdx, FreeExtentStartIdx));
+
+ return idx;
+ }
+
+ private static void FreeNativeDelegateRecord(int idx) {
+ int table;
+ int offset;
+
+ DebugPrint("FreeNativeDelegateRecord {0} (list={1}, extent {2})\n",
+ __arglist(idx, FreeListStartIdx, FreeExtentStartIdx));
+
+ SplitIdx (idx, out table, out offset);
+ NativeDelegateTable[table][offset].DeAllocate(FreeListStartIdx);
+ FreeListStartIdx = idx;
+ }
+
+ [RequiredByBartok]
+ private static Delegate IdxToDelegate(int idx) {
+ int table;
+ int offset;
+ Delegate result;
+
+ SplitIdx (idx, out table, out offset);
+ result = NativeDelegateTable[table][offset].Delegate();
+ DebugPrint("IdxToDelegate {0} -> {1}\n", __arglist(idx, result));
+
+ return result;
+ }
+
+ private static void SplitIdx(int idx, out int table, out int offset) {
+ table = 0;
+ offset = idx;
+ while (offset >= NativeDelegateTable[table].Length) {
+ offset -= NativeDelegateTable[table].Length;
+ table ++;
+ }
+ DebugPrint("SplitIdx {0} -> {1}.{2}\n", __arglist(idx, table, offset));
+ }
+
+ static Delegate() {
+ CriticalSection = new Mutex();
+ NativeDelegateTable = new NativeDelegateRecord[24][];
+ NativeDelegateTable[0] = new NativeDelegateRecord[FIRST_TABLE_SIZE];
+ FreeExtentStartIdx = 0;
+ FreeListStartIdx = FREE_LIST_EMPTY;
+
+#if FALSE // Enable this code to force testing of the FreeNativeDelegateRecord fn
+ for (int i = 0; i < FIRST_TABLE_SIZE * 2; i ++) {
+ int idx = AllocateNativeDelegateRecord(CriticalSection);
+ VTable.Assert (idx == i);
+ }
+ for (int i = 0; i < FIRST_TABLE_SIZE * 2; i ++) {
+ FreeNativeDelegateRecord(i);
+ }
+#endif
+ }
+
+ [System.Diagnostics.Conditional("ENABLE_DEBUG_PRINT")]
+ [NoInline]
+ internal static void DebugPrint(String v, __arglist)
+ {
+ VTable.DebugPrint(v, new ArgIterator(__arglist));
+ }
+ }
+}
diff --git a/base/Kernel/System/Diagnostics/Assert.cs b/base/Applications/Runtime/Full/System/Diagnostics/Assert.cs
similarity index 90%
rename from base/Kernel/System/Diagnostics/Assert.cs
rename to base/Applications/Runtime/Full/System/Diagnostics/Assert.cs
index bc0b919..1fa322b 100644
--- a/base/Kernel/System/Diagnostics/Assert.cs
+++ b/base/Applications/Runtime/Full/System/Diagnostics/Assert.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Diagnostics {
+namespace System.Diagnostics
+{
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -26,8 +27,7 @@ namespace System.Diagnostics {
//|
public static void AddFilter(AssertFilter filter)
{
- if (iFilterArraySize <= iNumOfFilters)
- {
+ if (iFilterArraySize <= iNumOfFilters) {
AssertFilter[] newFilterArray = new AssertFilter [iFilterArraySize+2];
if (iNumOfFilters > 0)
@@ -46,8 +46,7 @@ namespace System.Diagnostics {
//|
public static void Check(bool condition, String conditionString, String message)
{
- if (!condition)
- {
+ if (!condition) {
Fail (conditionString, message);
}
}
@@ -61,13 +60,11 @@ namespace System.Diagnostics {
// one filter to handle the assert.
int iTemp = iNumOfFilters;
- while (iTemp > 0)
- {
+ while (iTemp > 0) {
AssertFilters iResult = ListOfFilters [--iTemp].AssertFailure (conditionString, message);
- if (iResult == AssertFilters.FailDebug)
- {
+ if (iResult == AssertFilters.FailDebug) {
#if SINGULARITY_KERNEL
DebugStub.Break();
#elif SINGULARITY_PROCESS
diff --git a/base/Kernel/System/Diagnostics/AssertFilter.cs b/base/Applications/Runtime/Full/System/Diagnostics/AssertFilter.cs
similarity index 95%
rename from base/Kernel/System/Diagnostics/AssertFilter.cs
rename to base/Applications/Runtime/Full/System/Diagnostics/AssertFilter.cs
index 33e4f95..818f150 100644
--- a/base/Kernel/System/Diagnostics/AssertFilter.cs
+++ b/base/Applications/Runtime/Full/System/Diagnostics/AssertFilter.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Diagnostics {
+namespace System.Diagnostics
+{
using System;
diff --git a/base/Applications/Runtime/Full/System/Diagnostics/AssertFilters.cs b/base/Applications/Runtime/Full/System/Diagnostics/AssertFilters.cs
new file mode 100644
index 0000000..3d96049
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Diagnostics/AssertFilters.cs
@@ -0,0 +1,25 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System.Diagnostics
+{
+
+ //
+ // FailDebug indicates the debugger should be invoked
+ // FailIgnore indicates the failure should be ignored & the
+ // program continued
+ // FailTerminate indicates that the program should be terminated
+ // FailContinue indicates that no decision is made -
+ // the previous Filter should be invoked
+ //
+ using System;
+ internal enum AssertFilters
+ {
+ FailDebug = 0,
+ FailIgnore = 1,
+ FailTerminate = 2,
+ FailContinueFilter = 3,
+ }
+}
diff --git a/base/Kernel/System/Diagnostics/ConditionalAttribute.cs b/base/Applications/Runtime/Full/System/Diagnostics/ConditionalAttribute.cs
similarity index 92%
rename from base/Kernel/System/Diagnostics/ConditionalAttribute.cs
rename to base/Applications/Runtime/Full/System/Diagnostics/ConditionalAttribute.cs
index 1bbd402..359714b 100644
--- a/base/Kernel/System/Diagnostics/ConditionalAttribute.cs
+++ b/base/Applications/Runtime/Full/System/Diagnostics/ConditionalAttribute.cs
@@ -5,7 +5,8 @@
// ==--==
using System;
-namespace System.Diagnostics {
+namespace System.Diagnostics
+{
//|
[AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
public sealed class ConditionalAttribute : Attribute
diff --git a/base/Applications/Runtime/Full/System/Diagnostics/Debug.cs b/base/Applications/Runtime/Full/System/Diagnostics/Debug.cs
new file mode 100644
index 0000000..d188a56
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Diagnostics/Debug.cs
@@ -0,0 +1,38 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using Microsoft.Singularity;
+
+namespace System.Diagnostics
+{
+
+ public sealed class Debug {
+
+ [Conditional("DEBUG")]
+ public static void Assert(bool truth)
+ {
+ VTable.Assert(truth);
+ }
+
+ [Conditional("DEBUG")]
+ public static void Assert(bool truth, string statement)
+ {
+ VTable.Assert(truth, statement);
+ }
+
+ public static void AssertValidReference(Object obj) {
+ VTable.Assert(obj == null || obj.vtable != null);
+ }
+
+ public static void WriteLine(string text)
+ {
+ if (text == null)
+ text = "";
+ DebugStub.WriteLine(text);
+ }
+
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Diagnostics/Debugger.cs b/base/Applications/Runtime/Full/System/Diagnostics/Debugger.cs
new file mode 100644
index 0000000..5c0ce4a
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Diagnostics/Debugger.cs
@@ -0,0 +1,41 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using Microsoft.Singularity;
+using System.Runtime.CompilerServices;
+
+namespace System.Diagnostics
+{
+
+ ///
+ /// This class provides some of the methods defined by the CLR's version of
+ /// the Debugger static class. This makes writing portable apps easier.
+ ///
+ public /*static*/ sealed class Debugger {
+ private Debugger() { }
+
+ public static void Break()
+ {
+ DebugStub.Break();
+ }
+
+ public static bool IsAttached
+ {
+ [NoHeapAllocation]
+ get
+ {
+#if SINGULARITY_KERNEL
+ return DebugStub.IsDebuggerPresent();
+#elif SINGULARITY_PROCESS
+ return true;
+#else
+#error No environment has been specified.
+#endif
+ }
+ }
+
+ }
+}
diff --git a/base/Kernel/System/Diagnostics/DebuggerAttributes.cs b/base/Applications/Runtime/Full/System/Diagnostics/DebuggerAttributes.cs
similarity index 88%
rename from base/Kernel/System/Diagnostics/DebuggerAttributes.cs
rename to base/Applications/Runtime/Full/System/Diagnostics/DebuggerAttributes.cs
index 3bd0a76..427decb 100644
--- a/base/Kernel/System/Diagnostics/DebuggerAttributes.cs
+++ b/base/Applications/Runtime/Full/System/Diagnostics/DebuggerAttributes.cs
@@ -3,20 +3,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: DebuggerAttributes
-**
-**
-** Purpose: Attributes for debugger
-**
-** Date: Feb 01, 2000
-**
-===========================================================*/
+//============================================================
+//
+// Class: DebuggerAttributes
+//
+// Purpose: Attributes for debugger
+//
+//===========================================================
-namespace System.Diagnostics {
+namespace System.Diagnostics
+{
//|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
public sealed class DebuggerStepThroughAttribute : Attribute
diff --git a/base/Applications/Runtime/Full/System/DivideByZeroException.cs b/base/Applications/Runtime/Full/System/DivideByZeroException.cs
new file mode 100644
index 0000000..0a18e5c
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/DivideByZeroException.cs
@@ -0,0 +1,39 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: DivideByZeroException
+//
+// Purpose: Exception class for bad arithmetic conditions!
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ [AccessedByRuntime("referenced from halasm.asm")]
+ //|
+ public partial class DivideByZeroException : ArithmeticException {
+ //|
+ [AccessedByRuntime("referenced from halasm.asm")]
+ public DivideByZeroException()
+ : base("Arg_DivideByZero") {
+ }
+
+ //|
+ public DivideByZeroException(String message)
+ : base(message) {
+ }
+
+ //|
+ public DivideByZeroException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Kernel/System/Double.cs b/base/Applications/Runtime/Full/System/Double.cs
similarity index 90%
rename from base/Kernel/System/Double.cs
rename to base/Applications/Runtime/Full/System/Double.cs
index 21391e5..e4a5243 100644
--- a/base/Kernel/System/Double.cs
+++ b/base/Applications/Runtime/Full/System/Double.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Double
-**
-**
-** Purpose: A representation of an IEEE double precision
-** floating point number.
-**
-** Date: July 23, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: Double
+//
+// Purpose: A representation of an IEEE double precision
+// floating point number.
+//
+//===========================================================
+namespace System
+{
using System;
using System.Globalization;
@@ -78,7 +76,7 @@ namespace System {
//|
public static bool IsNaN(double d) {
- // rusa: see also Lightning\Src\ClassLibNative\Float\COMFloat::IsNAN
+ // See also Lightning\Src\ClassLibNative\Float\COMFloat::IsNAN
ulong v = BitConverter.DoubleToUInt64Bits(d);
return (((v & PositiveInfinityAsUInt64) == v) &&
((v & MantissaAsUInt64) != 0));
@@ -156,7 +154,8 @@ namespace System {
public static double Parse(String s, NumberStyles style) {
try {
return Number.ParseDouble(s, style);
- } catch (FormatException) {
+ }
+ catch (FormatException) {
//If we caught a FormatException, it may be from one of our special strings.
//Check the three with which we're concerned and rethrow if it's not one of
//those strings.
@@ -186,11 +185,14 @@ namespace System {
String sTrim = s.Trim();
if (sTrim.Equals(NumberFormatInfo.positiveInfinitySymbol)) {
result = PositiveInfinity;
- } else if (sTrim.Equals(NumberFormatInfo.negativeInfinitySymbol)) {
+ }
+ else if (sTrim.Equals(NumberFormatInfo.negativeInfinitySymbol)) {
result = NegativeInfinity;
- } else if (sTrim.Equals(NumberFormatInfo.nanSymbol)) {
+ }
+ else if (sTrim.Equals(NumberFormatInfo.nanSymbol)) {
result = NaN;
- } else
+ }
+ else
return false; // We really failed
}
return true;
diff --git a/base/Kernel/System/Empty.cs b/base/Applications/Runtime/Full/System/Empty.cs
similarity index 93%
rename from base/Kernel/System/Empty.cs
rename to base/Applications/Runtime/Full/System/Empty.cs
index e700835..7775f5c 100644
--- a/base/Kernel/System/Empty.cs
+++ b/base/Applications/Runtime/Full/System/Empty.cs
@@ -8,7 +8,8 @@
// This class represents an empty variant
////////////////////////////////////////////////////////////////////////////////
-namespace System {
+namespace System
+{
using System;
diff --git a/base/Kernel/System/Enum.cs b/base/Applications/Runtime/Full/System/Enum.cs
similarity index 96%
rename from base/Kernel/System/Enum.cs
rename to base/Applications/Runtime/Full/System/Enum.cs
index 4fd4333..0a50b3e 100644
--- a/base/Kernel/System/Enum.cs
+++ b/base/Applications/Runtime/Full/System/Enum.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
diff --git a/base/Applications/Runtime/Full/System/Environment.cs b/base/Applications/Runtime/Full/System/Environment.cs
new file mode 100644
index 0000000..3218622
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Environment.cs
@@ -0,0 +1,71 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: Environment
+//
+// Purpose: Provides some basic access to some environment
+// functionality.
+//
+//============================================================
+namespace System
+{
+ using System.Globalization;
+ using System.Collections;
+ using System.Text;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+ using System.Reflection;
+ using System.Diagnostics;
+ using Microsoft.Singularity;
+ using Microsoft.Singularity.V1.Services;
+
+ //|
+ public sealed class Environment {
+
+ private Environment() {} // Prevent from begin created
+
+ //==================================TickCount===================================
+ //Action: Gets the number of ticks since the system was started.
+ //Returns: The number of ticks since the system was started.
+ //Arguments: None
+ //Exceptions: None
+ //==============================================================================
+ //|
+ public static int TickCount {
+ get {
+ return unchecked((int)(ProcessService.GetUpTime().Ticks / 10000));
+ }
+ }
+
+ //===================================NewLine====================================
+ //Action: A property which returns the appropriate newline string for the given
+ // platform.
+ //Returns: \r\n on Win32.
+ //Arguments: None.
+ //Exceptions: None.
+ //==============================================================================
+ //|
+ public static String NewLine {
+ get {
+ return "\r\n";
+ }
+ }
+
+ //|
+ public static void Exit(int exitCode) {
+ ProcessService.Stop(exitCode);
+ }
+
+ // [Bartok]:
+ public static String StackTrace
+ {
+ get {
+ return "
+ public delegate void EventHandler(Object sender, EventArgs e);
+}
diff --git a/base/Applications/Runtime/Full/System/Exception.cs b/base/Applications/Runtime/Full/System/Exception.cs
new file mode 100644
index 0000000..3e266e2
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Exception.cs
@@ -0,0 +1,157 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: Exception
+//
+// Purpose: The base class for all exceptional conditions.
+//
+//=============================================================================
+
+namespace System
+{
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+ using System.Diagnostics;
+ using System.Text;
+ using System.Reflection;
+#if SINGULARITY_KERNEL
+ using Microsoft.Singularity;
+#elif SINGULARITY_PROCESS
+ using Microsoft.Singularity.V1.Services;
+#endif // SINGULARITY_PROCESS
+
+
+ //|
+ [AccessedByRuntime("referenced from halexn.cpp")]
+ public partial class Exception
+ {
+ //|
+ public Exception() {
+ _message = null;
+#if SINGULARITY_KERNEL
+ //DebugStub.Break();
+#elif SINGULARITY_PROCESS
+ //DebugService.Break();
+#endif // SINGULARITY_PROCESS
+ }
+
+ // Creates a new Exception. All derived classes should
+ // provide this constructor.
+ // Note: the stack trace is not started until the exception
+ // is thrown
+ //
+ //|
+ public Exception (String message, Exception innerException)
+ {
+ // TODO: The innerException will be provided by the runtime
+ // in the M9 time frame. Until then, we need this method.
+ _message = message;
+ _innerException = innerException;
+ }
+
+ //|
+ public virtual String Message {
+ get {
+ if (_message == null) {
+ return "Exception_WasThrown";
+ }
+ else {
+ return _message;
+ }
+ }
+ }
+
+ private String GetClassName() {
+ return this.vtable.vtableType.FullName;
+ }
+
+ // Retrieves the lowest exception (inner most) for the given Exception.
+ // This will traverse exceptions using the innerException property.
+ //
+ //|
+ public virtual Exception GetBaseException()
+ {
+ Exception inner = InnerException;
+ Exception back = this;
+
+ while (inner != null) {
+ back = inner;
+ inner = inner.InnerException;
+ }
+
+ return back;
+ }
+
+ // Returns the inner exception contained in this exception
+ //
+ //|
+ public Exception InnerException {
+ get { return _innerException; }
+ }
+
+ //|
+ public override String ToString() {
+ String message = Message;
+
+ if (_innerException != null) {
+ message = message + " ---> " + _innerException.ToString() + "\r\n" + " " + "Exception_EndOfInnerExceptionStack";
+ }
+
+ return message;
+ }
+
+ [AccessedByRuntime("referenced from halasm.asm")]
+ internal static unsafe bool IsUnlinkStack(UIntPtr throwAddr) {
+ UIntPtr unlinkBegin;
+ UIntPtr unlinkLimit;
+
+ fixed (byte *begin = &Microsoft.Singularity.Memory.Stacks.LinkStackBegin) {
+ unlinkBegin = (UIntPtr)begin;
+ }
+ fixed (byte *limit = &Microsoft.Singularity.Memory.Stacks.LinkStackLimit) {
+ unlinkLimit = (UIntPtr)limit;
+ }
+
+ if (throwAddr >= unlinkBegin && throwAddr <= unlinkLimit) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ // This is the function that users can override
+
+ // BUGBUG: provide a better default (probably deep copy). The
+ // current one does not deal with references well, and so, is
+ // not even a good shallow copy (it should at least null out the
+ // references).
+ virtual protected Exception cloneForUndo() {
+ return (Exception)this.MemberwiseClone();
+ }
+
+ [AccessedByRuntime("referenced from halexn.cpp")]
+ internal String _message;
+
+ private Exception _innerException;
+
+ [AccessedByRuntime("referenced from halexn.cpp")]
+ private UIntPtr _throwAddress;
+
+ [AccessedByRuntime("referenced from halexn.cpp")]
+ private bool _notifiedDebugger; // True if debugger first chance already thrown.
+
+ // [Bartok]:
+ public string StackTrace
+ {
+ get {
+ return "";
+ }
+ }
+ }
+}
diff --git a/base/Kernel/System/FlagsAttribute.cs b/base/Applications/Runtime/Full/System/FlagsAttribute.cs
similarity index 94%
rename from base/Kernel/System/FlagsAttribute.cs
rename to base/Applications/Runtime/Full/System/FlagsAttribute.cs
index 7c5e639..3ab7dae 100644
--- a/base/Kernel/System/FlagsAttribute.cs
+++ b/base/Applications/Runtime/Full/System/FlagsAttribute.cs
@@ -5,7 +5,8 @@
// ==--==
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-namespace System {
+namespace System
+{
using System;
// Custom attribute to indicate that the enum
diff --git a/base/Applications/Runtime/Full/System/FormatException.cs b/base/Applications/Runtime/Full/System/FormatException.cs
new file mode 100644
index 0000000..c44f19e
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/FormatException.cs
@@ -0,0 +1,34 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: FormatException
+//
+// Purpose: Exception to designate an illegal argument to Format.
+//
+//===========================================================
+namespace System
+{
+
+ using System;
+ //|
+ public class FormatException : SystemException {
+ //|
+ public FormatException()
+ : base("Arg_FormatException") {
+ }
+
+ //|
+ public FormatException(String message)
+ : base(message) {
+ }
+
+ //|
+ public FormatException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Kernel/System/Globalization/CharacterInfo.cs b/base/Applications/Runtime/Full/System/Globalization/CharacterInfo.cs
similarity index 91%
rename from base/Kernel/System/Globalization/CharacterInfo.cs
rename to base/Applications/Runtime/Full/System/Globalization/CharacterInfo.cs
index 318bcc9..52864d5 100644
--- a/base/Kernel/System/Globalization/CharacterInfo.cs
+++ b/base/Applications/Runtime/Full/System/Globalization/CharacterInfo.cs
@@ -7,16 +7,14 @@
//
// Class: CharacterInfo
//
-//
// Purpose: This class implements a set of methods for retrieving
// character type information. Character type information is
// independent of culture and region.
//
-// Date: August 12, 1998
-//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
+namespace System.Globalization
+{
using System;
using System.Runtime.CompilerServices;
@@ -76,13 +74,13 @@ namespace System.Globalization {
}
- /*=================================IsMark==========================
- **Action: Returns true if and only if the character c has one of the properties NonSpacingMark, SpacingCombiningMark,
- ** or EnclosingMark. Marks usually modify one or more other
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
+ //=================================IsMark==========================
+ //Action: Returns true if and only if the character c has one of the properties NonSpacingMark, SpacingCombiningMark,
+ // or EnclosingMark. Marks usually modify one or more other
+ //Returns:
+ //Arguments:
+ //Exceptions:
+ //============================================================================
public static bool IsMark(char ch) {
UnicodeCategory uc = GetUnicodeCategory(ch);
@@ -91,14 +89,14 @@ namespace System.Globalization {
|| uc == UnicodeCategory.EnclosingMark);
}
- /*=================================IsNumber==========================
- **Action: Returns true if and only if the character c has one of the properties DecimalDigitNumber,
- ** LetterNumber, or OtherNumber. Use the GetNumericValue method to determine the numeric value.
- **Returns:
- **Arguments:
- **Exceptions:
- **Note: GetNuemricValue is not yet implemented.
- ============================================================================*/
+ //=================================IsNumber==========================
+ //Action: Returns true if and only if the character c has one of the properties DecimalDigitNumber,
+ // LetterNumber, or OtherNumber. Use the GetNumericValue method to determine the numeric value.
+ //Returns:
+ //Arguments:
+ //Exceptions:
+ //Note: GetNuemricValue is not yet implemented.
+ //============================================================================
public static bool IsNumber(char ch) {
UnicodeCategory uc = GetUnicodeCategory(ch);
return (uc == UnicodeCategory.DecimalDigitNumber
@@ -106,49 +104,49 @@ namespace System.Globalization {
|| uc == UnicodeCategory.OtherNumber);
}
- /*=================================IsDigit==========================
- **Action: Returns true if and only if the character c has the property DecimalDigitNumber.
- ** Use the GetNumericValue method to determine the numeric value.
- **Returns:
- **Arguments:
- **Exceptions:
- **Note: GetNuemricValue is not yet implemented.
- ============================================================================*/
+ //=================================IsDigit==========================
+ //Action: Returns true if and only if the character c has the property DecimalDigitNumber.
+ // Use the GetNumericValue method to determine the numeric value.
+ //Returns:
+ //Arguments:
+ //Exceptions:
+ //Note: GetNuemricValue is not yet implemented.
+ //============================================================================
public static bool IsDigit(char ch) {
UnicodeCategory uc = GetUnicodeCategory(ch);
return (uc == UnicodeCategory.DecimalDigitNumber);
}
- /*=================================IsSeparator==========================
- **Action: Returns true if and only if the character c has one of the properties SpaceSeparator, LineSeparator
- **or ParagraphSeparator.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
+ //=================================IsSeparator==========================
+ //Action: Returns true if and only if the character c has one of the properties SpaceSeparator, LineSeparator
+ //or ParagraphSeparator.
+ //Returns:
+ //Arguments:
+ //Exceptions:
+ //============================================================================
public static bool IsSeparator(char ch) {
UnicodeCategory uc = GetUnicodeCategory(ch);
return (uc == UnicodeCategory.SpaceSeparator || uc == UnicodeCategory.LineSeparator || uc == UnicodeCategory.ParagraphSeparator);
}
- /*=================================IsControl==========================
- **Action: Returns true if and only if the character c has the property Control.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
+ //=================================IsControl==========================
+ //Action: Returns true if and only if the character c has the property Control.
+ //Returns:
+ //Arguments:
+ //Exceptions:
+ //============================================================================
public static bool IsControl(char ch) {
return (GetUnicodeCategory(ch) == UnicodeCategory.Control);
}
- /*=================================IsSurrogate==========================
- **Action: Returns true if and only if the character c has the property PrivateUse.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
+ //=================================IsSurrogate==========================
+ //Action: Returns true if and only if the character c has the property PrivateUse.
+ //Returns:
+ //Arguments:
+ //Exceptions:
+ //============================================================================
public static bool IsSurrogate(char ch) {
return (GetUnicodeCategory(ch) == UnicodeCategory.Surrogate);
@@ -292,17 +290,17 @@ namespace System.Globalization {
return (false);
}
- /*=================================IsCombiningCharacter==========================
- **Action: Returns if the specified character is a combining character.
- **Returns:
- ** TRUE if ch is a combining character.
- **Arguments:
- ** ch a Unicode character
- **Exceptions:
- ** None
- **Notes:
- ** Used by StringInfo.ParseCombiningCharacter.
- ============================================================================*/
+ //=================================IsCombiningCharacter==========================
+ //Action: Returns if the specified character is a combining character.
+ //Returns:
+ // TRUE if ch is a combining character.
+ //Arguments:
+ // ch a Unicode character
+ //Exceptions:
+ // None
+ //Notes:
+ // Used by StringInfo.ParseCombiningCharacter.
+ //============================================================================
internal static bool IsCombiningCharacter(char ch) {
UnicodeCategory uc = CharacterInfo.GetUnicodeCategory(ch);
return (
diff --git a/base/Kernel/System/Globalization/CompareInfo.cs b/base/Applications/Runtime/Full/System/Globalization/CompareInfo.cs
similarity index 95%
rename from base/Kernel/System/Globalization/CompareInfo.cs
rename to base/Applications/Runtime/Full/System/Globalization/CompareInfo.cs
index f38007b..86d620f 100644
--- a/base/Kernel/System/Globalization/CompareInfo.cs
+++ b/base/Applications/Runtime/Full/System/Globalization/CompareInfo.cs
@@ -7,15 +7,13 @@
//
// Class: CompareInfo
//
-//
// Purpose: This class implements a set of methods for comparing
// strings.
//
-// Date: August 12, 1998
-//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
+namespace System.Globalization
+{
//
// NOTE NOTE NOTE
@@ -132,7 +130,8 @@ namespace System.Globalization {
// equal, then the longer string is greater.
return CompareOrdinal(string1, 0, string1.Length,
string2, 0, string2.Length);
- } else {
+ }
+ else {
throw new ArgumentException("options", "Argument_CompareOptionOrdinal");
}
}
@@ -147,7 +146,7 @@ namespace System.Globalization {
// change is for adding the null-embedded string support in
// CompareString().
- // (markples) REVIEW: CLR has C# pass in a C++ object pointer that
+ // REVIEW: CLR has C# pass in a C++ object pointer that
// it finds this CompareString() method in. Do we need to do this,
// or do we have enough state in the CompareInfo object?
@@ -228,19 +227,19 @@ namespace System.Globalization {
// OffsetX >= 0
// LengthX >= 0 || LengthX == -1 (that is, LengthX >= -1)
// If LengthX >= 0, OffsetX + LengthX <= realLenX
- if (offset1<0) {
+ if (offset1 < 0) {
throw new ArgumentOutOfRangeException
("offset1", "ArgumentOutOfRange_Index");
}
- if (offset2<0) {
+ if (offset2 < 0) {
throw new ArgumentOutOfRangeException
("offset2", "ArgumentOutOfRange_Index");
}
- if (length1 >= 0 && length1>realLen1 - offset1) {
+ if (length1 >= 0 && length1 > realLen1 - offset1) {
throw new ArgumentOutOfRangeException
("string1", "ArgumentOutOfRange_OffsetLength");
}
- if (length2 >= 0 && length2>realLen2 - offset2){
+ if (length2 >= 0 && length2 > realLen2 - offset2) {
throw new ArgumentOutOfRangeException
("string2", "ArgumentOutOfRange_OffsetLength");
}
@@ -296,10 +295,10 @@ namespace System.Globalization {
if (count > Length2)
count = Length2;
- // markples: simplified and removed optimizations
+ // simplified and removed optimizations
while (--count >= 0) {
- if(string1[strIndex1] != string2[strIndex2]) {
+ if (string1[strIndex1] != string2[strIndex2]) {
return string1[strIndex1] - string2[strIndex2];
}
++strIndex1;
@@ -310,12 +309,12 @@ namespace System.Globalization {
}
- /*============================CompareString==========================
- **Action: Compare two string in a linguistic way.
- **Returns:
- **Arguments:
- **Exceptions:
- =======================================================================*/
+ //============================CompareString==========================
+ //Action: Compare two string in a linguistic way.
+ //Returns:
+ //Arguments:
+ //Exceptions:
+ //=======================================================================
private static int CompareString(CompareOptions dwCmpFlags,
String lpString1,
int lpStringIndex1,
@@ -385,8 +384,8 @@ namespace System.Globalization {
// _ASSERTE(pString1 != null && pString2 != null);
// Do a wchar by wchar compare.
- // markples: collapsed 8 times unrolled loop
- while((cchCount1 != 0 && cchCount2 != 0) &&
+ // collapsed 8 times unrolled loop
+ while ((cchCount1 != 0 && cchCount2 != 0) &&
(pString1[pStringIndex1] == pString2[pStringIndex2])) {
pStringIndex1++; pStringIndex2++;
@@ -411,7 +410,8 @@ namespace System.Globalization {
// no flags and the ignore case flag.
if (dwCmpFlags == CompareOptions.None) {
Mask = CMP_MASKOFF_NONE;
- } else {
+ }
+ else {
Mask = CMP_MASKOFF_CW;
}
@@ -472,7 +472,8 @@ namespace System.Globalization {
if (fIgnorePunct) {
pStringIndex1++; cchCount1--;
fContinue = true;
- } else if (sm2 != ScriptMember_Punctuation) {
+ }
+ else if (sm2 != ScriptMember_Punctuation) {
// The character in the second string is
// NOT punctuation.
if (WhichPunct2 != 0) {
@@ -485,7 +486,8 @@ namespace System.Globalization {
// the string.
WhichPunct2 = CSTR_GREATER_THAN;
fIgnorePunct = true;
- } else {
+ }
+ else {
// Set WP 1 to show that string 2 is smaller,
// and that string 1 has had a punctuation
// char - since no punctuation chars have
@@ -519,7 +521,8 @@ namespace System.Globalization {
// Pointer 2 will be advanced after if-else
// statement.
;
- } else if (sm1 != ScriptMember_Punctuation) {
+ }
+ else if (sm1 != ScriptMember_Punctuation) {
// The character in the first string is
// NOT punctuation.
if (WhichPunct1 != 0) {
@@ -533,7 +536,8 @@ namespace System.Globalization {
// string.
WhichPunct1 = CSTR_LESS_THAN;
fIgnorePunct = true;
- } else {
+ }
+ else {
// Set WP 2 to show that string 1 is smaller,
// and that string 2 has had a punctuation
// char - since no punctuation chars have
@@ -543,7 +547,8 @@ namespace System.Globalization {
// Pointer 2 will be advanced after if-else
// statement.
- } else {
+ }
+ else {
// Both code points are punctuation.
//
// See if either of the strings has encountered
@@ -553,12 +558,14 @@ namespace System.Globalization {
// it should be the smaller string (since
// both have punctuation chars).
WhichPunct1 = CSTR_LESS_THAN;
- } else if (WhichPunct2 != 0) {
+ }
+ else if (WhichPunct2 != 0) {
// String 2 has had a punctuation char, so
// it should be the smaller string (since
// both have punctuation chars).
WhichPunct2 = CSTR_GREATER_THAN;
- } else {
+ }
+ else {
// Position is the same, so compare the
// special weights. Set WhichPunct1 to
// the smaller special weight.
@@ -658,7 +665,8 @@ namespace System.Globalization {
return (WhichPunct2);
}
return (CSTR_EQUAL);
- } else {
+ }
+ else {
// String 2 is longer.
pString1 = pString2;
pStringIndex1 = pStringIndex2;
@@ -944,13 +952,14 @@ namespace System.Globalization {
}
if (count == -1) {
count = stringLen - startIndex;
- } else if (count < 0 || count + startIndex > stringLen) {
+ }
+ else if (count < 0 || count + startIndex > stringLen) {
throw new ArgumentOutOfRangeException("count");
}
int endIndex = startIndex + count - 1;
bool fAscii = false;
if (options != CompareOptions.Ordinal) {
- if(source.StringState == StringState.Undetermined) {
+ if (source.StringState == StringState.Undetermined) {
source.CheckHighChars();
}
fAscii = ((source.IsFastIndex() && value < 0x7f) || value == 0);
@@ -963,7 +972,8 @@ namespace System.Globalization {
}
}
return -1;
- } else if (fAscii && options == CompareOptions.IgnoreCase) {
+ }
+ else if (fAscii && options == CompareOptions.IgnoreCase) {
char lowerValue = value;
if (value >= 'A' && value <= 'Z') {
lowerValue = (char) (value | 0x20);
@@ -978,7 +988,8 @@ namespace System.Globalization {
}
}
return -1;
- } else {
+ }
+ else {
return SlowIndexOfString(source, String.StringCTOR(value, 1),
startIndex, endIndex, options);
}
@@ -998,7 +1009,8 @@ namespace System.Globalization {
if (sourceLen == 0) {
if (valueLen == 0) {
return 0;
- } else {
+ }
+ else {
return -1;
}
}
@@ -1007,7 +1019,8 @@ namespace System.Globalization {
}
if (count == -1) {
count = sourceLen - startIndex;
- } else if (count < 0 || count + startIndex > sourceLen) {
+ }
+ else if (count < 0 || count + startIndex > sourceLen) {
throw new ArgumentOutOfRangeException("count");
}
if (valueLen == 0) {
@@ -1015,7 +1028,7 @@ namespace System.Globalization {
}
int endIndex = startIndex + count - 1;
- // NOTE Currently we do not support cultures, so make
+ // NOTE: Currently we do not support cultures, so make
// requests for default comparisons the same as 'Ordinal' (fast,
// unicode-value-based). When we add proper support for
// cultures, take out the == CompareOptions.None case.
@@ -1041,7 +1054,7 @@ namespace System.Globalization {
for (int i = startIndex; i <= endPattern; i++) {
int j = 0;
- while (source[i+j] == value[j]) {
+ while (source[i + j] == value[j]) {
j++;
if (j == valueLen) {
return i;
@@ -1059,27 +1072,27 @@ namespace System.Globalization {
char srcChar, patChar;
int endPattern = endIndex - pattern.Length + 1;
- if(endPattern < 0) {
+ if (endPattern < 0) {
return -1;
}
- for(int ctrSrc = startIndex; ctrSrc <= endPattern; ctrSrc++) {
+ for (int ctrSrc = startIndex; ctrSrc <= endPattern; ctrSrc++) {
int ctrPat;
- for(ctrPat = 0; ctrPat < pattern.Length; ctrPat++) {
+ for (ctrPat = 0; ctrPat < pattern.Length; ctrPat++) {
srcChar = source[ctrSrc + ctrPat];
- if(srcChar >= 'A' && srcChar <= 'Z') {
+ if (srcChar >= 'A' && srcChar <= 'Z') {
srcChar |= (char)0x20;
}
patChar = pattern[ctrPat];
- if(patChar >= 'A' && patChar <= 'Z') {
+ if (patChar >= 'A' && patChar <= 'Z') {
patChar |= (char)0x20;
}
- if(srcChar != patChar) {
+ if (srcChar != patChar) {
break;
}
}
- if(ctrPat == pattern.Length) {
+ if (ctrPat == pattern.Length) {
return ctrSrc;
}
}
@@ -1243,14 +1256,16 @@ namespace System.Globalization {
if (count == -1) {
endIndex = 0;
count = startIndex + 1; // REVIEW: not the same as BCL code
- } else if (count < 0 || count > startIndex + 1) {
+ }
+ else if (count < 0 || count > startIndex + 1) {
throw new ArgumentOutOfRangeException("count");
- } else {
+ }
+ else {
endIndex = startIndex - count + 1;
}
bool fAscii = false;
if (options != CompareOptions.Ordinal) {
- if(source.StringState == StringState.Undetermined) {
+ if (source.StringState == StringState.Undetermined) {
source.CheckHighChars();
}
fAscii = (source.IsFastIndex() && value < 0x7f) || value == 0;
@@ -1263,7 +1278,8 @@ namespace System.Globalization {
}
}
return -1;
- } else if (fAscii && options == CompareOptions.IgnoreCase) {
+ }
+ else if (fAscii && options == CompareOptions.IgnoreCase) {
char lowerValue = value;
if (value >= 'A' && value <= 'Z') {
lowerValue = (char) (value | 0x20);
@@ -1278,8 +1294,9 @@ namespace System.Globalization {
}
}
return -1;
- } else {
- // probably wrong, but needed for Bartok.
+ }
+ else {
+ // Probably wrong, but needed for Bartok.
// throw new Exception("CompareInfo.SlowLastIndexOfChar not implemented in Bartok!");
for (int i = startIndex; i >= endIndex; i--) {
if (source[i] == value) {
@@ -1306,7 +1323,8 @@ namespace System.Globalization {
if (valueLen == 0) {
matchEndIndex = 0;
return 0;
- } else {
+ }
+ else {
matchEndIndex = -1; // REVIEW: not the same as BCL
return -1;
}
@@ -1318,9 +1336,11 @@ namespace System.Globalization {
if (count == -1) {
endIndex = 0;
count = startIndex + 1; // REVIEW: not the same as BCL
- } else if (count < 0 || count - 1 > startIndex) {
+ }
+ else if (count < 0 || count - 1 > startIndex) {
throw new ArgumentOutOfRangeException("count");
- } else {
+ }
+ else {
endIndex = startIndex - count + 1;
}
if (valueLen == 0) {
@@ -1332,7 +1352,7 @@ namespace System.Globalization {
value, out matchEndIndex);
}
- // NOTE Currently we do not support cultures, so make
+ // NOTE: Currently we do not support cultures, so make
// requests for default comparisons the same as 'Ordinal' (fast,
// unicode-value-based). When we add proper support for
// cultures, take out the == CompareOptions.None case.
diff --git a/base/Kernel/System/Globalization/CultureInfo.cs b/base/Applications/Runtime/Full/System/Globalization/CultureInfo.cs
similarity index 96%
rename from base/Kernel/System/Globalization/CultureInfo.cs
rename to base/Applications/Runtime/Full/System/Globalization/CultureInfo.cs
index 37aa036..2b87594 100644
--- a/base/Kernel/System/Globalization/CultureInfo.cs
+++ b/base/Applications/Runtime/Full/System/Globalization/CultureInfo.cs
@@ -7,18 +7,16 @@
//
// Class: CultureInfo
//
-//
// Purpose: This class represents the software preferences of a particular
// culture or community. It includes information such as the
// language, writing system, and a calendar used by the culture
// as well as methods for common operations such as printing
// dates and sorting strings.
//
-// Date: March 31, 1999
-//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
+namespace System.Globalization
+{
using System;
using System.Threading;
using System.Runtime.CompilerServices;
diff --git a/base/Kernel/System/Globalization/NumberFormatInfo.cs b/base/Applications/Runtime/Full/System/Globalization/NumberFormatInfo.cs
similarity index 95%
rename from base/Kernel/System/Globalization/NumberFormatInfo.cs
rename to base/Applications/Runtime/Full/System/Globalization/NumberFormatInfo.cs
index 0330d8c..d240841 100644
--- a/base/Kernel/System/Globalization/NumberFormatInfo.cs
+++ b/base/Applications/Runtime/Full/System/Globalization/NumberFormatInfo.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Globalization {
+namespace System.Globalization
+{
using System;
//|
diff --git a/base/Kernel/System/Globalization/NumberStyles.cs b/base/Applications/Runtime/Full/System/Globalization/NumberStyles.cs
similarity index 89%
rename from base/Kernel/System/Globalization/NumberStyles.cs
rename to base/Applications/Runtime/Full/System/Globalization/NumberStyles.cs
index 7d37055..6f39b81 100644
--- a/base/Kernel/System/Globalization/NumberStyles.cs
+++ b/base/Applications/Runtime/Full/System/Globalization/NumberStyles.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Enum: NumberStyles.cool
-**
-**
-** Purpose: Contains valid formats for Numbers recognized by
-** the Number class' parsing code.
-**
-** Date: August 9, 1999
-**
-===========================================================*/
-namespace System.Globalization {
+//============================================================
+//
+// Enum: NumberStyles.cool
+//
+// Purpose: Contains valid formats for Numbers recognized by
+// the Number class' parsing code.
+//
+//===========================================================
+namespace System.Globalization
+{
using System;
//|
diff --git a/base/Kernel/System/Globalization/TextInfo.cs b/base/Applications/Runtime/Full/System/Globalization/TextInfo.cs
similarity index 98%
rename from base/Kernel/System/Globalization/TextInfo.cs
rename to base/Applications/Runtime/Full/System/Globalization/TextInfo.cs
index ac92144..7136c63 100644
--- a/base/Kernel/System/Globalization/TextInfo.cs
+++ b/base/Applications/Runtime/Full/System/Globalization/TextInfo.cs
@@ -7,16 +7,14 @@
//
// Class: TextInfo
//
-//
// Purpose: This Class defines behaviors specific to a writing system.
// A writing system is the collection of scripts and
// orthographic rules required to represent a language as text.
//
-// Date: March 31, 1999
-//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
+namespace System.Globalization
+{
using System.Text;
using System;
using System.Runtime.CompilerServices;
diff --git a/base/Kernel/System/Globalization/UnicodeCategory.cs b/base/Applications/Runtime/Full/System/Globalization/UnicodeCategory.cs
similarity index 92%
rename from base/Kernel/System/Globalization/UnicodeCategory.cs
rename to base/Applications/Runtime/Full/System/Globalization/UnicodeCategory.cs
index 96b6b8d..6a7c68e 100644
--- a/base/Kernel/System/Globalization/UnicodeCategory.cs
+++ b/base/Applications/Runtime/Full/System/Globalization/UnicodeCategory.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: UnicodeCategory
-**
-**
-** Purpose:
-**
-** Date:
-**
-============================================================*/
-namespace System.Globalization {
+//============================================================
+//
+// Class: UnicodeCategory
+//
+// Purpose:
+//
+//============================================================
+namespace System.Globalization
+{
//|
public enum UnicodeCategory {
//|
diff --git a/base/Kernel/System/Guid.cs b/base/Applications/Runtime/Full/System/Guid.cs
similarity index 85%
rename from base/Kernel/System/Guid.cs
rename to base/Applications/Runtime/Full/System/Guid.cs
index f314556..7df3cc3 100644
--- a/base/Kernel/System/Guid.cs
+++ b/base/Applications/Runtime/Full/System/Guid.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
using System.Diagnostics;
@@ -43,7 +44,7 @@ namespace System {
//|
public Guid(byte[] b)
{
- if (b==null)
+ if (b == null)
throw new ArgumentNullException("b");
if (b.Length != 16)
throw new ArgumentException(String.Format("Arg_GuidArrayCtor", "16"));
@@ -95,9 +96,13 @@ namespace System {
_k = 0;
if (!blank) {
// Create a new Guid...
- VTable.DebugPrint("CreateGuid.Guid()\n");
+ Counter++;
+ _k = (byte) (Counter & 0xff);
+ _j = (byte) (Counter >> 8);
+ VTable.DebugPrint("CreateGuid.Guid(" + Counter + ")\n");
}
}
+ private static int Counter = 0;
// Creates a new guid based on the value in the string. The value is made up
// of hex digits speared by the dash ("-"). The string may begin and end with
@@ -110,7 +115,7 @@ namespace System {
//|
public Guid(String g)
{
- if (g==null)
+ if (g == null)
throw new ArgumentNullException("g", "ArgumentNull_String");
int startPos=0;
@@ -120,25 +125,21 @@ namespace System {
byte []dstartArray;
byte []dArray;
- try
- {
+ try {
// Check if it's of the form dddddddd-dddd-dddd-dddd-dddddddddddd
- if(g.IndexOf('-', 0) >= 0)
- {
+ if (g.IndexOf('-', 0) >= 0) {
String guidString = g.Trim(); //Remove Whitespace
// check to see that it's the proper length
- if (guidString[0]=='{') {
- if (guidString.Length!=38 || guidString[37]!='}') {
+ if (guidString[0] =='{') {
+ if (guidString.Length != 38 || guidString[37]!='}') {
throw new FormatException("Format_GuidInvLen");
}
startPos=1;
}
- else if (guidString[0]=='(')
- {
- if (guidString.Length!=38 || guidString[37]!=')')
- {
+ else if (guidString[0] =='(') {
+ if (guidString.Length != 38 || guidString[37]!=')') {
throw new FormatException("Format_GuidInvLen");
}
startPos=1;
@@ -164,7 +165,7 @@ namespace System {
spArray[0]++; //Increment past the '-';
startPos=spArray[0];
_dTemp = ParseNumbers.StringToLong(guidString, 16, 0, spArray);
- if (spArray[0]-startPos!=12) {
+ if (spArray[0] - startPos != 12) {
throw new FormatException(String.Format("Format_GuidInvLen"));
}
dstartArray = BitConverter.GetBytes(_dStartTemp);
@@ -179,7 +180,8 @@ namespace System {
_i = dArray[2];
_j = dArray[1];
_k = dArray[0];
- } else {
+ }
+ else {
_d = dstartArray[0];
_e = dstartArray[1];
_f = dArray[0];
@@ -193,8 +195,7 @@ namespace System {
// Else check if it is of the form
// {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
- else if(g.IndexOf('{', 0) >= 0)
- {
+ else if(g.IndexOf('{', 0) >= 0) {
int numStart = 0;
int numLen = 0;
@@ -205,17 +206,17 @@ namespace System {
g = EatAllWhitespace(g);
// Check for leading '{'
- if(g[0] != '{')
+ if (g[0] != '{')
throw new FormatException("Format_GuidBrace");
// Check for '0x'
- if(!IsHexPrefix(g, 1))
+ if (!IsHexPrefix(g, 1))
throw new FormatException(String.Format("Format_GuidHexPrefix", "{0xdddddddd, etc}"));
// Find the end of this hex number (since it is not fixed length)
numStart = 3;
numLen = g.IndexOf(',', numStart) - numStart;
- if(numLen <= 0)
+ if (numLen <= 0)
throw new FormatException("Format_GuidComma");
// Read in the number
@@ -224,13 +225,13 @@ namespace System {
ParseNumbers.IsTight); // tight parsing
// Check for '0x'
- if(!IsHexPrefix(g, numStart+numLen+1))
+ if (!IsHexPrefix(g, numStart + numLen + 1))
throw new FormatException(String.Format("Format_GuidHexPrefix", "{0xdddddddd, 0xdddd, etc}"));
// +3 to get by ',0x'
numStart = numStart + numLen + 3;
numLen = g.IndexOf(',', numStart) - numStart;
- if(numLen <= 0)
+ if (numLen <= 0)
throw new FormatException("Format_GuidComma");
// Read in the number
@@ -240,13 +241,13 @@ namespace System {
ParseNumbers.IsTight); // tight parsing
// Check for '0x'
- if(!IsHexPrefix(g, numStart+numLen+1))
+ if (!IsHexPrefix(g, numStart + numLen + 1))
throw new FormatException(String.Format("Format_GuidHexPrefix", "{0xdddddddd, 0xdddd, 0xdddd, etc}"));
// +3 to get by ',0x'
numStart = numStart + numLen + 3;
numLen = g.IndexOf(',', numStart) - numStart;
- if(numLen <= 0)
+ if (numLen <= 0)
throw new FormatException("Format_GuidComma");
// Read in the number
@@ -256,24 +257,23 @@ namespace System {
ParseNumbers.IsTight); // tight parsing
// Check for '{'
- if(g.Length <= numStart+numLen+1 || g[numStart+numLen+1] != '{')
+ if (g.Length <= numStart + numLen + 1 || g[numStart + numLen + 1] != '{')
throw new FormatException("Format_GuidBrace");
// Prepare for loop
numLen++;
byte[] bytes = new byte[8];
- for(int i = 0; i < 8; i++)
- {
+ for (int i = 0; i < 8; i++) {
// Check for '0x'
- if(!IsHexPrefix(g, numStart+numLen+1))
+ if (!IsHexPrefix(g, numStart + numLen + 1))
throw new FormatException(String.Format("Format_GuidHexPrefix", "{... { ... 0xdd, ...}}"));
// +3 to get by ',0x' or '{0x' for first case
numStart = numStart + numLen + 3;
// Calculate number length
- if(i < 7) // first 7 cases
+ if (i < 7) // first 7 cases
{
numLen = g.IndexOf(',', numStart) - numStart;
}
@@ -281,7 +281,7 @@ namespace System {
{
numLen = g.IndexOf('}', numStart) - numStart;
}
- if(numLen <= 0)
+ if (numLen <= 0)
throw new FormatException("Format_GuidComma");
// Read in the number
@@ -300,7 +300,7 @@ namespace System {
_k = bytes[7];
// Check for last '}'
- if(numStart+numLen+1 >= g.Length || g[numStart+numLen+1] != '}')
+ if (numStart + numLen + 1 >= g.Length || g[numStart + numLen + 1] != '}')
throw new FormatException("Format_GuidEndBrace");
return;
@@ -310,7 +310,7 @@ namespace System {
{
String guidString = g.Trim(); //Remove Whitespace
- if(guidString.Length != 32) {
+ if (guidString.Length != 32) {
throw new FormatException("Format_GuidInvLen");
}
@@ -333,7 +333,7 @@ namespace System {
startPos += 4;
spArray[0] = startPos;
_dTemp = ParseNumbers.StringToLong(guidString, 16, startPos, spArray);
- if (spArray[0]-startPos!=12) {
+ if (spArray[0] - startPos != 12) {
throw new FormatException(String.Format("Format_GuidInvLen"));
}
dstartArray = BitConverter.GetBytes(_dStartTemp);
@@ -348,7 +348,8 @@ namespace System {
_i = dArray[2];
_j = dArray[1];
_k = dArray[0];
- } else {
+ }
+ else {
_d = dstartArray[0];
_e = dstartArray[1];
_f = dArray[0];
@@ -360,8 +361,7 @@ namespace System {
}
}
}
- catch(IndexOutOfRangeException)
- {
+ catch (IndexOutOfRangeException) {
throw new FormatException("Format_GuidUnrecognized");
}
}
@@ -371,10 +371,10 @@ namespace System {
//|
public Guid(int a, short b, short c, byte[] d)
{
- if (d==null)
+ if (d == null)
throw new ArgumentNullException("d");
// Check that array is not too big
- if(d.Length != 8)
+ if (d.Length != 8)
throw new ArgumentException(String.Format("Arg_GuidArrayCtor", "8"));
_a = a;
@@ -413,17 +413,15 @@ namespace System {
private static int TryParse(String str, int []parsePos, int requiredLength) {
int currStart = parsePos[0];
int retVal;
- try
- {
+ try {
retVal = ParseNumbers.StringToInt(str, 16, 0, parsePos);
}
- catch (FormatException)
- {
+ catch (FormatException) {
throw new FormatException("Format_GuidUnrecognized");
}
//If we didn't parse enough characters, there's clearly an error.
- if (parsePos[0]-currStart!=requiredLength) {
+ if (parsePos[0] - currStart != requiredLength) {
throw new FormatException("Format_GuidUnrecognized");
}
return retVal;
@@ -436,11 +434,9 @@ namespace System {
char curChar;
// Now get each char from str and if it is not whitespace add it to chArr
- for(int i = 0; i < str.Length; i++)
- {
+ for (int i = 0; i < str.Length; i++) {
curChar = str[i];
- if(!Char.IsWhiteSpace(curChar))
- {
+ if (!Char.IsWhiteSpace(curChar)) {
chArr[newLength++] = curChar;
}
}
@@ -451,7 +447,7 @@ namespace System {
private static bool IsHexPrefix(String str, int i)
{
- if(str[i] == '0' && (Char.ToLower(str[i+1]) == 'x'))
+ if (str[i] == '0' && (Char.ToLower(str[i + 1]) == 'x'))
return true;
else
return false;
@@ -464,13 +460,13 @@ namespace System {
{
byte[] g = new byte[16];
byte[] tmp = BitConverter.GetBytes(_a);
- for(int i=0; i<4; i++)
+ for (int i = 0; i < 4; i++)
g[i] = tmp[i];
tmp = BitConverter.GetBytes(_b);
- for(int i=0; i<2; i++)
+ for (int i = 0; i < 2; i++)
g[i+4] = tmp[i];
tmp = BitConverter.GetBytes(_c);
- for(int i=0; i<2; i++)
+ for (int i = 0; i < 2; i++)
g[i+6] = tmp[i];
g[8] = _d;
@@ -506,16 +502,16 @@ namespace System {
{
Guid g;
// Check that o is a Guid first
- if(o == null || !(o is Guid))
+ if (o == null || !(o is Guid))
return false;
else g = (Guid) o;
// Now compare each of the elements
- if(g._a != _a)
+ if (g._a != _a)
return false;
- if(g._b != _b)
+ if (g._b != _b)
return false;
- if(g._c != _c)
+ if (g._c != _c)
return false;
if (g._d != _d)
return false;
@@ -538,7 +534,7 @@ namespace System {
}
private int GetResult(uint me, uint them) {
- if (me
public static bool operator ==(Guid a, Guid b)
@@ -645,27 +641,23 @@ namespace System {
byte[] tmp;
int i;
- if (format.Equals("N") || format.Equals("n"))
- {
+ if (format.Equals("N") || format.Equals("n")) {
guidChars = new char[32];
tmp = BitConverter.GetBytes(_a);
- for (i = 3; i >= 0; i--)
- {
+ for (i = 3; i >= 0; i--) {
guidChars[offset++] = HexToChar((tmp[i]>>4) & 0xf);
guidChars[offset++] = HexToChar(tmp[i] & 0xf);
}
tmp = BitConverter.GetBytes(_b);
- for (i = 1; i >= 0; i--)
- {
+ for (i = 1; i >= 0; i--) {
guidChars[offset++] = HexToChar((tmp[i]>>4) & 0xf);
guidChars[offset++] = HexToChar(tmp[i] & 0xf);
}
tmp = BitConverter.GetBytes(_c);
- for (i = 1; i >= 0; i--)
- {
+ for (i = 1; i >= 0; i--) {
guidChars[offset++] = HexToChar((tmp[i]>>4) & 0xf);
guidChars[offset++] = HexToChar(tmp[i] & 0xf);
}
@@ -697,31 +689,26 @@ namespace System {
}
int strLength = 38;
- if (format.Equals("B") || format.Equals("b"))
- {
+ if (format.Equals("B") || format.Equals("b")) {
guidChars = new char[38];
guidChars[offset++] = '{';
guidChars[37] = '}';
}
- if (format.Equals("P") || format.Equals("p"))
- {
+ if (format.Equals("P") || format.Equals("p")) {
guidChars = new char[38];
guidChars[offset++] = '(';
guidChars[37] = ')';
}
- if (format.Equals("D") || format.Equals("d"))
- {
+ if (format.Equals("D") || format.Equals("d")) {
guidChars = new char[36];
strLength = 36;
}
- else
- {
+ else {
throw new FormatException("Format_InvalidGuidFormatSpecification");
}
tmp = BitConverter.GetBytes(_a);
- for (i = 3; i >= 0; i--)
- {
+ for (i = 3; i >= 0; i--) {
guidChars[offset++] = HexToChar((tmp[i]>>4) & 0xf);
guidChars[offset++] = HexToChar(tmp[i] & 0xf);
}
@@ -729,8 +716,7 @@ namespace System {
guidChars[offset++] = '-';
tmp = BitConverter.GetBytes(_b);
- for (i = 1; i >= 0; i--)
- {
+ for (i = 1; i >= 0; i--) {
guidChars[offset++] = HexToChar((tmp[i]>>4) & 0xf);
guidChars[offset++] = HexToChar(tmp[i] & 0xf);
@@ -739,8 +725,7 @@ namespace System {
guidChars[offset++] = '-';
tmp = BitConverter.GetBytes(_c);
- for (i = 1; i >= 0; i--)
- {
+ for (i = 1; i >= 0; i--) {
guidChars[offset++] = HexToChar((tmp[i]>>4) & 0xf);
guidChars[offset++] = HexToChar(tmp[i] & 0xf);
}
diff --git a/base/Applications/Runtime/Full/System/IAsyncResult.cs b/base/Applications/Runtime/Full/System/IAsyncResult.cs
new file mode 100644
index 0000000..96216bb
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/IAsyncResult.cs
@@ -0,0 +1,39 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Interface: IAsyncResult
+//
+// Purpose: Interface to encapsulate the results of an async
+// operation
+//
+//===========================================================
+namespace System
+{
+
+ using System;
+ using System.Threading;
+ //|
+ [CLSCompliant(false)]
+ public interface IAsyncResult
+ {
+ //|
+ bool IsCompleted { get; }
+
+ //|
+ WaitHandle AsyncWaitHandle { get; }
+
+
+ //|
+ Object AsyncState { get; }
+
+ //|
+ bool CompletedSynchronously { get; }
+
+
+ }
+
+}
diff --git a/base/Kernel/System/ICloneable.cs b/base/Applications/Runtime/Full/System/ICloneable.cs
similarity index 76%
rename from base/Kernel/System/ICloneable.cs
rename to base/Applications/Runtime/Full/System/ICloneable.cs
index facae1e..544c8e4 100644
--- a/base/Kernel/System/ICloneable.cs
+++ b/base/Applications/Runtime/Full/System/ICloneable.cs
@@ -3,14 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: ICloneable
-**
-** This interface is implemented by classes that support cloning.
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: ICloneable
+//
+// This interface is implemented by classes that support cloning.
+//
+//===========================================================
+namespace System
+{
using System;
// Defines an interface indicating that an object may be cloned. Only objects
diff --git a/base/Kernel/System/IComparable.cs b/base/Applications/Runtime/Full/System/IComparable.cs
similarity index 95%
rename from base/Kernel/System/IComparable.cs
rename to base/Applications/Runtime/Full/System/IComparable.cs
index 07babdc..64ba49e 100644
--- a/base/Kernel/System/IComparable.cs
+++ b/base/Applications/Runtime/Full/System/IComparable.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
// The IComparable interface is implemented by classes that support an
diff --git a/base/Kernel/System/IDisposable.cs b/base/Applications/Runtime/Full/System/IDisposable.cs
similarity index 89%
rename from base/Kernel/System/IDisposable.cs
rename to base/Applications/Runtime/Full/System/IDisposable.cs
index 1682d4d..bd31827 100644
--- a/base/Kernel/System/IDisposable.cs
+++ b/base/Applications/Runtime/Full/System/IDisposable.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Interface: IDisposable
-**
-**
-** Purpose: Interface for assisting with deterministic finalization.
-**
-** Date: September 29, 2000
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Interface: IDisposable
+//
+// Purpose: Interface for assisting with deterministic finalization.
+//
+//===========================================================
+namespace System
+{
// IDisposable is an attempt at helping to solve problems with deterministic
// finalization. The GC of course doesn't leave any way to deterministically
// know when a finalizer will run. This forces classes that hold onto OS
diff --git a/base/Kernel/System/IFormattable.cs b/base/Applications/Runtime/Full/System/IFormattable.cs
similarity index 90%
rename from base/Kernel/System/IFormattable.cs
rename to base/Applications/Runtime/Full/System/IFormattable.cs
index 5a8fd65..44ec1ef 100644
--- a/base/Kernel/System/IFormattable.cs
+++ b/base/Applications/Runtime/Full/System/IFormattable.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
//|
diff --git a/base/Applications/Runtime/Full/System/IndexOutOfRangeException.cs b/base/Applications/Runtime/Full/System/IndexOutOfRangeException.cs
new file mode 100644
index 0000000..308307e
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/IndexOutOfRangeException.cs
@@ -0,0 +1,37 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: IndexOutOfRangeException
+//
+// Purpose: Exception class for invalid array indices.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ public sealed partial class IndexOutOfRangeException : SystemException {
+ //|
+ public IndexOutOfRangeException()
+ : base("Arg_IndexOutOfRangeException") {
+ }
+
+ //|
+ public IndexOutOfRangeException(String message)
+ : base(message) {
+ }
+
+ //|
+ public IndexOutOfRangeException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Kernel/System/Int16.cs b/base/Applications/Runtime/Full/System/Int16.cs
similarity index 87%
rename from base/Kernel/System/Int16.cs
rename to base/Applications/Runtime/Full/System/Int16.cs
index eb45e48..4fd3e11 100644
--- a/base/Kernel/System/Int16.cs
+++ b/base/Applications/Runtime/Full/System/Int16.cs
@@ -3,19 +3,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Int16.cool
-**
-**
-** Purpose: This class will encapsulate a short and provide an
-** Object representation of it.
-**
-** Date: August 3, 1998
-**
-===========================================================*/
+//============================================================
+//
+// Class: Int16.cool
+//
+// Purpose: This class will encapsulate a short and provide an
+// Object representation of it.
+//
+//===========================================================
-namespace System {
+namespace System
+{
using System;
using System.Globalization;
@@ -74,7 +72,7 @@ namespace System {
//|
public String ToString(String format) {
- if (m_value<0 && format!=null && format.Length>0 && (format[0]=='X' || format[0]=='x')) {
+ if (m_value < 0 && format != null && format.Length > 0 && (format[0] =='X' || format[0] =='x')) {
uint temp = (uint)(m_value & 0x0000FFFF);
return Number.FormatUInt32(temp,format);
}
diff --git a/base/Kernel/System/Int32.cs b/base/Applications/Runtime/Full/System/Int32.cs
similarity index 90%
rename from base/Kernel/System/Int32.cs
rename to base/Applications/Runtime/Full/System/Int32.cs
index 6a5aacd..cfa8a3b 100644
--- a/base/Kernel/System/Int32.cs
+++ b/base/Applications/Runtime/Full/System/Int32.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Int32
-**
-**
-** Purpose: A representation of a 32 bit 2's complement
-** integer.
-**
-** Date: July 23, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: Int32
+//
+// Purpose: A representation of a 32 bit 2's complement
+// integer.
+//
+//===========================================================
+namespace System
+{
using System;
using System.Globalization;
diff --git a/base/Kernel/System/Int64.cs b/base/Applications/Runtime/Full/System/Int64.cs
similarity index 89%
rename from base/Kernel/System/Int64.cs
rename to base/Applications/Runtime/Full/System/Int64.cs
index c10d2aa..ea80aa3 100644
--- a/base/Kernel/System/Int64.cs
+++ b/base/Applications/Runtime/Full/System/Int64.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Int64.cool
-**
-**
-** Purpose: This class will encapsulate a long and provide an
-** Object representation of it.
-**
-** Date: August 3, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: Int64.cool
+//
+// Purpose: This class will encapsulate a long and provide an
+// Object representation of it.
+//
+//===========================================================
+namespace System
+{
using System;
using System.Globalization;
diff --git a/base/Kernel/System/IntPtr.cs b/base/Applications/Runtime/Full/System/IntPtr.cs
similarity index 90%
rename from base/Kernel/System/IntPtr.cs
rename to base/Applications/Runtime/Full/System/IntPtr.cs
index 38df30c..b672c9b 100644
--- a/base/Kernel/System/IntPtr.cs
+++ b/base/Applications/Runtime/Full/System/IntPtr.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: IntPtr
-**
-**
-** Purpose: Platform neutral integer
-**
-** Date: July 21, 2000
-**
-===========================================================*/
+//============================================================
+//
+// Class: IntPtr
+//
+// Purpose: Platform neutral integer
+//
+//===========================================================
-namespace System {
+namespace System
+{
using System;
using System.Globalization;
@@ -74,7 +72,7 @@ namespace System {
[Inline]
public unsafe override String ToString()
{
- if(sizeof(IntPtr) == 4) {
+ if (sizeof(IntPtr) == 4) {
return this.ToInt32().ToString();
}
return this.ToInt64().ToString();
@@ -85,7 +83,7 @@ namespace System {
[Intrinsic]
public extern static unsafe explicit operator void* (IntPtr value);
- [CLSCompliant(false)] //
+ [CLSCompliant(false)]
[Intrinsic]
public extern static explicit operator UIntPtr (IntPtr value);
@@ -132,7 +130,7 @@ namespace System {
[Intrinsic]
public extern static IntPtr operator -- (IntPtr value);
- [CLSCompliant(false)] //
+ [CLSCompliant(false)]
[Intrinsic]
public extern static unsafe sbyte * operator + (sbyte* value1,
IntPtr value2);
diff --git a/base/Applications/Runtime/Full/System/Internal.cs b/base/Applications/Runtime/Full/System/Internal.cs
new file mode 100644
index 0000000..b847bc2
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Internal.cs
@@ -0,0 +1,16 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// This file exists to contain module-level custom attributes
+// for the BCL.
+//
+//===========================================================
+using System.Runtime.InteropServices;
+
+[assembly:Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D")]
+[assembly:System.CLSCompliantAttribute(true)]
+[assembly:System.Reflection.AssemblyDescriptionAttribute("Common Language Runtime Library")]
diff --git a/base/Applications/Runtime/Full/System/InvalidCastException.cs b/base/Applications/Runtime/Full/System/InvalidCastException.cs
new file mode 100644
index 0000000..965da3f
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/InvalidCastException.cs
@@ -0,0 +1,32 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: InvalidCastException
+//
+// Purpose: Exception class for bad cast conditions!
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ public partial class InvalidCastException : SystemException {
+ //|
+ public InvalidCastException(String message)
+ : base(message) {
+ }
+
+ //|
+ public InvalidCastException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/InvalidOperationException.cs b/base/Applications/Runtime/Full/System/InvalidOperationException.cs
new file mode 100644
index 0000000..d00a8b3
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/InvalidOperationException.cs
@@ -0,0 +1,38 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: InvalidOperationException
+//
+// Purpose: Exception class for denoting an object was in a state that
+// made calling a method illegal.
+//
+//=============================================================================
+namespace System
+{
+
+ using System;
+
+ //|
+ public class InvalidOperationException : SystemException
+ {
+ //|
+ public InvalidOperationException()
+ : base("Arg_InvalidOperationException") {
+ }
+
+ //|
+ public InvalidOperationException(String message)
+ : base(message) {
+ }
+
+ //|
+ public InvalidOperationException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
+
diff --git a/base/Kernel/System/Math.cs b/base/Applications/Runtime/Full/System/Math.cs
similarity index 92%
rename from base/Kernel/System/Math.cs
rename to base/Applications/Runtime/Full/System/Math.cs
index 7d9a92c..8afa787 100644
--- a/base/Kernel/System/Math.cs
+++ b/base/Applications/Runtime/Full/System/Math.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Math
-**
-**
-** Purpose: Some floating-point math operations
-**
-** Date: July 8, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: Math
+//
+// Purpose: Some floating-point math operations
+//
+//===========================================================
+namespace System
+{
using System;
using System.Runtime.CompilerServices;
@@ -21,6 +19,7 @@ namespace System {
//|
[CCtorIsRunDuringStartup]
+ [AccessedByRuntime("output to header : defined in Math.cpp")]
public sealed class Math {
// Prevent from begin created
@@ -121,7 +120,7 @@ namespace System {
}
private static double InternalRound(double d, int digits) {
- // rusa: see also Lightning\Src\ClassLibNative\Float\COMFloat.cpp::RoundDigits
+ // See also Lightning\Src\ClassLibNative\Float\COMFloat.cpp::RoundDigits
// Managed code ensures that (digits >= 0 && digits <= 15)
if (Abs(d) < 1E16) {
d *= dblPower10[digits];
@@ -222,9 +221,9 @@ namespace System {
return val;
}
- /*================================Abs=========================================
- **Returns the absolute value of its argument.
- ============================================================================*/
+ //================================Abs=========================================
+ //Returns the absolute value of its argument.
+ //============================================================================
//|
[CLSCompliant(false)]
public static sbyte Abs(sbyte value) {
@@ -339,9 +338,9 @@ namespace System {
return Decimal.Abs(value);
}
- /*================================MAX=========================================
- **Returns the larger of val1 and val2
- ============================================================================*/
+ //================================MAX=========================================
+ //Returns the larger of val1 and val2
+ //============================================================================
//|
[CLSCompliant(false)]
public static sbyte Max(sbyte val1, sbyte val2) {
@@ -413,9 +412,9 @@ namespace System {
return Decimal.Max(val1, val2);
}
- /*================================MIN=========================================
- **Returns the smaller of val1 and val2.
- ============================================================================*/
+ //================================MIN=========================================
+ //Returns the smaller of val1 and val2.
+ //============================================================================
//|
[CLSCompliant(false)]
public static sbyte Min(sbyte val1, sbyte val2) {
@@ -487,9 +486,9 @@ namespace System {
return Decimal.Min(val1, val2);
}
- /*=====================================Log======================================
- **
- ==============================================================================*/
+ //=====================================Log======================================
+ //
+ //==============================================================================
//|
public static double Log(double a, double newBase) {
return (Log(a) / Log(newBase));
diff --git a/base/Applications/Runtime/Full/System/MulticastDelegate.cs b/base/Applications/Runtime/Full/System/MulticastDelegate.cs
new file mode 100644
index 0000000..1714fba
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/MulticastDelegate.cs
@@ -0,0 +1,191 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System
+{
+ using System;
+ using System.Reflection;
+ using System.Runtime.CompilerServices;
+
+ //|
+ public abstract partial class MulticastDelegate : Delegate
+ {
+ internal MulticastDelegate Previous
+ {
+ get{return _prev;}
+ set{_prev = value;}
+ }
+
+ // equals returns true IIF the delegate is not null and has the
+ // same target, method and invocation list as this object
+ //|
+ public override sealed bool Equals(Object obj)
+ {
+ if (!base.Equals(obj))
+ return false;
+ if (_prev != null)
+ return _prev.InvocationListEquals(((MulticastDelegate) obj)._prev);
+ else {
+ // if we got here, "this" is a Multicast with only one listener.
+ if (obj is MulticastDelegate)
+ return ((MulticastDelegate)obj)._prev == null;
+ else if (obj is Delegate)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ // Recursive function which will check for equality of the invocation list.
+ private bool InvocationListEquals(MulticastDelegate d)
+ {
+ if (!base.Equals(d))
+ return false;
+ if (_prev == d._prev)
+ return true;
+ if (_prev == null)
+ return (d._prev == null) ? true : false;
+ return _prev.InvocationListEquals(d._prev);
+ }
+
+ // This method will combine this delegate with the passed delegate
+ // to form a new delegate.
+ //|
+ protected override sealed Delegate CombineImpl(Delegate follow)
+ {
+ // Verify that the types are the same...
+ if (this.GetType() != follow.GetType())
+ throw new ArgumentException("Arg_DlgtTypeMis");
+
+ // We always clone the delegate because this delegate is
+ // not changed by combine and remove. We can safely tack
+ // the follow delegate onto the end of the copy.
+ MulticastDelegate d = (MulticastDelegate) ((MulticastDelegate) follow).MemberwiseClone();
+ MulticastDelegate root = d;
+ while (d._prev != null) {
+ d._prev = (MulticastDelegate) d._prev.MemberwiseClone();
+ d = d._prev;
+ }
+ d._prev = (MulticastDelegate) this;
+ return root;
+ }
+
+ // This method currently looks backward on the invocation list
+ // for an element that has Delegate based equality with value. (Doesn't
+ // look at the invocation list.) If this is found we remove it from
+ // this list and return a new delegate. If its not found a copy of the
+ // current list is returned.
+ //|
+ protected override sealed Delegate RemoveImpl(Delegate value)
+ {
+ // There is a special case were we are removing using a delegate as
+ // the value we need to check for this case
+ //
+ if (!(value is MulticastDelegate)) {
+ if (base.Equals(value))
+ return _prev;
+ return this;
+ }
+
+ // Look for the delegate...
+ MulticastDelegate v = (MulticastDelegate) value;
+ if (InternalEquals(v)) {
+ int size = v.DelSize();
+ MulticastDelegate p = _prev;
+ while (--size != 0)
+ p = p._prev;
+ return p;
+ }
+
+ MulticastDelegate d = (MulticastDelegate) this.MemberwiseClone();
+ MulticastDelegate root = d;
+ while (d._prev != null && d._prev.InternalEquals(v) != true) {
+ d._prev = (MulticastDelegate) d._prev.MemberwiseClone();
+ d = d._prev;
+ }
+
+ if (d._prev != null) {
+ int size = v.DelSize();
+ MulticastDelegate p = d._prev._prev;
+ while (--size != 0)
+ p = p._prev;
+ d._prev = p;
+ }
+ return root;
+ }
+ private int DelSize()
+ {
+ int i=0;
+ MulticastDelegate d = this;
+ while (d != null) {
+ i++;
+ d = d._prev;
+ }
+ return i;
+ }
+
+
+ // Stupid helper function to check equality based upon the super class.
+ private bool InternalEquals(Delegate d)
+ {
+ if (!base.Equals(d))
+ return false;
+ if (((MulticastDelegate) d)._prev != null) {
+ if (_prev == null)
+ return false;
+ return _prev.InternalEquals(((MulticastDelegate) d)._prev);
+ }
+ return true;
+ }
+
+
+ // This method returns the Invocation list of this multicast delegate.
+ //|
+ public override sealed Delegate[] GetInvocationList() {
+ int i = 0;
+ MulticastDelegate p;
+
+ // How big is the invocation list?
+ for (p = this; p != null; p = p._prev)
+ i++;
+
+ // Create an array of delegate copies and each
+ // element into the array (Need to reverse the order and make sure
+ // we set the _prev to null.
+ Delegate[] del = new Delegate[i];
+ for (p = this; p != null; p = p._prev) {
+ del[--i] = (Delegate) p.MemberwiseClone();
+ ((MulticastDelegate) del[i])._prev = null;
+ }
+ return del;
+ }
+
+ // private static bool operator equals(MulticastDelegate d1, MulticastDelegate d2) {
+ // if ((Object)d1 == null)
+ // return (Object)d2 == null;
+ // return d1.Equals(d2);
+ // }
+
+ //|
+ public static bool operator ==(MulticastDelegate d1, MulticastDelegate d2) {
+ if ((Object)d1 == null)
+ return (Object)d2 == null;
+ return d1.Equals(d2);
+ }
+
+ //|
+ public static bool operator !=(MulticastDelegate d1, MulticastDelegate d2) {
+ if ((Object)d1 == null)
+ return (Object)d2 != null;
+ return !d1.Equals(d2);
+ }
+
+ //|
+ public override sealed int GetHashCode() {
+ return base.GetHashCode();
+ }
+
+ }
+}
diff --git a/base/Kernel/System/MulticastNotSupportedException.cs b/base/Applications/Runtime/Full/System/MulticastNotSupportedException.cs
similarity index 95%
rename from base/Kernel/System/MulticastNotSupportedException.cs
rename to base/Applications/Runtime/Full/System/MulticastNotSupportedException.cs
index 1fbd40e..04fb551 100644
--- a/base/Kernel/System/MulticastNotSupportedException.cs
+++ b/base/Applications/Runtime/Full/System/MulticastNotSupportedException.cs
@@ -8,7 +8,8 @@
// This is thrown when you add multiple callbacks to a non-multicast delegate.
////////////////////////////////////////////////////////////////////////////////
-namespace System {
+namespace System
+{
using System;
diff --git a/base/Applications/Runtime/Full/System/NotImplementedException.cs b/base/Applications/Runtime/Full/System/NotImplementedException.cs
new file mode 100644
index 0000000..7bc5090
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/NotImplementedException.cs
@@ -0,0 +1,22 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System
+{
+
+ public class NotImplementedException : SystemException {
+ public NotImplementedException()
+ : base("Not implemented") {
+ }
+
+ public NotImplementedException(String message)
+ : base(message) {
+ }
+
+ public NotImplementedException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/NotSupportedException.cs b/base/Applications/Runtime/Full/System/NotSupportedException.cs
new file mode 100644
index 0000000..e295530
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/NotSupportedException.cs
@@ -0,0 +1,37 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: NotSupportedException
+//
+// Purpose: For methods that should be implemented on subclasses.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+
+ //|
+ public class NotSupportedException : SystemException
+ {
+ //|
+ public NotSupportedException()
+ : base("Arg_NotSupportedException") {
+ }
+
+ //|
+ public NotSupportedException(String message)
+ : base(message) {
+ }
+
+ //|
+ public NotSupportedException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/NullReferenceException.cs b/base/Applications/Runtime/Full/System/NullReferenceException.cs
new file mode 100644
index 0000000..9f9f297
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/NullReferenceException.cs
@@ -0,0 +1,39 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: NullReferenceException
+//
+// Purpose: Exception class for dereferencing a null reference.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ [AccessedByRuntime("referenced from halasm.asm")]
+ public partial class NullReferenceException : SystemException {
+ //|
+ [AccessedByRuntime("referenced from halasm.asm")]
+ public NullReferenceException()
+ : base("Arg_NullReferenceException") {
+ }
+
+ //|
+ public NullReferenceException(String message)
+ : base(message) {
+ }
+
+ //|
+ public NullReferenceException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Kernel/System/Number.cs b/base/Applications/Runtime/Full/System/Number.cs
similarity index 92%
rename from base/Kernel/System/Number.cs
rename to base/Applications/Runtime/Full/System/Number.cs
index c4daef1..44c4cab 100644
--- a/base/Kernel/System/Number.cs
+++ b/base/Applications/Runtime/Full/System/Number.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
using System.Globalization;
@@ -280,6 +281,8 @@ namespace System {
// specified. Note, however, that the Parse methods do not accept
// NaNs or Infinities.
//
+
+ [AccessedByRuntime("functions defined in Number.cpp")]
internal class Number
{
private Number() {
@@ -309,7 +312,8 @@ namespace System {
this.precision = INT32_PRECISION;
if (value >= 0) {
this.negative = false;
- } else {
+ }
+ else {
this.negative = true;
value = -value;
}
@@ -349,7 +353,8 @@ namespace System {
this.precision = INT64_PRECISION;
if (value >= 0) {
this.negative = false;
- } else {
+ }
+ else {
this.negative = true;
value = -value;
}
@@ -399,14 +404,13 @@ namespace System {
return index;
}
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
// wchar* MatchChars(wchar* p, wchar* str)
// will now return -1 instead of NULL on failure
private static int MatchChars(String str1, int p, String str) {
int str_i=0;
if (EndString(str,str_i)) return -1;
- for (; !EndString(str,str_i); p++, str_i++)
- {
+ for (; !EndString(str,str_i); p++, str_i++) {
if (str1[p] != str[str_i]) //We only hurt the failure case
{
if ((str[str_i] == 0xA0) && (str1[p] == 0x20))
@@ -421,7 +425,7 @@ namespace System {
return p;
}
- // REVIEW: (markples) why is this the only thing that is hardcoded
+ // REVIEW: why is this the only thing that is hardcoded
// anywhere in the system?
private bool ISWHITE(char ch) {
return (((ch) == 0x20)||((ch) >= 0x09 && (ch) <= 0x0D));
@@ -460,6 +464,7 @@ namespace System {
};
private static String posNumberFormat = "#";
+ [AccessedByRuntime("defined in Number.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[GCAnnotation(GCOption.NOGC)]
[StackBound(1024)]
@@ -469,7 +474,7 @@ namespace System {
out int decimalpoint,
out bool negative);
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
// void DoubleToNumber(double value, int precision, NUMBER* number)
private Number(double value, int precision) {
this.precision = precision;
@@ -481,7 +486,7 @@ namespace System {
return i1000) {
+ if (exp > 1000) {
exp=9999;
- while(ch>='0' && ch<='9') {
+ while (ch >='0' && ch <='9') {
ch = Get(str, ++p);
}
}
} while (ch >= '0' && ch <= '9');
if (negExp) exp = -exp;
this.scale += exp;
- } else {
+ }
+ else {
p = temp;
ch = Get(str, p);
}
@@ -607,7 +621,8 @@ namespace System {
if (ISWHITE(ch) &&
((style & NumberStyles.AllowTrailingWhite) != 0)) {
// do nothing
- } else if ((signflag =
+ }
+ else if ((signflag =
(((style & NumberStyles.AllowTrailingSign) != 0)
&&
!((state & STATE_SIGN) != 0))) &&
@@ -615,15 +630,18 @@ namespace System {
MatchChars(str, p, NumberFormatInfo.positiveSign)) != -1) {
state |= STATE_SIGN;
p = next - 1;
- } else if (signflag &&
+ }
+ else if (signflag &&
(next = MatchChars(str, p,
NumberFormatInfo.negativeSign)) != -1) {
state |= STATE_SIGN;
this.negative = true;
p = next - 1;
- } else if (ch == ')' && ((state & STATE_PARENS) != 0)) {
+ }
+ else if (ch == ')' && ((state & STATE_PARENS) != 0)) {
state &= ~STATE_PARENS;
- } else {
+ }
+ else {
break;
}
ch = Get(str, ++p);
@@ -646,7 +664,7 @@ namespace System {
}
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
//void StringToNumber(STRINGREF str, int options,
// NUMBER* number, NUMFMTREF numfmt)
private Number(String str, NumberStyles style) {
@@ -668,7 +686,7 @@ namespace System {
}
public static String FormatDecimal(Decimal value, String format) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::FormatDecimal
+ // See also Lightning\Src\VM\COMNumber.cpp::FormatDecimal
if (format == null) {
throw new ArgumentNullException("format");
}
@@ -677,7 +695,7 @@ namespace System {
}
public static String FormatDouble(double value, String format) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::FormatDouble
+ // See also Lightning\Src\VM\COMNumber.cpp::FormatDouble
Number number;
int digits;
@@ -736,7 +754,7 @@ namespace System {
}
public static String FormatInt32(int value, String format) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::FormatInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::FormatInt32
int digits;
char fmt = ParseFormatSpecifier(format, out digits);
switch (fmt) {
@@ -762,13 +780,14 @@ namespace System {
Number number = new Number(value);
if (fmt == 0) {
return number.ToStringFormat(format);
- } else {
+ }
+ else {
return number.ToString(fmt, digits);
}
}
public static String FormatUInt32(uint value, String format) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::FormatUInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::FormatUInt32
int digits;
char fmt = ParseFormatSpecifier(format, out digits);
switch (fmt) {
@@ -794,13 +813,14 @@ namespace System {
Number number = new Number(value);
if (fmt == 0) {
return number.ToStringFormat(format);
- } else {
+ }
+ else {
return number.ToString(fmt, digits);
}
}
public static String FormatInt64(long value, String format) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::FormatInt64
+ // See also Lightning\Src\VM\COMNumber.cpp::FormatInt64
int digits;
char fmt = ParseFormatSpecifier(format, out digits);
switch (fmt) {
@@ -826,13 +846,14 @@ namespace System {
Number number = new Number(value);
if (fmt == 0) {
return number.ToStringFormat(format);
- } else {
+ }
+ else {
return number.ToString(fmt, digits);
}
}
public static String FormatUInt64(ulong value, String format) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::FormatUInt64
+ // See also Lightning\Src\VM\COMNumber.cpp::FormatUInt64
int digits;
char fmt = ParseFormatSpecifier(format, out digits);
switch (fmt) {
@@ -856,13 +877,14 @@ namespace System {
Number number = new Number(value);
if (fmt == 0) {
return number.ToStringFormat(format);
- } else {
+ }
+ else {
return number.ToString(fmt, digits);
}
}
public static String FormatSingle(float value, String format) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::FormatSingle
+ // See also Lightning\Src\VM\COMNumber.cpp::FormatSingle
Number number;
int digits;
@@ -927,7 +949,7 @@ namespace System {
}
public static Decimal ParseDecimal(String s, NumberStyles style) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::ParseDecimal
+ // See also Lightning\Src\VM\COMNumber.cpp::ParseDecimal
Number number = new Number(s, style);
Decimal result;
if (!NumberToDecimal(number, out result)) {
@@ -944,7 +966,7 @@ namespace System {
}
public static int ParseInt32(String s, NumberStyles style) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::ParseInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::ParseInt32
Number number = new Number(s, style);
int result;
if ((style & NumberStyles.AllowHexSpecifier) != 0) {
@@ -953,7 +975,8 @@ namespace System {
throw new OverflowException("Overflow_Int32");
}
result = unchecked((int) temp);
- } else {
+ }
+ else {
if (!NumberToInt32(number, out result)) {
throw new OverflowException("Overflow_Int32");
}
@@ -962,14 +985,15 @@ namespace System {
}
public static uint ParseUInt32(String s, NumberStyles style) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::ParseUInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::ParseUInt32
Number number = new Number(s, style);
uint result;
if ((style & NumberStyles.AllowHexSpecifier) != 0) {
if (!HexNumberToUInt32(number, out result)) {
throw new OverflowException("Overflow_UInt32");
}
- } else {
+ }
+ else {
if (!NumberToUInt32(number, out result)) {
throw new OverflowException("Overflow_UInt32");
}
@@ -978,7 +1002,7 @@ namespace System {
}
public static long ParseInt64(String s, NumberStyles style) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::ParseInt64
+ // See also Lightning\Src\VM\COMNumber.cpp::ParseInt64
Number number = new Number(s, style);
long result;
if ((style & NumberStyles.AllowHexSpecifier) != 0) {
@@ -987,7 +1011,8 @@ namespace System {
throw new OverflowException("Overflow_UInt32");
}
result = unchecked((long) temp);
- } else {
+ }
+ else {
if (!NumberToInt64(number, out result)) {
throw new OverflowException("Overflow_UInt32");
}
@@ -996,14 +1021,15 @@ namespace System {
}
public static ulong ParseUInt64(String s, NumberStyles style) {
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::ParseUInt64
+ // See also Lightning\Src\VM\COMNumber.cpp::ParseUInt64
Number number = new Number(s, style);
ulong result;
if ((style & NumberStyles.AllowHexSpecifier) != 0) {
if (!HexNumberToUInt64(number, out result)) {
throw new OverflowException("Overflow_UInt32");
}
- } else {
+ }
+ else {
if (!NumberToUInt64(number, out result)) {
throw new OverflowException("Overflow_UInt32");
}
@@ -1193,6 +1219,7 @@ namespace System {
throw new Exception("System.Number.NumberToDecimal not implemented in Bartok!");
}
+ [AccessedByRuntime("defined in Number.cpp")]
[MethodImpl(MethodImplOptions.InternalCall)]
[GCAnnotation(GCOption.NOGC)]
[StackBound(1024)]
@@ -1204,10 +1231,11 @@ namespace System {
int index = 0;
char[] src = number.digits;
if (number.negative) buffer[index++] = (byte) '-';
- for (int j=0; j INT32_PRECISION || i < number.precision) goto broken;
char[] c = number.digits;
@@ -1252,7 +1280,8 @@ namespace System {
if (number.negative) {
n = -n;
if (n > 0) goto broken;
- } else {
+ }
+ else {
if (n < 0) goto broken;
}
value = n;
@@ -1264,7 +1293,7 @@ namespace System {
}
private static bool NumberToUInt32(Number number, out uint value) {
- // markples: see also Lightning\Src\VM\COMNumber.cpp::NumberToInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::NumberToInt32
int i = number.scale;
if (i > UINT32_PRECISION || i < number.precision) goto broken;
if (number.negative) goto broken;
@@ -1285,7 +1314,7 @@ namespace System {
}
private static bool NumberToInt64(Number number, out long value) {
- // markples: see also Lightning\Src\VM\COMNumber.cpp::NumberToInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::NumberToInt32
int i = number.scale;
if (i > UINT64_PRECISION || i < number.precision) goto broken;
char[] c = number.digits;
@@ -1299,7 +1328,8 @@ namespace System {
if (number.negative) {
n = -n;
if (n > 0) goto broken;
- } else {
+ }
+ else {
if (n < 0) goto broken;
}
value = n;
@@ -1312,7 +1342,7 @@ namespace System {
private static bool NumberToUInt64(Number number, out ulong value)
{
- // markples: see also Lightning\Src\VM\COMNumber.cpp::NumberToInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::NumberToInt32
int i = number.scale;
if (i > INT64_PRECISION || i < number.precision) goto broken;
if (number.negative) goto broken;
@@ -1334,7 +1364,7 @@ namespace System {
private static bool HexNumberToUInt32(Number number, out uint value)
{
- // markples: see also Lightning\Src\VM\COMNumber.cpp::HexNumberToInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::HexNumberToInt32
int i = number.scale;
if (i > UINT32_PRECISION || i < number.precision) {
goto broken;
@@ -1369,7 +1399,7 @@ namespace System {
}
private static bool HexNumberToUInt64(Number number, out ulong value) {
- // markples: see also Lightning\Src\VM\COMNumber.cpp::HexNumberToInt32
+ // See also Lightning\Src\VM\COMNumber.cpp::HexNumberToInt32
int i = number.scale;
if (i > INT64_PRECISION || i < number.precision) {
goto broken;
@@ -1437,7 +1467,7 @@ namespace System {
return 'G';
}
- // rusa: see also Lightning\Src\VM\COMNumber.cpp::NumberToStringFormat
+ // See also Lightning\Src\VM\COMNumber.cpp::NumberToStringFormat
private String ToStringFormat(String format) {
int thousandCount = 0;
int section = (this.digits[0] == 0 ? 2 : (this.negative ? 1 : 0));
@@ -1536,7 +1566,8 @@ namespace System {
if (thousandPos >= 0) {
if (thousandPos == decimalPos) {
scaleAdjust -= thousandCount * 3;
- } else {
+ }
+ else {
thousandSeps = 1;
}
}
@@ -1553,7 +1584,8 @@ namespace System {
continue;
}
}
- } else {
+ }
+ else {
this.negative = false;
}
break;
@@ -1565,7 +1597,8 @@ namespace System {
if (scientific) {
digPos = decimalPos;
adjust = 0;
- } else {
+ }
+ else {
digPos = (this.scale > decimalPos) ? this.scale : decimalPos;
adjust = this.scale - decimalPos;
}
@@ -1593,7 +1626,8 @@ namespace System {
int groupSizeLen = NumberFormatInfo.numberGroupSizes.Length;
if (groupSizeLen == 0) {
thousandSeps = 0;
- } else {
+ }
+ else {
thousandSepPos = new int[bufferLength];
long groupTotalSizeCount = NumberFormatInfo.numberGroupSizes[0];
int groupSizeIndex = 0;
@@ -1674,7 +1708,8 @@ namespace System {
if (adjust < 0) {
adjust++;
ch = (digPos <= firstDigit) ? '0' : '\0';
- } else {
+ }
+ else {
ch = ((this.digits[digitOffset] != 0) ?
this.digits[digitOffset++] :
((digPos > lastDigit) ? '0' : '\0'));
@@ -1713,7 +1748,7 @@ namespace System {
buffer[dst] = Get(format, src);
dst++;
src++;
- if (dst == bufferLen-1) {
+ if (dst == bufferLen - 1) {
if ((ulong) (bufferLen - dst) < maxStrIncLen) {
bufferLen *= 2;
char[] oldBuffer = buffer;
@@ -1742,13 +1777,16 @@ namespace System {
if (scientific) {
if (Get(format, src) == '0') {
i++;
- } else if (Get(format, src) == '+' &&
+ }
+ else if (Get(format, src) == '+' &&
Get(format, src+1) == '0') {
sign = NumberFormatInfo.positiveSign;
- } else if (Get(format, src) == '-' &&
+ }
+ else if (Get(format, src) == '-' &&
Get(format, src+1) == '0') {
// Do nothing
- } else {
+ }
+ else {
buffer[dst] = ch;
dst++;
break;
@@ -1764,7 +1802,8 @@ namespace System {
(this.scale - decimalPos));
dst = FormatExponent(buffer, dst, exp, ch, sign, NumberFormatInfo.negativeSign, i);
scientific = false;
- } else {
+ }
+ else {
buffer[dst] = ch;
dst++;
if (Get(format, src) == '+' || Get(format, src) == '-') {
@@ -1826,7 +1865,7 @@ namespace System {
}
}
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
// STRINGREF Int32ToDecStr(int value, int digits, STRINGREF sNegative)
private static String Int32ToDecString(int value, int digits, String sign) {
//THROWSCOMPLUSEXCEPTION();
@@ -1901,7 +1940,7 @@ namespace System {
return (uint)((((ulong)x) & 0xFFFFFFFF00000000L) >> 32);
}
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
//STRINGREF Int64ToDecStr(__int64 value, int digits, STRINGREF sNegative)
private static String Int64ToDecString(long value, int digits, String sign) {
//THROWSCOMPLUSEXCEPTION();
@@ -1931,7 +1970,7 @@ namespace System {
}
Int32ToDecChars(buffer, ref p, LO32(unchecked((ulong)value)), digits);
if (signNum < 0) {
- for (int i=sign.Length - 1; i >= 0; i--) {
+ for (int i = sign.Length - 1; i >= 0; i--) {
buffer[--p] = sign[i];
}
}
@@ -1976,7 +2015,7 @@ namespace System {
return String.StringCTOR(buffer, p, bufferLength-p);
}
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
// wchar* Int32ToDecChars(wchar* p, unsigned int value, int digits)
// There's a x86 asm version there too.
private static void Int32ToDecChars(char[] buffer, ref int bufferIndex,
@@ -1995,7 +2034,7 @@ namespace System {
}
}
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
// void RoundNumber(NUMBER* number, int pos)
private void RoundNumber(int pos) {
int i = 0;
@@ -2004,12 +2043,14 @@ namespace System {
while (i > 0 && this.digits[i - 1] == '9') i--;
if (i > 0) {
this.digits[i - 1]++;
- } else {
+ }
+ else {
this.scale++;
this.digits[0] = '1';
i = 1;
}
- } else {
+ }
+ else {
while (i > 0 && this.digits[i - 1] == '0') i--;
}
if (i == 0) {
@@ -2030,7 +2071,8 @@ namespace System {
if (value < 0) {
bufferIndex = AddStringRef(buffer, bufferIndex, negSignStr);
value = -value;
- } else {
+ }
+ else {
if (posSignStr != null) {
bufferIndex = AddStringRef(buffer, bufferIndex, posSignStr);
}
@@ -2110,8 +2152,8 @@ namespace System {
// REVIEW: call the real wcslen?
private static int wcslen(char[] c, int i) {
int j;
- for(j=i; j=0; i--) {
+ for (int i = digPos - 1; i >= 0; i--) {
buffer[p--] = (i 0) {
digitCount++;
if (digitCount == groupSize && i != 0) {
- for (int j = groupSeparatorLen - 1; j >=0; j--) {
+ for (int j = groupSeparatorLen - 1; j >= 0; j--) {
buffer[p--] = sGroup[j];
}
@@ -2199,7 +2241,8 @@ namespace System {
}
bufferIndex += bufferSize;
dig += digStart;
- } else {
+ }
+ else {
do {
buffer[bufferIndex++] =
this.digits[dig] != 0 ? this.digits[dig++] : '0';
@@ -2311,7 +2354,7 @@ namespace System {
return result;
}
- // markples: see also Lightning\Src\VM\COMNumber.cpp::
+ // See also Lightning\Src\VM\COMNumber.cpp::
// unsigned int Int64DivMod1E9(unsigned __int64* value)
// There's a x86 asm version there too.
// The interface is different because Bartok does not support
diff --git a/base/Applications/Runtime/Full/System/Object.cs b/base/Applications/Runtime/Full/System/Object.cs
new file mode 100644
index 0000000..42cd2a5
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Object.cs
@@ -0,0 +1,301 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: Object
+//
+// Object is the root class for all CLR objects. This class
+// defines only the basics.
+//
+//===========================================================
+
+namespace System
+{
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+ using CultureInfo = System.Globalization.CultureInfo;
+ using System.Threading;
+
+ using Microsoft.Bartok.Runtime;
+
+ // The Object is the root class for all object in the CLR System. Object
+ // is the super class for all other CLR objects and provide a set of methods and low level
+ // services to subclasses. These services include object synchronization and support for clone
+ // operations.
+ //
+ //|
+ [AccessedByRuntime("Accessed from halexn.cpp")]
+ public partial class Object
+ {
+ internal PreHeader preHeader;
+ [AccessedByRuntime("Accessed from halexn.cpp")]
+ internal PostHeader postHeader;
+
+ // Allow us to pretend that the vtable field lives directly in Object.
+ internal extern VTable vtable {
+ [NoHeapAllocation]
+ [Inline]
+ get;
+ [NoHeapAllocation]
+ [Inline]
+ set;
+ }
+
+ internal unsafe extern UIntPtr* VTableFieldAddr {
+ [NoHeapAllocation]
+ get;
+ }
+
+#if REFERENCE_COUNTING_GC
+ internal uint REF_STATE {
+ [Inline]
+ [ManualRefCounts]
+ [NoHeapAllocation]
+ get {
+ return this.postHeader.refState;
+ }
+ [Inline]
+ [ManualRefCounts]
+ [NoHeapAllocation]
+ set {
+ this.postHeader.refState = value;
+ }
+ }
+#else // REFERENCE_COUNTING_GC
+ internal uint REF_STATE {
+ [NoHeapAllocation]
+ [Inline]
+ get {
+ return 1;
+ }
+ [NoHeapAllocation]
+ [Inline]
+ set {
+ }
+ }
+#endif
+
+ // Creates a new instance of an Object.
+ //|
+ [Inline]
+ public Object()
+ {
+ }
+
+ // Returns a String which represents the object instance. The default
+ // for an object is to return the fully qualified name of the class.
+ //
+ //|
+ public virtual String ToString()
+ {
+ return GetType().FullName;
+ }
+
+ //|
+ public static bool Equals(Object objA, Object objB) {
+ if (objA == objB) {
+ return true;
+ }
+ if (objA == null || objB == null) {
+ return false;
+ }
+ return objA.Equals(objB);
+ }
+
+ //|
+ public static bool ReferenceEquals (Object objA, Object objB) {
+ return objA == objB;
+ }
+
+ // GetHashCode is intended to serve as a hash function for this object.
+ // Based on the contents of the object, the hash function will return a suitable
+ // value with a relatively random distribution over the various inputs.
+ //
+ // The default implementation returns the sync block index for this instance.
+ // Calling it on the same object multiple times will return the same value, so
+ // it will technically meet the needs of a hash function, but it's pretty lame.
+ // Objects (& especially value classes) should override this method.
+ //
+ //|
+ public virtual int GetHashCode()
+ {
+ return MultiUseWord.GetHashCode(this);
+ }
+
+ ///
+ /// Test and set the state of the GC mark bit to be the same
+ /// as the passed flag. Note that this operation is not
+ /// synchronized so it is possible for multiple marking threads
+ /// to 'mark' the same object.
+ ///
+ [NoHeapAllocation]
+ internal unsafe bool GcMark(UIntPtr flag) {
+ UIntPtr *loc = this.VTableFieldAddr;
+ UIntPtr val = *loc;
+ VTable.Deny(val == UIntPtr.Zero);
+
+ if ((val & (UIntPtr)3) != flag) {
+ *loc = (val & ~(UIntPtr)3) + flag;
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Return the current state of the GC mark bit.
+ ///
+ [NoHeapAllocation]
+ internal unsafe UIntPtr GcMark() {
+ UIntPtr *loc = this.VTableFieldAddr;
+ UIntPtr val = *loc;
+ return (val & 3);
+ }
+
+ internal unsafe VTable GcUnmarkedVTable {
+ [Inline]
+ [NoHeapAllocation]
+ get {
+ UIntPtr *loc = this.VTableFieldAddr;
+ return Magic.toVTable(Magic.fromAddress(~(UIntPtr)3 & *loc));
+ }
+ }
+
+ // Returns a Type object which represent this object instance.
+ //
+ //|
+ [NoHeapAllocation]
+ public Type GetType()
+ {
+ return vtable.vtableType;
+ }
+
+ [NoHeapAllocation]
+ public virtual TypeCode GetTypeCode()
+ {
+ return TypeCode.Object;
+ }
+
+ // Returns a new object instance that is a memberwise copy of this
+ // object. This is always a shallow copy of the instance. The method is protected
+ // so that other object may only call this method on themselves. It is intended to
+ // support the ICloneable interface.
+ //
+ //|
+ // BUGBUG: maybe we can try harder to mess up the GC?
+ protected Object MemberwiseClone()
+ {
+ if (this is String) {
+ return this;
+ // REVIEW: ok, but what in the world is the CLR doing?
+ }
+ Thread thread = Thread.CurrentThread;
+ if (this is Array) {
+ Array srcArray = (Array) this;
+ Array cloneArray;
+ int srcLength = srcArray.Length;
+ if (srcArray.IsVector) {
+ cloneArray = GC.AllocateVector(srcArray.vtable, srcLength);
+ CloneVectorContents(srcArray, cloneArray);
+ }
+ else {
+ int rank = srcArray.Rank;
+ cloneArray =
+ GC.AllocateArray(srcArray.vtable, rank, srcLength);
+ CloneArrayContents(srcArray, cloneArray);
+ }
+ return cloneArray;
+ }
+ else {
+ Object clone = GC.AllocateObject(this.vtable);
+ CloneObjectContents(this, clone);
+ return clone;
+ }
+ }
+
+#if !REFERENCE_COUNTING_GC && !DEFERRED_REFERENCE_COUNTING_GC
+
+ private unsafe static void CloneObjectContents(Object src, Object dst)
+ {
+ System.GCs.Barrier.Clone(src, dst);
+ }
+
+ private unsafe static void CloneVectorContents(Array srcArray,
+ Array dstArray)
+ {
+ System.GCs.Barrier.Clone(srcArray, dstArray);
+ }
+
+ private unsafe static void CloneArrayContents(Array srcArray,
+ Array dstArray)
+ {
+ System.GCs.Barrier.Clone(srcArray, dstArray);
+ }
+
+#else
+
+ private unsafe static void CloneObjectContents(Object src, Object dst)
+ {
+ byte * dstNOTFIXED = (byte *)(Magic.addressOf(dst) + PostHeader.Size);
+ byte * srcNOTFIXED = (byte *)(Magic.addressOf(src) + PostHeader.Size);
+ int size = unchecked((int) src.vtable.baseLength);
+ // We don't copy the header fields, the vtable or the RS field!
+ size -= (PreHeader.Size + PostHeader.Size);
+#if REFERENCE_COUNTING_GC
+ GCs.ReferenceCountingCollector.
+ IncrementReferentRefCounts(Magic.addressOf(src), src.vtable);
+ GCs.ReferenceCountingCollector.
+ DecrementReferentRefCounts(Magic.addressOf(dst), dst.vtable);
+#elif DEFERRED_REFERENCE_COUNTING_GC
+ GCs.DeferredReferenceCountingCollector.
+ IncrementReferentRefCounts(Magic.addressOf(src), src.vtable);
+ GCs.DeferredReferenceCountingCollector.
+ DecrementReferentRefCounts(Magic.addressOf(dst), dst.vtable);
+#endif // REFERENCE_COUNTING_GC
+ Buffer.MoveMemory(dstNOTFIXED,srcNOTFIXED,size);
+ }
+
+ private unsafe static void CloneVectorContents(Array srcArray,
+ Array dstArray)
+ {
+ int srcLength = srcArray.Length;
+ fixed (int *srcFieldPtr = &srcArray.field1) {
+ fixed (int *dstFieldPtr = &dstArray.field1) {
+ byte *srcDataPtr = (byte *)
+ srcArray.GetFirstElementAddress(srcFieldPtr);
+ byte *dstDataPtr = (byte *)
+ dstArray.GetFirstElementAddress(dstFieldPtr);
+ int size = srcArray.vtable.arrayElementSize * srcLength;
+ Buffer.MoveMemory(dstDataPtr, srcDataPtr, size);
+ }
+ }
+ }
+
+ private unsafe static void CloneArrayContents(Array srcArray,
+ Array dstArray)
+ {
+ int srcLength = srcArray.Length;
+ fixed (int *srcFieldPtr = &srcArray.field1) {
+ fixed (int *dstFieldPtr = &dstArray.field1) {
+ byte *srcDataPtr = (byte *)
+ srcArray.GetFirstElementAddress(srcFieldPtr);
+ byte *dstDataPtr = (byte *)
+ dstArray.GetFirstElementAddress(dstFieldPtr);
+ byte *srcDimPtr = (byte *)
+ srcArray.GetFirstDimInfoRectangleArray();
+ int dimInfoSize = (int) (srcDataPtr - srcDimPtr);
+ int size = srcArray.vtable.arrayElementSize * srcLength;
+ Buffer.MoveMemory(dstDataPtr - dimInfoSize,
+ srcDataPtr - dimInfoSize,
+ size + dimInfoSize);
+ }
+ }
+ }
+
+#endif
+
+ }
+}
diff --git a/base/Kernel/System/ObjectDisposedException.cs b/base/Applications/Runtime/Full/System/ObjectDisposedException.cs
similarity index 96%
rename from base/Kernel/System/ObjectDisposedException.cs
rename to base/Applications/Runtime/Full/System/ObjectDisposedException.cs
index a6663fd..9cd676b 100644
--- a/base/Kernel/System/ObjectDisposedException.cs
+++ b/base/Applications/Runtime/Full/System/ObjectDisposedException.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
//|
diff --git a/base/Kernel/System/ObsoleteAttribute.cs b/base/Applications/Runtime/Full/System/ObsoleteAttribute.cs
similarity index 85%
rename from base/Kernel/System/ObsoleteAttribute.cs
rename to base/Applications/Runtime/Full/System/ObsoleteAttribute.cs
index f53a3fb..e0ab64e 100644
--- a/base/Kernel/System/ObsoleteAttribute.cs
+++ b/base/Applications/Runtime/Full/System/ObsoleteAttribute.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: ObsoleteAttribute
-**
-**
-** Purpose: Attribute for functions, etc that will be removed.
-**
-** Date: September 22, 1999
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: ObsoleteAttribute
+//
+// Purpose: Attribute for functions, etc that will be removed.
+//
+//===========================================================
+namespace System
+{
using System;
// This attribute is attached to members that are not to be used any longer.
diff --git a/base/Applications/Runtime/Full/System/OutOfMemoryException.cs b/base/Applications/Runtime/Full/System/OutOfMemoryException.cs
new file mode 100644
index 0000000..a82cdc6
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/OutOfMemoryException.cs
@@ -0,0 +1,37 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: OutOfMemoryException
+//
+// Purpose: The exception class for OOM.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ public class OutOfMemoryException : SystemException {
+ //|
+ public OutOfMemoryException()
+ : base("Arg_OutOfMemoryException") {
+ }
+
+ //|
+ public OutOfMemoryException(String message)
+ : base(message) {
+ }
+
+ //|
+ public OutOfMemoryException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/OverflowException.cs b/base/Applications/Runtime/Full/System/OverflowException.cs
new file mode 100644
index 0000000..f7729fe
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/OverflowException.cs
@@ -0,0 +1,39 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: OverflowException
+//
+// Purpose: Exception class for Arithmetic Overflows.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ [AccessedByRuntime("referenced from halasm.asm")]
+ public partial class OverflowException : ArithmeticException {
+ //|
+ [AccessedByRuntime("referenced from halasm.asm")]
+ public OverflowException()
+ : base("Arg_OverflowException") {
+ }
+
+ //|
+ public OverflowException(String message)
+ : base(message) {
+ }
+
+ //|
+ public OverflowException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/ParamArrayAttribute.cs b/base/Applications/Runtime/Full/System/ParamArrayAttribute.cs
new file mode 100644
index 0000000..948ba97
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/ParamArrayAttribute.cs
@@ -0,0 +1,22 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: ParamArrayAttribute
+//
+// Purpose: Container for assemblies.
+//
+//=============================================================================
+namespace System
+{
+ //|
+ [AttributeUsage (AttributeTargets.Parameter, Inherited=true, AllowMultiple=false)]
+ public sealed class ParamArrayAttribute : Attribute
+ {
+ //|
+ public ParamArrayAttribute () {}
+ }
+}
diff --git a/base/Kernel/System/ParseNumbers.cs b/base/Applications/Runtime/Full/System/ParseNumbers.cs
similarity index 78%
rename from base/Kernel/System/ParseNumbers.cs
rename to base/Applications/Runtime/Full/System/ParseNumbers.cs
index 3790732..f4afa6a 100644
--- a/base/Kernel/System/ParseNumbers.cs
+++ b/base/Applications/Runtime/Full/System/ParseNumbers.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: ParseNumbers
-**
-**
-** Purpose: Methods for Parsing numbers and Strings.
-** All methods are implemented in native.
-**
-** Date: April 7, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: ParseNumbers
+//
+// Purpose: Methods for Parsing numbers and Strings.
+// All methods are implemented in native.
+//
+//===========================================================
+namespace System
+{
using System;
using System.Runtime.CompilerServices;
@@ -60,7 +58,7 @@ namespace System {
internal const int MaxRadix=36;
static private int EatWhiteSpace(String buffer, int length, int i) {
- for (; i maxVal || ((int)result)<0) {
+ if (result > maxVal || ((int)result) < 0) {
throw new OverflowException("Overflow_Int32");
}
result = result * radix + value;
i++;
}
- if ((int)result<0 && result!=0x80000000) {
+ if ((int)result < 0 && result != 0x80000000) {
throw new OverflowException("Overflow_Int32");
}
- } else {
+ }
+ else {
maxVal = UInt32.MaxValue / radix;
while (i < length && IsDigit(buffer[i], radix, out value)) {
// Read all of the digits and convert to a number
@@ -124,7 +123,8 @@ namespace System {
if ((long) result < 0 && result != 0x8000000000000000) {
throw new OverflowException("Overflow_Int64");
}
- } else {
+ }
+ else {
maxVal = unchecked((ulong) -1L) / radix;
while (i < length && IsDigit(buffer[i], radix, out value)) {
// Read all of the digits and convert to a number
@@ -140,14 +140,16 @@ namespace System {
}
static bool IsDigit(char c, uint radix, out uint result) {
- if (c>='0' && c<='9') {
+ if (c >='0' && c <='9') {
result = (uint) (c-'0');
- } else {
+ }
+ else {
char d = Char.ToLower(c);
- if (d>='a' && d<='z') {
+ if (d >='a' && d <='z') {
//+10 is necessary because a is actually 10, etc.
result = (uint) (d-'a'+10);
- } else {
+ }
+ else {
result = 0;
return false;
}
@@ -166,24 +168,24 @@ namespace System {
//A radix of -1 says to use whatever base is spec'd on the number.
//Parse in Base10 until we figure out what the base actually is.
uint r = (-1==radix)?10U:(uint)radix;
- if (r!=2 && r!=10 && r!=8 && r!=16) {
+ if (r != 2 && r != 10 && r != 8 && r != 16) {
throw new ArgumentException("Arg_InvalidBase");
}
int length = s.Length;
- if (i <0 || i>=length) {
+ if (i < 0 || i >= length) {
throw new ArgumentOutOfRangeException("startIndex(currPos[0])");
}
// Get rid of the whitespace and then check that we've still got
// some digits to parse.
if ((flags & IsTight) != 0) {
i = EatWhiteSpace(s,length,i);
- if (i==length) {
+ if (i == length) {
throw new FormatException("Format_EmptyInputString");
}
}
int sign = 1;
bool isUnsigned = ((flags & TreatAsUnsigned) != 0);
- if (s[i]=='-') { // Check for a sign
+ if (s[i] =='-') { // Check for a sign
if (r != 10) {
throw new ArgumentException("ArgCannotHaveNegativeValue");
}
@@ -192,25 +194,26 @@ namespace System {
}
sign = -1;
i++;
- } else if (s[i]=='+') {
+ }
+ else if (s[i] =='+') {
i++;
}
//Consume the 0x if we're in an unknown base or in base 16.
- if ((radix==-1||radix==16) && (i+1= 0x80){
+ if (result >= 0x80) {
sign = -1;
}
- } else if ((flags & TreatAsI2) != 0) {
+ }
+ else if ((flags & TreatAsI2) != 0) {
if (result > 0xFFFF) {
throw new OverflowException("Overflow_Int16");
}
@@ -233,12 +237,14 @@ namespace System {
if (result >= 0x8000) {
sign = -1;
}
- } else if (result == 0x80000000 && sign==1 && r==10) {
+ }
+ else if (result == 0x80000000 && sign == 1 && r == 10) {
throw new OverflowException("Overflow_Int32");
}
if (r == 10) {
return unchecked((int)result) * sign;
- } else {
+ }
+ else {
return unchecked((int) result);
}
}
@@ -252,7 +258,7 @@ namespace System {
//A radix of -1 says to use whatever base is spec'd on the number.
//Parse in Base10 until we figure out what the base actually is.
uint r = (-1==radix)?10U:(uint)radix;
- if (r!=2 && r!=10 && r!=8 && r!=16) {
+ if (r != 2 && r != 10 && r != 8 && r != 16) {
throw new ArgumentException("Arg_InvalidBase");
}
int length = s.Length;
@@ -278,12 +284,13 @@ namespace System {
}
sign = -1;
i++;
- } else if (s[i] == '+') {
+ }
+ else if (s[i] == '+') {
i++;
}
//Consume the 0x if we're in an unknown base or in base 16.
- if ((radix==-1||radix==16) && (i+1MaxRadix) {
+ if (radix < MinRadix || radix > MaxRadix) {
throw new ArgumentException("Argument_InvalidBase");
//COMPlusThrowArgumentException(L"radix", L"Arg_InvalidBase");
}
@@ -387,15 +396,16 @@ namespace System {
//If the number is negative, make it positive and remember the sign.
//If the number is MIN_VALUE, this will still be negative,
//so we'll have to special case this later.
- if (n<0) {
+ if (n < 0) {
isNegative=true;
// For base 10, write out -num, but other bases write out the
// 2's complement bit pattern
- if (10==radix)
+ if (10 == radix)
l = (uint)(-n);
else
- l = (uint)n; // REVIEW: markples: comment suggests ~n wanted
- } else {
+ l = (uint)n; // REVIEW: comment suggests ~n wanted
+ }
+ else {
l=(uint)n;
}
@@ -404,62 +414,71 @@ namespace System {
//number.
if ((flags & PrintAsI1) != 0) {
l = l&0xFF;
- } else if ((flags & PrintAsI2) != 0) {
+ }
+ else if ((flags & PrintAsI2) != 0) {
l = l&0xFFFF;
- } else if ((flags & PrintAsI4) != 0) {
+ }
+ else if ((flags & PrintAsI4) != 0) {
l=l&0xFFFFFFFF;
}
- if (0==l) { //Special case the 0.
+ if (0 == l) { //Special case the 0.
buffer[--index]='0';
- } else {
+ }
+ else {
do {
charVal = (int) (l%(uint)radix);
l=l/(uint)radix;
- if (charVal<10) {
+ if (charVal < 10) {
buffer[--index] = (char)(charVal + '0');
- } else {
+ }
+ else {
buffer[--index] = (char)(charVal + 'a' - 10);
}
- } while (l!=0);
+ } while (l != 0);
}
//If they want the base, append that to the string (in reverse order)
- if (radix!=10 && ((flags & PrintBase)!=0)) {
- if (16==radix) {
+ if (radix != 10 && ((flags & PrintBase) != 0)) {
+ if (16 == radix) {
buffer[--index]='x';
buffer[--index]='0';
- } else if (8==radix) {
+ }
+ else if (8 == radix) {
buffer[--index]='0';
}
}
- if (10==radix) {
+ if (10 == radix) {
if (isNegative) {
//If it was negative, append the sign.
buffer[--index]='-';
- } else if ((flags&PrintSign)!=0) {
+ }
+ else if ((flags & PrintSign) != 0) {
//else if they requested, add the '+';
buffer[--index]='+';
- } else if ((flags&PrefixSpace)!=0) {
+ }
+ else if ((flags & PrefixSpace) != 0) {
//If they requested a leading space, put it on.
buffer[--index]=' ';
}
}
//Figure out the size of our string.
- if (width<=bufSize-index) {
+ if (width <= bufSize - index) {
buffLength=bufSize-index;
- } else {
+ }
+ else {
buffLength=width;
}
String local = String.StringCTOR(buffer, index, bufSize-index);
- //markples: Pad if necessary, open up access to String if you
+ // Pad if necessary, open up access to String if you
//don't want to make a new string here
- if ((flags&LeftAlign)!=0) {
+ if ((flags & LeftAlign) != 0) {
local = local.PadRight(buffLength,paddingChar);
- } else {
+ }
+ else {
local = local.PadLeft(buffLength,paddingChar);
}
@@ -470,7 +489,7 @@ namespace System {
// INT64 n, WCHAR paddingChar, INT32 flags)
public static String LongToString(long n, int radix, int width,
char paddingChar, int flags) {
- // rusa: see also Lightning\Src\VM\COMUtilNative.cpp::LongToString,
+ // See also Lightning\Src\VM\COMUtilNative.cpp::LongToString,
bool isNegative = false;
int charVal;
ulong l;
@@ -482,88 +501,99 @@ namespace System {
char[] buffer = new char[67];
int index=bufSize;
- if (radixMaxRadix) {
+ if (radix < MinRadix || radix > MaxRadix) {
throw new ArgumentException("Argument_InvalidBase");
//COMPlusThrowArgumentException(L"radix", L"Arg_InvalidBase");
}
//If the number is negative, make it positive and remember the sign.
- if (n<0) {
+ if (n < 0) {
isNegative=true;
// For base 10, write out -num, but other bases write out the
// 2's complement bit pattern
- if (10==radix)
+ if (10 == radix)
l = (ulong)(-n);
else
- l = (ulong)n; // REVIEW: markples: comment suggests ~n wanted
- } else {
+ l = (ulong)n; // REVIEW: comment suggests ~n wanted
+ }
+ else {
l=(ulong)n;
}
if ((flags & PrintAsI1) != 0) {
l = l&0xFF;
- } else if ((flags&PrintAsI2) != 0) {
+ }
+ else if ((flags & PrintAsI2) != 0) {
l = l&0xFFFF;
- } else if ((flags&PrintAsI4) != 0) {
+ }
+ else if ((flags & PrintAsI4) != 0) {
l=l&0xFFFFFFFF;
}
//Special case the 0.
- if (0==l) {
+ if (0 == l) {
buffer[--index]='0';
- } else {
+ }
+ else {
//Pull apart the number and put the digits (in
//reverse order) into the buffer.
- for ( ; l>0; l=l/(ulong)radix) {
- if ((charVal=(int)(l%(ulong)radix))<10) {
+ for (; l > 0; l = l/(ulong)radix) {
+ if ((charVal =(int)(l%(ulong)radix)) < 10) {
buffer[--index] = (char)(charVal + '0');
- } else {
+ }
+ else {
buffer[--index] = (char)(charVal + 'a' - 10);
}
}
}
//If they want the base, append that to the string (in reverse order)
- if (radix!=10 && ((flags&PrintBase)!=0)) {
- if (16==radix) {
+ if (radix != 10 && ((flags & PrintBase) != 0)) {
+ if (16 == radix) {
buffer[--index]='x';
buffer[--index]='0';
- } else if (8==radix) {
+ }
+ else if (8 == radix) {
buffer[--index]='0';
- } else if ((flags&PrintRadixBase)!=0) {
+ }
+ else if ((flags & PrintRadixBase) != 0) {
buffer[--index]='#';
buffer[--index]=(char)((radix%10)+'0');
buffer[--index]=(char)((radix/10)+'0');
}
}
- if (10==radix) {
+ if (10 == radix) {
if (isNegative) {
//If it was negative, append the sign.
buffer[--index]='-';
- } else if ((flags&PrintSign)!=0) {
+ }
+ else if ((flags & PrintSign) != 0) {
//else if they requested, add the '+';
buffer[--index]='+';
- } else if ((flags&PrefixSpace)!=0) {
+ }
+ else if ((flags & PrefixSpace) != 0) {
//If they requested a leading space, put it on.
buffer[--index]=' ';
}
}
//Figure out the size of our string.
- if (width<=bufSize-index) {
+ if (width <= bufSize - index) {
buffLength=bufSize-index;
- } else {
+ }
+ else {
buffLength=width;
}
String local = String.StringCTOR(buffer, index, bufSize-index);
- //markples: Pad if necessary, open up access to String if you
+ //Pad if necessary, open up access to String if you
//don't want to make a new string here
- if ((flags&LeftAlign)!=0) {
+ if ((flags & LeftAlign) != 0) {
local = local.PadRight(buffLength,paddingChar);
- } else {
+ }
+ else {
local = local.PadLeft(buffLength,paddingChar);
}
diff --git a/base/Applications/Runtime/System/Principal.sg b/base/Applications/Runtime/Full/System/Principal.sg
similarity index 82%
rename from base/Applications/Runtime/System/Principal.sg
rename to base/Applications/Runtime/Full/System/Principal.sg
index 5337411..f80cf6c 100644
--- a/base/Applications/Runtime/System/Principal.sg
+++ b/base/Applications/Runtime/Full/System/Principal.sg
@@ -1,7 +1,8 @@
-///////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
+// ----------------------------------------------------------------------------
namespace Microsoft.Singularity.Security
{
@@ -46,6 +47,11 @@ namespace Microsoft.Singularity.Security
return new Principal(ep->PeerPrincipalHandle);
}
+ public static Principal EndpointOwner(Endpoint*! in ExHeap ep)
+ {
+ return new Principal(ep->OwnerPrincipalHandle);
+ }
+
public static string ExpandAclIndirection (string! name)
{
return PrincipalHandle.ExpandAclIndirection(name);
diff --git a/base/Applications/Runtime/System/Process.sg b/base/Applications/Runtime/Full/System/Process.sg
similarity index 94%
rename from base/Applications/Runtime/System/Process.sg
rename to base/Applications/Runtime/Full/System/Process.sg
index ceab039..cef543c 100644
--- a/base/Applications/Runtime/System/Process.sg
+++ b/base/Applications/Runtime/Full/System/Process.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Process.sg
-//
// Note:
//
@@ -86,7 +84,7 @@ namespace System
null,
out count,
out totalCharCount);
- //Review for now NotSet is ignored and we return a string[1] below
+ // REVIEW: for now NotSet is ignored and we return a string[1] below
if (code != ParameterCode.Success && code != ParameterCode.NotSet) {
arguments = new string[0];
return code;
@@ -128,8 +126,8 @@ namespace System
value = null;
return code;
}
- if ( len == 0 ) {
- // should this be "" or null?
+ if (len == 0) {
+ // REVIEW: should this be "" or null?
value = null;
return ParameterCode.Success;
}
@@ -198,7 +196,7 @@ namespace System
// need to copy until the kernel and system are compiled
// with the same compiler
char[] c = new char[value.Length];
- for (int i=0; i < value.Length; i++){
+ for (int i = 0; i < value.Length; i++) {
c[i] = value[i];
}
fixed ( char *argptr = &c[0] ) {
@@ -306,6 +304,8 @@ namespace System
String action,
String role)
{
+ if (cmd.Length == 0)
+ throw new ArgumentException("The 'cmd' argument is required, and cannot be null or empty.", "cmd");
char[]! cmdVector;
char[]! actionVector;
@@ -321,7 +321,7 @@ namespace System
cmd.CopyTo(0, cmdVector, 0, cmdLength);
// package the action parameter(if present)
- if (action != null) {
+ if (action != null && action.Length != 0) {
actionLength = action.Length;
actionVector = new char[actionLength];
action.CopyTo(0, actionVector, 0, actionLength);
@@ -332,7 +332,7 @@ namespace System
}
// package the role parameters (if present)
- if (role != null) {
+ if (role != null && role.Length != 0) {
roleLength = role.Length;
roleVector = new char[roleLength];
role.CopyTo(0, roleVector, 0, roleLength);
@@ -396,7 +396,7 @@ namespace System
public unsafe Process(String[]! arguments,
String role,
[Claims] Endpoint* in ExHeap endpoint)
- : this((!)arguments[0], null, null)
+ : this((!)arguments[0], null, role)
{
ProcessHandle.SetStartupEndpoint(handle, 0,
(SharedHeapService.Allocation *)endpoint);
@@ -413,8 +413,8 @@ namespace System
[Microsoft.Contracts.NotDelayed]
public unsafe Process(String[]! arguments,
- String roll)
- : this(arguments, roll, 0)
+ String role)
+ : this(arguments, role, 0)
{
}
@@ -557,8 +557,7 @@ namespace System
{
get
{
- if (handle.id == 0)
- {
+ if (handle.id == 0) {
throw new ProcessStateException("disposed");
}
Principal p =
diff --git a/base/Applications/Runtime/System/ProcessCreateException.cs b/base/Applications/Runtime/Full/System/ProcessCreateException.cs
similarity index 100%
rename from base/Applications/Runtime/System/ProcessCreateException.cs
rename to base/Applications/Runtime/Full/System/ProcessCreateException.cs
diff --git a/base/Kernel/System/ProcessExitCode.cs b/base/Applications/Runtime/Full/System/ProcessExitCode.cs
similarity index 100%
rename from base/Kernel/System/ProcessExitCode.cs
rename to base/Applications/Runtime/Full/System/ProcessExitCode.cs
diff --git a/base/Kernel/System/ProcessStateException.cs b/base/Applications/Runtime/Full/System/ProcessStateException.cs
similarity index 100%
rename from base/Kernel/System/ProcessStateException.cs
rename to base/Applications/Runtime/Full/System/ProcessStateException.cs
diff --git a/base/Applications/Runtime/Full/System/Random.cs b/base/Applications/Runtime/Full/System/Random.cs
new file mode 100644
index 0000000..a1fd677
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Random.cs
@@ -0,0 +1,194 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: Random.cool
+//
+// Purpose: A random number generator.
+//
+//===========================================================
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+ //|
+
+ public class Random {
+ //
+ // Private Constants
+ //
+ private const int MBIG = Int32.MaxValue;
+ private const int MSEED = 161803398;
+ private const int MZ = 0;
+
+
+ //
+ // Member Variables
+ //
+ private int inext, inextp;
+ private int[] SeedArray = new int[56];
+
+ //
+ // Public Constants
+ //
+
+ //
+ // Native Declarations
+ //
+
+ //
+ // Constructors
+ //
+
+ //|
+ public Random()
+ : this(Environment.TickCount) {
+ }
+
+ //|
+ public Random(int Seed) {
+ int ii;
+ int mj, mk;
+
+ //Initialize our Seed array.
+ //This algorithm comes from Numerical Recipes in C (2nd Ed.)
+ mj = MSEED - Math.Abs(Seed);
+ SeedArray[55]=mj;
+ mk=1;
+ for (int i = 1; i < 55; i++) { //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position.
+ ii = (21*i)%55;
+ SeedArray[ii]=mk;
+ mk = mj - mk;
+ if (mk < 0) mk += MBIG;
+ mj=SeedArray[ii];
+ }
+ for (int k = 1; k < 5; k++) {
+ for (int i = 1; i < 56; i++) {
+ SeedArray[i] -= SeedArray[1+(i+30)%55];
+ if (SeedArray[i] < 0) SeedArray[i] += MBIG;
+ }
+ }
+ inext=0;
+ inextp = 21;
+ Seed = 1;
+ }
+
+ //
+ // Package Private Methods
+ //
+
+ //====================================Sample====================================
+ //Action: Return a new random number [0..1) and reSeed the Seed array.
+ //Returns: A double [0..1)
+ //Arguments: None
+ //Exceptions: None
+ //==============================================================================
+ //|
+ protected virtual double Sample() {
+ int retVal;
+ int locINext = inext;
+ int locINextp = inextp;
+
+ if (++locINext >= 56) locINext = 1;
+ if (++locINextp >= 56) locINextp = 1;
+
+ retVal = SeedArray[locINext]-SeedArray[locINextp];
+
+ if (retVal < 0) retVal += MBIG;
+
+ SeedArray[locINext]=retVal;
+
+ inext = locINext;
+ inextp = locINextp;
+
+ //Including this division at the end gives us significantly improved
+ //random number distribution.
+ return (retVal*(1.0/MBIG));
+ }
+
+ //
+ // Public Instance Methods
+ //
+
+
+ //=====================================Next=====================================
+ //Returns: An int [0.._int4.MaxValue)
+ //Arguments: None
+ //Exceptions: None.
+ //==============================================================================
+ //|
+ public virtual int Next() {
+ return (int)(Sample()*Int32.MaxValue);
+ }
+
+ //=====================================Next=====================================
+ //Returns: An int [minvalue..maxvalue)
+ //Arguments: minValue -- the least legal value for the Random number.
+ // maxValue -- the greatest legal return value.
+ //Exceptions: None.
+ //==============================================================================
+ //|
+ public virtual int Next(int minValue, int maxValue) {
+ if (minValue > maxValue) {
+ throw new ArgumentOutOfRangeException("minValue",String.Format("Argument_MinMaxValue", "minValue", "maxValue"));
+ }
+
+ int range = (maxValue-minValue);
+
+ //This is the case where we flipped around (e.g. MaxValue-MinValue);
+ if (range < 0) {
+ long longRange = (long)maxValue-(long)minValue;
+ return (int)(((long)(Sample()*((double)longRange)))+minValue);
+ }
+
+ return ((int)(Sample()*(range)))+minValue;
+ }
+
+
+ //=====================================Next=====================================
+ //Returns: An int [0..maxValue)
+ //Arguments: maxValue -- the greatest legal return value.
+ //Exceptions: None.
+ //==============================================================================
+ //|
+ public virtual int Next(int maxValue) {
+ if (maxValue < 0) {
+ throw new ArgumentOutOfRangeException("maxValue", String.Format("ArgumentOutOfRange_MustBePositive", "maxValue"));
+ }
+ return (int)(Sample()*maxValue);
+ }
+
+
+ //=====================================Next=====================================
+ //Returns: A double [0..1)
+ //Arguments: None
+ //Exceptions: None
+ //==============================================================================
+ //|
+ public virtual double NextDouble() {
+ return Sample();
+ }
+
+
+ //==================================NextBytes===================================
+ //Action: Fills the byte array with random bytes [0..0x7f]. The entire array is filled.
+ //Returns:Void
+ //Arguments: buffer -- the array to be filled.
+ //Exceptions: None
+ //==============================================================================
+ //|
+ public virtual void NextBytes(byte [] buffer){
+ if (buffer==null) throw new ArgumentNullException("buffer");
+ for (int i = 0; i < buffer.Length; i++) {
+ buffer[i]=(byte)(Sample()*(Byte.MaxValue+1));
+ }
+ }
+ }
+
+
+
+}
diff --git a/base/Applications/Runtime/Full/System/RankException.cs b/base/Applications/Runtime/Full/System/RankException.cs
new file mode 100644
index 0000000..edc2b0d
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/RankException.cs
@@ -0,0 +1,38 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: RankException
+//
+// Purpose: For methods that are passed arrays with the wrong number of
+// dimensions.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+
+ //|
+ public class RankException : SystemException
+ {
+ //|
+ public RankException()
+ : base("Arg_RankException") {
+ }
+
+ //|
+ public RankException(String message)
+ : base(message) {
+ }
+
+ //|
+ public RankException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Reflection/Assembly.cs b/base/Applications/Runtime/Full/System/Reflection/Assembly.cs
new file mode 100644
index 0000000..90fdab5
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Reflection/Assembly.cs
@@ -0,0 +1,106 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: Assembly
+//
+// Purpose: For Assembly-related stuff.
+//
+//=============================================================================
+
+namespace System.Reflection
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ public partial class Assembly
+ {
+ // ---------- Bartok code ----------
+
+ public AssemblyName Name
+ {
+ get {
+ return this.assemblyName;
+ }
+ }
+
+ internal String nGetSimpleName() {
+ return this.assemblyName.Name;
+ }
+
+ private String GetFullName() {
+ String name =
+ this.nGetSimpleName()
+ + ", Version=" + this.assemblyName.Version.Major
+ + "." + this.assemblyName.Version.Minor
+ + "." + this.assemblyName.Version.Build
+ + "." + this.assemblyName.Version.Revision
+ + ", Culture="
+ + (this.assemblyName.Culture != ""
+ ? this.assemblyName.Culture
+ : "neutral")
+ + ", PublicKeyToken="
+ + (this.assemblyName.GetPublicKeyToken() != null
+ ? (Assembly.EncodeHexString
+ (this.assemblyName.GetPublicKeyToken()))
+ : "null");
+ return name;
+ }
+
+ // ---------- copied from mscorlib System.Security.Util.Hex ----------
+
+ // changed to lowercase to avoid ToLower call since the code is no
+ // longer shared in Util.Hex
+ private static char[] hexValues =
+ { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ private static String EncodeHexString(byte[] sArray)
+ {
+ String result = null;
+
+ if (sArray != null) {
+ char[] hexOrder = new char[sArray.Length * 2];
+
+ int digit;
+ for (int i = 0, j = 0; i < sArray.Length; i++) {
+ digit = (int)((sArray[i] & 0xf0) >> 4);
+ hexOrder[j++] = hexValues[digit];
+ digit = (int)(sArray[i] & 0x0f);
+ hexOrder[j++] = hexValues[digit];
+ }
+ result = new String(hexOrder);
+ }
+ return result;
+ }
+
+ // ---------- mscorlib code ----------
+ // (some modifications to pull in less code)
+
+ //|
+ public virtual String FullName {
+ get {
+ // If called by Object.ToString(), return val may be NULL.
+ String s;
+
+ // not implementing InternalCache for now
+ //if ((s = (String)Cache[CacheObjType.AssemblyName]) != null)
+ // return s;
+ //
+
+ s = GetFullName();
+ // not implementing InternalCache for now
+ //if (s != null)
+ // Cache[CacheObjType.AssemblyName] = s;
+ //
+
+ return s;
+ }
+ }
+ }
+}
diff --git a/base/Kernel/System/Reflection/AssemblyAttributes.cs b/base/Applications/Runtime/Full/System/Reflection/AssemblyAttributes.cs
similarity index 90%
rename from base/Kernel/System/Reflection/AssemblyAttributes.cs
rename to base/Applications/Runtime/Full/System/Reflection/AssemblyAttributes.cs
index c8c7b50..ce3e755 100644
--- a/base/Kernel/System/Reflection/AssemblyAttributes.cs
+++ b/base/Applications/Runtime/Full/System/Reflection/AssemblyAttributes.cs
@@ -3,18 +3,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** File: AssemblyAttributes
-**
-**
-** Purpose: For Assembly-related custom attributes.
-**
-** Date: April 12, 2000
-**
-=============================================================================*/
+//=============================================================================
+//
+// Purpose: For Assembly-related custom attributes.
+//
+//=============================================================================
-namespace System.Reflection {
+namespace System.Reflection
+{
using System;
diff --git a/base/Applications/Runtime/Full/System/Reflection/AssemblyName.cs b/base/Applications/Runtime/Full/System/Reflection/AssemblyName.cs
new file mode 100644
index 0000000..03224f8
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Reflection/AssemblyName.cs
@@ -0,0 +1,57 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Purpose: Used for binding and retrieving info about an assembly
+//
+//===========================================================
+namespace System.Reflection
+{
+ using System.Runtime.CompilerServices;
+
+ public partial class AssemblyName {
+ public String Culture {
+ get { return _Culture; }
+ }
+
+ // Set and get the name of the assembly. If this is a weak Name
+ // then it optionally contains a site. For strong assembly names,
+ // the name partitions up the strong name's namespace
+ //|
+ public String Name
+ {
+ get { return _Name; }
+ // not needed for now
+ //set { _Name = value; }
+ //
+ }
+
+ //|
+ public Version Version
+ {
+ get {
+ return _Version;
+ }
+ // not needed for now
+ //set {
+ // _Version = value;
+ //}
+ //
+ }
+
+ // The compressed version of the public key formed from a truncated hash.
+ //|
+ public byte[] GetPublicKeyToken()
+ {
+ // not needed for now
+ //if ((_PublicKeyToken == null) &&
+ // (_Flags & AssemblyNameFlags.PublicKey) != 0)
+ // _PublicKeyToken = nGetPublicKeyToken();
+ //
+ return _PublicKeyToken;
+ }
+ }
+}
diff --git a/base/Kernel/System/Reflection/AssemblyReflectionAttributes.cs b/base/Applications/Runtime/Full/System/Reflection/AssemblyReflectionAttributes.cs
similarity index 92%
rename from base/Kernel/System/Reflection/AssemblyReflectionAttributes.cs
rename to base/Applications/Runtime/Full/System/Reflection/AssemblyReflectionAttributes.cs
index 9f4e121..963e88d 100644
--- a/base/Kernel/System/Reflection/AssemblyReflectionAttributes.cs
+++ b/base/Applications/Runtime/Full/System/Reflection/AssemblyReflectionAttributes.cs
@@ -3,18 +3,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** File: AssemblyReflectionAttributes.cool
-**
-**
-** Purpose: For Assembly-related reflection custom attributes.
-**
-** Date: April 12, 2000
-**
-=============================================================================*/
+//=============================================================================
+//
+// Purpose: For Assembly-related reflection custom attributes.
+//
+//=============================================================================
-namespace System.Reflection {
+namespace System.Reflection
+{
using System;
diff --git a/base/Kernel/System/Reflection/DefaultMemberAttribute.cs b/base/Applications/Runtime/Full/System/Reflection/DefaultMemberAttribute.cs
similarity index 94%
rename from base/Kernel/System/Reflection/DefaultMemberAttribute.cs
rename to base/Applications/Runtime/Full/System/Reflection/DefaultMemberAttribute.cs
index 2242cdc..7a126d9 100644
--- a/base/Kernel/System/Reflection/DefaultMemberAttribute.cs
+++ b/base/Applications/Runtime/Full/System/Reflection/DefaultMemberAttribute.cs
@@ -10,9 +10,8 @@
// member used by Type.InvokeMember. The default member is simply a name given
// to a type.
//
-// Date: Oct 99
-//
-namespace System.Reflection {
+namespace System.Reflection
+{
using System;
diff --git a/base/Kernel/System/Reflection/TypeAttributes.cs b/base/Applications/Runtime/Full/System/Reflection/TypeAttributes.cs
similarity index 97%
rename from base/Kernel/System/Reflection/TypeAttributes.cs
rename to base/Applications/Runtime/Full/System/Reflection/TypeAttributes.cs
index 8c451de..8955930 100644
--- a/base/Kernel/System/Reflection/TypeAttributes.cs
+++ b/base/Applications/Runtime/Full/System/Reflection/TypeAttributes.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Reflection {
+namespace System.Reflection
+{
using System.Runtime.InteropServices;
using System;
// This Enum matches the CorTypeAttr defined in CorHdr.h
diff --git a/base/Kernel/System/Runtime/CompilerServices/DecimalConstantAttribute.cs b/base/Applications/Runtime/Full/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
similarity index 100%
rename from base/Kernel/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
rename to base/Applications/Runtime/Full/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
diff --git a/base/Kernel/System/Runtime/CompilerServices/IndexerNameAttribute.cs b/base/Applications/Runtime/Full/System/Runtime/CompilerServices/IndexerNameAttribute.cs
similarity index 100%
rename from base/Kernel/System/Runtime/CompilerServices/IndexerNameAttribute.cs
rename to base/Applications/Runtime/Full/System/Runtime/CompilerServices/IndexerNameAttribute.cs
diff --git a/base/Kernel/System/Runtime/CompilerServices/IsVolatile.cs b/base/Applications/Runtime/Full/System/Runtime/CompilerServices/IsVolatile.cs
similarity index 100%
rename from base/Kernel/System/Runtime/CompilerServices/IsVolatile.cs
rename to base/Applications/Runtime/Full/System/Runtime/CompilerServices/IsVolatile.cs
diff --git a/base/Kernel/System/Runtime/CompilerServices/MethodImplAttribute.cs b/base/Applications/Runtime/Full/System/Runtime/CompilerServices/MethodImplAttribute.cs
similarity index 95%
rename from base/Kernel/System/Runtime/CompilerServices/MethodImplAttribute.cs
rename to base/Applications/Runtime/Full/System/Runtime/CompilerServices/MethodImplAttribute.cs
index 7819c7e..b4d46d6 100644
--- a/base/Kernel/System/Runtime/CompilerServices/MethodImplAttribute.cs
+++ b/base/Applications/Runtime/Full/System/Runtime/CompilerServices/MethodImplAttribute.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Runtime.CompilerServices {
+namespace System.Runtime.CompilerServices
+{
using System;
diff --git a/base/Kernel/System/Runtime/CompilerServices/RuntimeHelpers.cs b/base/Applications/Runtime/Full/System/Runtime/CompilerServices/RuntimeHelpers.cs
similarity index 92%
rename from base/Kernel/System/Runtime/CompilerServices/RuntimeHelpers.cs
rename to base/Applications/Runtime/Full/System/Runtime/CompilerServices/RuntimeHelpers.cs
index f61fe5d..d40cb4c 100644
--- a/base/Kernel/System/Runtime/CompilerServices/RuntimeHelpers.cs
+++ b/base/Applications/Runtime/Full/System/Runtime/CompilerServices/RuntimeHelpers.cs
@@ -9,9 +9,8 @@
// RuntimeHelpers
// This class defines a set of static methods that provide support for compilers.
//
-// Date: April 2000
-//
-namespace System.Runtime.CompilerServices {
+namespace System.Runtime.CompilerServices
+{
using System;
using System.Runtime.CompilerServices;
@@ -36,7 +35,7 @@ namespace System.Runtime.CompilerServices {
// or pass it as a parameter. The goal is to make sure that boxed
// value types work identical to unboxed value types - ie, they get
// cloned when you pass them around, and are always passed by value.
- // Of course, reference types are not cloned. -- BrianGru 7/12/2001
+ // Of course, reference types are not cloned.
//
//|
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -65,6 +64,7 @@ namespace System.Runtime.CompilerServices {
//|
public static int OffsetToStringData
{
+ [NoHeapAllocation]
get {
// Number of bytes from the address pointed to by a reference to
// a String to the first 16-bit character in the String. Skip
@@ -72,7 +72,7 @@ namespace System.Runtime.CompilerServices {
// length. Of course, the String reference points to the memory
// after the sync block, so don't count that.
// This property allows C#'s fixed statement to work on Strings.
- // On 64 bit platforms, this should be 16. -- BrianGru
+ // On 64 bit platforms, this should be 16.
#if PTR_SIZE_32
return 12;
#else
diff --git a/base/Applications/Runtime/Full/System/Runtime/InteropServices/Attributes.cs b/base/Applications/Runtime/Full/System/Runtime/InteropServices/Attributes.cs
new file mode 100644
index 0000000..72214df
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Runtime/InteropServices/Attributes.cs
@@ -0,0 +1,96 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.InteropServices
+{
+
+ using System;
+
+ //|
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Delegate, Inherited = false)]
+ public sealed class GuidAttribute : Attribute
+ {
+ internal String _val;
+ //|
+ public GuidAttribute(String guid)
+ {
+ _val = guid;
+ }
+ //|
+ public String Value { get {return _val;} }
+ }
+
+ //|
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class InAttribute : Attribute
+ {
+ //|
+ public InAttribute()
+ {
+ }
+ }
+
+ //|
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class OutAttribute : Attribute
+ {
+ //|
+ public OutAttribute()
+ {
+ }
+ }
+
+ //|
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class OptionalAttribute : Attribute
+ {
+ //|
+ public OptionalAttribute()
+ {
+ }
+ }
+
+ //|
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
+ public sealed class StructLayoutAttribute : Attribute
+ {
+ internal LayoutKind _val;
+ //|
+ public StructLayoutAttribute(LayoutKind layoutKind)
+ {
+ _val = layoutKind;
+ }
+ //|
+ public StructLayoutAttribute(short layoutKind)
+ {
+ _val = (LayoutKind)layoutKind;
+ }
+ //|
+ public LayoutKind Value { get {return _val;} }
+ //|
+ public int Pack;
+ //|
+ public int Size;
+ //|
+ public CharSet CharSet;
+ }
+
+ //|
+ [AttributeUsage(AttributeTargets.Field, Inherited = false)]
+ public sealed class FieldOffsetAttribute : Attribute
+ {
+ internal int _val;
+ //|
+ public FieldOffsetAttribute(int offset)
+ {
+ _val = offset;
+ }
+ //|
+ public int Value { get {return _val;} }
+ }
+
+}
diff --git a/base/Kernel/System/Runtime/InteropServices/CharSet.cs b/base/Applications/Runtime/Full/System/Runtime/InteropServices/CharSet.cs
similarity index 93%
rename from base/Kernel/System/Runtime/InteropServices/CharSet.cs
rename to base/Applications/Runtime/Full/System/Runtime/InteropServices/CharSet.cs
index 036d548..50cf748 100644
--- a/base/Kernel/System/Runtime/InteropServices/CharSet.cs
+++ b/base/Applications/Runtime/Full/System/Runtime/InteropServices/CharSet.cs
@@ -5,7 +5,8 @@
// ==--==
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices {
+namespace System.Runtime.InteropServices
+{
using System;
//|
public enum CharSet
diff --git a/base/Applications/Runtime/Full/System/Runtime/InteropServices/GCHandle.cs b/base/Applications/Runtime/Full/System/Runtime/InteropServices/GCHandle.cs
new file mode 100644
index 0000000..8eb9708
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Runtime/InteropServices/GCHandle.cs
@@ -0,0 +1,284 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System.Runtime.InteropServices
+{
+
+ using System;
+ using System.Threading;
+ using System.Runtime.CompilerServices;
+
+ // These are the types of handles used by the EE. IMPORTANT: These must
+ // match the definitions in ObjectHandle.h in the EE.
+ //|
+ public enum GCHandleType
+ {
+ //|
+ Weak = 0,
+ //|
+ WeakTrackResurrection = 1,
+ //|
+ Normal = 2,
+ //|
+ Pinned = 3
+ }
+
+ // This class allows you to create an opaque, GC handle to any
+ // managed object. A GC handle is used when an object reference must be
+ // reachable from unmanaged memory. There are 3 kinds of roots:
+ // Normal - keeps the object from being collected.
+ // Weak - allows object to be collected and handle contents will be zeroed.
+ // Weak references are zeroed before the finalizer runs, so if the
+ // object is resurrected in the finalizer the weak reference is
+ // still zeroed.
+ // WeakTrackResurrection - Same as weak, but stays until after object is
+ // really gone.
+ // Pinned - same as normal, but allows the address of the actual object
+ // to be taken.
+ //
+ //|
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+ public struct GCHandle
+ {
+ // Allocate a handle storing the object and the type.
+ internal GCHandle(Object value, GCHandleType type)
+ {
+ m_handle = InternalAlloc(value, type);
+
+ // Record if the handle is pinned.
+ if (type == GCHandleType.Pinned)
+ m_handle |= 1;
+ }
+
+ // Used in the conversion functions below.
+ internal GCHandle(IntPtr handle)
+ {
+ InternalCheckDomain((int) handle);
+ m_handle = (int)handle;
+ }
+
+ // Creates a new GC handle for an object.
+ //
+ // value - The object that the GC handle is created for.
+ // type - The type of GC handle to create.
+ //
+ // returns a new GC handle that protects the object.
+ //|
+ public static GCHandle Alloc(Object value)
+ {
+ return new GCHandle(value, GCHandleType.Normal);
+ }
+
+ //|
+ public static GCHandle Alloc(Object value, GCHandleType type)
+ {
+ return new GCHandle(value, type);
+ }
+
+ // Frees a GC handle. The caller must provide synchronization to
+ // prevent multiple threads from executing this simultaneously for
+ // a given handle. If you modify this method please modify the
+ // __InternalFree also which is the internal without the link-time check.
+ //|
+ public void Free()
+ {
+ // Check if the handle was never initialized for was freed.
+ if (m_handle == 0)
+ throw new InvalidOperationException("InvalidOperation_HandleIsNotInitialized");
+
+ // Free the handle.
+ InternalFree(m_handle & ~0x1);
+ m_handle = 0;
+ }
+
+ internal void __InternalFree()
+ {
+ // Check if the handle was never initialized for was freed.
+ if (m_handle == 0)
+ throw new InvalidOperationException("InvalidOperation_HandleIsNotInitialized");
+
+ // Free the handle.
+ InternalFree(m_handle & ~0x1);
+ m_handle = 0;
+ }
+
+ // Target property - allows getting / updating of the handle's referent. If you modify this method
+
+ // then modify the __InternalTarget too which is the internal method without the link-time check.
+ //|
+ public Object Target
+ {
+ get
+ {
+ // Check if the handle was never initialized or was freed.
+ if (m_handle == 0)
+ throw new InvalidOperationException("InvalidOperation_HandleIsNotInitialized");
+
+ return InternalGet(m_handle & ~0x1);
+ }
+
+ set
+ {
+ // Check if the handle was never initialized or was freed.
+ if (m_handle == 0)
+ throw new InvalidOperationException("InvalidOperation_HandleIsNotInitialized");
+
+ InternalSet(m_handle & ~0x1, value, (m_handle & 0x1) != 0 /* isPinned */);
+ }
+ }
+
+ internal Object __InternalTarget
+ {
+ get
+ {
+ // Check if the handle was never initialized or was freed.
+ if (m_handle == 0)
+ throw new InvalidOperationException("InvalidOperation_HandleIsNotInitialized");
+
+ return InternalGet(m_handle & ~0x1);
+ }
+ }
+
+ // Retrieve the address of an object in a Pinned handle. This throws
+ // an exception if the handle is any type other than Pinned.
+ //|
+ public IntPtr AddrOfPinnedObject()
+ {
+ // Check if the handle was not a pinned handle.
+ if ((m_handle & 1) == 0) {
+ // Check if the handle was never initialized for was freed.
+ if (m_handle == 0)
+ throw new InvalidOperationException("InvalidOperation_HandleIsNotInitialized");
+
+ // You can only get the address of pinned handles.
+ throw new InvalidOperationException("InvalidOperation_HandleIsNotPinned");
+ }
+
+ // Get the address.
+ return InternalAddrOfPinnedObject(m_handle & ~0x1);
+ }
+
+ // Determine whether this handle has been allocated or not.
+ //|
+ public bool IsAllocated
+ {
+ get
+ {
+ return m_handle != 0;
+ }
+ }
+
+ // Used to create a GCHandle from an int. This is intended to
+ // be used with the reverse conversion.
+ //|
+ public static explicit operator GCHandle(IntPtr value)
+ {
+ return new GCHandle(value);
+ }
+
+ // Used to get the internal integer representation of the handle out.
+ //|
+ public static explicit operator IntPtr(GCHandle value)
+ {
+ return (IntPtr)value.m_handle;
+ }
+
+ // Internal native calls that this implementation uses.
+ internal static int InternalAlloc(Object value, GCHandleType type)
+ {
+ int result, newIndex;
+ if (type == GCHandleType.Pinned) {
+ throw new Exception("GCHandle for pinned objects not yet implemented");
+ }
+ do {
+ if (nextFreeIndex < 0) {
+ lock (handleToken) {
+ if (nextFreeIndex < 0) {
+ if (handleTable == null) {
+ handleTable = new HandleData[3];
+ handleTable[0].nextIndex = -1;
+ handleTable[1].nextIndex = 2;
+ handleTable[2].nextIndex = -1;
+ nextFreeIndex = 1;
+ }
+ else {
+ int oldLength = handleTable.Length;
+ int newLength = oldLength * 2;
+ HandleData[] newTable = new HandleData[newLength];
+ Array.Copy(handleTable, 0, newTable, 0, oldLength);
+ handleTable = newTable;
+ for (int i = oldLength + 1; i < newLength; i++) {
+ handleTable[i].nextIndex = i + 1;
+ }
+ handleTable[newLength-1].nextIndex = -1;
+ nextFreeIndex = oldLength+1;
+ }
+ }
+ }
+ }
+ result = nextFreeIndex;
+ newIndex = handleTable[result].nextIndex;
+ } while (Interlocked.CompareExchange(ref nextFreeIndex, newIndex, result) != result);
+ handleTable[result].obj = value;
+ handleTable[result].type = type;
+ // TODO: We should probably maintain a list of handles of each type
+ return result;
+ }
+
+ internal static void InternalFree(int handle)
+ {
+ handleTable[handle].obj = null;
+ int oldFreeIndex = nextFreeIndex;
+ handleTable[handle].nextIndex = oldFreeIndex;
+ while (Interlocked.CompareExchange(ref nextFreeIndex, handle, oldFreeIndex) != oldFreeIndex) {
+ oldFreeIndex = nextFreeIndex;
+ handleTable[handle].nextIndex = oldFreeIndex;
+ }
+ }
+
+ internal static Object InternalGet(int handle)
+ {
+ return handleTable[handle].obj;
+ }
+
+ internal static void InternalSet(int handle, Object value, bool isPinned)
+ {
+ throw new Exception("System.Runtime.InteropServices.GCHandle.InternalSet not implemented in Bartok!");
+ }
+
+ internal static void InternalCompareExchange(int handle, Object value, Object oldValue, bool isPinned)
+ {
+ if (isPinned) {
+ throw new Exception("CompareExchange on a pinned object?!?");
+ }
+ Interlocked.CompareExchange(ref handleTable[handle].obj, value, oldValue);
+ }
+
+ internal static IntPtr InternalAddrOfPinnedObject(int handle)
+ {
+ throw new Exception("System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject not implemented in Bartok!");
+ }
+
+ internal static void InternalCheckDomain(int handle)
+ {
+ throw new Exception("System.Runtime.InteropServices.GCHandle.InternalCheckDomain not implemented in Bartok!");
+ }
+
+ // The actual integer handle value that the EE uses internally.
+ private int m_handle;
+
+ private static HandleData[] handleTable;
+
+ private static int nextFreeIndex = -1;
+
+ private static Object handleToken = new Object();
+
+ private struct HandleData {
+ public Object obj;
+ public GCHandleType type;
+ public int nextIndex;
+ }
+ }
+}
diff --git a/base/Kernel/System/Runtime/InteropServices/LayoutKind.cs b/base/Applications/Runtime/Full/System/Runtime/InteropServices/LayoutKind.cs
similarity index 92%
rename from base/Kernel/System/Runtime/InteropServices/LayoutKind.cs
rename to base/Applications/Runtime/Full/System/Runtime/InteropServices/LayoutKind.cs
index 86167da..dd42de7 100644
--- a/base/Kernel/System/Runtime/InteropServices/LayoutKind.cs
+++ b/base/Applications/Runtime/Full/System/Runtime/InteropServices/LayoutKind.cs
@@ -5,7 +5,8 @@
// ==--==
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices {
+namespace System.Runtime.InteropServices
+{
using System;
// Used in the StructLayoutAttribute class
//|
diff --git a/base/Kernel/System/Runtime/InteropServices/Marshal.cs b/base/Applications/Runtime/Full/System/Runtime/InteropServices/Marshal.cs
similarity index 83%
rename from base/Kernel/System/Runtime/InteropServices/Marshal.cs
rename to base/Applications/Runtime/Full/System/Runtime/InteropServices/Marshal.cs
index 5e47596..3c0d5ae 100644
--- a/base/Kernel/System/Runtime/InteropServices/Marshal.cs
+++ b/base/Applications/Runtime/Full/System/Runtime/InteropServices/Marshal.cs
@@ -3,19 +3,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*=============================================================================
-**
-** Class: Marshal
-**
-**
-** Purpose: This class contains methods that are mainly used to marshal
-** between unmanaged and managed types.
-**
-** Date: January 31, 2000
-**
-=============================================================================*/
+//=============================================================================
+//
+// Class: Marshal
+//
+// Purpose: This class contains methods that are mainly used to marshal
+// between unmanaged and managed types.
+//
+//=============================================================================
-namespace System.Runtime.InteropServices {
+namespace System.Runtime.InteropServices
+{
using Microsoft.Bartok.Runtime;
using System;
@@ -41,10 +39,12 @@ namespace System.Runtime.InteropServices {
if (vtable.arrayOf == StructuralType.None) {
if (vtable.Equals("string".vtable)) {
throw new Exception("SizeOf not implemented for string objects");
- } else {
+ }
+ else {
return vtable.marshalSize;
}
- } else {
+ }
+ else {
int elementSize = vtable.arrayElementSize;
int elementMask = elementSize - 1;
int numElements = ((Array) structure).Length;
@@ -62,7 +62,8 @@ namespace System.Runtime.InteropServices {
if (vtable.arrayOf == StructuralType.None &&
!t.Equals("string".GetType())) {
return vtable.marshalSize;
- } else {
+ }
+ else {
throw new Exception("SizeOf not implemented for type "+t);
}
}
@@ -77,7 +78,8 @@ namespace System.Runtime.InteropServices {
if (vtable.arrayOf == StructuralType.None &&
!t.Equals("string".GetType())) {
return vtable.arrayElementSize;
- } else {
+ }
+ else {
throw new Exception("SizeOf not implemented for type "+t);
}
}
diff --git a/base/Applications/Runtime/Full/System/RuntimeArgumentHandle.cs b/base/Applications/Runtime/Full/System/RuntimeArgumentHandle.cs
new file mode 100644
index 0000000..af74f33
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/RuntimeArgumentHandle.cs
@@ -0,0 +1,25 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+ // This value type is used for constructing System.ArgIterator.
+ //
+ // SECURITY : m_ptr cannot be set to anything other than null by untrusted
+ // code.
+ //
+ // This corresponds to EE VARARGS cookie.
+
+ //|
+ public unsafe partial struct RuntimeArgumentHandle {
+ internal IntPtr Pointer {
+ [NoHeapAllocation]
+ get { return (IntPtr) (UIntPtr) m_ptr; }
+ }
+ }
+}
diff --git a/base/Kernel/System/RuntimeFieldHandle.cs b/base/Applications/Runtime/Full/System/RuntimeFieldHandle.cs
similarity index 93%
rename from base/Kernel/System/RuntimeFieldHandle.cs
rename to base/Applications/Runtime/Full/System/RuntimeFieldHandle.cs
index 046fa2e..93d8322 100644
--- a/base/Kernel/System/RuntimeFieldHandle.cs
+++ b/base/Applications/Runtime/Full/System/RuntimeFieldHandle.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
using System.Reflection;
diff --git a/base/Kernel/System/RuntimeMethodHandle.cs b/base/Applications/Runtime/Full/System/RuntimeMethodHandle.cs
similarity index 93%
rename from base/Kernel/System/RuntimeMethodHandle.cs
rename to base/Applications/Runtime/Full/System/RuntimeMethodHandle.cs
index 01d85cb..e9037b9 100644
--- a/base/Kernel/System/RuntimeMethodHandle.cs
+++ b/base/Applications/Runtime/Full/System/RuntimeMethodHandle.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
using System.Reflection;
diff --git a/base/Kernel/System/RuntimeTypeHandle.cs b/base/Applications/Runtime/Full/System/RuntimeTypeHandle.cs
similarity index 88%
rename from base/Kernel/System/RuntimeTypeHandle.cs
rename to base/Applications/Runtime/Full/System/RuntimeTypeHandle.cs
index e2c6314..80be078 100644
--- a/base/Kernel/System/RuntimeTypeHandle.cs
+++ b/base/Applications/Runtime/Full/System/RuntimeTypeHandle.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using Microsoft.Bartok.Runtime;
@@ -32,6 +33,8 @@ namespace System {
//|
public IntPtr Value {
+ // BUGBUG: What if the handle is a field in a class? --Bjarne
+ [NoBarriers]
[NoHeapAllocation]
get {
return m_ptr;
diff --git a/base/Kernel/System/SByte.cs b/base/Applications/Runtime/Full/System/SByte.cs
similarity index 90%
rename from base/Kernel/System/SByte.cs
rename to base/Applications/Runtime/Full/System/SByte.cs
index 7809280..97f447e 100644
--- a/base/Kernel/System/SByte.cs
+++ b/base/Applications/Runtime/Full/System/SByte.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: SByte
-**
-**
-** Purpose:
-**
-** Date: March 15, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: SByte
+//
+// Purpose:
+//
+//===========================================================
+namespace System
+{
using System.Globalization;
using System;
using System.Runtime.CompilerServices;
@@ -78,7 +76,7 @@ namespace System {
//|
public String ToString(String format) {
- if (m_value<0 && format!=null && format.Length>0 && (format[0]=='X' || format[0]=='x')) {
+ if (m_value < 0 && format != null && format.Length > 0 && (format[0] =='X' || format[0] =='x')) {
uint temp = (uint)(m_value & 0x000000FF);
return Number.FormatUInt32(temp,format);
}
diff --git a/base/Kernel/System/SchedulerTime.cs b/base/Applications/Runtime/Full/System/SchedulerTime.cs
similarity index 96%
rename from base/Kernel/System/SchedulerTime.cs
rename to base/Applications/Runtime/Full/System/SchedulerTime.cs
index 6938cee..414ea98 100644
--- a/base/Kernel/System/SchedulerTime.cs
+++ b/base/Applications/Runtime/Full/System/SchedulerTime.cs
@@ -8,7 +8,8 @@
// Used to keep track of timeouts and deadline in thread scheduling
//
// ==--==
-namespace System {
+namespace System
+{
using Microsoft.Singularity;
@@ -24,8 +25,8 @@ namespace System {
#endif
// This value type represents an absolute time on the scheduler timeline,
- // which is kernel time increasing monotonically and independently of
- // the world time the machine thinks it is on.
+ // which is kernel time increasing monotonically and independently of
+ // the world time the machine thinks it is on.
// The reason to separate world time and scheduler time is that world time can
// change at any time due to users changing the time and date, or due to
// adjustments for accuracy or daylight-savings.
@@ -213,8 +214,7 @@ namespace System {
{
//TimeSpan.TimeToTicks is a family access function which does no error checking, so
//we need to put some error checking out here.
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >=0 && second < 60)
- {
+ if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60) {
return (TimeSpan.TimeToTicks(hour, minute, second));
}
throw new ArgumentOutOfRangeException("ArgumentOutOfRange_BadHourMinuteSecond");
diff --git a/base/Kernel/System/Single.cs b/base/Applications/Runtime/Full/System/Single.cs
similarity index 92%
rename from base/Kernel/System/Single.cs
rename to base/Applications/Runtime/Full/System/Single.cs
index cb1f1e4..456bfb6 100644
--- a/base/Kernel/System/Single.cs
+++ b/base/Applications/Runtime/Full/System/Single.cs
@@ -3,17 +3,15 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: Single
-**
-**
-** Purpose: A wrapper class for the primitive type float.
-**
-** Date: August 3, 1998
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: Single
+//
+// Purpose: A wrapper class for the primitive type float.
+//
+//===========================================================
+namespace System
+{
using System.Globalization;
using System;
@@ -75,7 +73,7 @@ namespace System {
//|
+ public sealed partial class String : IComparable, ICloneable, IEnumerable {
+ //
+ //Native Static Methods
+ //
+
+ // Joins an array of strings together as one string with a separator between each original string.
+ //
+ //|
+ public static String Join(String separator, String[] value) {
+ if (value == null) {
+ throw new ArgumentNullException("value");
+ }
+ return Join(separator, value, 0, value.Length);
+ }
+
+ ///
+ // Joins an array of strings together as one string with a separator
+ // between each original string.
+ //
+ // @param separator the string used as a separator.
+ // @param value the array of strings to be joined.
+ // @param startIndex the position within the array to start using
+ // strings.
+ // @param count the number of strings to take from the array.
+ //
+ // @return a string consisting of the strings contained in value
+ // from startIndex to startIndex + count
+ // joined together to form a single string, with each of the original
+ // strings separated by separator.
+ //
+ //|
+ public static String Join(String separator, String[] value,
+ int startIndex, int count)
+ {
+ // See also Lightning\Src\VM\COMString.cpp::JoinArray
+ if (separator == null) {
+ separator = String.Empty;
+ }
+ if (value == null) {
+ throw new ArgumentNullException("value array is null");
+ }
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (count < 0) {
+ throw new ArgumentOutOfRangeException("count is negative");
+ }
+ if (startIndex + count > value.Length) {
+ throw new ArgumentOutOfRangeException("startIndex+count>value.Length");
+ }
+ // Special case the empty list of strings
+ if (count == 0) {
+ return String.Empty;
+ }
+ // Compute the length of the new string
+ int newLength = 0;
+ int limit = startIndex + count;
+ for (int i = startIndex; i < limit; i++) {
+ String s = value[i];
+ if (s != null) {
+ newLength += s.m_stringLength;
+ }
+ }
+ newLength += (count - 1) * separator.m_stringLength;
+ // Create a new String
+ String result = FastAllocateString(newLength);
+ if (newLength == 0) {
+ return result;
+ }
+ // Fill in the string
+ int dstIndex = 0;
+ String firstString = value[startIndex];
+ if (firstString != null) {
+ FillString(result, 0, firstString);
+ dstIndex = firstString.m_stringLength;
+ }
+ for (int i = startIndex + 1; i < limit; i++) {
+ FillString(result, dstIndex, separator);
+ dstIndex += separator.m_stringLength;
+ String elementString = value[i];
+ if (elementString != null) {
+ FillString(result, dstIndex, elementString);
+ dstIndex += elementString.m_stringLength;
+ }
+ }
+ return result;
+ }
+
+ private unsafe static bool CaseInsensitiveCompHelper(char * strAChars,
+ char * strBChars,
+ int aLength,
+ int bLength,
+ out int result) {
+ char charA;
+ char charB;
+ char *strAStart;
+
+ strAStart = strAChars;
+
+ result = 0;
+
+ // setup the pointers so that we can always increment them.
+ // We never access these pointers at the negative offset.
+ strAChars--;
+ strBChars--;
+
+ do {
+ strAChars++; strBChars++;
+
+ charA = *strAChars;
+ charB = *strBChars;
+
+ //Case-insensitive comparison on chars greater than 0x80 requires
+ //a locale-aware casing operation and we're not going there.
+ if (charA >= 0x80 || charB >= 0x80) {
+ // TODO: We should be able to fix this.
+ return false;
+ }
+
+ // Do the right thing if they differ in case only.
+ // We depend on the fact that the uppercase and lowercase letters
+ // in the range which we care about (A-Z,a-z) differ only by the
+ // 0x20 bit.
+ // The check below takes the xor of the two characters and
+ // determines if this bit is only set on one of them.
+ // If they're different cases, we know that we need to execute
+ // only one of the conditions within block.
+ if (((charA^charB) & 0x20) != 0) {
+ if (charA >='A' && charA <='Z') {
+ charA |= (char)0x20;
+ }
+ else if (charB >='A' && charB <='Z') {
+ charB |= (char)0x20;
+ }
+ }
+ } while (charA == charB && charA != 0);
+
+ // Return the (case-insensitive) difference between them.
+ if (charA != charB) {
+ result = (int)(charA-charB);
+ return true;
+ }
+
+ // The length of b was unknown because it was just a pointer to a
+ // null-terminated string.
+ // If we get here, we know that both A and B are pointing at a null.
+ // However, A can have an embedded null. Check the number of
+ // characters that we've walked in A against the expected length.
+ if (bLength == -1) {
+ if ((strAChars - strAStart) != aLength) {
+ result = 1;
+ return true;
+ }
+ result=0;
+ return true;
+ }
+
+ result = (aLength - bLength);
+ return true;
+ }
+
+ internal unsafe static int nativeCompareOrdinal(String strA, String strB,
+ bool bIgnoreCase)
+ {
+ // See also Lightning\Src\VM\COMString.cpp::FCCompareOrdinal
+ int strALength = strA.Length;
+ int strBLength = strB.Length;
+ fixed(char * strAChars = &strA.m_firstChar) {
+ fixed(char * strBCharsStart = &strB.m_firstChar) {
+
+ // Need copy because fixed vars are readonly
+ char * strBChars = strBCharsStart;
+
+ // Handle the comparison where we wish to ignore case.
+ if (bIgnoreCase) {
+ int result;
+ if (CaseInsensitiveCompHelper(strAChars, strBChars,
+ strALength, strBLength,
+ out result)) {
+ return result;
+ }
+ else {
+ // This will happen if we have characters greater
+ // than 0x7F.
+ throw new ArgumentException();
+ }
+ }
+
+ // If the strings are the same length, compare exactly the
+ // right # of chars. If they are different, compare the
+ // shortest # + 1 (the '\0').
+ int count = strALength;
+ if (count > strBLength)
+ count = strBLength;
+
+ long diff = (byte*)strAChars - (byte*)strBChars;
+
+ // Loop comparing a DWORD at a time.
+ while ((count -= 2) >= 0) {
+ if (((*(int*)((byte*)strBChars + diff))
+ - *(int*)strBChars) != 0) {
+ char * ptr1 = (char*)((byte*)strBChars + diff);
+ char * ptr2 = strBChars;
+ if (*ptr1 != *ptr2) {
+ return ((int)*ptr1 - (int)*ptr2);
+ }
+ return ((int)*(ptr1+1) - (int)*(ptr2+1));
+ }
+
+ // differs from COMString.cpp because they have DWORD*
+ // and we use char*
+ strBChars += 2;
+ }
+
+ // Handle an extra WORD.
+ int c;
+ if (count == -1) {
+ c = *((char*)((byte*)strBChars+diff)) - *strBChars;
+ if (c != 0) {
+ return c;
+ }
+ }
+ return strALength - strBLength;
+ }
+ }
+ }
+
+ internal static int nativeCompareOrdinalEx(String strA, int indexA,
+ String strB, int indexB,
+ int count)
+ {
+ // See also Lightning\Src\VM\COMString.cpp::CompareOrdinalEx
+ throw new Exception("System.String.nativeCompareOrdinalEx not implemented in Bartok!");
+ }
+
+ //
+ // This is a helper method for the security team. They need to uppercase some strings (guaranteed to be less
+ // than 0x80) before security is fully initialized. Without security initialized, we can't grab resources (the nlp's)
+ // from the assembly. This provides a workaround for that problem and should NOT be used anywhere else.
+ //
+ internal static String SmallCharToUpper(String strA)
+ {
+ String newString = FastAllocateString(strA.Length);
+ nativeSmallCharToUpper(strA, newString);
+ return newString;
+ }
+
+ private static void nativeSmallCharToUpper(String strIn, String strOut)
+ {
+ // See also Lightning\Src\VM\COMString.cpp::SmallCharToUpper
+ throw new Exception("System.String.nativeSmallCharToUpper not implemented in Bartok!");
+ }
+
+ // This is a helper method for the security team. They need to construct strings from a char[]
+ // within their homebrewed XML parser. They guarantee that the char[] they pass in isn't null and
+ // that the provided indices are valid so we just stuff real fast.
+ internal static String CreateFromCharArray(char[] array, int start, int count)
+ {
+ String newString = FastAllocateString(count);
+ FillStringArray(newString, 0, array, start, count);
+ return newString;
+ }
+
+ //
+ //
+ // NATIVE INSTANCE METHODS
+ //
+ //
+
+ //
+ // Search/Query methods
+ //
+
+ // Determines whether two strings match.
+ //|
+ public override bool Equals(Object obj) {
+ if (obj is String) {
+ return this.Equals((String) obj);
+ }
+ else {
+ return false;
+ }
+ }
+
+ // Determines whether two strings match.
+ //|
+ public unsafe bool Equals(String value) {
+ if (value == null) {
+ return false;
+ }
+ if (this.m_stringLength != value.m_stringLength) {
+ return false;
+ }
+ fixed (char *thisCharPtr = &this.m_firstChar) {
+ fixed (char *valueCharPtr = &value.m_firstChar) {
+ char *thisCursor = thisCharPtr;
+ char *valueCursor = valueCharPtr;
+ for (int i = this.m_stringLength; i > 0; i--) {
+ if (*thisCursor != *valueCursor) {
+ return false;
+ }
+ thisCursor++;
+ valueCursor++;
+ }
+ }
+ }
+ return true;
+ }
+
+ // Determines whether two Strings match.
+ //|
+ public static bool Equals(String a, String b) {
+ if ((Object)a ==(Object)b) {
+ return true;
+ }
+
+ if ((Object)a == null || (Object)b == null) {
+ return false;
+ }
+
+ return a.Equals(b);
+ }
+
+ //|
+ public static bool operator == (String a, String b)
+ {
+ return String.Equals(a, b);
+ }
+
+ //|
+ public static bool operator != (String a, String b)
+ {
+ return !String.Equals(a, b);
+ }
+
+ internal unsafe char InternalGetChar(int index)
+ {
+ // See also Lightning\Src\VM\COMString.cpp::GetCharAt
+ if ((uint) index >= (uint) this.m_stringLength) {
+ throw new IndexOutOfRangeException();
+ }
+ fixed (char *charPtr = &this.m_firstChar) {
+ return charPtr[index];
+ }
+ }
+
+ // Gets the character at a specified position.
+ //
+ //|
+ public char this[int index] {
+ get { return InternalGetChar(index); }
+ }
+
+ internal unsafe int InternalGetChars(char *output, int maxput)
+ {
+ fixed (char *charPtr = &this.m_firstChar) {
+ int i;
+ for (i = 0; i < m_stringLength && i < maxput; i++) {
+ output[i] = charPtr[i];
+ }
+ return i;
+ }
+ }
+
+ // Converts a substring of this string to an array of characters. Copies the
+ // characters of this string beginning at position startIndex and ending at
+ // startIndex + length - 1 to the character array buffer, beginning
+ // at bufferStartIndex.
+ //
+ //|
+ public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
+ {
+ if (destination == null)
+ throw new ArgumentNullException("destination");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_NegativeCount");
+ if (sourceIndex < 0)
+ throw new ArgumentOutOfRangeException("sourceIndex", "ArgumentOutOfRange_Index");
+ if (count > Length - sourceIndex)
+ throw new ArgumentOutOfRangeException("sourceIndex", "ArgumentOutOfRange_IndexCount");
+ if (destinationIndex > destination.Length - count || destinationIndex < 0)
+ throw new ArgumentOutOfRangeException("destinationIndex", "ArgumentOutOfRange_IndexCount");
+ InternalCopyTo(sourceIndex, destination, destinationIndex, count);
+ }
+
+ internal unsafe void InternalCopyTo(int sourceIndex, char[] destination,
+ int destinationIndex, int count) {
+ // See also Lightning\Src\VM\COMString.cpp::GetPreallocatedCharArray
+ if (sourceIndex + count > this.m_stringLength) {
+ throw new ArgumentOutOfRangeException();
+ }
+ if (count > 0) {
+ // Necessary test as &destination[0] is illegal for empty array
+ fixed (char *srcPtrFixed = &this.m_firstChar) {
+ fixed (char *dstPtrFixed = destination) {
+ char *srcPtr = srcPtrFixed + sourceIndex;
+ char *dstPtr = dstPtrFixed + destinationIndex;
+ Buffer.MoveMemory((byte *)dstPtr, (byte *)srcPtr,
+ count * sizeof(char));
+ }
+ }
+ }
+ }
+
+ internal unsafe void CopyToByteArray(int sourceIndex, byte[] destination,
+ int destinationIndex, int charCount)
+ {
+ // See also Lightning\Src\VM\COMString.cpp::InternalCopyToByteArray
+ // Called by System.Text.UnicodeEncoding.GetBytes() for little-endian Unicode.
+
+ if (destination == null)
+ throw new ArgumentNullException("destination");
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException("charCount");
+ if (destinationIndex < 0)
+ throw new ArgumentOutOfRangeException("destinationIndex");
+ if (sourceIndex < 0)
+ throw new ArgumentOutOfRangeException("sourceIndex");
+ if (sourceIndex + charCount > this.m_stringLength)
+ throw new ArgumentOutOfRangeException("charCount");
+
+ int byteCount = charCount * 2;
+ if (destinationIndex + byteCount > destination.Length)
+ throw new ArgumentOutOfRangeException("destinationLength");
+
+ if (charCount > 0) {
+ fixed (byte* dest = &destination[destinationIndex])
+ fixed (char* src_char0 = &this.m_firstChar) {
+ byte* src_bytes = (byte*)(&src_char0[sourceIndex]);
+ Buffer.MoveMemory(dest, src_bytes, byteCount);
+ }
+ }
+ }
+
+ // Returns the entire string as an array of characters.
+ //|
+ public char[] ToCharArray() {
+ return ToCharArray(0,Length);
+ }
+
+ // Returns a substring of this string as an array of characters.
+ //
+ //|
+ public char[] ToCharArray(int startIndex, int length)
+ {
+ // Range check everything.
+ if (startIndex < 0 || startIndex > Length || startIndex > Length - length)
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_Index");
+ if (length < 0)
+ throw new ArgumentOutOfRangeException("length", "ArgumentOutOfRange_Index");
+
+ char[] chars = new char[length];
+ InternalCopyTo(startIndex, chars, 0, length);
+ return chars;
+ }
+
+ // Gets a hash code for this string. If strings A and B are such that A.Equals(B), then
+ // they will return the same hash code.
+ //|
+ public unsafe override int GetHashCode() {
+ // See also Lightning\Src\VM\COMString.cpp::GetHashCode
+ fixed (char *charPtrFixed = &this.m_firstChar) {
+ char *charPtr = charPtrFixed;
+ if (charPtr[this.m_stringLength] != 0) {
+ throw new Exception("Bartok string is not null terminated");
+ }
+ // See also Lightning\Src\UtilCode.h::HashString
+ uint hash = 5381;
+ char c = *charPtr;
+ while (c != 0) {
+ hash = ((hash << 5) + hash) ^ c;
+ charPtr++;
+ c = *charPtr;
+ }
+ return (int) hash;
+ }
+ }
+
+ // Gets the length of this string
+ //|
+ public int Length {
+ [NoHeapAllocation]
+ get { return InternalLength(); }
+ }
+
+ ///
+ internal int ArrayLength {
+ [NoHeapAllocation]
+ get { return (m_arrayLength); }
+ }
+
+ // Used by StringBuilder
+ internal int Capacity {
+ [NoHeapAllocation]
+ get { return (m_arrayLength - 1); }
+ }
+
+ // Creates an array of strings by splitting this string at each
+ // occurrence of a separator. The separator is searched for, and if found,
+ // the substring preceding the occurrence is stored as the first element in
+ // the array of strings. We then continue in this manner by searching
+ // the substring that follows the occurrence. On the other hand, if the separator
+ // is not found, the array of strings will contain this instance as its only element.
+ // If the separator is null
+ // whitespace (i.e., Character.IsWhitespace) is used as the separator.
+ //
+ //|
+ public String [] Split(params char [] separator) {
+ return Split(separator, Int32.MaxValue);
+ }
+
+ //==============================MakeSeparatorList========================
+ //Args: baseString -- the string to parse for the given list of
+ // separator chars.
+ // Separator -- A string containing all of the split characters.
+ // list -- a pointer to a caller-allocated array of ints for
+ // split char indices.
+ // listLength -- the number of slots allocated in list.
+ //Returns: A list of all of the places within baseString where instances
+ // of characters in Separator occur.
+ //Exceptions: None.
+ //N.B.: This just returns silently if the caller hasn't allocated
+ // enough space for the int list.
+ //=======================================================================
+
+ // WCHAR * -> char *
+ // int * -> int[]
+
+ // CHARARRAYREF --> char[]
+ // c->GetNumComponents --> c.Length
+
+ // STRINGREF --> String
+ // s->GetStringLength --> s.Length
+ // s->GetBuffer --> fixed(&s.m_firstChar)
+
+ // COMNlsInfo::nativeIsWhiteSpace --> Char.IsWhiteSpace
+ // ArrayContains(char,char* start,char* end)
+ // --> ArrayContains(char, char[] buf)
+ private unsafe static int MakeSeparatorList(String baseString, char[] Separator, int[] list, int listLength) {
+ // From Lightning\Src\VM\COMString.cpp::MakeSeparatorList
+ int i;
+ int foundCount=0;
+ fixed (char *thisChars = &baseString.m_firstChar) {
+ int thisLength = baseString.Length;
+
+ if (Separator == null || Separator.Length == 0) {
+ //If they passed null or an empty string,
+ //look for whitespace.
+ for (i = 0; i < thisLength && foundCount < listLength; i++) {
+ // was nativeIsWhiteSpace()
+ if (Char.IsWhiteSpace(thisChars[i])) {
+ list[foundCount++]=i;
+ }
+ }
+ }
+ else {
+ //WCHAR *searchChars = (WCHAR *)Separator->GetDataPtr();
+
+ int searchLength = Separator.Length;
+ //If they passed in a string of chars,
+ //actually look for those chars.
+ for (i = 0; i < thisLength && foundCount < listLength; i++) {
+ if (ArrayContains(thisChars[i],Separator) >= 0) {
+ list[foundCount++]=i;
+ }
+ }
+ }
+ return foundCount;
+ }
+ }
+
+ // Creates an array of strings by splitting this string at each
+ // occurrence of a separator. The separator is searched for, and if found,
+ // the substring preceding the occurrence is stored as the first element in
+ // the array of strings. We then continue in this manner by searching
+ // the substring that follows the occurrence. On the other hand, if the separator
+ // is not found, the array of strings will contain this instance as its only element.
+ // If the separator is the empty string (i.e., String.Empty), then
+ // whitespace (i.e., Character.IsWhitespace) is used as the separator.
+ // If there are more than count different strings, the last n-(count-1)
+ // elements are concatenated and added as the last String.
+ //
+ //|
+ //|
+
+ // STRINGREF --> String
+ // PTRARRAYREF --> String[]
+ // p->SetAt(0, v) --> p[0] = v
+ //
+ // LPVOID --> gone
+ // CQuickBytes --> gone
+
+ // AllocateObjectArray(x,g_pStringClass) --> new String[x]
+ // NewString(&ref, index, size) --> ref.Substring(index, size)
+
+ public String[] Split(char[] separator, int count) {
+ // See also Lightning\Src\VM\COMString.cpp::Split
+ // This implementation based on COMString
+
+ int numReplaces;
+ int numActualReplaces;
+ int[] sepList;
+ int currIndex=0;
+ int arrIndex=0;
+ //char *thisChars;
+ int thisLength;
+ int i;
+ String[] splitStrings;
+ String temp;
+
+ if (count < 0) {
+ throw new ArgumentOutOfRangeException
+ ("count", "ArgumentOutOfRange_Negative");
+ }
+
+ //Allocate space and fill an array of ints with a list of everyplace
+ //within our String that a separator character occurs.
+ sepList = new int[this.Length];
+ numReplaces = MakeSeparatorList(this, separator, sepList, this.Length);
+ //Handle the special case of no replaces.
+ if (0 == numReplaces) {
+ splitStrings = new String[1];
+ splitStrings[0] = this;
+ return splitStrings;
+ }
+ thisLength = Length;
+
+ count--;
+ numActualReplaces = (numReplaces
+ public String Substring(int startIndex) {
+ return this.Substring (startIndex, Length-startIndex);
+ }
+
+ // Returns a substring of this string.
+ //
+ //|
+ public String Substring(int startIndex, int length) {
+
+ int thisLength = Length;
+
+ //Bounds Checking.
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_StartIndex");
+ }
+
+ if (length < 0) {
+ throw new ArgumentOutOfRangeException("length", "ArgumentOutOfRange_NegativeLength");
+ }
+
+ if (startIndex > thisLength - length) {
+ throw new ArgumentOutOfRangeException("length", "ArgumentOutOfRange_IndexLength");
+ }
+
+ String s = FastAllocateString(length);
+ FillSubstring(s, 0, this, startIndex, length);
+
+ return s;
+ }
+
+ internal String TrimHelper(char[] trimChars, int trimType)
+ {
+ // See also Lighting\Src\VM\COMString.cpp::TrimHelper
+ int stringLength = this.m_stringLength;
+ int iLeft = 0;
+ int iRight = stringLength - 1;
+ this.TrimHelper(trimChars, trimType, ref iLeft, ref iRight);
+ int newLength = iRight - iLeft + 1;
+ if (newLength == stringLength) {
+ return this;
+ }
+ else if (newLength == 0) {
+ return String.Empty;
+ }
+ else {
+ String result = FastAllocateString(newLength);
+ FillSubstring(result, 0, this, iLeft, newLength);
+ return result;
+ }
+ }
+
+ private unsafe void TrimHelper(char[] trimChars, int trimType,
+ ref int iLeft, ref int iRight)
+ {
+ fixed (char *charPtr = &this.m_firstChar) {
+ if (trimType == String.TrimHead ||
+ trimType == String.TrimBoth) {
+ while (iLeft <= iRight &&
+ ArrayContains(charPtr[iLeft], trimChars) >= 0) {
+ iLeft++;
+ }
+ }
+ if (trimType == String.TrimTail ||
+ trimType == String.TrimBoth) {
+ while (iRight >= iLeft &&
+ ArrayContains(charPtr[iRight], trimChars) >= 0) {
+ iRight--;
+ }
+ }
+ }
+ }
+
+ private static int ArrayContains(char c, char[] charArray) {
+ int limit = charArray.Length;
+ for (int i = 0; i < limit; i++) {
+ if (charArray[i] == c) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ ///
+ // Creates a new string from the characters in a subarray. The new
+ // string will be created from the characters in value between
+ // startIndex and startIndex + length - 1.
+ //
+ // @param value an array of characters.
+ // @param startIndex the index at which the subarray begins.
+ // @param length the length of the subarray.
+ //
+ // @exception ArgumentException if value is null.
+ // @exception ArgumentException if startIndex or
+ // startIndex+length-1 are not valid indices of
+ // value.
+ //
+ //|
+
+ public static String StringCTOR(char[] value, int startIndex,
+ int length) {
+ // See also Lightning\Src\VM\COMString.cpp::StringInitCharArray
+ if (value == null) {
+ throw new ArgumentNullException("array value is null");
+ }
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (length < 0) {
+ throw new ArgumentOutOfRangeException("length is negative");
+ }
+ if (length == 0) {
+ return String.Empty;
+ }
+ else {
+ String result = FastAllocateString(length);
+ FillStringArray(result, 0, value, startIndex, length);
+ return result;
+ }
+ }
+
+ ///
+ // Creates a new string from the characters in a subarray. The new
+ // string will be created from the characters in value.
+ //
+ // @param value an array of characters.
+ //
+ // @exception ArgumentException if value is null.
+ //
+ //|
+ public static String StringCTOR(char[] value) {
+ // See also Lightning\Src\VM\COMString.cpp::StringInitChars
+ if (value == null) {
+ return String.Empty;
+ }
+ int length = value.Length;
+ if (length == 0) {
+ return String.Empty;
+ }
+ String result = FastAllocateString(length);
+ FillStringArray(result, 0, value, 0, length);
+ return result;
+ }
+
+ internal static String NewString(String curr,int start,int copyLen,
+ int capacity) {
+ String result = FastAllocateString(capacity);
+ FillSubstring(result, 0, curr, start, copyLen);
+ return result;
+ }
+
+ //|
+ public static String StringCTOR(char c, int count) {
+ // See also Lightning\Src\VM\COMString.cpp::StringInitCharCount
+ if (count < 0) {
+ throw new ArgumentOutOfRangeException("count is negative");
+ }
+ if (count == 0) {
+ return String.Empty;
+ }
+ else {
+ String result = FastAllocateString(count);
+ FillStringChar(result, 0, c, count);
+ return result;
+ }
+ }
+
+ // Removes a string of characters from the ends of this string.
+ //|
+ public String Trim(params char[] trimChars) {
+ if (null == trimChars || trimChars.Length == 0) {
+ trimChars=CharacterInfo.WhitespaceChars;
+ }
+ return TrimHelper(trimChars,TrimBoth);
+ }
+
+ // Removes a string of characters from the beginning of this string.
+ //|
+ public String TrimStart(params char[] trimChars) {
+ if (null == trimChars || trimChars.Length == 0) {
+ trimChars=CharacterInfo.WhitespaceChars;
+ }
+ return TrimHelper(trimChars,TrimHead);
+ }
+
+
+ // Removes a string of characters from the end of this string.
+ //|
+ public String TrimEnd(params char[] trimChars) {
+ if (null == trimChars || trimChars.Length == 0) {
+ trimChars=CharacterInfo.WhitespaceChars;
+ }
+ return TrimHelper(trimChars,TrimTail);
+ }
+
+ unsafe static private String CreateString(sbyte *value, int startIndex, int length, Encoding enc) {
+ if (enc == null)
+ return new String(value, startIndex, length); // default to ANSI
+ if (length < 0)
+ throw new ArgumentOutOfRangeException("length","ArgumentOutOfRange_NeedNonNegNum");
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex","ArgumentOutOfRange_StartIndex");
+ }
+ if ((value + startIndex) < value) {
+ // overflow check
+ throw new ArgumentOutOfRangeException("startIndex","ArgumentOutOfRange_PartialWCHAR");
+ }
+ byte [] b = new byte[length];
+ if (length > 0) {
+ fixed(byte* pDest = b) {
+ Buffer.MoveMemory(pDest, ((byte*)value)+startIndex, length);
+ }
+ }
+ return enc.GetString(b);
+ }
+
+ // For ASCIIEncoding::GetString()
+ unsafe static internal String CreateStringFromASCII(byte[] bytes, int startIndex, int length) {
+ Debug.Assert(bytes != null, "need a byte[].");
+ Debug.Assert(startIndex >= 0 && (startIndex < bytes.Length || bytes.Length == 0), "startIndex >= 0 && startIndex < bytes.Length");
+ Debug.Assert(length >= 0 && length <= bytes.Length - startIndex, "length >= 0 && length <= bytes.Length - startIndex");
+ if (length == 0)
+ return String.Empty;
+ String s = FastAllocateString(length);
+ fixed(char* pChars = &s.m_firstChar) {
+ for (int i = 0; i < length; i++)
+ pChars[i] = (char) (bytes[i+startIndex] & 0x7f);
+ }
+ return s;
+ }
+
+ // For Latin1Encoding::GetString()
+ unsafe static internal String CreateStringFromLatin1(byte[] bytes, int startIndex, int length) {
+ Debug.Assert(bytes != null, "need a byte[].");
+ Debug.Assert(startIndex >= 0 && (startIndex < bytes.Length || bytes.Length == 0), "startIndex >= 0 && startIndex < bytes.Length");
+ Debug.Assert(length >= 0 && length <= bytes.Length - startIndex, "length >= 0 && length <= bytes.Length - startIndex");
+ if (length == 0)
+ return String.Empty;
+ String s = FastAllocateString(length);
+ fixed(char* pChars = &s.m_firstChar) {
+ for (int i = 0; i < length; i++)
+ pChars[i] = (char) (bytes[i+startIndex]);
+ }
+ return s;
+ }
+
+ private static String FastAllocateString(int stringLength) {
+ return GC.AllocateString(stringLength);
+ }
+
+ [Inline]
+ internal void InitializeStringLength(int stringLength) {
+ this.m_arrayLength = stringLength+1;
+ this.m_stringLength = stringLength;
+ }
+
+ private unsafe static void FillString(String dest, int destPos,
+ String src) {
+ fixed (char *srcPtr = &src.m_firstChar) {
+ FillStringCharPtr(dest, destPos, srcPtr, src.m_stringLength);
+ }
+ }
+
+ private unsafe static void FillStringChecked(String dest, int destPos,
+ String src) {
+ if (!(src.Length <= dest.ArrayLength - destPos)) {
+ throw new IndexOutOfRangeException(); // REVIEW: param?
+ }
+ fixed (char *srcPtr = &src.m_firstChar) {
+ FillStringCharPtr(dest, destPos, srcPtr, src.m_stringLength);
+ }
+ }
+
+ private unsafe static void FillStringEx(String dest, int destPos,
+ String src,int srcLength) {
+ // ASSERT(srcLength <= dest.ArrayLength - destPos);
+ fixed (char *srcPtr = &src.m_firstChar) {
+ FillStringCharPtr(dest, destPos, srcPtr, srcLength);
+ }
+ }
+
+ private unsafe static void FillStringChar(String dest, int destPos,
+ char c, int count) {
+ fixed (char *destPtr = &dest.m_firstChar) {
+ char *charPtr = destPtr + destPos;
+ // Set the odd leader char if necessary
+ if (destPos % 2 == 1) {
+ *charPtr = c;
+ charPtr++;
+ count--;
+ }
+ // Set the buffer 2 chars at a time
+ int c2 = (c << 16) | c;
+ int *intPtr = (int *) charPtr;
+ count--; // Prevent overruns from odd lengths
+ while (count > 0) {
+ *intPtr = c2;
+ intPtr++;
+ count -= 2;
+ }
+ // Set the odd trailer char if necessary
+ if (count == 0) {
+ *((char *) intPtr) = c;
+ }
+ }
+ }
+
+ private unsafe static void FillStringCharPtr(String dest, int destPos,
+ char *srcPtr, int count) {
+ fixed (char *charPtr = &dest.m_firstChar) {
+ char *destPtr = charPtr + destPos;
+ Buffer.MoveMemory((byte *)destPtr, (byte *)srcPtr, count * sizeof(char));
+ }
+ }
+
+ private unsafe static void FillStringBytePtr(String dest, int destPos,
+ byte *srcPtr, int count) {
+ fixed (char *charPtr = &dest.m_firstChar) {
+ char *destPtr = charPtr + destPos;
+ for (int i = 0; i < count; i++) {
+ *destPtr++ = (char)*srcPtr++;
+ }
+ }
+ }
+
+ private unsafe static void FillStringArray(String dest, int stringStart,
+ char[] array, int charStart,
+ int count) {
+ fixed (char *destPtr = &array[charStart]) {
+ FillStringCharPtr(dest, stringStart, destPtr, count);
+ }
+ }
+
+ private unsafe static void FillSubstring(String dest, int destPos,
+ String src, int startPos,
+ int count) {
+ fixed (char *srcPtr = &src.m_firstChar) {
+ FillStringCharPtr(dest, destPos, srcPtr + startPos, count);
+ }
+ }
+
+ //
+ //
+ // INSTANCE METHODS
+ //
+ //
+
+ // Provides a culture-correct string comparison. StrA is compared to StrB
+ // to determine whether it is lexicographically less, equal, or greater, and then returns
+ // either a negative integer, 0, or a positive integer; respectively.
+ //
+ //|
+ public static int Compare(String strA, String strB) {
+ return CompareInfo.Compare(strA, strB, CompareOptions.None);
+ }
+
+ // Provides a culture-correct string comparison. strA is compared to strB
+ // to determine whether it is lexicographically less, equal, or greater, and then a
+ // negative integer, 0, or a positive integer is returned; respectively.
+ // The case-sensitive option is set by ignoreCase
+ //
+ //|
+ public static int Compare(String strA, String strB, bool ignoreCase) {
+ if (ignoreCase) {
+ return CompareInfo.Compare(strA, strB, CompareOptions.IgnoreCase);
+ }
+ return CompareInfo.Compare(strA, strB, CompareOptions.None);
+ }
+
+ // [Bartok]:
+ public static int Compare(String strA, String strB, bool ignoreCase,
+ CultureInfo info)
+ {
+ return Compare(strA, strB, ignoreCase);
+ }
+
+ // Determines whether two string regions match. The substring of strA beginning
+ // at indexA of length count is compared with the substring of strB
+ // beginning at indexB of the same length.
+ //
+ //|
+ public static int Compare(String strA, int indexA, String strB, int indexB, int length) {
+ int lengthA = length;
+ int lengthB = length;
+
+ if (strA != null) {
+ if (strA.Length - indexA < lengthA) {
+ lengthA = (strA.Length - indexA);
+ }
+ }
+
+ if (strB != null) {
+ if (strB.Length - indexB < lengthB) {
+ lengthB = (strB.Length - indexB);
+ }
+ }
+ return CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);
+ }
+
+
+ // Determines whether two string regions match. The substring of strA beginning
+ // at indexA of length count is compared with the substring of strB
+ // beginning at indexB of the same length. Case sensitivity is determined by the ignoreCase boolean.
+ //
+ //|
+ public static int Compare(String strA, int indexA, String strB, int indexB, int length, bool ignoreCase) {
+ int lengthA = length;
+ int lengthB = length;
+
+ if (strA != null) {
+ if (strA.Length - indexA < lengthA) {
+ lengthA = (strA.Length - indexA);
+ }
+ }
+
+ if (strB != null) {
+ if (strB.Length - indexB < lengthB) {
+ lengthB = (strB.Length - indexB);
+ }
+ }
+
+ if (ignoreCase) {
+ return CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.IgnoreCase);
+ }
+ return CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);
+ }
+
+ // Compares this object to another object, returning an integer that
+ // indicates the relationship. This method returns a value less than 0 if this is less than value, 0
+ // if this is equal to value, or a value greater than 0
+ // if this is greater than value. Strings are considered to be
+ // greater than all non-String objects. Note that this means sorted
+ // arrays would contain nulls, other objects, then Strings in that order.
+ //
+ //|
+ public int CompareTo(Object value) {
+ if (value == null) {
+ return 1;
+ }
+
+ if (!(value is String)) {
+ throw new ArgumentException("Arg_MustBeString");
+ }
+
+ return String.Compare(this,(String)value);
+ }
+
+ // Determines the sorting relation of StrB to the current instance.
+ //
+ //|
+ public int CompareTo(String strB) {
+ if (strB == null) {
+ return 1;
+ }
+ return CompareInfo.Compare(this, strB, 0);
+ }
+
+ // Compares strA and strB using an ordinal (code-point) comparison.
+ //
+ //|
+ public static int CompareOrdinal(String strA, String strB) {
+ if (strA == null || strB == null) {
+ if ((Object)strA ==(Object)strB) { //they're both null;
+ return 0;
+ }
+ return (strA==null)? -1 : 1; //-1 if A is null, 1 if B is null.
+ }
+
+ return nativeCompareOrdinal(strA, strB, false);
+ }
+
+ // Compares strA and strB using an ordinal (code-point) comparison.
+ //
+ //|
+ public static int CompareOrdinal(String strA, String strB, bool ignoreCase) {
+ if (strA == null || strB == null) {
+ if ((Object)strA ==(Object)strB) { //they're both null;
+ return 0;
+ }
+ return (strA==null)? -1 : 1; //-1 if A is null, 1 if B is null.
+ }
+
+ return nativeCompareOrdinal(strA, strB, ignoreCase);
+ }
+
+ // Compares strA and strB using an ordinal (code-point) comparison.
+ //
+ //|
+ public static int CompareOrdinal(String strA, int indexA, String strB, int indexB, int length) {
+ if (strA == null || strB == null) {
+ if ((Object)strA ==(Object)strB) { //they're both null;
+ return 0;
+ }
+
+ return (strA==null)? -1 : 1; //-1 if A is null, 1 if B is null.
+ }
+
+ return nativeCompareOrdinalEx(strA, indexA, strB, indexB, length);
+ }
+
+
+ // Determines whether a specified string is a suffix of the the current instance.
+ //
+ // The case-sensitive and culture-sensitive option is set by options,
+ // and the default culture is used.
+ //
+ //|
+ public bool EndsWith(String value) {
+ if (null == value) {
+ throw new ArgumentNullException("value");
+ }
+ int valueLen = value.Length;
+ int thisLen = this.Length;
+ if (valueLen > thisLen) {
+ return false;
+ }
+ return (0==Compare(this, thisLen-valueLen, value, 0, valueLen));
+ }
+
+ public bool EndsWith(char value) {
+ int thisLen = this.Length;
+ if (thisLen != 0) {
+ if (this[thisLen - 1] == value)
+ return true;
+ }
+ return false;
+ }
+
+
+ // Returns the index of the first occurrence of value in the current instance.
+ // The search starts at startIndex and runs thorough the next count characters.
+ //
+ //|
+ public int IndexOf(char value) {
+ return IndexOf(value, 0, this.Length);
+ }
+
+ //|
+ public int IndexOf(char value, int startIndex) {
+ return IndexOf(value, startIndex, this.Length - startIndex);
+ }
+
+ //|
+ public unsafe int IndexOf(char value, int startIndex, int count) {
+ // See also Lightning\Src\VM\COMString.cpp::IndexOfChar
+ if (startIndex < 0 || startIndex > this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("startIndex out of range");
+ }
+ if (count < 0 || startIndex + count > this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("count out of range");
+ }
+ fixed (char *charPtr = &this.m_firstChar) {
+ char *cursor = charPtr + startIndex;
+ for (int i = count; i > 0; i--) {
+ if (*cursor == value) {
+ return (startIndex + (count - i));
+ }
+ cursor++;
+ }
+ }
+ return -1;
+ }
+
+ // Returns the index of the first occurrence of any character in value in the current instance.
+ // The search starts at startIndex and runs to endIndex-1. [startIndex,endIndex).
+ //
+
+ //|
+ public int IndexOfAny(char [] anyOf) {
+ return IndexOfAny(anyOf,0, this.Length);
+ }
+
+ //|
+ public int IndexOfAny(char [] anyOf, int startIndex) {
+ return IndexOfAny(anyOf, startIndex, this.Length - startIndex);
+ }
+
+ //|
+ public unsafe int IndexOfAny(char [] anyOf, int startIndex, int count) {
+ // See also Lightning\Src\VM\COMString.cpp::IndexOfCharArray
+ if (anyOf == null) {
+ throw new ArgumentNullException("anyOf array is null");
+ }
+ if (startIndex < 0 || startIndex > this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("startIndex out of range");
+ }
+ if (count < 0 || startIndex + count > this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("count out of range");
+ }
+ fixed (char *charPtr = &this.m_firstChar) {
+ char *cursor = charPtr + startIndex;
+ for (int i = count; i > 0; i--) {
+ if (ArrayContains(*cursor, anyOf) >= 0) {
+ return (startIndex + (count - i));
+ }
+ cursor++;
+ }
+ }
+ return -1;
+ }
+
+ // Determines the position within this string of the first occurrence of the specified
+ // string, according to the specified search criteria. The search begins at
+ // the first character of this string, it is case-sensitive and culture-sensitive,
+ // and the default culture is used.
+ //
+ //|
+ public int IndexOf(String value) {
+ return CompareInfo.IndexOf(this,value);
+ }
+
+ // Determines the position within this string of the first occurrence of the specified
+ // string, according to the specified search criteria. The search begins at
+ // startIndex, it is case-sensitive and culture-sensitve, and the default culture is used.
+ //
+ //|
+ public int IndexOf(String value, int startIndex){
+ return CompareInfo.IndexOf(this,value,startIndex);
+ }
+
+ // Determines the position within this string of the first occurrence of the specified
+ // string, according to the specified search criteria. The search begins at
+ // startIndex, ends at endIndex and the default culture is used.
+ //
+ //|
+ public int IndexOf(String value, int startIndex, int count){
+ if (startIndex + count > this.Length) {
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_Index");
+ }
+ return CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.None);
+ }
+
+
+ // Returns the index of the last occurrence of value in the current instance.
+ // The search starts at startIndex and runs to endIndex. [startIndex,endIndex].
+ // The character at position startIndex is included in the search. startIndex is the larger
+ // index within the string.
+ //
+ //|
+ public int LastIndexOf(char value) {
+ return LastIndexOf(value, this.Length-1, this.Length);
+ }
+
+ //|
+ public int LastIndexOf(char value, int startIndex){
+ return LastIndexOf(value,startIndex,startIndex + 1);
+ }
+
+ //|
+ public unsafe int LastIndexOf(char value, int startIndex, int count) {
+ // See also Lightning\Src\VM\COMString.cpp::LastIndexOfChar
+ if (this.m_stringLength == 0) {
+ return -1;
+ }
+ if (startIndex < 0 || startIndex >= this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("startIndex out of range");
+ }
+ if (count < 0 || count - 1 > startIndex) {
+ throw new ArgumentOutOfRangeException("count out of range");
+ }
+ fixed (char *charPtr = &this.m_firstChar) {
+ char *cursor = charPtr + startIndex;
+ for (int i = count; i > 0; i--) {
+ if (*cursor == value) {
+ return (startIndex - (count - i));
+ }
+ cursor--;
+ }
+ }
+ return -1;
+ }
+
+ // Returns the index of the last occurrence of any character in value in the current instance.
+ // The search starts at startIndex and runs to endIndex. [startIndex,endIndex].
+ // The character at position startIndex is included in the search. startIndex is the larger
+ // index within the string.
+ //
+
+ //|
+ public int LastIndexOfAny(char [] anyOf) {
+ return LastIndexOfAny(anyOf,this.Length-1,this.Length);
+ }
+
+ //|
+ public int LastIndexOfAny(char [] anyOf, int startIndex) {
+ return LastIndexOfAny(anyOf,startIndex,startIndex + 1);
+ }
+
+ //|
+ public unsafe int LastIndexOfAny(char [] anyOf, int startIndex,
+ int count) {
+ // See also Lightning\Src\VM\COMString.cpp::LastIndexOfCharArray
+ if (anyOf == null) {
+ throw new ArgumentNullException("anyOf array is null");
+ }
+ if (this.m_stringLength == 0) {
+ return -1;
+ }
+ if (startIndex < 0 || startIndex >= this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("startIndex out of range");
+ }
+ if (count < 0 || count - 1 > startIndex) {
+ throw new ArgumentOutOfRangeException("count out of range");
+ }
+ fixed (char *charPtr = &this.m_firstChar) {
+ char *cursor = charPtr + startIndex;
+ for (int i = count; i > 0; i--) {
+ if (ArrayContains(*cursor, anyOf) >= 0) {
+ return (startIndex - (count - 1));
+ }
+ cursor--;
+ }
+ }
+ return -1;
+ }
+
+ // Returns the index of the last occurrence of any character in value in the current instance.
+ // The search starts at startIndex and runs to endIndex. [startIndex,endIndex].
+ // The character at position startIndex is included in the search. startIndex is the larger
+ // index within the string.
+ //
+ //|
+ public int LastIndexOf(String value) {
+ return LastIndexOf(value, this.Length-1,this.Length);
+ }
+
+ //|
+ public int LastIndexOf(String value, int startIndex) {
+ return LastIndexOf(value, startIndex, startIndex + 1);
+ }
+
+ //|
+ public int LastIndexOf(String value, int startIndex, int count) {
+ if (count < 0) {
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_Count");
+ }
+ return CompareInfo.LastIndexOf(this, value, startIndex, count, CompareOptions.None);
+ }
+
+
+ //
+ //
+ //|
+ public String PadLeft(int totalWidth) {
+ return PadHelper(totalWidth, ' ', false);
+ }
+
+ //|
+ public String PadLeft(int totalWidth, char paddingChar) {
+ return PadHelper(totalWidth, paddingChar, false);
+ }
+
+ //|
+ public String PadRight(int totalWidth) {
+ return PadHelper(totalWidth, ' ', true);
+ }
+
+ //|
+ public String PadRight(int totalWidth, char paddingChar) {
+ return PadHelper(totalWidth, paddingChar, true);
+ }
+
+ private String PadHelper(int totalWidth, char paddingChar,
+ bool isRightPadded) {
+ // See also Lightning\Src\VM\COMString.cpp::PadHelper
+ if (totalWidth < 0) {
+ throw new ArgumentOutOfRangeException("totalWidth is negative");
+ }
+ if (totalWidth <= this.m_stringLength) {
+ return this;
+ }
+ int padCount = totalWidth - this.m_stringLength;
+ String result = FastAllocateString(totalWidth);
+ if (isRightPadded) {
+ FillString(result, 0, this);
+ FillStringChar(result, this.m_stringLength,
+ paddingChar, padCount);
+ }
+ else {
+
+ FillStringChar(result, 0, paddingChar, padCount);
+ FillString(result, padCount, this);
+ }
+ return result;
+ }
+
+ // Determines whether a specified string is a prefix of the current instance
+ //
+ //|
+ public bool StartsWith(String value) {
+ if (null == value) {
+ throw new ArgumentNullException("value");
+ }
+ if (this.Length < value.Length) {
+ return false;
+ }
+ return (0==Compare(this,0, value,0, value.Length));
+ }
+
+ // Creates a copy of this string in lower case.
+ //|
+ public String ToLower() {
+ return TextInfo.ToLower(this);
+ }
+
+ // Creates a copy of this string in upper case.
+ //|
+ public String ToUpper() {
+ return TextInfo.ToUpper(this);
+ }
+
+ // Returns this string.
+ //|
+ public override String ToString() {
+ return this;
+ }
+
+ // Method required for the ICloneable interface.
+ // There's no point in cloning a string since they're immutable, so we simply return this.
+ //|
+ public Object Clone() {
+ return this;
+ }
+
+
+ // Trims the whitespace from both ends of the string. Whitespace is defined by
+ // CharacterInfo.WhitespaceChars.
+ //
+ //|
+ public String Trim() {
+ return this.Trim(CharacterInfo.WhitespaceChars);
+ }
+
+ //
+ //
+ //|
+ public String Insert(int startIndex, String value) {
+ // See also Lightning\Src\VM\COMString.cpp::Insert
+ if (startIndex < 0 || startIndex > this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("startIndex out of range");
+ }
+ if (value == null) {
+ throw new ArgumentNullException("value string is null");
+ }
+ int newLength = this.m_stringLength + value.m_stringLength;
+ String result = FastAllocateString(newLength);
+ FillSubstring(result, 0, this, 0, startIndex);
+ FillSubstring(result, startIndex, value, 0, value.m_stringLength);
+ FillSubstring(result, startIndex + value.m_stringLength,
+ this, startIndex, this.m_stringLength - startIndex);
+ return result;
+ }
+
+ internal unsafe void InsertHoleInString(int startIndex, int holeSize) {
+ int tail = this.m_stringLength - startIndex;
+ this.m_stringLength += holeSize;
+ if (tail > 0) {
+ fixed (char *charPtr = &this.m_firstChar) {
+ char *srcPtr = charPtr + startIndex;
+ char *dstPtr = charPtr + holeSize;
+ Buffer.MoveMemory((byte *)dstPtr, (byte *)srcPtr,
+ tail * sizeof(char));
+ }
+ }
+ }
+
+ internal unsafe void InsertStringOverwrite(String value, int startIndex, int valueLength) {
+ fixed (char *charPtr = &this.m_firstChar) {
+ char *dstPtr = charPtr + startIndex;
+ fixed (char *srcPtr = &value.m_firstChar) {
+ Buffer.MoveMemory((byte *)dstPtr, (byte *)srcPtr,
+ valueLength * sizeof(char));
+ }
+ }
+ }
+
+ // Replaces all instances of oldChar with newChar.
+ //
+ //|
+ public String Replace(char oldChar, char newChar) {
+ // See also Lightning\Src\VM\COMString.cpp::Replace
+ String result = FastAllocateString(this.m_stringLength);
+ this.Replace(oldChar, newChar, result);
+ return result;
+ }
+
+ private unsafe void Replace(char oldChar, char newChar, String newString) {
+ fixed (char *srcPtr = &this.m_firstChar) {
+ fixed (char *destPtr = &newString.m_firstChar) {
+ char *srcCursor = srcPtr;
+ char *destCursor = destPtr;
+ for (int i = this.m_stringLength; i > 0; i--) {
+ char c = *srcCursor;
+ *destCursor = (c == oldChar) ? newChar : c;
+ srcCursor++;
+ destCursor++;
+ }
+ }
+ }
+ }
+
+ // This method contains the same functionality as StringBuilder Replace. The only difference is that
+ // a new String has to be allocated since Strings are immutable
+ //|
+ public String Replace(String oldValue, String newValue) {
+ // See also Lightning\Src\VM\COMString.cpp::ReplaceString
+ if (oldValue == null) {
+ throw new ArgumentNullException("oldString is null");
+ }
+ if (newValue == null) {
+ newValue = String.Empty;
+ }
+ if (oldValue.m_stringLength == 0) {
+ throw new ArgumentException("oldString is empty string");
+ }
+ int matchIndex = LocalIndexOfString(oldValue, 0);
+ if (matchIndex < 0) {
+ return this;
+ }
+ // Compute a table of where to insert newValue
+ int replaceCount = 0;
+ int[] replacementTable = new int[(this.m_stringLength - matchIndex) / oldValue.m_stringLength + 1];
+ do {
+ replacementTable[replaceCount] = matchIndex;
+ replaceCount++;
+ matchIndex = LocalIndexOfString(oldValue, matchIndex+oldValue.m_stringLength);
+ } while (matchIndex >= 0);
+ int newLength = this.m_stringLength + replaceCount * (newValue.m_stringLength - oldValue.m_stringLength);
+ String result = FastAllocateString(newLength);
+ int srcIndex = 0;
+ int destIndex = 0;
+ for (int replIndex = 0; replIndex < replaceCount; replIndex++) {
+ int count = replacementTable[replIndex] - srcIndex;
+ FillSubstring(result, destIndex, this, srcIndex, count);
+ srcIndex += count + oldValue.m_stringLength;
+ destIndex += count;
+ FillString(result, destIndex, newValue);
+ destIndex += newValue.m_stringLength;
+ }
+ FillSubstring(result, destIndex, this, srcIndex,
+ this.m_stringLength - srcIndex);
+ return result;
+ }
+
+ private unsafe int LocalIndexOfString(String pattern, int startPos) {
+ fixed (char *stringPtr = &this.m_firstChar) {
+ fixed (char *patternPtr = &pattern.m_firstChar) {
+ char *stringCharPtr = stringPtr + startPos;
+ int count = this.m_stringLength - pattern.m_stringLength -
+ startPos + 1;
+ for (int index = 0; index < count; index++) {
+ char *stringCursor = stringCharPtr + index;
+ char *patternCursor = patternPtr;
+ int i = pattern.m_stringLength;
+ while (i > 0 && *stringCursor == *patternCursor) {
+ i--;
+ stringCursor++;
+ patternCursor++;
+ }
+ if (i == 0) {
+ return (startPos + index);
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ //|
+ public String Remove(int startIndex, int count) {
+ if (count < 0) {
+ throw new ArgumentOutOfRangeException("count is negative");
+ }
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex is negative");
+ }
+ if (startIndex + count > this.m_stringLength) {
+ throw new ArgumentOutOfRangeException("startIndex+count>Length");
+ }
+ int newLength = this.m_stringLength - count;
+ String result = FastAllocateString(newLength);
+ FillSubstring(result, 0, this, 0, startIndex);
+ FillSubstring(result, startIndex, this, startIndex + count,
+ newLength - startIndex);
+ return result;
+ }
+
+ internal unsafe void RemoveRange(int startIndex, int count) {
+ int tail = this.m_stringLength - startIndex;
+ this.m_stringLength -= count;
+ if (tail > 0) {
+ fixed (char *charPtr = &this.m_firstChar) {
+ char *dstPtr = charPtr + startIndex;
+ char *srcPtr = dstPtr + count;
+ Buffer.MoveMemory((byte *)dstPtr, (byte *)srcPtr,
+ tail * sizeof(char));
+ }
+ }
+ }
+
+ //|
+ public static String Format(String format, Object arg0) {
+ return Format(format, new Object[] {arg0});
+ }
+
+ //|
+ public static String Format(String format, Object arg0, Object arg1) {
+ return Format(format, new Object[] {arg0, arg1});
+ }
+
+ //|
+ public static String Format(String format, Object arg0, Object arg1, Object arg2) {
+ return Format(format, new Object[] {arg0, arg1, arg2});
+ }
+
+ //|
+ public static String Format(String format, params Object[] args) {
+ if (format == null || args == null)
+ throw new ArgumentNullException((format==null)?"format":"args");
+ StringBuilder sb = new StringBuilder(format.Length + args.Length * 8);
+ sb.AppendFormat(format,args);
+ return sb.ToString();
+ }
+
+ //|
+ public static String Copy (String str) {
+ if (str == null) {
+ throw new ArgumentNullException("str");
+ }
+
+ int length = str.Length;
+
+ String result = FastAllocateString(length);
+ FillString(result, 0, str);
+ return result;
+ }
+
+ // Used by StringBuilder to avoid data corruption
+ internal static String InternalCopy (String str) {
+ int length = str.Length;
+ String result = FastAllocateString(length);
+ FillStringEx(result, 0, str, length); // The underlying's String can changed length is StringBuilder
+ return result;
+ }
+
+ //|
+ public static String Concat(Object arg0) {
+ if (arg0 == null) {
+ return String.Empty;
+ }
+ return arg0.ToString();
+ }
+
+ //|
+ public static String Concat(Object arg0, Object arg1) {
+ if (arg0 == null) {
+ arg0 = String.Empty;
+ }
+
+ if (arg1 == null) {
+ arg1 = String.Empty;
+ }
+ return Concat(arg0.ToString(), arg1.ToString());
+ }
+
+ //|
+ public static String Concat(Object arg0, Object arg1, Object arg2) {
+ if (arg0 == null) {
+ arg0 = String.Empty;
+ }
+
+ if (arg1 == null) {
+ arg1 = String.Empty;
+ }
+
+ if (arg2 == null) {
+ arg2 = String.Empty;
+ }
+
+ return Concat(arg0.ToString(), arg1.ToString(), arg2.ToString());
+ }
+
+ //|
+ public static String Concat(params Object[] args) {
+ if (args == null) {
+ throw new ArgumentNullException("args");
+ }
+
+ String[] sArgs = new String[args.Length];
+ int totalLength=0;
+
+ for (int i = 0; i < args.Length; i++) {
+ object value = args[i];
+ sArgs[i] = ((value==null)?(String.Empty):(value.ToString()));
+ totalLength += sArgs[i].Length;
+ // check for overflow
+ if (totalLength < 0) {
+ throw new OutOfMemoryException();
+ }
+ }
+ return ConcatArray(sArgs, totalLength);
+ }
+
+
+ //|
+ public static String Concat(String str0, String str1) {
+ if (str0 == null) {
+ if (str1 == null) {
+ return String.Empty;
+ }
+ return str1;
+ }
+
+ if (str1 == null) {
+ return str0;
+ }
+
+ int str0Length = str0.Length;
+
+ String result = FastAllocateString(str0Length + str1.Length);
+
+ FillStringChecked(result, 0, str0);
+ FillStringChecked(result, str0Length, str1);
+
+ return result;
+ }
+
+ //|
+ public static String Concat(String str0, String str1, String str2) {
+ if (str0 == null && str1 == null && str2 == null) {
+ return String.Empty;
+ }
+
+ if (str0 == null) {
+ str0 = String.Empty;
+ }
+
+ if (str1 == null) {
+ str1 = String.Empty;
+ }
+
+ if (str2 == null) {
+ str2 = String.Empty;
+ }
+
+ int totalLength = str0.Length + str1.Length + str2.Length;
+
+ String result = FastAllocateString(totalLength);
+ FillStringChecked(result, 0, str0);
+ FillStringChecked(result, str0.Length, str1);
+ FillStringChecked(result, str0.Length + str1.Length, str2);
+
+ return result;
+ }
+
+ //|
+ public static String Concat(String str0, String str1, String str2, String str3) {
+ if (str0 == null && str1 == null && str2 == null && str3 == null) {
+ return String.Empty;
+ }
+
+ if (str0 == null) {
+ str0 = String.Empty;
+ }
+
+ if (str1 == null) {
+ str1 = String.Empty;
+ }
+
+ if (str2 == null) {
+ str2 = String.Empty;
+ }
+
+ if (str3 == null) {
+ str3 = String.Empty;
+ }
+
+ int totalLength = str0.Length + str1.Length + str2.Length + str3.Length;
+
+ String result = FastAllocateString(totalLength);
+ FillStringChecked(result, 0, str0);
+ FillStringChecked(result, str0.Length, str1);
+ FillStringChecked(result, str0.Length + str1.Length, str2);
+ FillStringChecked(result, str0.Length + str1.Length + str2.Length, str3);
+
+ return result;
+ }
+
+ private static String ConcatArray(String[] values, int totalLength) {
+ String result = FastAllocateString(totalLength);
+ int currPos=0;
+
+ for (int i = 0; i < values.Length; i++) {
+ Debug.Assert((currPos + values[i].Length <= totalLength),
+ "[String.ConcatArray](currPos + values[i].Length <= totalLength)");
+
+ FillStringChecked(result, currPos, values[i]);
+ currPos+=values[i].Length;
+ }
+
+ return result;
+ }
+
+ // poor man's varargs for String.Concat: 8 strings
+ public static String Concat(object obj0, object obj1, object obj2,
+ object obj3, string obj4, string obj5,
+ string obj6, string obj7) {
+ String[] strs = new String[8];
+ strs[0] = obj0.ToString();
+ strs[1] = obj1.ToString();
+ strs[2] = obj2.ToString();
+ strs[3] = obj3.ToString();
+ strs[4] = obj4.ToString();
+ strs[5] = obj5.ToString();
+ strs[6] = obj6.ToString();
+ strs[7] = obj7.ToString();
+ return Join(null,strs,0,8);
+ }
+
+ private static String[] CopyArrayOnNull(String[] values, out int totalLength) {
+ totalLength = 0;
+
+ String[] outValues = new String[values.Length];
+
+ for (int i = 0; i < values.Length; i++) {
+ outValues[i] = ((values[i]==null)?String.Empty:values[i]);
+ totalLength += outValues[i].Length;
+ }
+ return outValues;
+ }
+
+ //|
+ public static String Concat(params String[] values) {
+ int totalLength=0;
+
+ if (values == null) {
+ throw new ArgumentNullException("values");
+ }
+
+ // Always make a copy to prevent changing the array on another thread.
+ String[] internalValues = new String[values.Length];
+
+ for (int i = 0; i < values.Length; i++) {
+ string value = values[i];
+ internalValues[i] = ((value==null)?(String.Empty):(value));
+ totalLength += internalValues[i].Length;
+ // check for overflow
+ if (totalLength < 0) {
+ throw new OutOfMemoryException();
+ }
+ }
+
+ return ConcatArray(internalValues, totalLength);
+ }
+
+ //|
+ public static String Intern(String str) {
+ str.CheckHighChars();
+ if (str == null) {
+ throw new ArgumentNullException("str");
+ }
+ if (internedStringVector == null) {
+ InitializeInternedTable();
+ }
+ int code = str.GetHashCode();
+ lock (internedStringVector) {
+ int[] codeTable= internedStringHashCodes;
+ String[] stringTable = internedStringVector;
+ int tableSize = codeTable.Length;
+ int indexMask = tableSize - 1;
+ int hx = code & indexMask;
+ //Scan up from our initial hash index guess
+ while (true) { // It is guaranteed there are holes in table
+ int tableCode = codeTable[hx];
+ if (tableCode == code) {
+ String s = stringTable[hx];
+ if (str.Equals(s)) {
+ return s;
+ }
+ }
+ else if (tableCode == 0 && stringTable[hx] == null) {
+ // We need to insert the string here!
+ int stringLength = str.Length;
+ if (str.m_arrayLength > stringLength + 1) {
+ str = NewString(str, 0, stringLength, stringLength);
+ }
+ internedStringCount++;
+ stringTable[hx] = str; // Set string entry first
+ codeTable[hx] = code; // then set code!
+ if (internedStringCount >= internedStringBound) {
+ RehashInternedStrings();
+ }
+ return str;
+ }
+ hx++;
+ hx &= indexMask;
+ }
+ }
+ }
+
+ //|
+ public static String IsInterned(String str) {
+ if (str == null) {
+ throw new ArgumentNullException("str");
+ }
+ if (internedStringVector == null) {
+ InitializeInternedTable();
+ }
+ int code = str.GetHashCode();
+ int[] codeTable;
+ String[] stringTable;
+ do {
+ codeTable = internedStringHashCodes;
+ stringTable = internedStringVector;
+ } while (codeTable.Length != stringTable.Length);
+ int tableSize = codeTable.Length;
+ int indexMask = tableSize - 1;
+ int hx = code & indexMask;
+ // Scan up from our initial hash index guess
+ while (true) { // It is guaranteed there are holes in table
+ int tableCode = codeTable[hx];
+ if (tableCode == code) {
+ String s = stringTable[hx];
+ if (str.Equals(s)) {
+ return s;
+ }
+ }
+ else if (tableCode == 0 && stringTable[hx] == null) {
+ return null;
+ }
+ hx++;
+ hx &= indexMask;
+ }
+ }
+
+ private static void InitializeInternedTable() {
+ lock (typeof(String)) {
+ if (internedStringVector != null) {
+ return;
+ }
+ int tableSize = 128;
+ int constantCount = internedStringConstants.Length;
+ while (tableSize <= constantCount) {
+ tableSize <<= 1;
+ }
+ int indexMask = tableSize - 1;
+ String[] stringTable = new String[tableSize];
+ int[] codeTable = new int[tableSize];
+ for (int i = 0; i < constantCount; i++) {
+ String s = internedStringConstants[i];
+ int code = s.GetHashCode();
+ int hx = code & indexMask;
+ while (true) {
+ int tableCode = codeTable[hx];
+ VTable.Assert(tableCode != code ||
+ !s.Equals(stringTable[hx]),
+ "Duplicate interned strings!");
+ if (tableCode == 0 && stringTable[hx] == null) {
+ internedStringCount++;
+ stringTable[hx] = s;
+ codeTable[hx] = code;
+ break;
+ }
+ hx++;
+ hx &= indexMask;
+ }
+ }
+ internedStringBound = tableSize >> 1;
+ internedStringHashCodes = codeTable;
+ internedStringVector = stringTable;
+ }
+ }
+
+ private static void RehashInternedStrings() {
+ int[] oldCodeTable = internedStringHashCodes;
+ String[] oldStringTable = internedStringVector;
+ int oldSize = oldCodeTable.Length;
+ int oldIndexMask = oldSize - 1;
+ int newSize = oldSize << 1;
+ int newIndexMask = newSize -1;
+ int[] newCodeTable = new int[newSize];
+ String[] newStringTable = new String[newSize];
+ for (int i = 0; i < oldSize; i++) {
+ String s = oldStringTable[i];
+ if (s != null) {
+ int code = oldCodeTable[i];
+ int hx = code & newIndexMask;
+ while (true) {
+ if (newCodeTable[hx] == 0 &&
+ newStringTable[hx] == null) {
+ newStringTable[hx] = s;
+ newCodeTable[hx] = code;
+ break;
+ }
+ hx++;
+ hx &= newIndexMask;
+ }
+ }
+ }
+ internedStringBound = newSize >> 1;
+ internedStringHashCodes = newCodeTable;
+ internedStringVector = newStringTable;
+ }
+
+ private static int internedStringCount;
+ private static int internedStringBound;
+ private static int[] internedStringHashCodes;
+ private static String[] internedStringVector;
+ private static String[] internedStringConstants;
+
+ private static readonly bool [] HighCharTable = {
+ false, // 0x00, 0x0
+ true, // 0x01, .
+ true, // 0x02, .
+ true, // 0x03, .
+ true, // 0x04, .
+ true, // 0x05, .
+ true, // 0x06, .
+ true, // 0x07, .
+ true, // 0x08, .
+ false, // 0x09,
+ false, // 0x0A,
+ false, // 0x0B, .
+ false, // 0x0C, .
+ false, // 0x0D,
+ true, // 0x0E, .
+ true, // 0x0F, .
+ true, // 0x10, .
+ true, // 0x11, .
+ true, // 0x12, .
+ true, // 0x13, .
+ true, // 0x14, .
+ true, // 0x15, .
+ true, // 0x16, .
+ true, // 0x17, .
+ true, // 0x18, .
+ true, // 0x19, .
+ true, // 0x1A,
+ true, // 0x1B, .
+ true, // 0x1C, .
+ true, // 0x1D, .
+ true, // 0x1E, .
+ true, // 0x1F, .
+ false, // 0x20,
+ false, // 0x21, !
+ false, // 0x22, "
+ false, // 0x23, #
+ false, // 0x24, $
+ false, // 0x25, %
+ false, // 0x26, &
+ true, // 0x27, '
+ false, // 0x28, (
+ false, // 0x29, )
+ false, // 0x2A *
+ false, // 0x2B, +
+ false, // 0x2C, ,
+ true, // 0x2D, -
+ false, // 0x2E, .
+ false, // 0x2F, /
+ false, // 0x30, 0
+ false, // 0x31, 1
+ false, // 0x32, 2
+ false, // 0x33, 3
+ false, // 0x34, 4
+ false, // 0x35, 5
+ false, // 0x36, 6
+ false, // 0x37, 7
+ false, // 0x38, 8
+ false, // 0x39, 9
+ false, // 0x3A, :
+ false, // 0x3B, ;
+ false, // 0x3C, <
+ false, // 0x3D, =
+ false, // 0x3E, >
+ false, // 0x3F, ?
+ false, // 0x40, @
+ false, // 0x41, A
+ false, // 0x42, B
+ false, // 0x43, C
+ false, // 0x44, D
+ false, // 0x45, E
+ false, // 0x46, F
+ false, // 0x47, G
+ false, // 0x48, H
+ false, // 0x49, I
+ false, // 0x4A, J
+ false, // 0x4B, K
+ false, // 0x4C, L
+ false, // 0x4D, M
+ false, // 0x4E, N
+ false, // 0x4F, O
+ false, // 0x50, P
+ false, // 0x51, Q
+ false, // 0x52, R
+ false, // 0x53, S
+ false, // 0x54, T
+ false, // 0x55, U
+ false, // 0x56, V
+ false, // 0x57, W
+ false, // 0x58, X
+ false, // 0x59, Y
+ false, // 0x5A, Z
+ false, // 0x5B, [
+ false, // 0x5C, \
+ false, // 0x5D, ]
+ false, // 0x5E, ^
+ false, // 0x5F, _
+ false, // 0x60, `
+ false, // 0x61, a
+ false, // 0x62, b
+ false, // 0x63, c
+ false, // 0x64, d
+ false, // 0x65, e
+ false, // 0x66, f
+ false, // 0x67, g
+ false, // 0x68, h
+ false, // 0x69, i
+ false, // 0x6A, j
+ false, // 0x6B, k
+ false, // 0x6C, l
+ false, // 0x6D, m
+ false, // 0x6E, n
+ false, // 0x6F, o
+ false, // 0x70, p
+ false, // 0x71, q
+ false, // 0x72, r
+ false, // 0x73, s
+ false, // 0x74, t
+ false, // 0x75, u
+ false, // 0x76, v
+ false, // 0x77, w
+ false, // 0x78, x
+ false, // 0x79, y
+ false, // 0x7A, z
+ false, // 0x7B, {
+ false, // 0x7C, |
+ false, // 0x7D, }
+ false, // 0x7E, ~
+ true, // 0x7F,
+ };
+
+ //
+ // IValue implementation
+ //
+
+ //|
+ [NoHeapAllocation]
+ public override TypeCode GetTypeCode() {
+ return TypeCode.String;
+ }
+
+ // Is this a string that can be compared quickly (that is it has only characters > 0x80
+ // and not a - or '
+ internal bool IsFastSort() {
+ return ((StringState & StringState.SpecialSort) != 0);
+ }
+
+ internal bool IsSlowSort() {
+ return !IsFastSort();
+ }
+
+ internal bool IsFastOpsExceptSort() {
+ return ((StringState & StringState.SpecialSort) != 0 ||
+ (StringState & StringState.FastOps) != 0);
+ }
+
+ internal bool IsFastCasing() {
+ return ((StringState & StringState.SpecialSort) != 0 ||
+ (StringState & StringState.FastOps) != 0);
+ }
+
+ internal bool IsFastIndex() {
+ return ((StringState & StringState.SpecialSort) != 0 ||
+ (StringState & StringState.FastOps) != 0);
+ }
+
+ internal bool IsStringStateUndetermined() {
+ return (StringState == StringState.Undetermined);
+ }
+
+ internal bool HasHighChars() {
+ return (StringState == StringState.HighChars);
+ }
+
+
+ ///
+ /// Get or set the string state for this string.
+ ///
+ internal unsafe StringState StringState {
+ [NoLoggingForUndo]
+ get {
+ StringState result = MultiUseWord.GetStringState(this);
+ return (StringState)result;
+ }
+ [NoLoggingForUndo]
+ set {
+ MultiUseWord.SetStringState(this, value);
+ }
+ }
+
+ internal unsafe StringState CheckHighChars() {
+ char c;
+ StringState ss = StringState.FastOps;
+ int length = m_stringLength;
+ fixed(char *charPtr = &this.m_firstChar) {
+ for (int i = 0; i < length; i++) {
+ c = charPtr[i];
+ if (c >= 0x80) {
+ StringState = StringState.HighChars;
+ return StringState;
+ }
+ else if (HighCharTable[(int)c]) {
+ ss = StringState.SpecialSort;
+ }
+ }
+ }
+
+ StringState = ss;
+ return StringState;
+ }
+
+ ///
+ unsafe internal void SetChar(int index, char value)
+ {
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+
+ //Bounds check and then set the actual bit.
+ if ((UInt32)index >= (UInt32)Length)
+ throw new ArgumentOutOfRangeException("index", "ArgumentOutOfRange_Index");
+
+ fixed (char *p = &this.m_firstChar) {
+ // Set the character.
+ p[index] = value;
+ }
+ }
+
+#if _DEBUG
+ // Only used in debug build. Insure that the HighChar state information for a string is not set as known
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private bool ValidModifiableString() {
+ throw new Exception("System.String.ValidModifiableString not implemented in Bartok!");
+ }
+#endif
+
+ ///
+ unsafe internal void AppendInPlace(char value,int currentLength)
+ {
+ Debug.Assert(currentLength < m_arrayLength, "[String.AppendInPlace(char)currentLength < m_arrayLength");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+
+ fixed (char *p = &this.m_firstChar)
+ {
+ // Append the character.
+ p[currentLength] = value;
+ p[++currentLength] = '\0';
+ m_stringLength = currentLength;
+ }
+ }
+
+
+ ///
+ unsafe internal void AppendInPlace(char value, int repeatCount, int currentLength)
+ {
+ Debug.Assert(currentLength+repeatCount < m_arrayLength, "[String.AppendInPlace]currentLength+repeatCount < m_arrayLength");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+
+ int newLength = currentLength + repeatCount;
+
+
+ fixed (char *p = &this.m_firstChar)
+ {
+ int i;
+ for (i = currentLength; i < newLength; i++) {
+ p[i] = value;
+ }
+ p[i] = '\0';
+ }
+ this.m_stringLength = newLength;
+ }
+
+ ///
+ internal unsafe void AppendInPlace(String value, int currentLength) {
+ Debug.Assert(value!=null, "[String.AppendInPlace]value!=null");
+ Debug.Assert(value.Length + currentLength < this.m_arrayLength, "[String.AppendInPlace]Length is wrong.");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+
+ FillString(this, currentLength, value);
+ SetLength(currentLength + value.Length);
+ NullTerminate();
+ }
+
+ internal void AppendInPlace(String value, int startIndex, int count, int currentLength) {
+ Debug.Assert(value!=null, "[String.AppendInPlace]value!=null");
+ Debug.Assert(count + currentLength < this.m_arrayLength, "[String.AppendInPlace]count + currentLength < this.m_arrayLength");
+ Debug.Assert(count>=0, "[String.AppendInPlace]count>=0");
+ Debug.Assert(startIndex>=0, "[String.AppendInPlace]startIndex>=0");
+ Debug.Assert(startIndex <= (value.Length - count), "[String.AppendInPlace]startIndex <= (value.Length - count)");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+
+ FillSubstring(this, currentLength, value, startIndex, count);
+ SetLength(currentLength + count);
+ NullTerminate();
+ }
+
+ internal unsafe void AppendInPlace(char *value, int count,int currentLength) {
+ Debug.Assert(value!=null, "[String.AppendInPlace]value!=null");
+ Debug.Assert(count + currentLength < this.m_arrayLength, "[String.AppendInPlace]count + currentLength < this.m_arrayLength");
+ Debug.Assert(count>=0, "[String.AppendInPlace]count>=0");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+ fixed(char *p = &this.m_firstChar) {
+ int i;
+ for (i = 0; i < count; i++) {
+ p[currentLength+i] = value[i];
+ }
+ }
+ SetLength(currentLength + count);
+ NullTerminate();
+ }
+
+
+ ///
+ internal unsafe void AppendInPlace(char[] value, int start, int count, int currentLength) {
+ Debug.Assert(value!=null, "[String.AppendInPlace]value!=null");
+ Debug.Assert(count + currentLength < this.m_arrayLength, "[String.AppendInPlace]Length is wrong.");
+ Debug.Assert(value.Length-count>=start, "[String.AppendInPlace]value.Length-count>=start");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+
+ FillStringArray(this, currentLength, value, start, count);
+ this.m_stringLength = (currentLength + count);
+ this.NullTerminate();
+ }
+
+
+ ///
+ unsafe internal void ReplaceCharInPlace(char oldChar, char newChar, int startIndex, int count,int currentLength) {
+ Debug.Assert(startIndex>=0, "[String.ReplaceCharInPlace]startIndex>0");
+ Debug.Assert(startIndex<=currentLength, "[String.ReplaceCharInPlace]startIndex>=Length");
+ Debug.Assert((startIndex<=currentLength-count), "[String.ReplaceCharInPlace]count>0 && startIndex<=currentLength-count");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+
+ int endIndex = startIndex+count;
+
+ fixed (char *p = &this.m_firstChar) {
+ for (int i = startIndex; i < endIndex; i++) {
+ if (p[i] == oldChar) {
+ p[i]=newChar;
+ }
+ }
+ }
+ }
+
+
+ ///
+ internal static String GetStringForStringBuilder(String value, int capacity) {
+ Debug.Assert(value!=null, "[String.GetStringForStringBuilder]value!=null");
+ Debug.Assert(capacity>=value.Length, "[String.GetStringForStringBuilder]capacity>=value.Length");
+
+ String newStr = FastAllocateString(capacity);
+ if (value.Length == 0) {
+ newStr.m_stringLength=0;
+ newStr.m_firstChar='\0';
+ return newStr;
+ }
+ FillString(newStr, 0, value);
+ newStr.m_stringLength = value.m_stringLength;
+ return newStr;
+ }
+
+ ///
+ private unsafe void NullTerminate() {
+ fixed(char *p = &this.m_firstChar) {
+ p[m_stringLength] = '\0';
+ }
+ }
+
+ ///
+ unsafe internal void ClearPostNullChar() {
+ int newLength = Length+1;
+ if (newLength < m_arrayLength) {
+ fixed(char *p = &this.m_firstChar) {
+ p[newLength] = '\0';
+ }
+ }
+ }
+
+ ///
+ internal void SetLength(int newLength) {
+ Debug.Assert(newLength <= m_arrayLength, "newLength<=m_arrayLength");
+ m_stringLength = newLength;
+ }
+
+
+
+ //|
+ public CharEnumerator GetEnumerator() {
+ return new CharEnumerator(this);
+ }
+
+ //|
+ ///
+ IEnumerator IEnumerable.GetEnumerator() {
+ return new CharEnumerator(this);
+ }
+
+ //
+ // This is just designed to prevent compiler warnings.
+ // This field is used from native, but we need to prevent the compiler warnings.
+ //
+#if _DEBUG
+ private void DontTouchThis() {
+ m_arrayLength = 0;
+ m_stringLength = 0;
+ m_firstChar = m_firstChar;
+ }
+#endif
+
+ internal unsafe void InternalSetCharNoBoundsCheck(int index, char value) {
+ fixed (char *p = &this.m_firstChar) {
+ p[index] = value;
+ }
+ }
+
+
+#if false // Unused
+
+ // NOTE: len is not the length in characters, but the length in bytes
+
+ // Copies the source String (byte buffer) to the destination IntPtr memory allocated with len bytes.
+ internal unsafe static void InternalCopy(String src, IntPtr dest,int len)
+ {
+ if (len == 0)
+ return;
+ fixed(char* charPtr = &src.m_firstChar) {
+ byte* srcPtr = (byte*) charPtr;
+ byte* dstPtr = (byte*) dest.ToPointer();
+ Buffer.MoveMemory(dstPtr, srcPtr, len);
+ }
+ }
+
+ // memcopies characters inside a String.
+ internal unsafe static void InternalMemCpy(String src, int srcOffset, String dst, int destOffset, int len)
+ {
+ if (len == 0)
+ return;
+ fixed(char* srcPtr = &src.m_firstChar) {
+ fixed(char* dstPtr = &dst.m_firstChar) {
+ Buffer.MoveMemory((byte*)(dstPtr + destOffset),
+ (byte*)(srcPtr + srcOffset),
+ len);
+ }
+ }
+ }
+#endif
+
+ // Copies the source String to the destination byte[]
+ internal unsafe static void InternalCopy(String src, byte[] dest, int stringLength)
+ {
+ if (stringLength == 0)
+ return;
+ int len = stringLength * sizeof(char);
+
+ Debug.Assert(dest.Length >= len);
+
+ fixed(char* charPtr = &src.m_firstChar) {
+ fixed(byte* destPtr = &dest[0]) {
+ byte* srcPtr = (byte*) charPtr;
+ Buffer.MoveMemory(destPtr, srcPtr, len);
+ }
+ }
+ }
+
+ internal unsafe void InsertInPlace(int index, String value, int repeatCount, int currentLength, int requiredLength) {
+ Debug.Assert(requiredLength < m_arrayLength, "[String.InsertString] requiredLength < m_arrayLength");
+ Debug.Assert(index + value.Length * repeatCount < m_arrayLength, "[String.InsertString] index + value.Length * repeatCount < m_arrayLength");
+#if _DEBUG
+ Debug.Assert(ValidModifiableString(), "Modifiable string must not have highChars flags set");
+#endif
+ //Copy the old characters over to make room and then insert the new characters.
+ fixed(char* srcPtr = &this.m_firstChar) {
+ fixed(char* valuePtr = &value.m_firstChar) {
+ Buffer.MoveMemory((byte*)(srcPtr + index + value.Length * repeatCount),
+ (byte*)(srcPtr + index),
+ (currentLength - index) * sizeof(char));
+ for (int i = 0; i < repeatCount; i++) {
+ Buffer.MoveMemory((byte*)(srcPtr + index + i * value.Length),
+ (byte*)valuePtr,
+ value.Length * sizeof(char));
+ }
+ }
+ srcPtr[requiredLength] = '\0';
+ }
+ this.m_stringLength = requiredLength;
+ }
+
+ [CLSCompliant(false)]
+ [NoHeapAllocation]
+ public unsafe int LimitedFormatTo(char *buffer, int length)
+ {
+ unchecked {
+ fixed (char *fmtBeg = &m_firstChar) {
+ char *fmtPtr = fmtBeg;
+ char *fmtEnd = fmtBeg + m_stringLength;
+
+ char *outPtr = buffer;
+ char *outEnd = buffer + length;
+
+ while (fmtPtr < fmtEnd && outPtr < outEnd) {
+ *outPtr++ = *fmtPtr++;
+ }
+ return (int)(outPtr - buffer);
+ }
+ }
+ }
+
+ [CLSCompliant(false)]
+ [NoHeapAllocation]
+ public static unsafe int LimitedFormatTo(String format,
+ ArgIterator args,
+ char *buffer,
+ int length)
+ {
+ unchecked {
+
+ fixed (char *fmtBeg = &format.m_firstChar) {
+ char *fmtPtr = fmtBeg;
+ char *fmtEnd = fmtBeg + format.m_stringLength;
+
+ char *outPtr = buffer;
+ char *outEnd = buffer + length;
+
+ while (fmtPtr < fmtEnd && outPtr < outEnd) {
+ if (*fmtPtr == '{') {
+ char * fmtPos = fmtPtr;
+ bool bad = false;
+ fmtPtr++;
+
+ int ndx = 0;
+ int aln = 0;
+ int wid = 0;
+ char fmt = 'd';
+
+ if (*fmtPtr == '{') {
+ *outPtr++ = *fmtPtr++;
+ }
+ else if (*fmtPtr >= '0' && *fmtPtr <= '9') {
+
+ // {index,alignment:type width}
+ // Get Index
+ while (*fmtPtr >= '0' && *fmtPtr <= '9') {
+ ndx = ndx * 10 + (*fmtPtr++ - '0');
+ }
+
+ // Get Alignment
+ if (*fmtPtr == ',') {
+ fmtPtr++;
+ if (*fmtPtr == '-') {
+ // We just ignore left alignment for now.
+ fmtPtr++;
+ }
+ while (*fmtPtr >= '0' && *fmtPtr <= '9') {
+ aln = aln * 10 + (*fmtPtr++ - '0');
+ }
+ }
+
+ // Get FormatString
+ if (*fmtPtr == ':') {
+ fmtPtr++;
+ if (*fmtPtr >= 'a' && *fmtPtr <= 'z') {
+ fmt = *fmtPtr++;
+ }
+ else if (*fmtPtr >= 'A' && *fmtPtr <= 'Z') {
+ fmt = (char)(*fmtPtr++ - ('A' + 'a'));
+ }
+ while (*fmtPtr >= '0' && *fmtPtr <= '9') {
+ wid = wid * 10 + (*fmtPtr++ - '0');
+ }
+ }
+
+ // Get closing brace.
+ if (*fmtPtr == '}') {
+ fmtPtr++;
+ }
+ else {
+ bad = true;
+ }
+
+ if (ndx >= args.Length) {
+ bad = true;
+ }
+
+ if (bad) {
+ for (; fmtPos < fmtPtr; fmtPos++) {
+ if (outPtr < outEnd) {
+ *outPtr++ = *fmtPos;
+ }
+ }
+ }
+ else {
+ // Get the value
+ char cvalue = '\0';
+ long ivalue = 0;
+ string svalue = null;
+ ulong value = 0;
+ IntPtr pvalue;
+ RuntimeType type;
+
+ type = args.GetArg(ndx, out pvalue);
+
+ switch (type.classVtable.structuralView) {
+ case StructuralType.Bool:
+ svalue =*(bool *)pvalue ? "true" : "false";
+ break;
+ case StructuralType.Char:
+ cvalue = *(char *)pvalue;
+ break;
+ case StructuralType.Int8:
+ ivalue = *(sbyte *)pvalue;
+ break;
+ case StructuralType.Int16:
+ ivalue = *(short *)pvalue;
+ break;
+ case StructuralType.Int32:
+ ivalue = *(int *)pvalue;
+ break;
+ case StructuralType.Int64:
+ ivalue = *(long *)pvalue;
+ break;
+ case StructuralType.UInt8:
+ value = *(byte *)pvalue;
+ break;
+ case StructuralType.UInt16:
+ value = *(ushort *)pvalue;
+ break;
+ case StructuralType.UInt32:
+ value = *(uint *)pvalue;
+ break;
+ case StructuralType.UInt64:
+ value = *(ulong *)pvalue;
+ break;
+ case StructuralType.IntPtr:
+ value = (ulong)*(IntPtr *)pvalue;
+ break;
+ case StructuralType.UIntPtr:
+ value = (ulong)*(UIntPtr *)pvalue;
+ break;
+ case StructuralType.Reference:
+ if (type == typeof(String)) {
+ svalue = Magic.toString(
+ Magic.fromAddress(*(UIntPtr *)pvalue));
+ }
+ else {
+ svalue = type.Name;
+ }
+ break;
+ default:
+ svalue = "???";
+ break;
+ }
+
+ if (cvalue != '\0') {
+ outPtr = AddChar(outPtr, outEnd, *(char *)pvalue, aln);
+ }
+ else if (svalue != null) {
+ outPtr = AddString(outPtr, outEnd, svalue, aln);
+ }
+ else {
+ if (aln < wid) {
+ aln = wid;
+ }
+
+ if (fmt == 'x') {
+ if (ivalue != 0) {
+ value = (ulong)ivalue;
+ }
+ outPtr = AddNumber(outPtr, outEnd, value, aln, 16, '0', '\0');
+ }
+ else {
+ char sign = '\0';
+ if (ivalue < 0) {
+ sign = '-';
+ value = unchecked((ulong)-ivalue);
+ }
+ else if (ivalue > 0) {
+ value = unchecked((ulong)ivalue);
+ }
+ outPtr = AddNumber(outPtr, outEnd, value, aln, 10, ' ', sign);
+ }
+ }
+ }
+ }
+ }
+ else if (*fmtPtr == '}') {
+ if (outPtr < outEnd) {
+ *outPtr++ = *fmtPtr;
+ }
+ fmtPtr++;
+ }
+ else {
+ if (outPtr < outEnd) {
+ *outPtr++ = *fmtPtr;
+ }
+ fmtPtr++;
+ }
+ }
+ return (int)(outPtr - buffer);
+ }
+ }
+ }
+
+ [NoHeapAllocation]
+ private static int CountDigits(ulong value, uint valueBase)
+ {
+ int used = 0;
+ do {
+ value /= valueBase;
+ used++;
+ } while (value != 0);
+
+ return used;
+ }
+
+ [NoHeapAllocation]
+ private static unsafe char * AddNumber(char *output, char *limit,
+ ulong value, int width, uint valueBase,
+ char fill, char sign)
+ {
+ // Make sure we won't overfill the buffer.
+ if (output >= limit) {
+ return output;
+ }
+
+ // Figure out how wide the string will be.
+ int used = CountDigits(value, valueBase);
+
+ // Check for overflow.
+ if (output + used + ((sign != '\0') ? 1 : 0) > limit) {
+ while (width > 0) {
+ *output++ = '#';
+ width--;
+ }
+ return output;
+ }
+
+ // Handle sign and space fill.
+ if (sign != '\0' && used < width) {
+ if (fill == ' ') {
+ while (width > used + 1) {
+ *output++ = fill;
+ width--;
+ }
+ fill = '\0';
+ }
+ *output++ = sign;
+ }
+
+ // Handle other non-zero fills.
+ if (fill != '\0') {
+ while (width > used) {
+ *output++ = fill;
+ width--;
+ }
+ }
+
+ // Write the characters into the buffer.
+ char *outp = output + used;
+ do {
+ uint digit = (uint)(value % valueBase);
+ value /= valueBase;
+
+ if (digit >= 0 && digit <= 9) {
+ *--outp = (char)('0' + digit);
+ }
+ else {
+ *--outp = (char)('a' + (digit - 10));
+ }
+ } while (value != 0);
+
+ return output + used;
+ }
+
+ [NoHeapAllocation]
+ private static unsafe char * AddString(char *output, char *limit,
+ string value, int width)
+ {
+ fixed (char *pwString = &value.m_firstChar) {
+ return AddString(output, limit, pwString, value.m_stringLength, width);
+ }
+ }
+
+ [NoHeapAllocation]
+ private static unsafe char * AddString(char *output, char *limit,
+ char *pwString, int cwString,
+ int width)
+ {
+ // width < 0: left justified at -width.
+ // width = 0: no specified width.
+ // width > 0: right justified at width.
+ if (width == 0) {
+ width = cwString;
+ }
+ else if (width < 0) {
+ width = -width;
+ for (; width > cwString; width--) {
+ if (output < limit) {
+ *output++ = ' ';
+ }
+ }
+ }
+
+ while (cwString > 0 && width > 0) {
+ if (output < limit) {
+ *output++ = (char)*pwString++;
+ }
+ width--;
+ cwString--;
+ }
+
+ for (; width > 0; width--) {
+ if (output < limit) {
+ *output++ = ' ';
+ }
+ }
+ return output;
+ }
+
+ [NoHeapAllocation]
+ private static unsafe char * AddChar(char *output, char *limit, char value, int width)
+ {
+ // width < 0: left justified at -width.
+ // width = 0: no specified width.
+ // width > 0: right justified at width.
+ if (width == 0) {
+ width = 1;
+ }
+ else if (width < 0) {
+ width = -width;
+ for (; width > 1; width--) {
+ if (output < limit) {
+ *output++ = ' ';
+ }
+ }
+ }
+
+ if (width > 0) {
+ if (output < limit) {
+ *output++ = (char)value;
+ }
+ width--;
+ }
+
+ for (; width > 0; width--) {
+ if (output < limit) {
+ *output++ = ' ';
+ }
+ }
+ return output;
+ }
+ }
+}
diff --git a/base/Kernel/System/SystemException.cs b/base/Applications/Runtime/Full/System/SystemException.cs
similarity index 94%
rename from base/Kernel/System/SystemException.cs
rename to base/Applications/Runtime/Full/System/SystemException.cs
index eda1ec6..64b5761 100644
--- a/base/Kernel/System/SystemException.cs
+++ b/base/Applications/Runtime/Full/System/SystemException.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System;
//|
diff --git a/base/Applications/Runtime/Full/System/Text/ASCIIEncoding.cs b/base/Applications/Runtime/Full/System/Text/ASCIIEncoding.cs
new file mode 100644
index 0000000..c2d44ca
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Text/ASCIIEncoding.cs
@@ -0,0 +1,208 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System.Text
+{
+ using System.Text;
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ public partial class ASCIIEncoding : Encoding
+ {
+ private const int ASCII_CODEPAGE=20127;
+
+ //|
+ public ASCIIEncoding() : base(ASCII_CODEPAGE) {
+ }
+
+ //|
+ public override int GetByteCount(char[] chars, int index, int count) {
+ if (chars == null) {
+ throw new ArgumentNullException("chars", "ArgumentNull_Array");
+ }
+ if (index < 0 || count < 0) {
+ throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+ if (chars.Length - index < count) {
+ throw new ArgumentOutOfRangeException("chars",
+ "ArgumentOutOfRange_IndexCountBuffer");
+ }
+
+ return (count);
+ }
+
+ //|
+ public override int GetByteCount(String chars) {
+ if (chars == null) {
+ throw new ArgumentNullException("chars", "ArgumentNull_Array");
+ }
+ return chars.Length;
+ }
+
+ //|
+ public override int GetBytes(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex) {
+ if (chars == null || bytes == null) {
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
+ "ArgumentNull_Array");
+ }
+ if (charIndex < 0 || charCount < 0) {
+ throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+ if (chars.Length - charIndex < charCount) {
+ throw new ArgumentOutOfRangeException("chars",
+ "ArgumentOutOfRange_IndexCountBuffer");
+ }
+ if (byteIndex < 0 || byteIndex > bytes.Length) {
+ throw new ArgumentOutOfRangeException("byteIndex",
+ "ArgumentOutOfRange_Index");
+ }
+ if (bytes.Length - byteIndex < charCount) {
+ throw new ArgumentException("Argument_ConversionOverflow");
+ }
+ int charEnd = charIndex + charCount;
+
+ while (charIndex < charEnd) {
+ char ch = chars[charIndex++];
+ if (ch >= 0x0080) ch = '?';
+ bytes[byteIndex++] = (byte)ch;
+ }
+ return charCount;
+ }
+
+ //|
+ public override int GetBytes(String chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex) {
+ if (chars == null || bytes == null) {
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
+ "ArgumentNull_Array");
+ }
+ if (charIndex < 0 || charCount < 0) {
+ throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+ if (chars.Length - charIndex < charCount) {
+ throw new ArgumentOutOfRangeException("chars",
+ "ArgumentOutOfRange_IndexCount");
+ }
+ if (byteIndex < 0 || byteIndex > bytes.Length) {
+ throw new ArgumentOutOfRangeException("byteIndex",
+ "ArgumentOutOfRange_Index");
+ }
+ if (bytes.Length - byteIndex < charCount) {
+ throw new ArgumentException("Argument_ConversionOverflow");
+ }
+ int charEnd = charIndex + charCount;
+
+ while (charIndex < charEnd) {
+ char ch = chars[charIndex++];
+ if (ch >= 0x0080) ch = '?';
+ bytes[byteIndex++] = (byte)ch;
+ }
+ return charCount;
+ }
+
+ //|
+ public override int GetCharCount(byte[] bytes, int index, int count) {
+ if (bytes == null) {
+ throw new ArgumentNullException("bytes",
+ "ArgumentNull_Array");
+ }
+ if (index < 0 || count < 0) {
+ throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+ if (bytes.Length - index < count) {
+ throw new ArgumentOutOfRangeException("bytes",
+ "ArgumentOutOfRange_IndexCountBuffer");
+ }
+ return (count);
+
+ }
+
+ //|
+ public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex) {
+ if (bytes == null || chars == null) {
+ throw new ArgumentNullException((bytes == null ? "bytes" : "chars"),
+ "ArgumentNull_Array");
+ }
+ if (byteIndex < 0 || byteCount < 0) {
+ throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+ if (bytes.Length - byteIndex < byteCount) {
+ throw new ArgumentOutOfRangeException("bytes",
+ "ArgumentOutOfRange_IndexCountBuffer");
+ }
+ if (charIndex < 0 || charIndex > chars.Length) {
+ throw new ArgumentOutOfRangeException("charIndex",
+ "ArgumentOutOfRange_Index");
+ }
+ if (chars.Length - charIndex < byteCount) {
+ throw new ArgumentException("Argument_ConversionOverflow");
+ }
+ int byteEnd = byteIndex + byteCount;
+ while (byteIndex < byteEnd) {
+ byte b = bytes[byteIndex++];
+ if (b > 0x7f) {
+ // This is an invalid byte in the ASCII encoding.
+ chars[charIndex++] = '?';
+ }
+ else {
+ chars[charIndex++] = (char)b;
+ }
+ }
+ return (byteCount);
+
+ }
+
+ //|
+ public override String GetString(byte[] bytes)
+ {
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", "ArgumentNull_Array");
+ return String.CreateStringFromASCII(bytes, 0, bytes.Length);
+ }
+
+ //|
+ public override String GetString(byte[] bytes, int byteIndex, int byteCount)
+ {
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", "ArgumentNull_Array");
+ if (byteIndex < 0 || byteCount < 0) {
+ throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+ if (bytes.Length - byteIndex < byteCount) {
+ throw new ArgumentOutOfRangeException("bytes",
+ "ArgumentOutOfRange_IndexCountBuffer");
+ }
+ return String.CreateStringFromASCII(bytes, byteIndex, byteCount);
+ }
+
+ //|
+ public override int GetMaxByteCount(int charCount) {
+ if (charCount < 0) {
+ throw new ArgumentOutOfRangeException("charCount",
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+
+ return (charCount);
+ }
+
+ //|
+ public override int GetMaxCharCount(int byteCount) {
+ if (byteCount < 0) {
+ throw new ArgumentOutOfRangeException("byteCount",
+ "ArgumentOutOfRange_NeedNonNegNum");
+ }
+ return byteCount;
+ }
+ }
+}
diff --git a/base/Kernel/System/Text/Decoder.cs b/base/Applications/Runtime/Full/System/Text/Decoder.cs
similarity index 96%
rename from base/Kernel/System/Text/Decoder.cs
rename to base/Applications/Runtime/Full/System/Text/Decoder.cs
index 68c3eb2..de2bd23 100644
--- a/base/Kernel/System/Text/Decoder.cs
+++ b/base/Applications/Runtime/Full/System/Text/Decoder.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Text {
+namespace System.Text
+{
using System.Text;
using System;
// A Decoder is used to decode a sequence of blocks of bytes into a
diff --git a/base/Kernel/System/Text/Encoder.cs b/base/Applications/Runtime/Full/System/Text/Encoder.cs
similarity index 97%
rename from base/Kernel/System/Text/Encoder.cs
rename to base/Applications/Runtime/Full/System/Text/Encoder.cs
index 0ef5d16..8f7e349 100644
--- a/base/Kernel/System/Text/Encoder.cs
+++ b/base/Applications/Runtime/Full/System/Text/Encoder.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Text {
+namespace System.Text
+{
using System.Text;
using System;
// An Encoder is used to encode a sequence of blocks of characters into
diff --git a/base/Kernel/System/Text/Encoding.cs b/base/Applications/Runtime/Full/System/Text/Encoding.cs
similarity index 97%
rename from base/Kernel/System/Text/Encoding.cs
rename to base/Applications/Runtime/Full/System/Text/Encoding.cs
index a6e11fe..1c2cc16 100644
--- a/base/Kernel/System/Text/Encoding.cs
+++ b/base/Applications/Runtime/Full/System/Text/Encoding.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Text {
+namespace System.Text
+{
using System;
using System.Collections;
@@ -64,7 +65,6 @@ namespace System.Text {
// generally executes faster.
//
//|
- [RequiredByBartok]
public abstract class Encoding
{
private static Encoding unicodeEncoding;
@@ -85,7 +85,7 @@ namespace System.Text {
//|
protected Encoding(int codePage) {
- if (codePage<0) {
+ if (codePage < 0) {
throw new ArgumentOutOfRangeException("codePage");
}
m_codePage = codePage;
@@ -99,7 +99,7 @@ namespace System.Text {
//|
public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
byte[] bytes) {
- if (bytes==null)
+ if (bytes == null)
throw new ArgumentNullException("bytes");
return Convert(srcEncoding, dstEncoding, bytes, 0, bytes.Length);
}
@@ -155,7 +155,7 @@ namespace System.Text {
//|
public virtual int GetByteCount(String s)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
char[] chars = s.ToCharArray();
return GetByteCount(chars, 0, chars.Length);
@@ -219,7 +219,7 @@ namespace System.Text {
public virtual int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
return GetBytes(s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
}
diff --git a/base/Kernel/System/Text/RegularExpressions/regex.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regex.cs
similarity index 93%
rename from base/Kernel/System/Text/RegularExpressions/regex.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regex.cs
index 69d6df4..7597f23 100644
--- a/base/Kernel/System/Text/RegularExpressions/regex.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regex.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// The Regex class represents a single compiled instance of a regular
@@ -11,7 +7,8 @@
//
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System;
using System.Threading;
@@ -114,9 +111,9 @@ namespace System.Text.RegularExpressions {
throw new ArgumentNullException("pattern");
- if (options < RegexOptions.None || ( ((int) options) >> MaxOptionShift) != 0)
+ if (options < RegexOptions.None || (((int) options) >> MaxOptionShift) != 0)
throw new ArgumentOutOfRangeException("options");
- if ((options & RegexOptions.ECMAScript) != 0
+ if ((options & RegexOptions.ECMAScript) != 0
&& (options & ~(RegexOptions.ECMAScript | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled
#if DBG
| RegexOptions.Debug
@@ -166,36 +163,36 @@ namespace System.Text.RegularExpressions {
cachedentry = cached;
}
-/*
- * Singularity does not support compilation of regular expressions
- // if the compile option is set, then compile the code if it's not already
- if (UseOptionC() && factory == null) {
- factory = Compile(code, roptions);
- cachedentry.AddCompiled(factory);
- code = null;
- }
- */
+//
+// Singularity does not support compilation of regular expressions
+// // if the compile option is set, then compile the code if it's not already
+// if (UseOptionC() && factory == null) {
+// factory = Compile(code, roptions);
+// cachedentry.AddCompiled(factory);
+// code = null;
+// }
+//
}
-/*
- // ISerializable constructor
- private Regex(SerializationInfo info, StreamingContext context) : this(info.GetString("pattern"), (RegexOptions) info.GetInt32("options")) {
- }
-
- // ISerializable method
- //|
- ///
- void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) {
- si.AddValue("pattern", this.ToString());
- si.AddValue("options", this.Options);
- }
- // This method is here for perf reasons: if the call to RegexCompiler is NOT in the
- // Regex constructor, we don't load RegexCompiler and its reflection classes when
- // instantiating a non-compiled regex
- // This method is internal virtual so the jit does not inline it.
- internal virtual RegexRunnerFactory Compile(RegexCode code, RegexOptions roptions) {
- return RegexCompiler.Compile(code, roptions);
- }
-*/
+//
+// // ISerializable constructor
+// private Regex(SerializationInfo info, StreamingContext context) : this(info.GetString("pattern"), (RegexOptions) info.GetInt32("options")) {
+// }
+//
+// // ISerializable method
+// //|
+// ///
+// void ISerializable.GetObjectData(SerializationInfo si, StreamingContext context) {
+// si.AddValue("pattern", this.ToString());
+// si.AddValue("options", this.Options);
+// }
+// // This method is here for perf reasons: if the call to RegexCompiler is NOT in the
+// // Regex constructor, we don't load RegexCompiler and its reflection classes when
+// // instantiating a non-compiled regex
+// // This method is internal virtual so the jit does not inline it.
+// internal virtual RegexRunnerFactory Compile(RegexCode code, RegexOptions roptions) {
+// return RegexCompiler.Compile(code, roptions);
+// }
+//
// No refs -> we can release our ref on the cached code
//|
///
@@ -220,7 +217,7 @@ namespace System.Text.RegularExpressions {
///
///
public static String Escape(String str) {
- if (str==null)
+ if (str == null)
throw new ArgumentNullException("str");
return RegexParser.Escape(str);
@@ -234,7 +231,7 @@ namespace System.Text.RegularExpressions {
///
///
public static String Unescape(String str) {
- if (str==null)
+ if (str == null)
throw new ArgumentNullException("str");
return RegexParser.Unescape(str);
@@ -723,7 +720,7 @@ namespace System.Text.RegularExpressions {
///
///
public String Replace(String input, MatchEvaluator evaluator) {
- if (input==null)
+ if (input == null)
throw new ArgumentNullException("input");
return Replace(input, evaluator, -1, UseOptionR() ? input.Length : 0);
@@ -739,7 +736,7 @@ namespace System.Text.RegularExpressions {
///
///
public String Replace(String input, MatchEvaluator evaluator, int count) {
- if (input==null)
+ if (input == null)
throw new ArgumentNullException("input");
return Replace(input, evaluator, count, UseOptionR() ? input.Length : 0);
@@ -755,7 +752,7 @@ namespace System.Text.RegularExpressions {
///
///
public String Replace(String input, MatchEvaluator evaluator, int count, int startat) {
- if (input==null)
+ if (input == null)
throw new ArgumentNullException("input");
return RegexReplacement.Replace(evaluator, this, input, count, startat);
@@ -794,7 +791,7 @@ namespace System.Text.RegularExpressions {
///
///
public String[] Split(String input) {
- if (input==null)
+ if (input == null)
throw new ArgumentNullException("input");
return Split(input, 0, UseOptionR() ? input.Length : 0);
@@ -809,7 +806,7 @@ namespace System.Text.RegularExpressions {
///
///
public String[] Split(String input, int count) {
- if (input==null)
+ if (input == null)
throw new ArgumentNullException("input");
return RegexReplacement.Split(this, input, count, UseOptionR() ? input.Length : 0);
@@ -824,7 +821,7 @@ namespace System.Text.RegularExpressions {
///
///
public String[] Split(String input, int count, int startat) {
- if (input==null)
+ if (input == null)
throw new ArgumentNullException("input");
return RegexReplacement.Split(this, input, count, startat);
@@ -1081,15 +1078,15 @@ namespace System.Text.RegularExpressions {
return(_references == 0);
}
- /*
- internal void AddCompiled(RegexRunnerFactory factory) {
- lock (this) {
- _code = null;
- _factory = factory;
- _references += 1; // will never be balanced since we never unload the type
- }
- }
- */
+ //
+ //internal void AddCompiled(RegexRunnerFactory factory) {
+ // lock (this) {
+ // _code = null;
+ // _factory = factory;
+ // _references += 1; // will never be balanced since we never unload the type
+ // }
+ //}
+ //
}
// Used to cache one exclusive weak reference
diff --git a/base/Kernel/System/Text/RegularExpressions/regexboyermoore.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexboyermoore.cs
similarity index 95%
rename from base/Kernel/System/Text/RegularExpressions/regexboyermoore.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexboyermoore.cs
index eb0199a..696a12f 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexboyermoore.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexboyermoore.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// The RegexBoyerMoore object precomputes the Boyer-Moore
@@ -49,9 +45,8 @@ namespace System.Text.RegularExpressions
int match;
char ch;
-
- if (caseInsensitive)
- {
+
+ if (caseInsensitive) {
// pattern = pattern.ToLower(culture);
pattern = pattern.ToLower();
}
@@ -60,7 +55,7 @@ namespace System.Text.RegularExpressions
_rightToLeft = rightToLeft;
_caseInsensitive = caseInsensitive;
_culture = culture;
-
+
if (!rightToLeft) {
beforefirst = -1;
last = pattern.Length - 1;
@@ -73,7 +68,7 @@ namespace System.Text.RegularExpressions
}
// PART I - the good-suffix shift table
- //
+ //
// compute the positive requirement:
// if char "i" is the first one from the right that doesn't match,
// then we know the matcher can advance by _positive[i].
@@ -105,7 +100,7 @@ namespace System.Text.RegularExpressions
if (scan == beforefirst || pattern[match] != pattern[scan]) {
// at the end of the match, note the difference in _positive
// this is not the length of the match, but the distance from the internal match
- // to the tail suffix.
+ // to the tail suffix.
if (_positive[match] == 0)
_positive[match] = match - scan;
@@ -137,10 +132,10 @@ namespace System.Text.RegularExpressions
//System.Diagnostics.Debug.WriteLine("good suffix shift table:");
//for (int i=0; i<_positive.Length; i++)
// System.Diagnostics.Debug.WriteLine("\t_positive[" + i + "] = " + _positive[i]);
-
+
// PART II - the bad-character shift table
- //
+ //
// compute the negative requirement:
// if char "ch" is the reject character when testing position "i",
// we can slide up by _negative[ch];
@@ -202,7 +197,7 @@ namespace System.Text.RegularExpressions
// When a regex is anchored, we can do a quick IsMatch test instead of a Scan
internal bool IsMatch(String text, int index, int beglimit, int endlimit) {
-
+
if (!_rightToLeft) {
if (index < beglimit || endlimit - index < _pattern.Length)
return false;
diff --git a/base/Kernel/System/Text/RegularExpressions/regexcapture.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcapture.cs
similarity index 89%
rename from base/Kernel/System/Text/RegularExpressions/regexcapture.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcapture.cs
index 6c78f0b..7342535 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexcapture.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcapture.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
+// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
// Capture is just a location/length pair that indicates the
@@ -12,15 +8,16 @@
// RegexGroup.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
//|
///
- ///
+ ///
/// Represents the results from a single subexpression capture. The object represents
/// one substring for a single successful capture.
///
- //[ Serializable() ]
+ //[ Serializable() ]
public class Capture {
internal String _text;
internal int _index;
@@ -71,7 +68,7 @@ namespace System.Text.RegularExpressions {
//|
///
///
- /// Returns
+ /// Returns
/// the substring that was matched.
///
///
diff --git a/base/Kernel/System/Text/RegularExpressions/regexcapturecollection.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcapturecollection.cs
similarity index 94%
rename from base/Kernel/System/Text/RegularExpressions/regexcapturecollection.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcapturecollection.cs
index e7f0cad..7b96981 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexcapturecollection.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcapturecollection.cs
@@ -1,16 +1,13 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// The CaptureCollection lists the captured Capture numbers
// contained in a compiled Regex.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
@@ -24,7 +21,7 @@ namespace System.Text.RegularExpressions {
/// to return the set of captures done by a single capturing group.
///
///
- //[ Serializable() ]
+ //[ Serializable() ]
public class CaptureCollection : ICollection {
internal Group _group;
internal int _capcount;
@@ -147,7 +144,7 @@ namespace System.Text.RegularExpressions {
// This non-public enumerator lists all the captures
// Should it be public?
- //[ Serializable() ]
+ //[ Serializable() ]
internal class CaptureEnumerator : IEnumerator {
internal CaptureCollection _rcc;
internal int _curindex;
diff --git a/base/Kernel/System/Text/RegularExpressions/regexcharclass.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcharclass.cs
similarity index 92%
rename from base/Kernel/System/Text/RegularExpressions/regexcharclass.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcharclass.cs
index 293eb5f..0bdc1f2 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexcharclass.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcharclass.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexCharClass class provides the "set of Unicode chars" functionality
@@ -25,7 +21,8 @@
//
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
using System.Globalization;
@@ -48,7 +45,7 @@ namespace System.Text.RegularExpressions {
internal const short NotSpaceConst = -100;
internal static readonly String Space = ((char) SpaceConst).ToString();
internal static readonly String NotSpace = NegateCategory(Space);
-
+
internal const String ECMASpace = "\u0009\u000E\u0020\u0021";
internal const String NotECMASpace = "\0\u0009\u000E\u0020\u0021";
internal const String ECMAWord = "\u0030\u003A\u0041\u005B\u005F\u0060\u0061\u007B\u0130\u0131";
@@ -63,10 +60,10 @@ namespace System.Text.RegularExpressions {
internal bool _canonical;
internal bool _negate;
-
+
static RegexCharClass() {
_definedCategories = new Hashtable(31);
-
+
char[] groups = new char[9];
StringBuilder word = new StringBuilder(11);
@@ -74,14 +71,14 @@ namespace System.Text.RegularExpressions {
groups[0] = GroupChar;
// We need the UnicodeCategory enum values as a char so we can put them in a string
- // in the hashtable. In order to get there, we first must cast to an int,
+ // in the hashtable. In order to get there, we first must cast to an int,
// then cast to a char
- // Also need to distinguish between positive and negative values. UnicodeCategory is zero
+ // Also need to distinguish between positive and negative values. UnicodeCategory is zero
// based, so we add one to each value and subtract it off later
// Others
groups[1] = (char) ((int) UnicodeCategory.Control + 1);
- _definedCategories["Cc"] = groups[1].ToString(); // Control
+ _definedCategories["Cc"] = groups[1].ToString(); // Control
groups[2] = (char) ((int) UnicodeCategory.Format + 1);
_definedCategories["Cf"] = groups[2].ToString(); // Format
groups[3] = (char) ((int) UnicodeCategory.OtherNotAssigned + 1);
@@ -100,7 +97,7 @@ namespace System.Text.RegularExpressions {
groups[2] = (char) ((int) UnicodeCategory.ModifierLetter + 1);
_definedCategories["Lm"] = groups[2].ToString(); // Modifier
groups[3] = (char) ((int) UnicodeCategory.OtherLetter + 1);
- _definedCategories["Lo"] = groups[3].ToString(); // Other
+ _definedCategories["Lo"] = groups[3].ToString(); // Other
groups[4] = (char) ((int) UnicodeCategory.TitlecaseLetter + 1);
_definedCategories["Lt"] = groups[4].ToString(); // Titlecase
groups[5] = (char) ((int) UnicodeCategory.UppercaseLetter + 1);
@@ -111,14 +108,14 @@ namespace System.Text.RegularExpressions {
word.Append(groups[1]);
word.Append(new String(groups, 3, 3));
- // Marks
+ // Marks
groups[1] = (char) ((int) UnicodeCategory.SpacingCombiningMark + 1);
_definedCategories["Mc"] = groups[1].ToString(); // Spacing combining
groups[2] = (char) ((int) UnicodeCategory.EnclosingMark + 1);
_definedCategories["Me"] = groups[2].ToString(); // Enclosing
groups[3] = (char) ((int) UnicodeCategory.NonSpacingMark + 1);
_definedCategories["Mn"] = groups[3].ToString(); // Non-spacing
-
+
groups[4] = GroupChar;
_definedCategories["M"] = new String(groups, 0, 5);
//word.Append(groups[1]);
@@ -130,7 +127,7 @@ namespace System.Text.RegularExpressions {
groups[2] = (char) ((int) UnicodeCategory.LetterNumber + 1);
_definedCategories["Nl"] = groups[2].ToString(); // Letter
groups[3] = (char) ((int) UnicodeCategory.OtherNumber + 1);
- _definedCategories["No"] = groups[3].ToString(); // Other
+ _definedCategories["No"] = groups[3].ToString(); // Other
//groups[4] = GroupChar;
_definedCategories["N"] = new String(groups, 0, 5);
@@ -156,7 +153,7 @@ namespace System.Text.RegularExpressions {
groups[8] = GroupChar;
_definedCategories["P"] = new String(groups, 0, 9);
word.Append(groups[1]);
-
+
// Symbols
groups[1] = (char) ((int) UnicodeCategory.CurrencySymbol + 1);
_definedCategories["Sc"] = groups[1].ToString(); // Currency
@@ -177,7 +174,7 @@ namespace System.Text.RegularExpressions {
_definedCategories["Zp"] = groups[2].ToString(); // Paragraph
groups[3] = (char) ((int) UnicodeCategory.SpaceSeparator + 1);
_definedCategories["Zs"] = groups[3].ToString(); // Space
-
+
groups[4] = GroupChar;
_definedCategories["Z"] = new String(groups, 0, 5);
@@ -189,9 +186,9 @@ namespace System.Text.RegularExpressions {
#if DBG
// make sure the _propTable is correctly ordered
int len = _propTable.GetLength(0);
- for (int i=0; i 0 && cc.RangeCount() > 0 &&
+ if (_canonical && RangeCount() > 0 && cc.RangeCount() > 0 &&
cc.Range(cc.RangeCount() - 1)._last <= Range(RangeCount() - 1)._last)
_canonical = false;
@@ -255,7 +252,7 @@ namespace System.Text.RegularExpressions {
internal void AddSet(String set) {
int i;
- if (_canonical && RangeCount() > 0 && set.Length > 0 &&
+ if (_canonical && RangeCount() > 0 && set.Length > 0 &&
set[0] <= Range(RangeCount() - 1)._last)
_canonical = false;
@@ -280,11 +277,11 @@ namespace System.Text.RegularExpressions {
}
internal string Category {
- get {
+ get {
//if (_negate)
// return NegateCategory(_categories.ToString());
//else
- return _categories.ToString();
+ return _categories.ToString();
}
}
@@ -302,7 +299,7 @@ namespace System.Text.RegularExpressions {
if (categoryName.Equals("Lu") || categoryName.Equals("Lt"))
catstr = /*catstr +*/ (string) _definedCategories["Ll"];
}
-
+
if (invert)
catstr = NegateCategory(catstr); // negate the category
@@ -317,33 +314,33 @@ namespace System.Text.RegularExpressions {
}
- /***************************************************************************
- Let U be the set of Unicode character values and let L be the lowercase
- function, mapping from U to U. To perform case insensitive matching of
- character sets, we need to be able to map an interval I in U, say
-
- I = [chMin, chMax] = { ch : chMin <= ch <= chMax }
-
- to a set A such that A contains L(I) and A is contained in the union of
- I and L(I).
-
- The table below partitions U into intervals on which L is non-decreasing.
- Thus, for any interval J = [a, b] contained in one of these intervals,
- L(J) is contained in [L(a), L(b)].
-
- It is also true that for any such J, [L(a), L(b)] is contained in the
- union of J and L(J). This does not follow from L being non-decreasing on
- these intervals. It follows from the nature of the L on each interval.
- On each interval, L has one of the following forms:
-
- (1) L(ch) = constant (LowercaseSet)
- (2) L(ch) = ch + offset (LowercaseAdd)
- (3) L(ch) = ch | 1 (LowercaseBor)
- (4) L(ch) = ch + (ch & 1) (LowercaseBad)
-
- It is easy to verify that for any of these forms [L(a), L(b)] is
- contained in the union of [a, b] and L([a, b]).
- ***************************************************************************/
+ ////////////////////////////////////////////////////////////////////////////
+ // Let U be the set of Unicode character values and let L be the lowercase
+ // function, mapping from U to U. To perform case insensitive matching of
+ // character sets, we need to be able to map an interval I in U, say
+ //
+ // I = [chMin, chMax] = { ch : chMin <= ch <= chMax }
+ //
+ // to a set A such that A contains L(I) and A is contained in the union of
+ // I and L(I).
+ //
+ // The table below partitions U into intervals on which L is non-decreasing.
+ // Thus, for any interval J = [a, b] contained in one of these intervals,
+ // L(J) is contained in [L(a), L(b)].
+ //
+ // It is also true that for any such J, [L(a), L(b)] is contained in the
+ // union of J and L(J). This does not follow from L being non-decreasing on
+ // these intervals. It follows from the nature of the L on each interval.
+ // On each interval, L has one of the following forms:
+ //
+ // (1) L(ch) = constant (LowercaseSet)
+ // (2) L(ch) = ch + offset (LowercaseAdd)
+ // (3) L(ch) = ch | 1 (LowercaseBor)
+ // (4) L(ch) = ch + (ch & 1) (LowercaseBad)
+ //
+ // It is easy to verify that for any of these forms [L(a), L(b)] is
+ // contained in the union of [a, b] and L([a, b]).
+ //////////////////////////////////////////////////////////////////////////
internal const int LowercaseSet = 0; // Set to arg.
internal const int LowercaseAdd = 1; // Add arg.
@@ -498,7 +495,7 @@ namespace System.Text.RegularExpressions {
return;
}
- for (i = 0, iMax = _lcTable.Length; i < iMax; ) {
+ for (i = 0, iMax = _lcTable.Length; i < iMax;) {
iMid = (i + iMax) / 2;
if (_lcTable[iMid]._chMax < chMin)
i = iMid + 1;
@@ -509,7 +506,7 @@ namespace System.Text.RegularExpressions {
if (i >= _lcTable.Length)
return;
- for ( ; i < _lcTable.Length && (lc = _lcTable[i])._chMin <= chMax; i++) {
+ for (; i < _lcTable.Length && (lc = _lcTable[i])._chMin <= chMax; i++) {
if ((chMinT = lc._chMin) < chMin)
chMinT = chMin;
@@ -687,11 +684,11 @@ namespace System.Text.RegularExpressions {
setJ = swap;
}
- OuterContinue:
+ OuterContinue:
;
}
- OuterBreak:
+ OuterBreak:
;
return sb.ToString();
@@ -700,7 +697,7 @@ namespace System.Text.RegularExpressions {
internal static String CategoryUnion(string catI, string catJ) {
return catI + catJ;
}
-
+
// SetFromChar()
//
// Builds the string representations of a class with a single character.
@@ -756,7 +753,7 @@ namespace System.Text.RegularExpressions {
internal static bool CharInSet(char ch, String set, String category) {
bool b = CharInSetInternal(ch, set, category);
-
+
if (set.Length >= 2 && (set[0] == 0) && (set[1] == 0))
return !b;
else
@@ -782,21 +779,21 @@ namespace System.Text.RegularExpressions {
min = mid + 1;
}
- if ((min & 0x1) != 0)
+ if ((min & 0x1) != 0)
return true;
else
return CharInCategory(ch, category);
}
internal static bool CharInCategory(char ch, string category) {
-
+
if (category.Length == 0)
return false;
UnicodeCategory chcategory = char.GetUnicodeCategory(ch);
int i=0;
- while (i 0) {
// greater than zero is a positive case
- if (curcat == SpaceConst) {
+ if (curcat == SpaceConst) {
if (Char.IsWhiteSpace(ch))
return true;
else {
@@ -830,7 +827,7 @@ namespace System.Text.RegularExpressions {
continue;
}
}
-
+
curcat = -curcat;
--curcat;
@@ -889,7 +886,7 @@ namespace System.Text.RegularExpressions {
StringBuilder sb = new StringBuilder();
- for (int i=0; i 1) {
Done = false;
- for (i = 1, j = 0; ; i++) {
- for (last = ((SingleRange)_rangelist[j])._last; ; i++) {
+ for (i = 1, j = 0;; i++) {
+ for (last = ((SingleRange)_rangelist[j])._last;; i++) {
if (i == _rangelist.Count || last == Lastchar) {
Done = true;
break;
@@ -981,23 +978,23 @@ namespace System.Text.RegularExpressions {
}
}
- // The property table contains all the block definitions defined in the
- // XML schema spec (http://www.w3.org/TR/2001/PR-xmlschema-2-20010316/#charcter-classes), Unicode 3.0 spec (www.unicode.org),
- // and Perl 5.6 (see Programming Perl, 3rd edition page 167). Three blocks defined by Perl (and here) may
- // not be in the Unicode: IsHighPrivateUseSurrogates, IsHighSurrogates, and IsLowSurrogates.
- //
- // In addition, there was some inconsistency in the definition of IsTibetan and IsArabicPresentationForms-B.
+ // The property table contains all the block definitions defined in the
+ // XML schema spec (http://www.w3.org/TR/2001/PR-xmlschema-2-20010316/#charcter-classes), Unicode 3.0 spec (www.unicode.org),
+ // and Perl 5.6 (see Programming Perl, 3rd edition page 167). Three blocks defined by Perl (and here) may
+ // not be in the Unicode: IsHighPrivateUseSurrogates, IsHighSurrogates, and IsLowSurrogates.
+ //
+ // In addition, there was some inconsistency in the definition of IsTibetan and IsArabicPresentationForms-B.
// Regex goes with with the XML spec on both of these, since it seems to be (oddly enough) more correct than the Unicode spec!
//
// This is what we use:
// IsTibetan: 0xF00 - 0x0FFF
// IsArabicPresentationForms-B: 0xFE70-0xFEFE
//
- // The Unicode spec is inconsistent for IsTibetan. Its range is 0x0F00 - 0x0FBF. However, it clearly defines
+ // The Unicode spec is inconsistent for IsTibetan. Its range is 0x0F00 - 0x0FBF. However, it clearly defines
// Tibetan characters above 0x0FBF. This appears to be an error between the 2.0 and 3.0 spec.
//
- // The Unicode spec is also unclear on IsArabicPresentationForms-B, defining it as 0xFE70-0xFEFF.
- // There is only one character different here, 0xFEFF, which is a byte-order mark character and
+ // The Unicode spec is also unclear on IsArabicPresentationForms-B, defining it as 0xFE70-0xFEFF.
+ // There is only one character different here, 0xFEFF, which is a byte-order mark character and
// is labeled in the spec as special. I have excluded it from IsArabicPresentationForms-B and left it in IsSpecial.
// Has to be sorted by the first column
private static readonly String[,] _propTable = {
@@ -1113,7 +1110,7 @@ namespace System.Text.RegularExpressions {
return invert ? SetInverse(set): set;
}
}
- throw new ArgumentException("Unknown property");//XXX: SR.GetString(SR.MakeException, pattern, SR.GetString(SR.UnknownProperty, capname)), pattern);
+ throw new ArgumentException("Unknown property");//XXX: SR.GetString(SR.MakeException, pattern, SR.GetString(SR.UnknownProperty, capname)), pattern);
//return invert ? Any : Empty ;
}
diff --git a/base/Kernel/System/Text/RegularExpressions/regexcode.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcode.cs
similarity index 94%
rename from base/Kernel/System/Text/RegularExpressions/regexcode.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcode.cs
index ad4b4dd..69d40fa 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexcode.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcode.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexCode class is internal to the regular expression package.
@@ -21,7 +17,8 @@
// Strings and sets are indices into a string table.
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
using System.Diagnostics;
@@ -144,8 +141,8 @@ namespace System.Text.RegularExpressions {
case Lazybranch:
case Branchmark:
case Lazybranchmark:
- case Nullcount:
- case Setcount:
+ case Nullcount:
+ case Setcount:
case Branchcount:
case Lazybranchcount:
case Setmark:
@@ -311,7 +308,7 @@ namespace System.Text.RegularExpressions {
case Capturemark:
sb.Append("Index = ");
sb.Append(_codes[offset+1]);
- if (_codes[offset+2] != -1) {
+ if (_codes[offset + 2] != -1) {
sb.Append(", Unindex = ");
sb.Append(_codes[offset+2]);
}
@@ -375,12 +372,12 @@ namespace System.Text.RegularExpressions {
Debug.WriteLine("Anchors: " + RegexFCD.AnchorDescription(_anchors));
Debug.WriteLine("Scanchars: " + (_scPrefix == null ? "n/a" : RegexCharClass.SetDescription(_scPrefix.Prefix)));
Debug.WriteLine("");
- /*
- if (_bmPrefix != null) {
- Debug.WriteLine("BoyerMoore:");
- Debug.WriteLine(_bmPrefix.Dump(" "));
- }
- */
+ //
+ //if (_bmPrefix != null) {
+ // Debug.WriteLine("BoyerMoore:");
+ // Debug.WriteLine(_bmPrefix.Dump(" "));
+ //}
+ //
for (i = 0; i < _codes.Length;) {
Debug.WriteLine(OpcodeDescription(i));
i += OpcodeSize(_codes[i]);
diff --git a/base/Kernel/System/Text/RegularExpressions/regexcompilationinfo.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcompilationinfo.cs
similarity index 90%
rename from base/Kernel/System/Text/RegularExpressions/regexcompilationinfo.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcompilationinfo.cs
index 40da0bf..ab913a0 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexcompilationinfo.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexcompilationinfo.cs
@@ -1,12 +1,9 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System;
//|
@@ -15,8 +12,8 @@ namespace System.Text.RegularExpressions {
/// [To be supplied]
///
///
- //[ Serializable() ]
- public class RegexCompilationInfo {
+ //[ Serializable() ]
+ public class RegexCompilationInfo {
private String pattern;
private RegexOptions options;
private String name;
@@ -45,7 +42,7 @@ namespace System.Text.RegularExpressions {
///
public String Pattern {
get { return pattern; }
- set {
+ set {
if (value == null)
throw new ArgumentNullException("value");
pattern = value;
@@ -71,7 +68,7 @@ namespace System.Text.RegularExpressions {
///
public String Name {
get { return name; }
- set {
+ set {
if (value == null)
throw new ArgumentNullException("value");
name = value;
@@ -86,7 +83,7 @@ namespace System.Text.RegularExpressions {
///
public String Namespace {
get { return nspace; }
- set {
+ set {
if (value == null)
throw new ArgumentNullException("value");
nspace = value;
diff --git a/base/Kernel/System/Text/RegularExpressions/regexfcd.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexfcd.cs
similarity index 95%
rename from base/Kernel/System/Text/RegularExpressions/regexfcd.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexfcd.cs
index b45826f..665b105 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexfcd.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexfcd.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexFCD class is internal to the Regex package.
@@ -12,20 +8,21 @@
//
// Implementation notes:
-//
+//
// This step is as simple as walking the tree and emitting
// sequences of codes.
//
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
using System.Globalization;
-
+
internal sealed class RegexFCD {
internal int[] _intStack;
- internal int _intDepth;
+ internal int _intDepth;
internal RegexFC[] _fcStack;
internal int _fcDepth;
internal bool _earlyexit;
@@ -55,7 +52,7 @@ namespace System.Text.RegularExpressions {
if (fc._nullable)
return null;
-
+
CultureInfo culture = ((t._options & RegexOptions.CultureInvariant) != 0) ? CultureInfo.InvariantCulture : CultureInfo.CurrentCulture;
return new RegexPrefix(fc.GetFirstChars(culture), fc.IsCaseInsensitive());
}
@@ -270,14 +267,14 @@ namespace System.Text.RegularExpressions {
// Convert anchor type to anchor bit.
internal static int AnchorFromType(int type) {
switch (type) {
- case RegexNode.Bol: return Bol;
- case RegexNode.Eol: return Eol;
- case RegexNode.Boundary: return Boundary;
+ case RegexNode.Bol: return Bol;
+ case RegexNode.Eol: return Eol;
+ case RegexNode.Boundary: return Boundary;
case RegexNode.ECMABoundary: return ECMABoundary;
- case RegexNode.Beginning: return Beginning;
- case RegexNode.Start: return Start;
- case RegexNode.EndZ: return EndZ;
- case RegexNode.End: return End;
+ case RegexNode.Beginning: return Beginning;
+ case RegexNode.Start: return Start;
+ case RegexNode.EndZ: return EndZ;
+ case RegexNode.End: return End;
default: return 0;
}
}
@@ -615,7 +612,7 @@ namespace System.Text.RegularExpressions {
internal String GetFirstChars(CultureInfo culture) {
return _cc.ToSetCi(_caseInsensitive, culture);
}
-
+
internal bool IsCaseInsensitive() {
return _caseInsensitive;
}
diff --git a/base/Kernel/System/Text/RegularExpressions/regexgroup.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexgroup.cs
similarity index 89%
rename from base/Kernel/System/Text/RegularExpressions/regexgroup.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexgroup.cs
index b23db75..357eadc 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexgroup.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexgroup.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// Group represents the substring or substrings that
@@ -11,20 +7,21 @@
// regular expression match.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
//|
///
- /// Group
+ /// Group
/// represents the results from a single capturing group. A capturing group can
/// capture zero, one, or more strings in a single match because of quantifiers, so
- /// Group supplies a collection of Capture objects.
+ /// Group supplies a collection of Capture objects.
///
- //[ Serializable() ]
+ //[ Serializable() ]
public class Group : Capture {
// the empty group object
internal static Group _emptygroup = new Group(String.Empty, new int[0], 0);
-
+
internal int[] _caps;
internal int _capcount;
internal CaptureCollection _capcoll;
@@ -70,7 +67,7 @@ namespace System.Text.RegularExpressions {
// Convert to a thread-safe object by precomputing cache contents
//|
///
- /// Returns
+ /// Returns
/// a Group object equivalent to the one supplied that is safe to share between
/// multiple threads.
///
diff --git a/base/Kernel/System/Text/RegularExpressions/regexgroupcollection.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexgroupcollection.cs
similarity index 94%
rename from base/Kernel/System/Text/RegularExpressions/regexgroupcollection.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexgroupcollection.cs
index 1f7863e..94fc227 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexgroupcollection.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexgroupcollection.cs
@@ -1,16 +1,13 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// The GroupCollection lists the captured Capture numbers
// contained in a compiled Regex.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
@@ -21,7 +18,7 @@ namespace System.Text.RegularExpressions {
/// to return the set of captures done by a single capturing group.
///
///
- //[ Serializable() ]
+ //[ Serializable() ]
public class GroupCollection : ICollection {
internal Match _match;
internal Hashtable _captureMap;
@@ -111,13 +108,13 @@ namespace System.Text.RegularExpressions {
o = _captureMap[groupnum];
if (o == null)
return Group._emptygroup;
- //throw new ArgumentOutOfRangeException("groupnum");
+ //throw new ArgumentOutOfRangeException("groupnum");
return GetGroupImpl((int)o);
}
else {
//if (groupnum >= _match._regex.CapSize || groupnum < 0)
- // throw new ArgumentOutOfRangeException("groupnum");
+ // throw new ArgumentOutOfRangeException("groupnum");
if (groupnum >= _match._matchcount.Length || groupnum < 0)
return Group._emptygroup;
diff --git a/base/Kernel/System/Text/RegularExpressions/regexinterpreter.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexinterpreter.cs
similarity index 95%
rename from base/Kernel/System/Text/RegularExpressions/regexinterpreter.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexinterpreter.cs
index e01a010..f895c08 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexinterpreter.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexinterpreter.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexInterpreter class is internal to the RegularExpression package.
@@ -450,9 +446,9 @@ namespace System.Text.RegularExpressions
Advance(2);
- /*
-
- */
+ //
+//
+ //
continue;
case RegexCode.Capturemark | RegexCode.Back:
@@ -471,12 +467,12 @@ namespace System.Text.RegularExpressions
matched = Textpos() - Stacked(0);
- if (matched != 0) { // Nonempty match -> loop now
+ if (matched != 0) { // Nonempty match->loop now
Track(Stacked(0), Textpos()); // Save old mark, textpos
Stack(Textpos()); // Make new mark
Goto(Operand(0)); // Loop
}
- else { // Empty match -> straight now
+ else { // Empty match->straight now
Track2(Stacked(0)); // Save old mark
Advance(1); // Straight
}
@@ -503,10 +499,10 @@ namespace System.Text.RegularExpressions
matched = Textpos() - Stacked(0);
- if (matched != 0) { // Nonempty match -> next loop
+ if (matched != 0) { // Nonempty match->next loop
Track(Stacked(0), Textpos()); // Save old mark, textpos
}
- else { // Empty match -> no loop
+ else { // Empty match->no loop
Track2(Stacked(0)); // Save old mark
}
Advance(1);
@@ -562,11 +558,11 @@ namespace System.Text.RegularExpressions
int count = Stacked(1);
int matched = Textpos() - mark;
- if (count >= Operand(1) || (matched == 0 && count >= 0)) { // Max loops or empty match -> straight now
+ if (count >= Operand(1) || (matched == 0 && count >= 0)) { // Max loops or empty match->straight now
Track2(mark, count); // Save old mark, count
Advance(2); // Straight
}
- else { // Nonempty match -> count+loop now
+ else { // Nonempty match->count + loop now
Track(mark); // remember mark
Stack(Textpos(), count + 1); // Make new mark, incr count
Goto(Operand(0)); // Loop
@@ -582,7 +578,7 @@ namespace System.Text.RegularExpressions
// 1: Count
Trackframe(1);
Stackframe(2);
- if (Stacked(1) > 0) { // Positive -> can go straight
+ if (Stacked(1) > 0) { // Positive->can go straight
Textto(Stacked(0)); // Zap to mark
Track2(Tracked(0), Stacked(1) - 1); // Save old mark, old count
Advance(2); // Straight
@@ -609,12 +605,12 @@ namespace System.Text.RegularExpressions
int mark = Stacked(0);
int count = Stacked(1);
- if (count < 0) { // Negative count -> loop now
+ if (count < 0) { // Negative count->loop now
Track2(mark); // Save old mark
Stack(Textpos(), count + 1); // Make new mark, incr count
Goto(Operand(0)); // Loop
}
- else { // Nonneg count -> straight now
+ else { // Nonneg count->straight now
Track(mark, count, Textpos()); // Save mark, count, position
Advance(2); // Straight
}
@@ -630,14 +626,14 @@ namespace System.Text.RegularExpressions
Trackframe(3);
int mark = Tracked(0);
int textpos = Tracked(2);
- if (Tracked(1) <= Operand(1) && textpos != mark) { // Under limit and not empty match -> loop
+ if (Tracked(1) <= Operand(1) && textpos != mark) { // Under limit and not empty match->loop
Textto(textpos); // Recall position
Stack(textpos, Tracked(1) + 1); // Make new mark, incr count
Track2(mark); // Save old mark
Goto(Operand(0)); // Loop
continue;
}
- else { // Max loops or empty match -> backtrack
+ else { // Max loops or empty match->backtrack
Stack(Tracked(0), Tracked(1)); // Recall old mark, count
break; // backtrack
}
@@ -793,7 +789,8 @@ namespace System.Text.RegularExpressions
if (IsMatched(capnum)) {
if (!Refmatch(MatchIndex(capnum), MatchLength(capnum)))
break;
- } else {
+ }
+ else {
if ((runregex.roptions & RegexOptions.ECMAScript) == 0)
break;
}
diff --git a/base/Kernel/System/Text/RegularExpressions/regexmatch.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexmatch.cs
similarity index 95%
rename from base/Kernel/System/Text/RegularExpressions/regexmatch.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexmatch.cs
index 489b530..eee03a3 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexmatch.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexmatch.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// Match is the result class for a regex search.
@@ -11,7 +7,8 @@
// the entire match as well as every captured group.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
using System.Diagnostics;
@@ -19,15 +16,15 @@ namespace System.Text.RegularExpressions {
//|
///
///
- /// Represents
+ /// Represents
/// the results from a single regular expression match.
///
///
- //[ Serializable() ]
+ //[ Serializable() ]
public class Match : Group {
internal static Match _empty = new Match(null, 1, String.Empty, 0, 0, 0);
internal GroupCollection _groupcoll;
-
+
// input to the match
internal Regex _regex;
internal int _textbeg;
@@ -71,9 +68,9 @@ namespace System.Text.RegularExpressions {
//if (_textbeg < 0 || _textstart < _textbeg || _textend < _textstart || _text.Length < _textend)
// throw new ArgumentOutOfRangeException();
- System.Diagnostics.Debug.Assert(!(_textbeg < 0 || _textstart < _textbeg || _textend < _textstart || _text.Length < _textend),
+ System.Diagnostics.Debug.Assert(!(_textbeg < 0 || _textstart < _textbeg || _textend < _textstart || _text.Length < _textend),
"The parameters are out of range.");
-
+
}
// Nonpublic set-text method
@@ -262,9 +259,9 @@ namespace System.Text.RegularExpressions {
return _matches[cap][-3 - i];
}
- /*
- */
-
+ //
+ //
+
// Nonpublic: tidy the match so that it can be used as an immutable result
internal virtual void Tidy(int textpos) {
diff --git a/base/Kernel/System/Text/RegularExpressions/regexmatchcollection.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexmatchcollection.cs
similarity index 94%
rename from base/Kernel/System/Text/RegularExpressions/regexmatchcollection.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexmatchcollection.cs
index 145dacd..8df6ec2 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexmatchcollection.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexmatchcollection.cs
@@ -1,16 +1,13 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// The MatchCollection lists the successful matches that
// result when searching a string for a regular expression.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
@@ -25,7 +22,7 @@ namespace System.Text.RegularExpressions {
/// names in a regular expression.
///
///
- //[ Serializable() ]
+ //[ Serializable() ]
public class MatchCollection : ICollection {
internal Regex _regex;
internal ArrayList _matches;
@@ -178,7 +175,7 @@ namespace System.Text.RegularExpressions {
// This non-public enumerator lists all the group matches.
// Should it be public?
- //[ Serializable() ]
+ //[ Serializable() ]
internal class MatchEnumerator : IEnumerator {
internal MatchCollection _matchcoll;
internal Match _match = null;
@@ -207,7 +204,7 @@ namespace System.Text.RegularExpressions {
// The current match
public Object Current {
- get {
+ get {
if (_match == null)
throw new InvalidOperationException("Enum not Started");//XXX: SR.GetString(SR.EnumNotStarted));
return _match;
diff --git a/base/Kernel/System/Text/RegularExpressions/regexnode.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexnode.cs
similarity index 96%
rename from base/Kernel/System/Text/RegularExpressions/regexnode.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexnode.cs
index bb92460..2b7a2a7 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexnode.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexnode.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexNode class is internal to the Regex package.
@@ -11,7 +7,7 @@
//
// Implementation notes:
-//
+//
// Since the node tree is a temporary data structure only used
// during compilation of the regexp to integer codes, it's
// designed for clarity and convenience rather than
@@ -46,14 +42,15 @@
//
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
using System.Diagnostics;
internal sealed class RegexNode {
// RegexNode types
- //
+ //
// the following are leaves, and correspond to primitive operations
@@ -114,7 +111,7 @@ namespace System.Text.RegularExpressions {
internal const int infinite = 0x7FFFFFFF;
// RegexNode data members
- //
+ //
internal int _type;
@@ -232,7 +229,7 @@ namespace System.Text.RegularExpressions {
// Simple optimization. If a concatenation or alternation has only
// one child strip out the intermediate node. If it has zero children,
// turn it into an empty.
- //
+ //
internal RegexNode StripEnation(int emptyType) {
switch (ChildCount()) {
@@ -253,7 +250,7 @@ namespace System.Text.RegularExpressions {
internal RegexNode ReduceGroup() {
RegexNode u;
- for (u = this; u.Type() == Group; )
+ for (u = this; u.Type() == Group;)
u = u.Child(0);
return u;
@@ -394,7 +391,7 @@ namespace System.Text.RegularExpressions {
prev._str = RegexCharClass.SetFromChar(prev._ch);
}
- if (at._type == RegexNode.One)
+ if (at._type == RegexNode.One)
prev._str = RegexCharClass.SetUnion(prev._str, RegexCharClass.SetFromChar(at._ch)); // no categories to worry about
else {
prev._str = RegexCharClass.SetUnion(prev._str, at._str);
@@ -525,7 +522,7 @@ namespace System.Text.RegularExpressions {
}
}
-
+
internal void AddChild(RegexNode newChild) {
RegexNode reducedChild;
@@ -622,7 +619,7 @@ namespace System.Text.RegularExpressions {
case Loop:
case Lazyloop:
ArgSb.Append("(Min = " + _m.ToString() + ", Max = " + (_n == infinite ? "inf" : Convert.ToString(_n)) + ")");
- break;
+ break;
}
return ArgSb.ToString();
diff --git a/base/Kernel/System/Text/RegularExpressions/regexoptions.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexoptions.cs
similarity index 92%
rename from base/Kernel/System/Text/RegularExpressions/regexoptions.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexoptions.cs
index c6f94fa..d1410fc 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexoptions.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexoptions.cs
@@ -1,14 +1,11 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System;
@@ -22,7 +19,7 @@ using System;
///
/// [To be supplied.]
///
- None = 0x0000,
+ None = 0x0000,
//|
///
@@ -35,31 +32,31 @@ using System;
/// [To be supplied.]
///
Multiline = 0x0002, // "m"
-
+
//|
///
/// [To be supplied.]
///
ExplicitCapture = 0x0004, // "n"
-
+
//|
///
/// [To be supplied.]
///
Compiled = 0x0008, // "c"
-
+
//|
///
/// [To be supplied.]
///
Singleline = 0x0010, // "s"
-
+
//|
///
/// [To be supplied.]
///
IgnorePatternWhitespace = 0x0020, // "x"
-
+
//|
///
/// [To be supplied.]
diff --git a/base/Kernel/System/Text/RegularExpressions/regexparser.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexparser.cs
similarity index 96%
rename from base/Kernel/System/Text/RegularExpressions/regexparser.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexparser.cs
index 7d7c646..6bcaa1d 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexparser.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexparser.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexParser class is internal to the Regex package.
@@ -16,7 +12,8 @@
// ScanBlank() calls are just kind of duct-taped in.
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
using System.Globalization;
@@ -228,7 +225,8 @@ namespace System.Text.RegularExpressions {
else if (IsSpecial(ch = RightChar())) {
isQuantifier = IsQuantifier(ch);
RightNext();
- } else
+ }
+ else
ch = ' '; // nonspecial, means at ordinary char
if (startpos < endpos) {
@@ -801,10 +799,10 @@ namespace System.Text.RegularExpressions {
throw MakeException("Alternation cannnot have comment"); //XXX: SR.GetString(SR.AlternationCantHaveComment));
// disallow named capture group (?<..>..) in the condition
- if (rightchar2 == '\'' )
+ if (rightchar2 == '\'')
throw MakeException("Alternation cannot capture"); //XXX: SR.GetString(SR.AlternationCantCapture));
else {
- if (charsRight >=4 && (rightchar2 == '<' && RightChar(3) != '!' && RightChar(3) != '='))
+ if (charsRight >= 4 && (rightchar2 == '<' && RightChar(3) != '!' && RightChar(3) != '='))
throw MakeException("Alternation cannot capture"); //XXX: SR.GetString(SR.AlternationCantCapture));
}
}
@@ -1019,8 +1017,8 @@ namespace System.Text.RegularExpressions {
}
if (capnum >= 0)
return new RegexNode(RegexNode.Ref, _options, capnum);
- } else
- {
+ }
+ else {
int capnum = ScanDecimal();
if (IsCaptureSlot(capnum))
@@ -1093,8 +1091,7 @@ namespace System.Text.RegularExpressions {
if (capnum >= 0)
return new RegexNode(RegexNode.Ref, _options, capnum);
}
- else
- {
+ else {
int capnum = ScanDecimal();
if (!angled || CharsRight() > 0 && RightCharNext() == '}') {
if (IsCaptureSlot(capnum))
@@ -1572,7 +1569,7 @@ namespace System.Text.RegularExpressions {
_capnumlist = new Object[_capcount];
int i = 0;
- for (IDictionaryEnumerator de = _caps.GetEnumerator(); de.MoveNext(); )
+ for (IDictionaryEnumerator de = _caps.GetEnumerator(); de.MoveNext();)
_capnumlist[i++] = de.Key;
//XXX: System.Array.Sort(_capnumlist, InvariantComparer.Default);
@@ -1870,8 +1867,8 @@ namespace System.Text.RegularExpressions {
_group.AddChild(_alternation);
}
- /*
- */
+ //
+ //
_unit = _group;
}
diff --git a/base/Kernel/System/Text/RegularExpressions/regexreplacement.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexreplacement.cs
similarity index 95%
rename from base/Kernel/System/Text/RegularExpressions/regexreplacement.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexreplacement.cs
index f4fe1f3..a325952 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexreplacement.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexreplacement.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// The RegexReplacement class represents a substitution string for
@@ -11,7 +7,8 @@
// a sequence intermixed (1) constant strings and (2) group numbers.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
@@ -68,8 +65,8 @@ namespace System.Text.RegularExpressions {
strings.Add(sb.ToString());
}
- _strings = strings;
- _rules = rules;
+ _strings = strings;
+ _rules = rules;
}
internal String _rep;
@@ -84,7 +81,7 @@ namespace System.Text.RegularExpressions {
internal const int LastGroup = -3;
internal const int WholeString = -4;
-
+
// Given a Match, emits into the StringBuilder the evaluated
// substitution pattern.
private void ReplacementImpl(StringBuilder sb, Match match) {
@@ -145,7 +142,7 @@ namespace System.Text.RegularExpressions {
if (count < -1)
throw new ArgumentOutOfRangeException("count", "Count too Small");//XXX: SR.GetString(SR.CountTooSmall));
- if (startat < 0 || startat > input.Length)
+ if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", "Begin Index Not Negative");//SR.GetString(SR.BeginIndexNotNegative));
if (count == 0)
@@ -306,9 +303,9 @@ namespace System.Text.RegularExpressions {
if (count < 0)
throw new ArgumentOutOfRangeException("count", ""); // XXX: SR.GetString(SR.CountTooSmall));
- if (startat < 0 || startat > input.Length)
+ if (startat < 0 || startat > input.Length)
throw new ArgumentOutOfRangeException("startat", ""); // XXX: SR.GetString(SR.BeginIndexNotNegative));
-
+
if (count == 1) {
result = new String[1];
result[0] = input;
@@ -334,7 +331,7 @@ namespace System.Text.RegularExpressions {
al.Add(input.Substring(prevat, match.Index - prevat));
prevat = match.Index + match.Length;
-
+
// add all matched capture groups to the list.
int i = 1;
while (match.IsMatched(i)) {
diff --git a/base/Kernel/System/Text/RegularExpressions/regexrunner.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexrunner.cs
similarity index 96%
rename from base/Kernel/System/Text/RegularExpressions/regexrunner.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexrunner.cs
index 32dd6bb..c237498 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexrunner.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexrunner.cs
@@ -1,16 +1,12 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexRunner class is a base class for compiled regex code.
//
// Implementation notes:
-//
+//
// RegexRunner provides a common calling convention and a common
// runtime environment for the interpreter and the compiled code.
//
@@ -23,7 +19,8 @@
// backtracked results from) the Match instance.
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
using System.Diagnostics;
diff --git a/base/Kernel/System/Text/RegularExpressions/regextree.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regextree.cs
similarity index 88%
rename from base/Kernel/System/Text/RegularExpressions/regextree.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regextree.cs
index ab30793..7678d47 100644
--- a/base/Kernel/System/Text/RegularExpressions/regextree.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regextree.cs
@@ -1,16 +1,13 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// RegexTree is just a wrapper for a node tree with some
// global information attached.
//
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
diff --git a/base/Kernel/System/Text/RegularExpressions/regexwriter.cs b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexwriter.cs
similarity index 96%
rename from base/Kernel/System/Text/RegularExpressions/regexwriter.cs
rename to base/Applications/Runtime/Full/System/Text/RegularExpressions/regexwriter.cs
index 193eaca..09f59fb 100644
--- a/base/Kernel/System/Text/RegularExpressions/regexwriter.cs
+++ b/base/Applications/Runtime/Full/System/Text/RegularExpressions/regexwriter.cs
@@ -1,9 +1,5 @@
//------------------------------------------------------------------------------
-//
-//
// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-//
//------------------------------------------------------------------------------
// This RegexWriter class is internal to the Regex package.
@@ -12,18 +8,19 @@
//
// Implementation notes:
-//
+//
// This step is as simple as walking the tree and emitting
// sequences of codes.
//
#define ECMA
-namespace System.Text.RegularExpressions {
+namespace System.Text.RegularExpressions
+{
using System.Collections;
//using System.Collections.Specialized;
using System.Globalization;
-
+
internal sealed class RegexWriter {
internal int[] _intStack;
internal int _depth;
@@ -159,7 +156,7 @@ namespace System.Text.RegularExpressions {
if (str == null)
str = String.Empty;
-
+
if (_stringhash.Contains(str)) {
i = (Int32)_stringhash[str];
}
@@ -381,7 +378,7 @@ namespace System.Text.RegularExpressions {
Emit(RegexCode.Getmark);
Emit(RegexCode.Forejump);
break;
- case 1:
+ case 1:
int Branchpos = PopInt();
PushInt(CurPos());
Emit(RegexCode.Goto, 0);
@@ -501,7 +498,7 @@ namespace System.Text.RegularExpressions {
if (node._m > 0)
Emit(RegexCode.Setrep | bits, StringCode(node._str), StringCode(node._str2), node._m);
if (node._n > node._m)
- Emit(node._type | bits, StringCode(node._str), StringCode(node._str2),
+ Emit(node._type | bits, StringCode(node._str), StringCode(node._str2),
(node._n == infinite) ? infinite : node._n - node._m);
break;
diff --git a/base/Applications/Runtime/Full/System/Text/StringBuilder.cs b/base/Applications/Runtime/Full/System/Text/StringBuilder.cs
new file mode 100644
index 0000000..ebcca4d
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Text/StringBuilder.cs
@@ -0,0 +1,1273 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: StringBuilder
+//
+// Purpose: A prototype implementation of the StringBuilder
+// class.
+//
+//===========================================================
+namespace System.Text
+{
+ using System.Text;
+ using System.Threading;
+ using System;
+ using System.Diagnostics;
+ using System.Runtime.CompilerServices;
+
+ // This class represents a mutable string. It is convenient for situations in
+ // which it is desirable to modify a string, perhaps by removing, replacing, or
+ // inserting characters, without creating a new String subsequent to
+ // each modification.
+ //
+ // The methods contained within this class do not return a new StringBuilder
+ // object unless specified otherwise. This class may be used in conjunction with the String
+ // class to carry out modifications upon strings.
+ //
+ // When passing null into a constructor in VJ and VC, the null
+ // should be explicitly type cast.
+ // For Example:
+ // StringBuilder sb1 = new StringBuilder((StringBuilder)null);
+ // StringBuilder sb2 = new StringBuilder((String)null);
+ //
+ //|
+ public sealed partial class StringBuilder {
+
+ //
+ //
+ // CLASS VARIABLES
+ //
+ //
+ internal int m_currentThread = InternalGetCurrentThread();
+ internal int m_MaxCapacity = 0;
+
+
+ //
+ //
+ // STATIC CONSTANTS
+ //
+ //
+ private const int DEFAULT_CAPACITY = 16;
+ private const int DEFAULT_MAX_CAPACITY = 0x7FFFFFFF;
+
+ //
+ //
+ //CONSTRUCTORS
+ //
+ //
+
+ // Creates a new empty string builder (i.e., it represents String.Empty)
+ // with the default capacity (16 characters).
+ //|
+ public StringBuilder()
+ : this(DEFAULT_CAPACITY) {
+ }
+
+ // Create a new empty string builder (i.e., it represents String.Empty)
+ // with the specified capacity.
+ //|
+ public StringBuilder(int capacity) {
+ if (capacity < 0) {
+ throw new ArgumentOutOfRangeException("capacity");
+ }
+
+ if (capacity == 0) { // MakeFromString enforces this
+ capacity = DEFAULT_CAPACITY;
+ }
+
+ m_StringValue = String.GetStringForStringBuilder(String.Empty, capacity);
+ m_MaxCapacity = Int32.MaxValue;
+ }
+
+ //=======================CalculateCapacity===============================
+ // Calculates the new capacity of our buffer. If the size of the
+ // buffer is less than a fixed number (10000 in this case), we just
+ // double the buffer until we have enough space. Once we get larger
+ // than 10000, we use a series of heuristics to determine the most
+ // appropriate size.
+ //======================================================================
+ private int CalculateCapacity(int currentCapacity, int neededCapacity)
+ {
+ // See also Lightning\Src\VM\COMStringBuffer.cpp::CalculateCapaity
+ int newCapacity = neededCapacity;
+ if (newCapacity == 0) {
+ newCapacity = DEFAULT_CAPACITY;
+ }
+ if (neededCapacity > this.m_MaxCapacity) {
+ throw new ArgumentOutOfRangeException("exceeding max capacity");
+ }
+ while (newCapacity < neededCapacity && newCapacity > 0) {
+ newCapacity <<= 1;
+ }
+ // Check for overflow
+ if (newCapacity <= 0) {
+ // The C++ code throws on overflow, but it really should not
+ newCapacity = this.m_MaxCapacity;
+ }
+ else if (newCapacity > this.m_MaxCapacity) {
+ // We doubled past the max capacity, so back down a bit
+ newCapacity = this.m_MaxCapacity;
+ }
+ return newCapacity;
+ }
+
+ // Creates a new string builder from the specified string. If value
+ // is a null String (i.e., if it represents String.NullString)
+ // then the new string builder will also be null (i.e., it will also represent
+ // String.NullString).
+ //
+ //|
+ public StringBuilder(String value){
+ MakeFromString(value, 0, -1, -1);
+ }
+
+ // Creates a new string builder from the specified string with the specified
+ // capacity. If value is a null String (i.e., if it represents
+ // String.NullString) then the new string builder will also be null
+ // (i.e., it will also represent String.NullString).
+ // The maximum number of characters this string may contain is set by capacity.
+ //
+ //|
+ public StringBuilder(String value, int capacity) {
+ if (capacity < 0) {
+ throw new ArgumentOutOfRangeException("capacity",
+ String.Format("ArgumentOutOfRange_MustBePositive", "capacity"));
+ }
+
+ MakeFromString(value, 0, -1, capacity);
+ }
+ // Creates a new string builder from the specified substring with the specified
+ // capacity. The maximum number of characters is set by capacity.
+ //
+
+ //|
+ public StringBuilder(String value, int startIndex, int length, int capacity) {
+ if (capacity < 0) {
+ throw new ArgumentOutOfRangeException("capacity",
+ String.Format("ArgumentOutOfRange_MustBePositive", "capacity"));
+ }
+ if (length < 0) {
+ throw new ArgumentOutOfRangeException("length",
+ String.Format("ArgumentOutOfRange_MustBeNonNegNum", "length"));
+ }
+
+ MakeFromString(value, startIndex, length, capacity);
+ }
+
+ // Creates an empty StringBuilder with a minimum capacity of capacity
+ // and a maximum capacity of maxCapacity.
+ //|
+ public StringBuilder(int capacity, int maxCapacity) {
+ if (capacity > maxCapacity) {
+ throw new ArgumentOutOfRangeException("capacity", "ArgumentOutOfRange_Capacity");
+ }
+ if (maxCapacity < 1) {
+ throw new ArgumentOutOfRangeException("maxCapacity", "ArgumentOutOfRange_SmallMaxCapacity");
+ }
+
+ if (capacity < 0) {
+ throw new ArgumentOutOfRangeException("capacity",
+ String.Format("ArgumentOutOfRange_MustBePositive", "capacity"));
+ }
+ if (capacity == 0) {
+ capacity = DEFAULT_CAPACITY;
+ }
+
+ m_StringValue = String.GetStringForStringBuilder(String.Empty, capacity);
+ m_MaxCapacity = maxCapacity;
+
+ }
+
+ private String GetThreadSafeString(out int tid) {
+ String temp = m_StringValue;
+ tid = InternalGetCurrentThread();
+ if (m_currentThread == tid)
+ return temp;
+ return String.GetStringForStringBuilder(temp, temp.Capacity);
+ }
+
+ private static int InternalGetCurrentThread()
+ {
+ return Thread.CurrentThread.GetThreadId();
+ }
+
+ //
+ // Private native functions
+ //
+ //=========================MakeFromString================================
+ // If value is null, we simply create an empty string with a default
+ // length. If it does contain data, we allocate space for twice this
+ // amount of data, copy the data, associate it with the StringBuffer
+ // and clear the CopyOnWrite bit.
+ //=======================================================================
+ private void MakeFromString(String value, int startIndex, int length, int capacity)
+ {
+ // See also Lightning\Src\VM\COMStringBuffer.cpp::MakeFromString
+ if (capacity <= 0) {
+ capacity = DEFAULT_CAPACITY;
+ }
+ this.m_MaxCapacity = DEFAULT_MAX_CAPACITY;
+ if (value != null) {
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("negative startIndex");
+ }
+ int stringLength = value.Length;
+ if (length == -1) {
+ length = stringLength - startIndex;
+ }
+ else if (length + startIndex > stringLength) {
+ throw new ArgumentOutOfRangeException("exceeding string length");
+ }
+ int newCapacity = this.CalculateCapacity(capacity, length);
+ String newString =
+ String.GetStringForStringBuilder(String.Empty, newCapacity);
+ newString.AppendInPlace(value, startIndex, length, 0);
+ this.m_StringValue = newString;
+ }
+ else if (capacity == 0) {
+ this.m_StringValue = String.Empty;
+ }
+ else {
+ this.m_StringValue =
+ String.GetStringForStringBuilder(String.Empty, capacity);
+ }
+ }
+
+ //|
+ public int Capacity {
+ get {return m_StringValue.Capacity;} //-1 to account for terminating null.
+ set {InternalSetCapacity(value);}
+ }
+
+
+ //|
+ public int MaxCapacity {
+ get { return m_MaxCapacity; }
+
+ }
+
+ // Read-Only Property
+ // Ensures that the capacity of this string builder is at least the specified value.
+ // If capacity is greater than the capacity of this string builder, then the capacity
+ // is set to capacity; otherwise the capacity is unchanged.
+ //
+ //|
+ public int EnsureCapacity(int capacity) {
+ if (capacity < 0) {
+ throw new ArgumentOutOfRangeException("capacity", "ArgumentOutOfRange_NeedPosCapacity");
+ }
+
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+
+ //If we need more space or the COW bit is set, copy the buffer.
+ if (!NeedsAllocation(currentString,capacity)) {
+ return currentString.Capacity;
+ }
+
+ String newString = GetNewString(currentString,capacity);
+ ReplaceString(tid,newString);
+ return newString.Capacity;
+ }
+
+ //Sets the capacity to be capacity. If capacity is less than the current
+ //instance an ArgumentException is thrown. If capacity is greater than the current
+ //instance, memory is allocated to allow the StringBuilder to grow.
+ //
+ internal int InternalSetCapacity(int capacity)
+ {
+ // See also Lighting\Src\VM\COMStringBuffer.cpp::SetCapacity
+ // The return value of the native code is a pointer to 'this', but
+ // since it isn't ever used, we return 0;
+
+ int tid;
+ String thisString = GetThreadSafeString(out tid);
+ if (capacity < 0) {
+ throw new ArgumentOutOfRangeException("capacity is negative");
+ }
+ if (capacity < thisString.Length) {
+ throw new ArgumentOutOfRangeException("capacity lesser than size");
+ }
+ if (capacity > this.m_MaxCapacity) {
+ throw new ArgumentOutOfRangeException("exceeds max capacity");
+ }
+ if (capacity != this.m_StringValue.ArrayLength - 1) {
+ this.m_StringValue = CopyString(this,thisString,capacity);
+ this.m_currentThread = tid;
+ }
+ return 0;
+ }
+
+ private String CopyString(StringBuilder thisRef,String CurrString,
+ int newCapacity)
+ {
+ int CurrLen = CurrString.Length;
+ int copyLength;
+ if (newCapacity >= CurrLen) {
+ copyLength = CurrLen;
+ }
+ else {
+ copyLength = newCapacity;
+ }
+ return String.NewString(CurrString,0,copyLength,newCapacity);
+ }
+
+ //|
+ public override String ToString() {
+ String currentString = m_StringValue;
+ int currentThread = m_currentThread;
+ if (currentThread != 0 && currentThread != InternalGetCurrentThread()) {
+ return String.InternalCopy(currentString);
+ }
+
+ if ((2 * currentString.Length) < currentString.ArrayLength) {
+ return String.InternalCopy(currentString);
+ }
+
+ currentString.ClearPostNullChar();
+ m_currentThread = 0;
+ return currentString;
+ }
+
+ // Converts a substring of this string builder to a String.
+ //|
+ public String ToString(int startIndex, int length) {
+ return m_StringValue.Substring(startIndex, length);
+ }
+
+ // Sets the length of the String in this buffer. If length is less than the current
+ // instance, the StringBuilder is truncated. If length is greater than the current
+ // instance, nulls are appended. The capacity is adjusted to be the same as the length.
+
+ //|
+ public int Length {
+ get {
+ return m_StringValue.Length;
+ }
+ set {
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+
+ if (value == 0) { //the user is trying to clear the string
+ currentString.SetLength(0);
+ ReplaceString(tid,currentString);
+ return;
+ }
+
+ int currentLength = currentString.Length;
+ int newlength = value;
+ //If our length is less than 0 or greater than our Maximum capacity, bail.
+ if (newlength < 0) {
+ throw new ArgumentOutOfRangeException("newlength", "ArgumentOutOfRange_NegativeLength");
+ }
+
+ if (newlength > MaxCapacity) {
+ throw new ArgumentOutOfRangeException("capacity", "ArgumentOutOfRange_SmallCapacity");
+ }
+
+ //Jump out early if our requested length our currentlength.
+ //This will be a pretty rare branch.
+ if (newlength == currentLength) {
+ return;
+ }
+
+
+ //If the StringBuilder has never been converted to a string, simply set the length
+ //without allocating a new string.
+ if (newlength <= currentString.Capacity) {
+ if (newlength > currentLength) {
+ for (int i = currentLength; i < newlength; i++) // This is a rare case anyway.
+ currentString.InternalSetCharNoBoundsCheck(i,'\0');
+ }
+
+ currentString.InternalSetCharNoBoundsCheck(newlength,'\0'); //Null terminate.
+ currentString.SetLength(newlength);
+ ReplaceString(tid,currentString);
+
+ return;
+ }
+
+ // CopyOnWrite set we need to allocate a String
+ int newCapacity = (newlength>currentString.Capacity)?newlength:currentString.Capacity;
+ String newString = String.GetStringForStringBuilder(currentString, newCapacity);
+
+ //We know exactly how many characters we need, so embed that knowledge in the String.
+ newString.SetLength(newlength);
+ ReplaceString(tid,newString);
+ }
+ }
+
+ //|
+ public char this[int index] {
+ get {
+ return m_StringValue[index];
+ }
+ set {
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+ currentString.SetChar(index, value);
+ ReplaceString(tid,currentString);
+ }
+ }
+
+ // Appends a character at the end of this string builder. The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(char value, int repeatCount) {
+ if (repeatCount == 0) {
+ return this;
+ }
+ if (repeatCount < 0) {
+ throw new ArgumentOutOfRangeException("repeatCount", "ArgumentOutOfRange_NegativeCount");
+ }
+
+
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+
+ int currentLength = currentString.Length;
+ int requiredLength = currentLength + repeatCount;
+
+ if (requiredLength < 0)
+ throw new OutOfMemoryException();
+
+ if (!NeedsAllocation(currentString,requiredLength)) {
+ currentString.AppendInPlace(value, repeatCount,currentLength);
+ ReplaceString(tid,currentString);
+ return this;
+ }
+
+ String newString = GetNewString(currentString,requiredLength);
+ newString.AppendInPlace(value, repeatCount,currentLength);
+ ReplaceString(tid,newString);
+ return this;
+ }
+
+ // Appends an array of characters at the end of this string builder. The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(char[] value, int startIndex, int charCount) {
+ int requiredLength;
+
+ if (value == null) {
+ if (startIndex == 0 && charCount == 0) {
+ return this;
+ }
+ throw new ArgumentNullException("value");
+ }
+
+ if (charCount == 0) {
+ return this;
+ }
+
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_GenericPositive");
+ }
+ if (charCount < 0) {
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_GenericPositive");
+ }
+ if (charCount > value.Length - startIndex) {
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_Index");
+ }
+
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+
+ int currentLength = currentString.Length;
+ requiredLength = currentLength + charCount;
+ if (NeedsAllocation(currentString,requiredLength)) {
+ String newString = GetNewString(currentString,requiredLength);
+ newString.AppendInPlace(value, startIndex, charCount,currentLength);
+ ReplaceString(tid,newString);
+ }
+ else {
+ currentString.AppendInPlace(value, startIndex, charCount,currentLength);
+ ReplaceString(tid,currentString);
+ }
+
+ return this;
+ }
+
+ // Appends a copy of this string at the end of this string builder.
+ //|
+ public StringBuilder Append(String value) {
+ //If the value being added is null, eat the null
+ //and return.
+ if (value == null) {
+ return this;
+ }
+
+ int tid;
+ // hand inlining of GetThreadSafeString
+ String currentString = m_StringValue;
+ tid = InternalGetCurrentThread();
+ if (m_currentThread != tid)
+ currentString = String.GetStringForStringBuilder(currentString, currentString.Capacity);
+
+ int currentLength = currentString.Length;
+
+ int requiredLength = currentLength + value.Length;
+
+ if (NeedsAllocation(currentString,requiredLength)) {
+ String newString = GetNewString(currentString,requiredLength);
+ newString.AppendInPlace(value,currentLength);
+ ReplaceString(tid,newString);
+ }
+ else {
+ currentString.AppendInPlace(value,currentLength);
+ ReplaceString(tid,currentString);
+ }
+
+ return this;
+ }
+
+ internal unsafe StringBuilder Append(char *value, int count) {
+ //If the value being added is null, eat the null
+ //and return.
+ if (value == null) {
+ return this;
+ }
+
+
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+ int currentLength = currentString.Length;
+
+ int requiredLength = currentLength + count;
+
+ if (NeedsAllocation(currentString,requiredLength)) {
+ String newString = GetNewString(currentString,requiredLength);
+ newString.AppendInPlace(value, count,currentLength);
+ ReplaceString(tid,newString);
+ }
+ else {
+ currentString.AppendInPlace(value,count,currentLength);
+ ReplaceString(tid,currentString);
+ }
+
+ return this;
+ }
+
+ private bool NeedsAllocation(String currentString,int requiredLength) {
+ //<= accounts for the terminating 0 which we require on strings.
+ return (currentString.ArrayLength<=requiredLength);
+ }
+
+ private String GetNewString(String currentString, int requiredLength) {
+ int newCapacity;
+
+ requiredLength++; //Include the terminating null.
+
+ if (requiredLength < 0) {
+ throw new OutOfMemoryException();
+ }
+
+ if (requiredLength > m_MaxCapacity) {
+ throw new ArgumentOutOfRangeException("ArgumentOutOfRange_NegativeCapacity",
+ "requiredLength");
+ }
+
+ newCapacity = ( currentString.Capacity)*2; // To force a predictable growth of 160,320 etc. for testing purposes
+
+ if (newCapacity < requiredLength) {
+ newCapacity = requiredLength;
+ }
+
+ if (newCapacity > m_MaxCapacity) {
+ newCapacity = m_MaxCapacity;
+ }
+
+ if (newCapacity <= 0) {
+ throw new ArgumentOutOfRangeException("ArgumentOutOfRange_NegativeCapacity");
+ }
+
+ return String.GetStringForStringBuilder( currentString, newCapacity);
+ }
+
+ private void ReplaceString(int tid, String value) {
+ Debug.Assert(value!=null, "[StringBuilder.ReplaceString]value!=null");
+
+ m_currentThread = tid; // new owner
+ m_StringValue = value;
+ }
+
+ // Appends a copy of the characters in value from startIndex to startIndex +
+ // count at the end of this string builder.
+ //|
+ public StringBuilder Append(String value, int startIndex, int count) {
+ //If the value being added is null, eat the null
+ //and return.
+ if (value == null) {
+ if (startIndex == 0 && count == 0) {
+ return this;
+ }
+ throw new ArgumentNullException("value");
+ }
+
+ if (count <= 0) {
+ if (count == 0) {
+ return this;
+ }
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_GenericPositive");
+ }
+
+ if (startIndex < 0 || (startIndex > value.Length - count)) {
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_Index");
+ }
+
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+ int currentLength = currentString.Length;
+
+ int requiredLength = currentLength + count;
+
+ if (NeedsAllocation(currentString,requiredLength)) {
+ String newString = GetNewString(currentString,requiredLength);
+ newString.AppendInPlace(value, startIndex, count, currentLength);
+ ReplaceString(tid,newString);
+ }
+ else {
+ currentString.AppendInPlace(value, startIndex, count, currentLength);
+ ReplaceString(tid,currentString);
+ }
+
+ return this;
+ }
+
+ // Inserts multiple copies of a string into this string builder at the specified position.
+ // Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, this
+ // string builder is not changed. Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public unsafe StringBuilder Insert(int index, String value, int count) {
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+ int currentLength = currentString.Length;
+
+ //If value isn't null, get all of our required values.
+ if (value == null) {
+ if (index == 0 && count == 0) {
+ return this;
+ }
+ throw new ArgumentNullException("ArgumentNull_String");
+ }
+
+ //Range check the index.
+ if (index < 0 || index > currentLength) {
+ throw new ArgumentOutOfRangeException("index","ArgumentOutOfRange_Index");
+ }
+
+ if (count < 1) {
+ throw new ArgumentOutOfRangeException("count","ArgumentOutOfRange_GenericPositive");
+ }
+
+ //Calculate the new length, ensure that we have the space and set the space variable for this buffer
+ int requiredLength;
+ try {
+ requiredLength = checked(currentLength + (value.Length * count));
+ }
+ catch (Exception) {
+ throw new OutOfMemoryException();
+ }
+
+ if (NeedsAllocation(currentString,requiredLength)) {
+ String newString = GetNewString(currentString,requiredLength);
+ newString.InsertInPlace(index, value, count, currentLength, requiredLength);
+ ReplaceString(tid,newString);
+ }
+ else {
+ currentString.InsertInPlace(index, value, count, currentLength, requiredLength);
+ ReplaceString(tid,currentString);
+ }
+ return this;
+ }
+
+
+
+ // Property.
+ // Removes the specified characters from this string builder.
+ // The length of this string builder is reduced by
+ // length, but the capacity is unaffected.
+ //
+ //|
+ public StringBuilder Remove(int startIndex, int length)
+ {
+ // See also Lightning\Src\VM\COMStringBuffer.cpp::Remove
+ int tid;
+ String thisString = GetThreadSafeString(out tid);
+ int thisLength = thisString.ArrayLength-1;
+ if (length < 0) {
+ throw new ArgumentOutOfRangeException("Negative length");
+ }
+ if (startIndex < 0) {
+ throw new ArgumentOutOfRangeException("Negative start index");
+ }
+ if (startIndex + length > thisLength) {
+ throw new ArgumentOutOfRangeException("Exceeding string length");
+ }
+ thisString.RemoveRange(startIndex, length);
+ this.m_StringValue = thisString;
+ this.m_currentThread = tid;
+ return this;
+ }
+
+ //
+ //
+ // PUBLIC INSTANCE FUNCTIONS
+ //
+ //
+
+ //====================================Append====================================
+ //
+ //==============================================================================
+ // Appends a boolean to the end of this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(bool value) {
+ return Append(value.ToString());
+ }
+
+ // Appends an sbyte to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Append(sbyte value) {
+ return Append(value.ToString());
+ }
+
+ // Appends a ubyte to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(byte value) {
+ return Append(value.ToString());
+ }
+
+ // Appends a character at the end of this string builder. The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(char value) {
+ int tid;
+
+ // hand inlining of GetThreadSafeString
+ String currentString = m_StringValue;
+ tid = InternalGetCurrentThread();
+ if (m_currentThread != tid)
+ currentString = String.GetStringForStringBuilder(currentString, currentString.Capacity);
+
+ int currentLength = currentString.Length;
+ if (!NeedsAllocation(currentString,currentLength + 1)) {
+ currentString.AppendInPlace(value,currentLength);
+ ReplaceString(tid,currentString);
+ return this;
+ }
+
+ String newString = GetNewString(currentString,currentLength+1);
+ newString.AppendInPlace(value,currentLength);
+ ReplaceString(tid,newString);
+ return this;
+ }
+
+ // Appends a short to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(short value) {
+ return Append(value.ToString());
+ }
+
+ // Appends an int to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(int value) {
+ return Append(value.ToString());
+ }
+
+ // Appends a long to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(long value) {
+ return Append(value.ToString());
+ }
+
+ // Appends a float to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(float value) {
+ return Append(value.ToString());
+ }
+
+ // Appends a double to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(double value) {
+ return Append(value.ToString());
+ }
+
+ //|
+ public StringBuilder Append(decimal value) {
+ return Append(value.ToString());
+ }
+
+ // Appends an ushort to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Append(ushort value) {
+ return Append(value.ToString());
+ }
+
+ // Appends an uint to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Append(uint value) {
+ return Append(value.ToString());
+ }
+
+ // Appends an unsigned long to this string builder.
+ // The capacity is adjusted as needed.
+
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Append(ulong value) {
+ return Append(value.ToString());
+ }
+
+ // Appends an Object to this string builder.
+ // The capacity is adjusted as needed.
+ //|
+ public StringBuilder Append(Object value) {
+ if (null == value) {
+ //Appending null is now a no-op.
+ return this;
+ }
+ return Append(value.ToString());
+ }
+
+ // Appends all of the characters in value to the current instance.
+ //|
+ public StringBuilder Append(char[] value) {
+ if (null == value) {
+ return this;
+ }
+
+ int valueLength = value.Length;
+
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+
+ int currentLength = currentString.Length;
+ int requiredLength = currentLength + value.Length;
+ if (NeedsAllocation(currentString,requiredLength)) {
+ String newString = GetNewString(currentString,requiredLength);
+ newString.AppendInPlace(value, 0, valueLength,currentLength);
+ ReplaceString(tid,newString);
+ }
+ else {
+ currentString.AppendInPlace(value, 0, valueLength, currentLength);
+ ReplaceString(tid,currentString);
+ }
+ return this;
+ }
+
+ //====================================Insert====================================
+ //
+ //==============================================================================
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, String value) {
+ if (value == null) // This is to do the index validation
+ return Insert(index,value,0);
+ else
+ return Insert(index,value,1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert( int index, bool value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, sbyte value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, byte value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, short value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, char value) {
+ return Insert(index,Char.ToString(value),1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, char[] value) {
+ if (null == value) {
+ return Insert(index, value, 0, 0);
+ }
+ return Insert(index, value, 0, value.Length);
+ }
+
+ // Returns a reference to the StringBuilder with charCount characters from
+ // value inserted into the buffer at index. Existing characters are shifted
+ // to make room for the new text and capacity is adjusted as required. If value is null, the StringBuilder
+ // is unchanged. Characters are taken from value starting at position startIndex.
+ //|
+ public StringBuilder Insert(int index, char []value, int startIndex, int charCount)
+ {
+ throw new Exception("System.Text.StringBuilder.Insert not implemented in Bartok");
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, int value){
+ return Insert(index,value.ToString(),1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, long value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, float value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. ; Inserts ";<;no object>;"; if value
+ // is null.
+ //
+ //|
+ public StringBuilder Insert(int index, double value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+ //|
+ public StringBuilder Insert(int index, decimal value) {
+ return Insert(index,value.ToString(),1);
+ }
+
+ // Returns a reference to the StringBuilder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed.
+ //
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, ushort value) {
+ return Insert(index, value.ToString(),1);
+ }
+
+
+ // Returns a reference to the StringBuilder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed.
+ //
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, uint value) {
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed.
+ //
+ //|
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, ulong value) {
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to this string builder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the
+ // new text. The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. No changes are made if value is null.
+ //
+ //|
+ public StringBuilder Insert(int index, Object value) {
+ //If we get a null
+ if (null == value) {
+ return this;
+ }
+ return Insert(index,value.ToString(),1);
+ }
+
+ //|
+ public StringBuilder AppendFormat(String format, Object arg0) {
+ return AppendFormat(format, new Object[] {arg0});
+ }
+
+ //|
+ public StringBuilder AppendFormat(String format, Object arg0, Object arg1) {
+ return AppendFormat(format, new Object[] {arg0, arg1});
+ }
+
+ //|
+ public StringBuilder AppendFormat(String format, Object arg0, Object arg1, Object arg2) {
+ return AppendFormat(format, new Object[] {arg0, arg1, arg2});
+ }
+
+ private static void FormatError() {
+ throw new FormatException("Format_InvalidString");
+ }
+
+ //|
+ public StringBuilder AppendFormat(String format, params Object[] args) {
+ if (format == null || args == null) {
+ throw new ArgumentNullException((format==null)?"format":"args");
+ }
+ char[] chars = format.ToCharArray(0, format.Length);
+ int pos = 0;
+ int len = chars.Length;
+ char ch = '\x0';
+
+ while (true) {
+ int p = pos;
+ int i = pos;
+ while (pos < len) {
+ ch = chars[pos];
+
+ pos++;
+ if (ch == '}') {
+ if (pos < len && chars[pos] =='}') // Treat as escape character for }}
+ pos++;
+ else
+ FormatError();
+ }
+
+ if (ch == '{') {
+ if (pos < len && chars[pos] =='{') // Treat as escape character for {{
+ pos++;
+ else {
+ pos--;
+ break;
+ }
+ }
+
+ chars[i++] = ch;
+ }
+ if (i > p) Append(chars, p, i - p);
+ if (pos == len) break;
+ pos++;
+ if (pos == len || (ch = chars[pos]) < '0' || ch > '9') FormatError();
+ int index = 0;
+ do {
+ index = index * 10 + ch - '0';
+ pos++;
+ if (pos == len) FormatError();
+ ch = chars[pos];
+ } while (ch >= '0' && ch <= '9' && index < 1000000);
+ if (index >= args.Length) throw new FormatException("Format_IndexOutOfRange");
+ while (pos < len && (ch = chars[pos]) == ' ') pos++;
+ bool leftJustify = false;
+ int width = 0;
+ if (ch == ',') {
+ pos++;
+ while (pos < len && chars[pos] == ' ') pos++;
+
+ if (pos == len) FormatError();
+ ch = chars[pos];
+ if (ch == '-') {
+ leftJustify = true;
+ pos++;
+ if (pos == len) FormatError();
+ ch = chars[pos];
+ }
+ if (ch < '0' || ch > '9') FormatError();
+ do {
+ width = width * 10 + ch - '0';
+ pos++;
+ if (pos == len) FormatError();
+ ch = chars[pos];
+ } while (ch >= '0' && ch <= '9' && width < 1000000);
+ }
+
+ while (pos < len && (ch = chars[pos]) == ' ') pos++;
+ Object arg = args[index];
+ String fmt = null;
+ if (ch == ':') {
+ pos++;
+ p = pos;
+ i = pos;
+ while (true) {
+ if (pos == len) FormatError();
+ ch = chars[pos];
+ pos++;
+ if (ch == '{') {
+ if (pos < len && chars[pos] =='{') // Treat as escape character for {{
+ pos++;
+ else
+ FormatError();
+ }
+ else if (ch == '}') {
+ if (pos < len && chars[pos] =='}') // Treat as escape character for }}
+ pos++;
+ else {
+ pos--;
+ break;
+ }
+ }
+
+ chars[i++] = ch;
+ }
+ if (i > p) fmt = new String(chars, p, i - p);
+ }
+ if (ch != '}') FormatError();
+ pos++;
+ String s = null;
+
+ if (s == null) {
+ if (arg is IFormattable) {
+ s = ((IFormattable)arg).ToString(fmt);
+ }
+ else if (arg != null) {
+ s = arg.ToString();
+ }
+ }
+
+ if (s == null) s = String.Empty;
+ int pad = width - s.Length;
+ if (!leftJustify && pad > 0) Append(' ', pad);
+ Append(s);
+ if (leftJustify && pad > 0) Append(' ', pad);
+ }
+ return this;
+ }
+
+ // Returns a reference to the current StringBuilder with all instances of oldString
+ // replaced with newString. If startIndex and count are specified,
+ // we only replace strings completely contained in the range of startIndex to startIndex +
+ // count. The strings to be replaced are checked on an ordinal basis (e.g. not culture aware). If
+ // newValue is null, instances of oldValue are removed (e.g. replaced with nothing.).
+ //
+ //|
+ public StringBuilder Replace(String oldValue, String newValue) {
+ return Replace(oldValue, newValue, 0, Length);
+ }
+
+ //|
+ public StringBuilder Replace(String oldValue, String newValue, int startIndex, int count)
+ {
+ throw new Exception("System.Text.StringBuilder.Replace not implemented in Bartok");
+ }
+
+ //|
+ public bool Equals(StringBuilder sb)
+ {
+ if (sb == null)
+ return false;
+ return ((this.Capacity == sb.Capacity) && (this.MaxCapacity == sb.MaxCapacity) && (this. m_StringValue.Equals(sb. m_StringValue)));
+ }
+
+ // Returns a StringBuilder with all instances of oldChar replaced with
+ // newChar. The size of the StringBuilder is unchanged because we're only
+ // replacing characters. If startIndex and count are specified, we
+ // only replace characters in the range from startIndex to startIndex+count
+ //
+ //|
+ public StringBuilder Replace(char oldChar, char newChar) {
+ return Replace(oldChar, newChar, 0, Length);
+ }
+ //|
+ public StringBuilder Replace(char oldChar, char newChar, int startIndex, int count) {
+ int tid;
+ String currentString = GetThreadSafeString(out tid);
+ int currentLength = currentString.Length;
+
+ if ((uint)startIndex > (uint)currentLength) {
+ throw new ArgumentOutOfRangeException("startIndex", "ArgumentOutOfRange_Index");
+ }
+
+ if (count < 0 || startIndex > currentLength - count) {
+ throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_Index");
+ }
+
+ if (!NeedsAllocation(currentString,currentLength)) {
+ currentString.ReplaceCharInPlace(oldChar, newChar, startIndex, count, currentLength);
+ ReplaceString(tid,currentString);
+ return this;
+ }
+
+ String newString = GetNewString(currentString,currentLength);
+ newString.ReplaceCharInPlace(oldChar, newChar, startIndex, count, currentLength);
+ ReplaceString(tid,newString);
+ return this;
+ }
+ }
+}
+
+
+
diff --git a/base/Kernel/System/Text/UTF8Encoding.cs b/base/Applications/Runtime/Full/System/Text/UTF8Encoding.cs
similarity index 92%
rename from base/Kernel/System/Text/UTF8Encoding.cs
rename to base/Applications/Runtime/Full/System/Text/UTF8Encoding.cs
index c6f18e2..ce821bf 100644
--- a/base/Kernel/System/Text/UTF8Encoding.cs
+++ b/base/Applications/Runtime/Full/System/Text/UTF8Encoding.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Text {
+namespace System.Text
+{
using System;
using System.Diagnostics;
@@ -19,18 +20,18 @@ namespace System.Text {
// switch the byte orderings.
//|
public class UTF8Encoding : Encoding {
- /*
- bytes bits UTF-8 representation
- ----- ---- -----------------------------------
- 1 7 0vvvvvvv
- 2 11 110vvvvv 10vvvvvv
- 3 16 1110vvvv 10vvvvvv 10vvvvvv
- 4 21 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
- ----- ---- -----------------------------------
-
- Surrogate:
- Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
- */
+ //
+ // bytes bits UTF-8 representation
+ // ----- ---- -----------------------------------
+ // 1 7 0vvvvvvv
+ // 2 11 110vvvvv 10vvvvvv
+ // 3 16 1110vvvv 10vvvvvv 10vvvvvv
+ // 4 21 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
+ // ----- ---- -----------------------------------
+//
+ // Surrogate:
+ // Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
+ //
private const int UTF8_CODEPAGE=65001;
@@ -89,7 +90,7 @@ namespace System.Text {
//|
public unsafe override int GetByteCount(String chars) {
- if (chars==null)
+ if (chars == null)
throw new ArgumentNullException("chars");
int retVal = -1;
fixed (char *p = chars) {
@@ -138,7 +139,8 @@ namespace System.Text {
// Encode the previous high-surrogate char.
byteCount += 3;
// The isSurrogate is still true, because this could be the start of another valid surrogate pair.
- } else {
+ }
+ else {
if (isThrowException) {
throw new ArgumentException("Argument_InvalidHighSurrogate");
}
@@ -148,11 +150,13 @@ namespace System.Text {
inSurrogate = false;
index--;
}
- } else if (ch < 0x0080)
+ }
+ else if (ch < 0x0080)
byteCount++;
else if (ch < 0x0800) {
byteCount += 2;
- } else {
+ }
+ else {
if (CharacterInfo.IsHighSurrogate(ch)) {
//
// Found the start of a surrogate.
@@ -216,7 +220,7 @@ namespace System.Text {
}
int retVal = -1;
- if (chars.Length==0) {
+ if (chars.Length == 0) {
return 0;
}
fixed (char *p = chars) {
@@ -299,7 +303,8 @@ namespace System.Text {
bytes[byteIndex++] = (byte)(0x80 | (surrogateChar >> 6) & 0x3F);
bytes[byteIndex++] = (byte)(0x80 | surrogateChar & 0x3F);
surrogateChar = -1;
- } else if (CharacterInfo.IsHighSurrogate(ch)) {
+ }
+ else if (CharacterInfo.IsHighSurrogate(ch)) {
// We have two high surrogate.
if (isThrowException) {
throw new ArgumentException("Argument_InvalidHighSurrogate");
@@ -307,7 +312,8 @@ namespace System.Text {
// Encode the previous high-surrogate char.
EncodeThreeBytes(surrogateChar, bytes, ref byteIndex);
surrogateChar = ch;
- } else {
+ }
+ else {
if (isThrowException) {
throw new ArgumentException("Argument_InvalidHighSurrogate");
}
@@ -318,19 +324,24 @@ namespace System.Text {
surrogateChar = -1;
charIndex--;
}
- } else if (ch < 0x0080) {
+ }
+ else if (ch < 0x0080) {
bytes[byteIndex++] = (byte)ch;
- } else if (ch < 0x0800) {
+ }
+ else if (ch < 0x0800) {
bytes[byteIndex++] = (byte)(0xC0 | ch >> 6 & 0x1F);
bytes[byteIndex++] = (byte)(0x80 | ch & 0x3F);
- } else if (CharacterInfo.IsHighSurrogate(ch)) {
+ }
+ else if (CharacterInfo.IsHighSurrogate(ch)) {
//
// Found the start of a surrogate.
//
surrogateChar = ch;
- } else if (CharacterInfo.IsLowSurrogate(ch) && isThrowException) {
+ }
+ else if (CharacterInfo.IsLowSurrogate(ch) && isThrowException) {
throw new ArgumentException("Argument_InvalidLowSurrogate");
- } else { //we now know that the char is >=0x0800 and isn't a high surrogate
+ }
+ else { //we now know that the char is >= 0x0800 and isn't a high surrogate
bytes[byteIndex++] = (byte)(0xE0 | ch >> 12 & 0x0F);
bytes[byteIndex++] = (byte)(0x80 | ch >> 6 & 0x3F);
bytes[byteIndex++] = (byte)(0x80 | ch & 0x3F);
@@ -348,7 +359,8 @@ namespace System.Text {
EncodeThreeBytes(surrogateChar, bytes, ref byteIndex);
}
}
- } catch (IndexOutOfRangeException) {
+ }
+ catch (IndexOutOfRangeException) {
throw new ArgumentException("Argument_ConversionOverflow");
}
@@ -397,7 +409,8 @@ namespace System.Text {
if ((b & 0x80) == 0) {
// This is an ASCII.
charCount++;
- } else {
+ }
+ else {
byte temp = b;
while ((temp & 0x80) != 0) {
temp <<= 1;
@@ -429,12 +442,14 @@ namespace System.Text {
if (isThrowException) {
throw new ArgumentException("Argument_InvalidByteSequence");
}
- } else {
+ }
+ else {
bits = temp >> trailCount;
trailCount--;
}
}
- } else {
+ }
+ else {
// We are expecting to see trailing bytes like 10vvvvvv
if ((b & 0xC0) != 0x80) {
// If not, this is NOT a valid sequence.
@@ -444,7 +459,8 @@ namespace System.Text {
index--;
trailCount = 0;
isSurrogate = false;
- } else {
+ }
+ else {
switch (byteSequence) {
case 3:
// Check 3-byte sequence for non-shortest form.
@@ -469,7 +485,8 @@ namespace System.Text {
}
trailCount = -1;
}
- } else if ((bits & 0x04) != 0) {
+ }
+ else if ((bits & 0x04) != 0) {
// Make sure that the resulting Unicode is within the valid surrogate range.
// The 4 byte code sequence can hold up to 21 bits, and the maximum valid code point range
// that Unicode (with surrogate) could represent are from U+000000 ~ U+10FFFF.
@@ -517,8 +534,7 @@ namespace System.Text {
throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
"ArgumentOutOfRange_NeedNonNegNum");
}
- if ( bytes.Length - byteIndex < byteCount)
- {
+ if (bytes.Length - byteIndex < byteCount) {
throw new ArgumentOutOfRangeException("bytes",
"ArgumentOutOfRange_IndexCountBuffer");
}
@@ -557,7 +573,8 @@ namespace System.Text {
// Found an ASCII character.
//
chars[charIndex++] = (char)b;
- } else {
+ }
+ else {
// Check if this is a valid starting byte.
byte temp = (byte)b;
while ((temp & 0x80) != 0) {
@@ -592,13 +609,15 @@ namespace System.Text {
if (isThrowException) {
throw new ArgumentException("Argument_InvalidByteSequence");
}
- } else {
+ }
+ else {
isSurrogate = (trailCount == 4);
bits = temp >> trailCount;
trailCount--;
}
}
- } else {
+ }
+ else {
// We are expecting to see bytes like 10vvvvvv
if ((b & 0xC0) != 0x80) {
// If not, this is NOT a valid sequence.
@@ -613,7 +632,8 @@ namespace System.Text {
byteIndex--;
bits = 0;
trailCount = 0;
- } else {
+ }
+ else {
switch (byteSequence) {
case 3:
// Check 3-byte sequence for non-shortest form.
@@ -637,7 +657,8 @@ namespace System.Text {
}
trailCount = -1;
}
- } else if ((bits & 0x04) != 0) {
+ }
+ else if ((bits & 0x04) != 0) {
// Make sure that the resulting Unicode is within the valid surrogate range.
// The 4 byte code sequence can hold up to 21 bits, and the maximum valid code point range
// that Unicode (with surrogate) could represent are from U+000000 ~ U+10FFFF.
@@ -673,7 +694,8 @@ namespace System.Text {
}
}
}
- } catch (IndexOutOfRangeException) {
+ }
+ catch (IndexOutOfRangeException) {
throw new ArgumentException("Argument_ConversionOverflow");
}
if (decoder != null) {
diff --git a/base/Kernel/System/Text/UnicodeEncoding.cs b/base/Applications/Runtime/Full/System/Text/UnicodeEncoding.cs
similarity index 95%
rename from base/Kernel/System/Text/UnicodeEncoding.cs
rename to base/Applications/Runtime/Full/System/Text/UnicodeEncoding.cs
index 24c5b2b..56f13ce 100644
--- a/base/Kernel/System/Text/UnicodeEncoding.cs
+++ b/base/Applications/Runtime/Full/System/Text/UnicodeEncoding.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Text {
+namespace System.Text
+{
using System;
//|
public class UnicodeEncoding : Encoding
@@ -53,7 +54,7 @@ namespace System.Text {
//|
public override int GetByteCount(String s)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException("s");
int byteCount = s.Length * CharSize;
@@ -149,7 +150,7 @@ namespace System.Text {
// @TODO: Consider pinning the String here and then using a managed
// memcpy implementation (see VTable). This would
// require a C# compiler that can get an interior pointer to a
- // String, probably via the fixed statement. -- BrianGru, 12/6/2000
+ // String, probably via the fixed statement.
s.CopyToByteArray(charIndex, bytes, byteIndex, charCount);
}
return byteCount;
@@ -165,8 +166,7 @@ namespace System.Text {
throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
"ArgumentOutOfRange_NeedNonNegNum");
}
- if ( bytes.Length - index < count)
- {
+ if (bytes.Length - index < count) {
throw new ArgumentOutOfRangeException("bytes",
"ArgumentOutOfRange_IndexCountBuffer");
}
@@ -185,8 +185,7 @@ namespace System.Text {
throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
"ArgumentOutOfRange_NeedNonNegNum");
}
- if ( bytes.Length - byteIndex < byteCount)
- {
+ if (bytes.Length - byteIndex < byteCount) {
throw new ArgumentOutOfRangeException("bytes",
"ArgumentOutOfRange_IndexCountBuffer");
}
@@ -314,8 +313,7 @@ namespace System.Text {
throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
"ArgumentOutOfRange_NeedNonNegNum");
}
- if (bytes.Length - byteIndex < byteCount)
- {
+ if (bytes.Length - byteIndex < byteCount) {
throw new ArgumentOutOfRangeException("bytes",
"ArgumentOutOfRange_IndexCountBuffer");
}
diff --git a/base/Applications/Runtime/System/Threading/AutoResetEvent.cs b/base/Applications/Runtime/Full/System/Threading/AutoResetEvent.cs
similarity index 95%
rename from base/Applications/Runtime/System/Threading/AutoResetEvent.cs
rename to base/Applications/Runtime/Full/System/Threading/AutoResetEvent.cs
index 39996fa..33b58c4 100644
--- a/base/Applications/Runtime/System/Threading/AutoResetEvent.cs
+++ b/base/Applications/Runtime/Full/System/Threading/AutoResetEvent.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Threading {
+namespace System.Threading
+{
using System;
using System.Runtime.CompilerServices;
diff --git a/base/Kernel/System/Threading/HandleCreateException.cs b/base/Applications/Runtime/Full/System/Threading/HandleCreateException.cs
similarity index 100%
rename from base/Kernel/System/Threading/HandleCreateException.cs
rename to base/Applications/Runtime/Full/System/Threading/HandleCreateException.cs
diff --git a/base/Applications/Runtime/Full/System/Threading/Interlocked.cs b/base/Applications/Runtime/Full/System/Threading/Interlocked.cs
new file mode 100644
index 0000000..a9dec5f
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/Interlocked.cs
@@ -0,0 +1,329 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+namespace System.Threading
+{
+
+ using System;
+ using System.Runtime.CompilerServices;
+
+#if SINGULARITY_KERNEL
+ using Microsoft.Singularity.Memory;
+#endif
+#if ISA_ARM
+ using Microsoft.Singularity;
+ using Microsoft.Singularity.Isal;
+#endif
+
+ //|
+#if ISA_ARM
+ [AccessedByRuntime("Routines defined in interlocked.cpp")]
+#endif
+ public sealed class Interlocked
+ {
+ private Interlocked() {
+ }
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern int Increment(ref int location);
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern int Decrement(ref int location);
+
+ //|
+ [NoHeapAllocation]
+ public static long Increment(ref long location) {
+ long value = location;
+ while (CompareExchange(ref location, value + 1, value) != value) {
+ value = location;
+ }
+ return value+1;
+ }
+
+ //|
+ [NoHeapAllocation]
+ public static long Decrement(ref long location) {
+ long value = location;
+ while (CompareExchange(ref location, value - 1, value) != value) {
+ value = location;
+ }
+ return value-1;
+ }
+
+ //|
+ [CLSCompliant(false)]
+ [NoHeapAllocation]
+ public static ulong Increment(ref ulong location) {
+ ulong value = location;
+ while (CompareExchange(ref location, value + 1, value) != value) {
+ value = location;
+ }
+ return value+1;
+ }
+
+ //|
+ [CLSCompliant(false)]
+ [NoHeapAllocation]
+ public static ulong Decrement(ref ulong location) {
+ ulong value = location;
+ while (CompareExchange(ref location, value - 1, value) != value) {
+ value = location;
+ }
+ return value-1;
+ }
+
+ [CLSCompliant(false)]
+ [NoHeapAllocation]
+ public static ulong Add(ref ulong location, ulong value) {
+ ulong tmp = location;
+ ulong newValue = tmp + value;
+
+ while (CompareExchange(ref location, newValue, tmp) != tmp) {
+ tmp = location;
+ newValue = tmp + value;
+ }
+ return newValue;
+ }
+
+ [CLSCompliant(false)]
+ [NoHeapAllocation]
+ public static ulong Subtract(ref ulong location, ulong value) {
+ ulong tmp = location;
+ ulong newValue = tmp - value;
+
+ while (CompareExchange(ref location, newValue, tmp) != tmp) {
+ tmp = location;
+ newValue = tmp - value;
+ }
+ return newValue;
+ }
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern int Exchange(ref int location1, int value);
+
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern int CompareExchange(ref int location1, int value, int comparand);
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern float Exchange(ref float location1, float value);
+
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern float CompareExchange(ref float location1, float value, float comparand);
+
+ // Added for thread initialization.
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern ThreadState CompareExchange(ref ThreadState location1, ThreadState value, ThreadState comparand);
+
+
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern long CompareExchange(ref long location1, long value, long comparand);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern ulong CompareExchange(ref ulong location1, ulong value, ulong comparand);
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern Object Exchange(ref Object location1, Object value);
+
+ //|
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern Object CompareExchange(ref Object location1, Object value, Object comparand);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern uint Exchange(ref uint location1, uint value);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern uint CompareExchange(ref uint location1, uint value, uint comparand);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ // [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern UIntPtr Exchange(ref UIntPtr location1, UIntPtr value);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ // [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern UIntPtr CompareExchange(ref UIntPtr location1, UIntPtr value, UIntPtr comparand);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern unsafe UIntPtr Exchange(UIntPtr * location1, UIntPtr value);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern unsafe UIntPtr CompareExchange(UIntPtr * location1, UIntPtr value, UIntPtr comparand);
+
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ public static extern unsafe void * CompareExchange(ref void * location1, void * value, void * comparand);
+
+#if SINGULARITY_KERNEL
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ internal static extern unsafe HandleTable.HandlePage * CompareExchange(
+ ref HandleTable.HandlePage * location1,
+ HandleTable.HandlePage * value,
+ HandleTable.HandlePage * comparand);
+
+ [CLSCompliant(false)]
+#if ISA_IX
+ [Intrinsic]
+#elif ISA_ARM
+ [AccessedByRuntime("defined in interlocked.cpp")]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ [StackBound(64)]
+#endif
+ [NoHeapAllocation]
+ internal static extern unsafe HandleTable.HandleEntry * CompareExchange(
+ ref HandleTable.HandleEntry * location1,
+ HandleTable.HandleEntry * value,
+ HandleTable.HandleEntry * comparand);
+#endif
+
+ }
+}
diff --git a/base/Applications/Runtime/System/Threading/ManualResetEvent.cs b/base/Applications/Runtime/Full/System/Threading/ManualResetEvent.cs
similarity index 95%
rename from base/Applications/Runtime/System/Threading/ManualResetEvent.cs
rename to base/Applications/Runtime/Full/System/Threading/ManualResetEvent.cs
index 3452d2c..d0e999f 100644
--- a/base/Applications/Runtime/System/Threading/ManualResetEvent.cs
+++ b/base/Applications/Runtime/Full/System/Threading/ManualResetEvent.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System.Threading {
+namespace System.Threading
+{
using System;
using System.Runtime.CompilerServices;
diff --git a/base/Applications/Runtime/Full/System/Threading/Monitor.cs b/base/Applications/Runtime/Full/System/Threading/Monitor.cs
new file mode 100644
index 0000000..2aecbcb
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/Monitor.cs
@@ -0,0 +1,393 @@
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+namespace System.Threading
+{
+
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+
+ using Microsoft.Bartok.Runtime;
+
+ using Microsoft.Singularity;
+
+ ///
+ /// A monitor is used for synchronization. Only a single thread can
+ /// hold the monitor at any given time.
+ ///
+ /// The monitor maintains two lists of threads: one for threads waiting
+ /// to enter the monitor, and one for threads waiting for a pulse within
+ /// the monitor.
+ ///
+ public sealed partial class Monitor {
+ ///
+ /// Private so that only we can create instances.
+ ///
+ internal Monitor()
+ {
+ this.mutex = new Mutex();
+ this.depth = 0;
+ }
+
+ ///
+ /// Wake up a thread waiting on the monitor.
+ ///
+ public static void Pulse(Object obj)
+ {
+ Monitor monitor = GetMonitorFromObject(obj);
+ monitor.Pulse();
+ }
+
+ ///
+ /// Wake up all threads waiting on the monitor.
+ ///
+ public static void PulseAll(Object obj)
+ {
+ Monitor monitor = GetMonitorFromObject(obj);
+ monitor.PulseAll();
+ }
+
+ ///
+ /// Attempt to enter the monitor, returning immediately if it is
+ /// already held by another thread.
+ ///
+ public static bool TryEnter(Object obj)
+ {
+ Monitor monitor = GetMonitorFromObject(obj);
+ return monitor.TryEnter();
+ }
+
+ ///
+ /// Attempt to enter the monitor, returning if it can not be taken
+ /// within the specified timeout.
+ ///
+ public static bool TryEnter(Object obj, TimeSpan timeout)
+ {
+ Monitor monitor = GetMonitorFromObject(obj);
+ return monitor.TryEnter(SchedulerTime.Now + timeout);
+ }
+
+ ///
+ /// Wait to be woken up by a holder of the monitor.
+ ///
+ public static bool Wait(Object obj)
+ {
+ Monitor monitor = GetMonitorFromObject(obj);
+ return monitor.Wait(SchedulerTime.MaxValue);
+ }
+
+ ///
+ /// Wait to be woken up by a holder of the monitor. Give up after
+ /// a specified timeout.
+ ///
+ public static bool Wait(Object obj, TimeSpan timeout)
+ {
+ Monitor monitor = GetMonitorFromObject(obj);
+ return monitor.Wait(SchedulerTime.Now + timeout);
+ }
+
+ ///
+ /// Wait to be woken up by a holder of the monitor. Give up after
+ /// a specified timeout.
+ ///
+ /// Overload exists to match the CLR. Exit Context not supported.
+ ///
+ public static bool Wait(Object obj,
+ TimeSpan timeout,
+ bool exitContext)
+ {
+ if (exitContext) {
+ DebugStub.Break();
+ throw new NotSupportedException("exitContext not supported!");
+ }
+ Monitor monitor = GetMonitorFromObject(obj);
+ return monitor.Wait(SchedulerTime.Now + timeout);
+ }
+
+ ///
+ /// Enter the monitor, blocking until it is held.
+ ///
+ internal void Enter()
+ {
+ TryEnter(SchedulerTime.MaxValue);
+ }
+
+ ///
+ /// Exit the monitor.
+ ///
+ internal void Exit()
+ {
+ if (!mutex.IsOwnedByCurrentThread()) {
+ DebugStub.Break();
+ throw new SynchronizationLockException("Monitor not held on Exit");
+ }
+
+ depth--;
+ if (depth == 0) {
+ mutex.ReleaseMutex();
+ }
+ }
+
+ ///
+ /// Wake up a single thread waiting on the monitor.
+ ///
+ internal void Pulse()
+ {
+ if (!mutex.IsOwnedByCurrentThread()) {
+ DebugStub.Break();
+ throw new SynchronizationLockException("Monitor not held on Pulse");
+ }
+
+ // Wake up thread at the head of the wait list.
+ if (waitListHead != null) {
+ Thread t = Dequeue();
+ if (t != null) {
+ t.nextThread = null;
+ t.SignalMonitor();
+ }
+ }
+ }
+
+ ///
+ /// Wake up all threads waiting on the monitor.
+ ///
+ internal void PulseAll()
+ {
+ if (!mutex.IsOwnedByCurrentThread()) {
+ DebugStub.Break();
+ throw new SynchronizationLockException("Monitor not held on PulseAll");
+ }
+
+ // Wake up all threads the wait list.
+ if (waitListHead != null) {
+ Thread t = waitListHead;
+ while (t != null) {
+ Thread next = t.nextThread;
+ t.nextThread = null;
+ t.SignalMonitor();
+ t = next;
+ }
+ waitListHead = null;
+ waitListTail = null;
+ }
+ }
+
+ ///
+ /// Try to enter the monitor, returning immediately if it is
+ /// already held.
+ ///
+ internal bool TryEnter()
+ {
+ return TryEnter(new SchedulerTime(0));
+ }
+
+ ///
+ /// Try to enter the monitor, giving up if it cannot be
+ /// entered after a timeout.
+ ///
+ internal bool TryEnter(SchedulerTime stop)
+ {
+ if (mutex.IsOwnedByCurrentThread()) {
+ depth++;
+ return true;
+ }
+
+ if (mutex.AcquireMutex(stop)) {
+ depth = 1;
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Wait within the monitor for a Pulse.
+ ///
+ internal bool Wait(SchedulerTime stop)
+ {
+ Thread currentThread = Thread.CurrentThread;
+ if (!mutex.IsOwnedByCurrentThread()) {
+ DebugStub.Break();
+ throw new SynchronizationLockException("Monitor not held on Wait");
+ }
+
+ int rememberedDepth = depth;
+ depth = 0;
+
+ // Add me onto the waiting list.
+ Enqueue(currentThread);
+
+ // Exit the monitor
+ mutex.ReleaseMutex();
+
+ // Wait
+ currentThread.WaitForMonitor(stop);
+
+ // Re-enter the monitor
+ mutex.AcquireMutex();
+ depth = rememberedDepth;
+
+ bool success = !Remove(currentThread);
+
+ if (!success && stop == SchedulerTime.MaxValue) {
+ VTable.DebugBreak();
+ }
+
+ return success;
+ }
+
+ ///
+ /// Ensure that the passed object has a monitor (and associated
+ /// SyncBlock) allocated.
+ ///
+ internal static void CreateMonitor(Object obj)
+ {
+ GetMonitorFromObject(obj);
+ }
+
+ // BUGBUG: The garbage collectors will not collect monitors that are
+ // in use. Use a very defensive strategy for now.
+ internal bool IsInUse() {
+ return true;
+ }
+
+ ///
+ /// Internal Type conversion method.
+ /// Note: we don't use VTable.fromAddress because we
+ /// cannot do a checked cast from Object to Monitor during GC
+ /// (because the GC may be using the vtable word)
+ ///
+ ///
+ internal static Monitor FromAddress(UIntPtr v) {
+ return Magic.toMonitor(Magic.fromAddress(v));
+ }
+
+ ///
+ /// Look up the Monitor for the specified object in the SyncBlock
+ /// tables. If no Monitor exists for the object then one is created.
+ ///
+ private static Monitor GetMonitorFromObject(Object obj)
+ {
+ if (obj == null) {
+ DebugStub.Break();
+ throw new ArgumentNullException("obj");
+ }
+ Monitor result = MultiUseWord.GetMonitor(obj);
+ return result;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // Linked list of threads waiting for a Pulse in a monitor.
+ private Thread waitListHead;
+ private Thread waitListTail;
+
+ ///
+ /// Dequeue a thread from the singly linked list from head to tail,
+ /// acquiring the ListLock if necessary.
+ ///
+ /// If the list is empty then this method returns null.
+ ///
+ [Inline]
+ private Thread Dequeue()
+ {
+ Thread result;
+ if (waitListHead == null) {
+ // Empty list
+ result = null;
+ }
+ else if (waitListHead == waitListTail) {
+ // Single entry on list
+ VTable.Assert(waitListHead.nextThread == null);
+ result = waitListHead;
+ waitListHead = waitListTail = null;
+ }
+ else {
+ // Multiple entries on list
+ result = waitListHead;
+ waitListHead = waitListHead.nextThread;
+ }
+ return result;
+ }
+
+ ///
+ /// Search the linked list and remove the specified thread if
+ /// it is linked in.
+ ///
+ /// Acquires the ListLock if necessary.
+ ///
+ [Inline]
+ private bool Remove(Thread target)
+ {
+ if (waitListHead == null) {
+ return false;
+ }
+
+ if (waitListHead == waitListTail) {
+ // Single entry on list
+ VTable.Assert(waitListHead.nextThread == null);
+
+ if (waitListHead != target) {
+ // Not on list
+ return false;
+ }
+
+ waitListHead = waitListTail = null;
+ }
+ else if (waitListHead == target) {
+ // At waitListHead of list
+ waitListHead = target.nextThread;
+ target.nextThread = null;
+ }
+ else {
+ // Multiple entries on list
+ Thread next = waitListHead;
+ while (next != null && next.nextThread != target) {
+ next = next.nextThread;
+ }
+
+ if (next == null) {
+ // Not on list
+ return false;
+ }
+
+ if (waitListTail == target) {
+ // Update the waitListTail
+ waitListTail = next;
+ }
+
+ next.nextThread = target.nextThread;
+ target.nextThread = null;
+ }
+ return true;
+ }
+
+ ///
+ /// Append a thread at the tail of a queue. If the queue is
+ /// currently null this method initializes it.
+ ///
+ /// Acquires the ListLock if necessary.
+ ///
+ [Inline]
+ private void Enqueue(Thread target)
+ {
+ if (waitListHead == null) {
+ waitListHead = waitListTail = target;
+ }
+ else {
+ waitListTail.nextThread = target;
+ waitListTail = target;
+ }
+ }
+
+ ///
+ /// The recursion depth of the current holder of the monitor.
+ ///
+ private int depth;
+
+ ///
+ /// The mutex that is held by the thread that holds the monitor
+ ///
+ private Mutex mutex;
+ }
+}
diff --git a/base/Applications/Runtime/System/Threading/Mutex.cs b/base/Applications/Runtime/Full/System/Threading/Mutex.cs
similarity index 100%
rename from base/Applications/Runtime/System/Threading/Mutex.cs
rename to base/Applications/Runtime/Full/System/Threading/Mutex.cs
diff --git a/base/Applications/Runtime/Full/System/Threading/SynchronizationLockException.cs b/base/Applications/Runtime/Full/System/Threading/SynchronizationLockException.cs
new file mode 100644
index 0000000..49a2788
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/SynchronizationLockException.cs
@@ -0,0 +1,39 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: SynchronizationLockException
+//
+// Purpose: Wait(), Notify() or NotifyAll() was called from an unsynchronized
+// block of code.
+//
+//=============================================================================
+
+namespace System.Threading
+{
+
+ using System;
+
+ //|
+ public class SynchronizationLockException : SystemException {
+ //|
+ public SynchronizationLockException()
+ : base("Arg_SynchronizationLockException") {
+ }
+
+ //|
+ public SynchronizationLockException(String message)
+ : base(message) {
+ }
+
+ //|
+ public SynchronizationLockException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
+
+
diff --git a/base/Applications/Runtime/Full/System/Threading/Thread.cs b/base/Applications/Runtime/Full/System/Threading/Thread.cs
new file mode 100644
index 0000000..6fba1e7
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/Thread.cs
@@ -0,0 +1,1296 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+
+// #define DEBUG_SWITCH
+
+namespace System.Threading
+{
+ using System;
+ using System.Collections;
+ using System.Diagnostics;
+ using System.GCs;
+ using System.Globalization;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+ using System.Threading;
+
+ using Microsoft.Bartok.Runtime;
+
+ using Microsoft.Singularity;
+ using Microsoft.Singularity.Channels;
+ using Microsoft.Singularity.V1.Services;
+ using Microsoft.Singularity.V1.Threads;
+
+ //|
+ public sealed partial class Thread
+ {
+ // Singularity specific fields
+ // Need CPU context
+ // Need stack
+
+ internal AutoResetEvent processGcEvent;
+
+ private AutoResetEvent autoEvent;
+ private ManualResetEvent joinEvent;
+
+ internal Thread blockingCctorThread;
+
+ // Singularity specific fields
+ [AccessedByRuntime("referenced from halforgc.asm")]
+ internal unsafe ThreadContext * context;
+ internal ThreadHandle threadHandle;
+
+ // Most recently thrown exception object that the thread
+ // did not catch at all (i.e. that propagated to the bottom
+ // of the stack or to a kernel/process boundary without
+ // encountering an appropriate catch clause).
+ private Exception lastUncaughtException;
+
+ private bool ignoredByJoinAll; // for "service" threads
+
+ private Object m_ExceptionStateInfo; // Exception info latched to the thread on a thread abort
+
+ // Bartok specific fields
+ internal Thread nextThread; // Link for linked lists of threads
+
+ // This array is of length 1 and contains a queue item for this
+ // thread. It allows WaitOne and the scheduler to add this thread
+ // to their queues without allocating memory.
+ internal ThreadQueueItem[] singleQueueItem;
+
+ // MultiUseWord (object header) fields.
+ internal UIntPtr externalMultiUseObjAllocListHead;
+ internal UIntPtr externalMultiUseObjAllocListTail;
+
+ // Bartok specific fields
+ internal int threadIndex;
+ private ThreadStart threadStart;
+ private ThreadState threadState;
+ internal int waitingCriticalSectionDepth;
+ internal Object waitingObject; // Not used, but useful for debugging
+
+ private static bool closing;
+ private static long totalArrayAllocations;
+ private static long totalArrayBytesAllocated;
+ private static long totalBytes;
+ private static long totalStructBytesAllocated;
+
+ internal static Thread[] threadTable;
+ private static SpinLock threadTableLock;
+
+ private static LocalDataStore localDataStore;
+ private object m_userScheduler;
+
+ internal static Thread initialThread;
+
+ //=========================================================================
+ // This manager is responsible for storing the global data that is
+ // shared amongst all the thread local stores.
+ //=========================================================================
+ static private LocalDataStoreMgr m_LocalDataStoreMgr;
+
+ internal const int maxThreads = 1024; // Must be power of 2 >= 64
+ private static int threadIndexGenerator;
+
+ //=========================================================================
+ // Creates a new Thread object which will begin execution at
+ // start.ThreadStart on a new thread when the Start method is called.
+ //
+ // Exceptions: ArgumentNullException if start == null.
+ //=========================================================================
+ //|
+ public unsafe Thread(ThreadStart start)
+ {
+ Tracing.Log(Tracing.Audit, "Application Thread()");
+
+ if (start == null) {
+ throw new ArgumentNullException("start");
+ }
+
+ threadIndex = -1;
+ threadState = ThreadState.Unstarted;
+ threadStart = start;
+
+ // Create the event for the thread to wait upon
+ autoEvent = new AutoResetEvent(false);
+ joinEvent = new ManualResetEvent(false);
+ processGcEvent = new AutoResetEvent(false);
+ singleQueueItem = new ThreadQueueItem [1] { new ThreadQueueItem(this) };
+
+ // Find a usable entry in the thread table
+ // Disable local preemption while holding the lock. This might also be a
+ // the property of the lock
+
+ bool disabled = Processor.DisableLocalPreemption();
+ Thread.threadTableLock.Acquire(CurrentThread);
+ try {
+ for (int i = 0; i < threadTable.Length; i++) {
+ int index = (threadIndexGenerator + i) % threadTable.Length;
+ if (threadTable[index] == null) {
+ threadTable[index] = this;
+ this.threadIndex = index;
+ threadIndexGenerator = index + 1;
+ // NB: We call this once, afterwards the GC visitor calls it.
+ break;
+ }
+ }
+ }
+ finally {
+ Thread.threadTableLock.Release(CurrentThread);
+ Processor.RestoreLocalPreemption(disabled);
+ }
+
+ VTable.Assert(threadIndex >= 0, "Out of thread slots!");
+
+ //MemoryBarrier();
+
+ // Must check closing after being insert into table to avoid race condition.
+ if (closing) {
+ threadState = ThreadState.Stopped;
+ joinEvent.Set();
+ Tracing.Log(Tracing.Warning, "Aborting: Runtime closing.");
+ return;
+ }
+
+ ThreadHandle handleOnStack;
+ UIntPtr threadContext;
+ if (!ThreadHandle.Create(threadIndex,
+ new ContainerHandle(),
+ out handleOnStack,
+ out threadContext)) {
+ Tracing.Log(Tracing.Warning, "Aborting: ThreadHandle.Create failed.");
+ threadState = ThreadState.Stopped;
+ joinEvent.Set();
+ return;
+ }
+ this.threadHandle = handleOnStack;
+ this.context = (ThreadContext *) threadContext;
+ this.context->threadIndex = unchecked((ushort) threadIndex);
+ this.context->UpdateAfterGC(this);
+ }
+
+
+
+ ///
+ /// Finalizer is responsible for freeing handle that keeps corresponding
+ /// kernel object live.
+ ///
+ ~Thread() {
+ if (this.threadHandle.id != 0) {
+ ThreadHandle.Dispose(this.threadHandle);
+ this.threadHandle = new ThreadHandle();
+ }
+ }
+
+ //=========================================================================
+ // Spawns off a new thread which will begin executing at the ThreadStart
+ // method on the IThreadable interface passed in the constructor. Once the
+ // thread is dead, it cannot be restarted with another call to Start.
+ //
+ // Exceptions: ThreadStateException if the thread has already been started.
+ //=========================================================================
+ //|
+ public void Start()
+ {
+ lock ((Object) this) {
+ if (closing) {
+ throw new ThreadStateException("Cannot start thread when closing");
+ }
+
+ ThreadState oldState = threadState;
+ if (oldState != ThreadState.Unstarted) {
+ throw new ThreadStateException("Cannot start thread in state "+oldState);
+ }
+
+ threadState = ThreadState.Running;
+
+ // Tell the GC that we have created the thread
+ GC.NewThreadNotification(this, false);
+
+ ThreadHandle.Start(threadHandle);
+ GC.KeepAlive(this);
+ }
+ }
+
+ // HalInitContext sets ThreadStub as the first process code to be
+ // executed in a new thread context.
+ [AccessedByRuntime("referenced from hal.cpp")]
+ private static unsafe void ThreadStub(int threadIndex)
+ {
+ Transitions.ThreadStart();
+ GC.ThreadStartNotification(threadIndex);
+ Thread currentThread = threadTable[threadIndex];
+ if (AddThread(threadIndex)) {
+ // Log Thread Start.
+ Tracing.Log(Tracing.Audit, "ThreadStub(atid={0}) Entered",
+ (UIntPtr)unchecked((uint)threadIndex));
+
+ ThreadStart startFun = currentThread.threadStart;
+
+ try {
+ startFun();
+ }
+ catch (Exception uncaughtException) {
+ // Save Uncaught Exception in Thread instance.
+ currentThread.lastUncaughtException = uncaughtException;
+
+ // Dump (possibly nested) Exceptions to the Debugger.
+ // Note: The first line identifies the outer exception,
+ // later lines identify the inner exceptions nesting level.
+ string formatString;
+ uint nestingLevel = 0;
+ Exception currentException = uncaughtException;
+ formatString = "Thread{0,3} Outer" +
+ " Exception: Type '{2}', Message '{3}'.";
+ while (currentException != null) {
+ DebugStub.WriteLine(
+ formatString,
+ __arglist(threadIndex,
+ nestingLevel,
+ currentException.GetType().ToString(),
+ currentException.Message));
+ currentException = currentException.InnerException;
+ formatString = "Thread{0,3} Inner{1,2}" +
+ " Exception: Type '{2}', Message '{3}'.";
+ if (++nestingLevel > 16) break;
+ }
+
+ // Assert (always asserts as exception is never null here).
+ string message = uncaughtException.Message;
+ if (message == null) message = String.Empty;
+
+ VTable.Assert(uncaughtException == null,
+ "Thread " + threadIndex +
+ " failed with Exception Type '" +
+ uncaughtException.GetType().ToString() +
+ "', Message '" + message + "'.");
+ }
+
+ // Log Thread Exit.
+ Tracing.Log(Tracing.Audit, "ThreadStub(atid={0}) Exiting",
+ (UIntPtr)unchecked((uint)threadIndex));
+ }
+
+ currentThread.joinEvent.Set();
+ RemoveThread(threadIndex);
+ GC.DeadThreadNotification(currentThread);
+
+ bool disabled = Processor.DisableLocalPreemption();
+ // REVIEW: this is a dangerous locking strategy as the transition code
+ // may decide it needs to wake up another thread.
+ Thread.threadTableLock.Acquire(currentThread);
+ try {
+ Transitions.ThreadEnd(threadIndex);
+ // You may not do any calls out of proc after this point!
+ threadTable[threadIndex] = null;
+ Transitions.DeadThreadNotification(threadIndex);
+ }
+ finally {
+ Thread.threadTableLock.Release(currentThread);
+ Processor.RestoreLocalPreemption(disabled);
+ }
+ }
+
+ //====================================================================
+ // Support for service threads. Service threads should not count
+ // towards keeping a process alive. When all non-service threads
+ // have terminated, the service threads are asked to stop themselves
+ // so the process can terminate gracefully.
+ //===================================================================
+
+ // The number of non-service threads running in the process
+ private static int threadCount;
+ private static Object notificationTableObject;
+ private static Object[] notificationTable;
+
+ public delegate void StopServiceNotice();
+
+ public void MakeServiceThread(StopServiceNotice notification)
+ {
+ Tracing.Log(Tracing.Audit, "MakeServiceThread {0}",
+ (UIntPtr) threadIndex);
+ if (this != Thread.CurrentThread) {
+ throw new Exception("Only the thread itself may call MakeServiceThread");
+ }
+ if (notificationTable == null) {
+ int tableSize = threadTable.Length;
+ Interlocked.CompareExchange(ref notificationTableObject,
+ new Object[tableSize],
+ null);
+ notificationTable = (Object[]) notificationTableObject;
+ }
+ Tracing.Log(Tracing.Audit, " previous notification: {0:x8}",
+ Magic.addressOf(notificationTable[threadIndex]));
+ // BUGBUG: Should have been Interlocked.Exchange, but that
+ // doesn't work due to a Bartok codegen bug.
+ Object oldNotification = notificationTable[threadIndex];
+ while (Interlocked.CompareExchange(ref notificationTable[threadIndex], notification, oldNotification) != oldNotification) {
+ oldNotification = notificationTable[threadIndex];
+ }
+ if (oldNotification == null) {
+ // We made the thread a service thread for the first time.
+ if (Interlocked.Decrement(ref threadCount) == 0) {
+ NotifyServiceThreads();
+ }
+ }
+ VTable.Assert(threadCount >= 0);
+ }
+
+ public void ClearServiceThread(Thread thread)
+ {
+ Tracing.Log(Tracing.Audit, "ClearServiceThread");
+ if (this != Thread.CurrentThread) {
+ throw new Exception("Only the thread itself may call ClearServiceThread");
+ }
+ if (notificationTable == null) {
+ return;
+ }
+ if (Interlocked.Exchange(ref notificationTable[threadIndex],
+ null) != null) {
+ // We cleared the notification
+ Interlocked.Increment(ref threadCount);
+ }
+ VTable.Assert(threadCount >= 0);
+ }
+
+ private static bool AddThread(int index)
+ {
+ Tracing.Log(Tracing.Audit, "AddThread {0} ({1})",
+ (UIntPtr) index, (UIntPtr) threadCount);
+ VTable.Assert(threadCount >= 0);
+ if (Interlocked.Increment(ref threadCount) == 1 &&
+ notificationTable != null) {
+ // The thread was started after we started sending out
+ // notifications, so indicate that the thread should not
+ // really be started
+ return false;
+ }
+ else {
+ return true;
+ }
+ }
+
+ internal static void RemoveThread(int index)
+ {
+ Tracing.Log(Tracing.Audit, "RemoveThread {0} ({1})",
+ (UIntPtr) index, (UIntPtr) threadCount);
+ if (Interlocked.Decrement(ref threadCount) == 0) {
+ NotifyServiceThreads();
+ }
+ VTable.Assert(threadCount >= 0);
+ }
+
+ private static void NotifyServiceThreads()
+ {
+ Tracing.Log(Tracing.Audit, "NotifyServiceThreads");
+ if (notificationTable == null) {
+ return;
+ }
+ for (int i = 0; i < notificationTable.Length; i++) {
+ if (notificationTable[i] != null) {
+ Tracing.Log(Tracing.Audit, " Notifying thread {0}",
+ (UIntPtr) i);
+ ((StopServiceNotice)notificationTable[i])();
+ }
+ }
+ }
+
+
+ //=========================================================================
+ // Returns true if the thread has been started and is not dead.
+ //=========================================================================
+ //|
+ public bool IsAlive {
+ [NoHeapAllocation]
+ get { return (threadState != ThreadState.Unstarted &&
+ threadState != ThreadState.Stopped); }
+ }
+
+
+ //=========================================================================
+ // Waits for the thread to die.
+ //
+ // Exceptions: ThreadStateException if the thread has not been started yet.
+ //=========================================================================
+ //|
+ public void Join()
+ {
+ Join(SchedulerTime.MaxValue);
+ }
+
+ //=========================================================================
+ // Waits for the thread to die or for timeout milliseconds to elapse.
+ // Returns true if the thread died, or false if the wait timed out.
+ //
+ // Exceptions: ArgumentException if timeout < 0.
+ // ThreadStateException if the thread has not been started yet.
+ //=========================================================================
+ //|
+ public bool Join(TimeSpan timeout)
+ {
+ if (threadState == ThreadState.Unstarted) {
+ throw new ThreadStateException();
+ }
+ return joinEvent.WaitOne(timeout);
+ }
+
+ public bool Join(SchedulerTime timeout)
+ {
+ if (threadState == ThreadState.Unstarted) {
+ throw new ThreadStateException();
+ }
+ return joinEvent.WaitOne(timeout);
+ }
+
+ internal static bool JoinAll()
+ {
+ // To avoid races, join all does the following:
+ // 1) Wait for all known peer threads to terminate.
+ // 2) Set the closing flag to disallow creating of new threads.
+ // 3) Wait for any threads that have started in the mean time.
+
+ for (uint iteration = 0; iteration < 2; iteration++) {
+ for (int i = 0; i < threadTable.Length; i++) {
+ Thread thread = null;
+
+ bool disabled = Processor.DisableLocalPreemption();
+ Thread.threadTableLock.Acquire(CurrentThread);
+ try {
+ thread = threadTable[i];
+ }
+ finally {
+ Thread.threadTableLock.Release(CurrentThread);
+ Processor.RestoreLocalPreemption(disabled);
+ }
+
+ if (thread != null &&
+ thread != CurrentThread &&
+ thread.threadState != ThreadState.Unstarted &&
+ !thread.ignoredByJoinAll) {
+ thread.Join();
+ }
+ }
+ closing = true;
+ }
+ return true;
+ }
+
+ //=========================================================================
+ // Suspends the current thread for timeout milliseconds. If timeout == 0,
+ // forces the thread to give up the remainder of its timeslice.
+ //
+ // Exceptions: ArgumentException if timeout < 0.
+ //=========================================================================
+
+ public static void Sleep(int milliseconds)
+ {
+ Sleep(TimeSpan.FromMilliseconds(milliseconds));
+ }
+
+ //|
+ public static void Sleep(TimeSpan timeout)
+ {
+ ThreadHandle.Sleep(timeout);
+ }
+
+ // wait for a length of time proportional to 'iterations'. Each iteration is should
+ // only take a few machine instructions. Calling this API is preferable to coding
+ // an explicit busy loop because the hardware can be informed that it is busy waiting.
+
+ //|
+ [NoHeapAllocation]
+ public static void SpinWait(int iterations)
+ {
+ for (int i = iterations; i > 0; i--) {
+ // Ensure that the optimizer doesn't remove this
+ NativeNoOp();
+ }
+ }
+
+ ///
+ ///
+ /// Notify thread that it acquired spinlock of specific rank
+ ///
+ ///
+ /// Type of spinlock
+ ///
+ [NoHeapAllocation]
+ internal void NotifySpinLockAboutToAcquire(int type)
+ {
+ // Add rank verification and etc ..
+ }
+
+ ///
+ ///
+ /// Notify thread that released a spinlock of specific rank
+ ///
+ ///
+ /// Type of spinlock
+ ///
+ [NoHeapAllocation]
+ internal void NotifySpinLockReleased(int type)
+ {
+ // Add rank verification and etc ..
+ }
+
+ ///
+ ///
+ /// Given a thread id, return actual thread
+ ///
+ ///
+ /// Thread id
+ ///
+ [NoHeapAllocation]
+ internal static Thread GetThreadFromThreadId(int threadId)
+ {
+ // Assert preconditions: threadId has to be in range and thread can't be null
+ VTable.Assert(threadId < threadTable.Length);
+ VTable.Assert(threadTable[threadId] != null);
+
+ return threadTable[threadId];
+ }
+
+
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void NativeNoOp();
+
+ internal static int GetCurrentProcessIndex() {
+ return ProcessService.GetCurrentProcessId();
+ }
+
+ internal bool WaitForMonitor(SchedulerTime timeOut)
+ {
+ return autoEvent.WaitOne(timeOut);
+ }
+
+ internal bool WaitForEvent(SchedulerTime timeOut)
+ {
+ DebugStub.Break();
+ return autoEvent.WaitOne(timeOut);
+ }
+
+ internal bool WaitForEvent(TimeSpan timeout)
+ {
+ DebugStub.Break();
+ return autoEvent.WaitOne(timeout);
+ }
+
+ internal static unsafe bool WaitForGCEvent(int currentThreadIndex)
+ {
+ AutoResetEvent are =
+ threadTable[currentThreadIndex].processGcEvent;
+ // BUGBUG: The restoration of the gcState should be taken
+ // care of by the compiler.
+ return are.WaitOneNoGC();
+ }
+
+ internal void SignalMonitor()
+ {
+ autoEvent.Set();
+ }
+
+ internal void SignalEvent()
+ {
+ DebugStub.Break();
+ autoEvent.Set();
+ }
+
+ [Inline]
+ internal static void SignalGCEvent(int currentThreadIndex,
+ int threadIndex)
+ {
+ SignalGCEvent(threadIndex);
+ }
+
+ internal static unsafe void SignalGCEvent(int threadIndex)
+ {
+ Thread thread = threadTable[threadIndex];
+ if (thread == null) {
+ return;
+ }
+ thread.processGcEvent.SetNoGC();
+ }
+
+ //|
+ public static Thread CurrentThread
+ {
+ [NoHeapAllocation]
+ [NoStackLinkCheckTrans]
+ get {
+ return Processor.GetCurrentThread();
+ }
+ }
+
+ internal ThreadHandle Handle
+ {
+ [NoHeapAllocation]
+ get { return threadHandle; }
+ }
+
+ [NoStackLinkCheckTrans]
+ [RequiredByBartok]
+ [NoHeapAllocation]
+ private static Thread GetCurrentThreadNative()
+ {
+ return Processor.GetCurrentThread();
+ }
+
+ [NoStackLinkCheckTrans]
+ [RequiredByBartok]
+ [NoHeapAllocation]
+ internal static int GetCurrentThreadIndex()
+ {
+ return Processor.GetCurrentThread().threadIndex;
+ }
+
+ //=========================================================================
+ // Return the thread state as a consistent set of bits. This is more
+ // general then IsAlive or IsBackground.
+ //=========================================================================
+ //|
+ public ThreadState ThreadState
+ {
+ [NoHeapAllocation]
+ get { return threadState; }
+ }
+
+ [NoHeapAllocation]
+ public int GetThreadId()
+ {
+ return threadIndex;
+ }
+
+ public object UserScheduler
+ {
+ get {
+ return m_userScheduler;
+ }
+ set {
+ if (null != m_userScheduler) {
+ // TODO make this a security exception
+ throw new Exception("User scheduler may not be changed");
+ }
+ m_userScheduler = value;
+ }
+ }
+
+ public int Affinity
+ {
+ get { return ThreadHandle.GetAffinity(threadHandle); }
+ set { ThreadHandle.SetAffinity(threadHandle, value); }
+ }
+
+
+ //=========================================================================
+ // Allocates an un-named data slot. The slot is allocated on ALL the
+ // threads.
+ //=========================================================================
+ //|
+ public static LocalDataStoreSlot AllocateDataSlot()
+ {
+ return m_LocalDataStoreMgr.AllocateDataSlot();
+ }
+
+ //=========================================================================
+ // Allocates a named data slot. The slot is allocated on ALL the
+ // threads. Named data slots are "public" and can be manipulated by
+ // anyone.
+ //=========================================================================
+ //|
+ public static LocalDataStoreSlot AllocateNamedDataSlot(String name)
+ {
+ return m_LocalDataStoreMgr.AllocateNamedDataSlot(name);
+ }
+
+ //=========================================================================
+ // Looks up a named data slot. If the name has not been used, a new slot is
+ // allocated. Named data slots are "public" and can be manipulated by
+ // anyone.
+ //=========================================================================
+ //|
+ public static LocalDataStoreSlot GetNamedDataSlot(String name)
+ {
+ return m_LocalDataStoreMgr.GetNamedDataSlot(name);
+ }
+
+ //=========================================================================
+ // Frees a named data slot. The slot is allocated on ALL the
+ // threads. Named data slots are "public" and can be manipulated by
+ // anyone.
+ //=========================================================================
+ //|
+ public static void FreeNamedDataSlot(String name)
+ {
+ m_LocalDataStoreMgr.FreeNamedDataSlot(name);
+ }
+
+ //=========================================================================
+ // Retrieves the value from the specified slot on the current thread.
+ //=========================================================================
+ //|
+ public static Object GetData(LocalDataStoreSlot slot)
+ {
+ m_LocalDataStoreMgr.ValidateSlot(slot);
+
+ if (localDataStore != null) {
+ return localDataStore.GetData(slot);
+ }
+ return null;
+ }
+
+ //=========================================================================
+ // Sets the data in the specified slot on the currently running thread.
+ //=========================================================================
+ //|
+ public static void SetData(LocalDataStoreSlot slot, Object data)
+ {
+ // Create new DLS if one hasn't been created for this thread.
+ if (localDataStore == null) {
+ localDataStore = m_LocalDataStoreMgr.CreateLocalDataStore();
+ }
+ localDataStore.SetData(slot, data);
+ }
+
+ //=============================================================
+
+ internal Object ExceptionState
+ {
+ [NoHeapAllocation]
+ get { return m_ExceptionStateInfo;}
+ [NoHeapAllocation]
+ set { m_ExceptionStateInfo = value;}
+ }
+
+ //
+ // This is just designed to prevent compiler warnings.
+ // This field is used from native, but we need to prevent the compiler warnings.
+ //
+#if _DEBUG
+ private void DontTouchThis()
+ {
+ threadStart = null;
+ m_Priority = 0;
+ }
+#endif
+ //=========================================================================
+ // Volatile Read & Write and MemoryBarrier methods.
+ // Provides the ability to read and write values ensuring that the values
+ // are read/written each time they are accessed.
+ //=========================================================================
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern byte VolatileRead(ref byte address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern short VolatileRead(ref short address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern int VolatileRead(ref int address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern long VolatileRead(ref long address);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern sbyte VolatileRead(ref sbyte address);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern ushort VolatileRead(ref ushort address);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern uint VolatileRead(ref uint address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern IntPtr VolatileRead(ref IntPtr address);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern UIntPtr VolatileRead(ref UIntPtr address);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern ulong VolatileRead(ref ulong address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern float VolatileRead(ref float address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern double VolatileRead(ref double address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern Object VolatileRead(ref Object address);
+
+ [Intrinsic]
+ [NoHeapAllocation]
+ internal static unsafe extern byte VolatileReadUnsafe(byte* address);
+
+ [Intrinsic]
+ [NoHeapAllocation]
+ internal static unsafe extern short VolatileReadUnsafe(short* address);
+
+ [Intrinsic]
+ [NoHeapAllocation]
+ internal static unsafe extern int VolatileReadUnsafe(int* address);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref byte address, byte value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref short address, short value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref int address, int value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref long address, long value);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref sbyte address, sbyte value);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref ushort address, ushort value);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref uint address, uint value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref IntPtr address, IntPtr value);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref UIntPtr address, UIntPtr value);
+
+ //|
+ [CLSCompliant(false)]
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref ulong address, ulong value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref float address, float value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref double address, double value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void VolatileWrite(ref Object address, Object value);
+
+ [Intrinsic]
+ [NoHeapAllocation]
+ internal static unsafe extern void VolatileWriteUnsafe(int* address,
+ int value);
+
+ [Intrinsic]
+ [NoHeapAllocation]
+ internal static unsafe extern void VolatileWriteUnsafe(short* address,
+ short value);
+
+ [Intrinsic]
+ [NoHeapAllocation]
+ internal static unsafe extern void VolatileWriteUnsafe(byte* address,
+ byte value);
+
+ //|
+ [Intrinsic]
+ [NoHeapAllocation]
+ public static extern void MemoryBarrier();
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [GCAnnotation(GCOption.NOGC)]
+ [StackBound(32)]
+ [NoHeapAllocation]
+ private static unsafe extern Thread HalGetThread();
+
+ [NoHeapAllocation]
+ public static void Yield()
+ {
+ ThreadHandle.Yield();
+ }
+
+ [NoHeapAllocation]
+ public bool IsStopped()
+ {
+ return (threadState == ThreadState.Stopped);
+ }
+
+ [PreInitRefCounts]
+ static unsafe Thread()
+ {
+ threadIndexGenerator = 1;
+
+ // Enable Thread.CurrentThread as soon as we can!
+ initialThread = Magic.toThread(BootstrapMemory.Allocate(typeof(Thread)));
+ initialThread.threadState = ThreadState.Running;
+ initialThread.threadIndex = 0;
+
+ // Allocate tables for thread management
+ threadTable = (Thread[])
+ BootstrapMemory.Allocate(typeof(Thread[]), maxThreads);
+
+ // Initialize the thread and event tables
+ threadTable[initialThread.threadIndex] = initialThread;
+ initialThread.context = Processor.GetCurrentThreadContext();
+ initialThread.context->threadIndex =
+ unchecked((ushort) initialThread.threadIndex);
+ initialThread.context->UpdateAfterGC(initialThread);
+
+ Tracing.Log(Tracing.Debug, "InitialThread={0:x8}",
+ Magic.addressOf(initialThread));
+ }
+
+ internal static unsafe void FinishInitializeThread()
+ {
+ int threadIndex = initialThread.threadIndex;
+ // Get the GC ready for initialThread
+ Transitions.RuntimeInitialized();
+ Transitions.ThreadStart();
+ initialThread.processGcEvent = new AutoResetEvent(false);
+ initialThread.autoEvent = new AutoResetEvent(false);
+ initialThread.joinEvent = new ManualResetEvent(false);
+ initialThread.singleQueueItem =
+ new ThreadQueueItem [1] { new ThreadQueueItem(initialThread) };
+ // Use CurrentThread to find our initial handle:
+ VTable.Assert(initialThread == CurrentThread);
+ initialThread.threadHandle = ThreadHandle.CurrentThread();
+ // Instantiate the static variable that needs to be initialized
+ m_LocalDataStoreMgr = new LocalDataStoreMgr();
+ AddThread(threadIndex);
+ }
+
+ public TimeSpan ExecutionTime
+ {
+ get {
+ TimeSpan t = ThreadHandle.GetExecutionTime(threadHandle);
+ GC.KeepAlive(this);
+ return t;
+ }
+ }
+
+ internal static
+ void VisitBootstrapData(GCs.ReferenceVisitor visitor)
+ {
+ visitor.VisitReferenceFields(Thread.initialThread);
+ visitor.VisitReferenceFields(Thread.threadTable);
+ }
+
+ internal static unsafe void UpdateAfterGC()
+ {
+ // Update all the thread pointers in the thread contexts
+ for (int i = 0; i < threadTable.Length; i++) {
+ Thread thread = threadTable[i];
+ if (thread != null) {
+ thread.context->UpdateAfterGC(thread);
+ }
+ }
+ }
+
+ // Cache for ABI synchronization
+ private SyncHandle[] syncHandles;
+ internal SyncHandle[] GetSyncHandles(int length)
+ {
+ if (syncHandles == null ||
+ syncHandles.Length < length) {
+
+ syncHandles = new SyncHandle[length + 8];
+ }
+ return syncHandles;
+ }
+
+
+ // Caches for Select synchronization
+ // We use stacks, because selectable abstractions might
+ // internally implement HeadMatches using select receive
+ // which is called from within an outer select.
+ // NOTE however that internal selects should never block
+ // (use timeout)
+ private Stack selectBoolsStack;
+ private Stack selectObjectsStack;
+ private Stack selectSyncHandlesStack;
+
+ public bool[] PopSelectBools(int size)
+ {
+ if (selectBoolsStack == null) {
+ selectBoolsStack = new Stack();
+ }
+ if (selectBoolsStack.Count == 0) {
+ return new bool [size];
+ }
+ bool[] selectBools = (bool[])selectBoolsStack.Pop();
+ if (selectBools.Length < size) {
+ return new bool [size];
+ }
+ return selectBools;
+ }
+
+ public void PushSelectBools(bool[] cache) {
+ selectBoolsStack.Push(cache);
+ }
+
+ public ISelectable[] PopSelectObjects(int size)
+ {
+ if (selectObjectsStack == null) {
+ selectObjectsStack = new Stack();
+ }
+ if (selectObjectsStack.Count == 0) {
+ return new ISelectable [size];
+ }
+ ISelectable[] selectObjects = (ISelectable[])selectObjectsStack.Pop();
+ if (selectObjects.Length < size) {
+ return new ISelectable [size];
+ }
+ return selectObjects;
+ }
+ public void PushSelectObjects(ISelectable[] cache) {
+ for (int i=0; ikernelMarkers;
+ CallStack.TransitionRecord *secondMarker = context->stackMarkers;
+ UIntPtr topMarkerPtr = (UIntPtr) topMarker;
+ // If the top marker is in our frame, we've reached a boundary:
+ if (esp < topMarkerPtr && topMarkerPtr <= ebp) {
+ context->uncaughtFlag = true;
+ Thread.CurrentThread.lastUncaughtException = exn;
+ Processor.GetCurrentThreadContext()->SetKernelMode();
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ // Most recently thrown exception object that the thread
+ // did not catch at all (i.e. that propagated to the bottom
+ // of the stack without encountering an appropriate catch clause).
+ public Exception LastUncaughtException
+ {
+ [NoHeapAllocation]
+ get {
+ return lastUncaughtException;
+ }
+ }
+
+ // Tell JoinAll not to block waiting for this thread to exit.
+ // Some special threads (e.g. the finalizer thread) need to run
+ // only as long as there are other threads running, and should
+ // not be considered by JoinAll.
+ [NoHeapAllocation]
+ internal void SetIgnoredByJoinAll()
+ {
+ ignoredByJoinAll = true;
+ }
+
+#if DEBUG || true
+ string debugName;
+ public string DebugName
+ {
+ [NoHeapAllocation]
+ get { return debugName; }
+
+ [NoHeapAllocation]
+ set { debugName = value; }
+ }
+#endif
+ }
+
+ // This class is designed to support queues whose enqueue,
+ // dequeue, and remove operations do not allocate memory.
+ // This feature is useful when writing code that needs to
+ // do such operations with interrupts off.
+ [CLSCompliant(false)]
+ public class ThreadQueue
+ {
+ private ThreadQueueItem head = null;
+ private ThreadQueueItem tail = null;
+
+ [NoHeapAllocation]
+ public void Enqueue(ThreadQueueItem item)
+ {
+ VTable.Assert(item.Next == null);
+ VTable.Assert(item.Prev == null);
+ VTable.Assert(item.Queue == null);
+
+ item.Queue = this;
+ item.Prev = tail;
+
+ if (tail != null) {
+ VTable.Assert(tail.Next == null);
+ tail.Next = item;
+ }
+ else {
+ VTable.Assert(head == null);
+ head = item;
+ }
+
+ tail = item;
+ }
+
+ [NoHeapAllocation]
+ public ThreadQueueItem Dequeue()
+ {
+ ThreadQueueItem item = head;
+
+ if (item != null) {
+ Remove(item);
+ }
+
+ return item;
+ }
+
+ [NoHeapAllocation]
+ public void Remove(ThreadQueueItem item)
+ {
+ VTable.Assert(item.Queue == this);
+
+ if (item.Next != null) {
+ item.Next.Prev = item.Prev;
+ }
+ else {
+ VTable.Assert(item == tail);
+ tail = item.Prev;
+ }
+
+ if (item.Prev != null) {
+ item.Prev.Next = item.Next;
+ }
+ else {
+ VTable.Assert(item == head);
+ head = item.Next;
+ }
+
+ item.Next = null;
+ item.Prev = null;
+ item.Queue = null;
+ }
+
+ [NoHeapAllocation]
+ public bool IsEmpty()
+ {
+ return (head == null);
+ }
+ }
+
+ [CLSCompliant(false)]
+ public class ThreadQueueItem
+ {
+ public readonly Thread Thread = null;
+
+ public ThreadQueueItem Next = null;
+ public ThreadQueueItem Prev = null;
+
+ public ThreadQueue Queue = null;
+
+ public ThreadQueueItem(Thread thread)
+ {
+ Thread = thread;
+ }
+
+ [NoHeapAllocation]
+ public void Remove()
+ {
+ if (Queue != null) {
+ Queue.Remove(this);
+ }
+
+ VTable.Assert(Next == null);
+ VTable.Assert(Prev == null);
+ VTable.Assert(Queue == null);
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Threading/ThreadState.cs b/base/Applications/Runtime/Full/System/Threading/ThreadState.cs
new file mode 100644
index 0000000..bcca2bd
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/ThreadState.cs
@@ -0,0 +1,59 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: ThreadState
+//
+// Purpose: Enum to represent the different thread states
+//
+//=============================================================================
+
+#if ISA_ARM
+using System.Runtime.CompilerServices;
+#endif
+
+namespace System.Threading
+{
+
+ ///
+ ///
+ /// Scheduler thread state
+ ///
+ ///
+#if ISA_ARM
+ [AccessedByRuntime("Referenced in interlocked.cpp")]
+#endif
+ public enum ThreadState:byte
+ {
+ Undefined = 0x0,
+ Running = 0x1,
+ Unstarted = 0x2,
+ Stopped = 0x4,
+ Suspended = 0x8,
+ Blocked = 0x10,
+ Runnable = 0x20,
+ }
+
+ ///
+ ///
+ /// Scheduler thread's actions
+ ///
+ ///
+ public enum ThreadActions
+ {
+ Undefined = 0x0,
+ Run = 0x1,
+ Unstart = 0x2,
+ Stop = 0x4,
+ Suspend = 0x8,
+ Block = 0x10,
+ MakeRunnable = 0x20,
+ Freeze = 0x40,
+ UnFreeze = 0x80,
+ DelayAbort = 0x100,
+ UndoDelayAbort = 0x200
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Threading/ThreadStateException.cs b/base/Applications/Runtime/Full/System/Threading/ThreadStateException.cs
new file mode 100644
index 0000000..cecc158
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/ThreadStateException.cs
@@ -0,0 +1,36 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: ThreadStateException
+//
+// Purpose: An exception class to indicate that the Thread class is in an
+// invalid state for the method.
+//
+//=============================================================================
+
+namespace System.Threading
+{
+ using System;
+
+ //|
+ public class ThreadStateException : SystemException {
+ //|
+ public ThreadStateException()
+ : base("Arg_ThreadStateException") {
+ }
+
+ //|
+ public ThreadStateException(String message)
+ : base(message) {
+ }
+
+ //|
+ public ThreadStateException(String message, Exception innerException)
+ : base(message, innerException) {
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Threading/Timeout.cs b/base/Applications/Runtime/Full/System/Threading/Timeout.cs
new file mode 100644
index 0000000..ba4f4fc
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/Timeout.cs
@@ -0,0 +1,26 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+
+namespace System.Threading
+{
+ using System.Threading;
+ using System;
+ // A constant used by methods that take a timeout (Object.Wait, Thread.Sleep
+ // etc) to indicate that no timeout should occur.
+ //
+ // @todo: this should become an enum.
+ //|
+ public sealed class Timeout
+ {
+ private Timeout()
+ {
+ }
+
+ //|
+ public static readonly TimeSpan Infinite = TimeSpan.Infinite;
+ }
+
+}
diff --git a/base/Applications/Runtime/Full/System/Threading/UserSpinlock.cs b/base/Applications/Runtime/Full/System/Threading/UserSpinlock.cs
new file mode 100644
index 0000000..463f10b
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/UserSpinlock.cs
@@ -0,0 +1,265 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+// User spinlock functionality
+//
+using System;
+using Microsoft.Singularity;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace System.Threading
+{
+ [NoCCtor]
+ [CLSCompliant(false)]
+ [AccessedByRuntime("referenced from halidt.asm")]
+ public struct SpinLock
+ {
+ ///
+ ///
+ /// Acquire spinlock
+ ///
+ ///
+ [NoHeapAllocation]
+ [Inline]
+ public void Acquire()
+ {
+ Thread thread = Thread.CurrentThread;
+ AcquireInternal(thread, thread.GetThreadId());
+ }
+
+ ///
+ ///
+ /// Acquire spinlock
+ ///
+ ///
+ /// Thread's Id acquiring spinlock
+ ///
+ [NoHeapAllocation]
+ [Inline]
+ public void Acquire(int threadId)
+ {
+ AcquireInternal(Thread.GetThreadFromThreadId(threadId), threadId);
+ }
+
+ ///
+ ///
+ /// Acquire spinlock
+ ///
+ ///
+ /// Thread acquiring spinlock
+ ///
+ [NoHeapAllocation]
+ public void Acquire(Thread thread)
+ {
+ AcquireInternal(thread, thread.GetThreadId());
+ }
+
+ ///
+ ///
+ /// Release spinlock
+ ///
+ ///
+ [NoHeapAllocation]
+ public void Release()
+ {
+ Thread thread = Thread.CurrentThread;
+
+ // Release spinlock
+ ReleaseInternal(thread, thread.GetThreadId());
+ }
+
+ ///
+ ///
+ /// Release spinlock
+ ///
+ ///
+ /// Thread's Id releasing spinlock
+ ///
+ [NoHeapAllocation]
+ public void Release(int threadId)
+ {
+ // Release spinlock
+ ReleaseInternal(Thread.GetThreadFromThreadId(threadId), threadId);
+ }
+
+ ///
+ ///
+ /// Release spinlock
+ ///
+ ///
+ /// Thread releasing spinlock
+ ///
+ [NoHeapAllocation]
+ public void Release(Thread thread)
+ {
+ // Release spinlock
+ ReleaseInternal(thread, thread.GetThreadId());
+ }
+
+ ///
+ ///
+ /// Try to acquire the spin lock. Always return immediately.
+ ///
+ ///
+ /// true if the spin lock is acquired.
+ [NoHeapAllocation]
+ public bool TryAcquire()
+ {
+ Thread thread = Thread.CurrentThread;
+ return TryAcquireInternal(thread, thread.GetThreadId());
+ }
+
+ ///
+ ///
+ /// Try to acquire the spin lock. Always return immediately.
+ ///
+ ///
+ /// true if the spin lock is acquired.
+ ///
+ /// Thread acquiring spinlock
+ ///
+
+ [NoHeapAllocation]
+ public bool TryAcquire(Thread thread)
+ {
+ int threadId = thread.GetThreadId();
+
+ return TryAcquireInternal(thread, thread.GetThreadId());
+ }
+
+ ///
+ ///
+ /// Method to find out if spinlock is held by specified thread
+ ///
+ /// true if the spin lock is acquired.
+ ///
+ /// Thread to verify possible spinlock's ownership
+ ///
+ [NoHeapAllocation]
+ public bool IsHeldBy(Thread thread)
+ {
+ return baseLock.IsHeldBy(thread.GetThreadId()+1);
+ }
+
+ ///
+ ///
+ /// Method to find out if spinlock is held by specified thread
+ ///
+ /// true if the spin lock is acquired.
+ ///
+ /// Thread's Id to verify possible spinlock's ownership
+ ///
+ [NoHeapAllocation]
+ public bool IsHeldBy(int threadId)
+ {
+ return baseLock.IsHeldBy(threadId+1);
+ }
+
+ ///
+ ///
+ /// Assert thatf spinlock is held by specified thread
+ ///
+ ///
+ /// Thread to verify possible spinlock's ownership
+ ///
+ [System.Diagnostics.Conditional("DEBUG")]
+ [NoHeapAllocation]
+ public void AssertHeldBy(Thread thread)
+ {
+ VTable.Assert(IsHeldBy(thread));
+ }
+
+ ///
+ ///
+ /// Assert thatf spinlock is held by specified thread
+ ///
+ ///
+ /// Thread's Id to verify possible spinlock's ownership
+ ///
+ [System.Diagnostics.Conditional("DEBUG")]
+ [NoHeapAllocation]
+ public void AssertHeldBy(int threadId)
+ {
+ VTable.Assert(IsHeldBy(threadId));
+ }
+
+ ///
+ ///
+ /// Try to acquire the spin lock. Always return immediately.
+ ///
+ /// true if the spin lock is acquired.
+ ///
+ /// Thread acquiring spinlock
+ /// Thread's Id acquiring spinlock
+ ///
+ [NoHeapAllocation]
+ private bool TryAcquireInternal(Thread thread, int threadId)
+ {
+ bool result;
+
+ VTable.Assert(thread != null);
+
+ // Notify thread that we are about to acquire spinlock
+ thread.NotifySpinLockAboutToAcquire(this.baseLock.Type);
+
+ result = baseLock.TryAcquire(threadId+1);
+
+ // If we didn't acquire spinlock -we should notify thread about it: Just use release
+ // notification
+ if (!result) {
+ thread.NotifySpinLockReleased(this.baseLock.Type);
+ }
+
+ return result;
+ }
+
+ ///
+ ///
+ /// Acquire the spin lock.
+ ///
+ ///
+ /// Thread acquiring spinlock
+ /// Thread's Id acquiring spinlock
+ ///
+ [NoHeapAllocation]
+ private void AcquireInternal(Thread thread, int threadId)
+ {
+ VTable.Assert(thread != null);
+
+ // Thread has to be notified if we are about to acquire spinlock
+ thread.NotifySpinLockAboutToAcquire(this.baseLock.Type);
+
+ // Get lock
+ baseLock.Acquire(threadId+1);
+ }
+
+ ///
+ ///
+ /// Release the spin lock.
+ ///
+ ///
+ /// Thread releasing spinlock
+ /// Thread's Id releasing spinlock
+ ///
+ [NoHeapAllocation]
+ private void ReleaseInternal(Thread thread, int threadId)
+ {
+ // Assert preconditions: Thread can't be null
+ VTable.Assert(thread != null);
+
+ // Release spinlock
+ baseLock.Release(threadId+1);
+
+ // Don't forget to notify thread that it just released spinlock
+ thread.NotifySpinLockReleased(this.baseLock.Type);
+ }
+
+ /// Actual mechanism implementing spinlock
+ private SpinLockBase baseLock;
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Threading/WaitHandle.cs b/base/Applications/Runtime/Full/System/Threading/WaitHandle.cs
new file mode 100644
index 0000000..269147e
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Threading/WaitHandle.cs
@@ -0,0 +1,145 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: WaitHandle (this name is NOT definitive)
+//
+// Purpose: Class to represent all synchronization objects in the runtime (that allow multiple wait)
+//
+//=============================================================================
+
+namespace System.Threading
+{
+ using System;
+ using System.Threading;
+ using System.Runtime.CompilerServices;
+ using System.Collections;
+ using Microsoft.Singularity;
+ using Microsoft.Singularity.V1.Threads;
+ using Microsoft.Singularity.V1.Services;
+
+ //|
+ [CLSCompliant(false)]
+ public abstract class WaitHandle : IDisposable
+ {
+ //|
+ public const int WaitTimeout = -1;
+
+ protected WaitHandle()
+ {
+ }
+
+ protected abstract SyncHandle Handle{
+ get;
+ }
+
+ //|
+ public abstract bool WaitOne(TimeSpan timeout);
+
+ //|
+ public abstract bool WaitOne(SchedulerTime stop);
+
+ [Obsolete("Do not use DateTime for scheduling. It is meaningless. Use SchedulerTime")]
+ public bool WaitOne(DateTime stop) {
+ SchedulerTime st = SchedulerTime.MinValue + (stop - DateTime.BootTime);
+ return WaitOne(st);
+ }
+
+ //|
+ public abstract bool WaitOne();
+
+ //|
+ public static unsafe int WaitAny(WaitHandle[] waitHandles,
+ TimeSpan timeout)
+ {
+ SyncHandle[] handles = Thread.CurrentThread.GetSyncHandles(waitHandles.Length);
+ for (int i = 0; i < waitHandles.Length; i++) {
+ handles[i] = waitHandles[i].Handle;
+ }
+ fixed (SyncHandle *array = &handles[0]) {
+ return SyncHandle.WaitAny(array, waitHandles.Length, timeout);
+ }
+ }
+
+ //|
+ public static unsafe int WaitAny(WaitHandle[] waitHandles,
+ SchedulerTime stop)
+ {
+ SyncHandle[] handles = Thread.CurrentThread.GetSyncHandles(waitHandles.Length);
+ for (int i = 0; i < waitHandles.Length; i++) {
+ handles[i] = waitHandles[i].Handle;
+ }
+ fixed (SyncHandle *array = &handles[0]) {
+ return SyncHandle.WaitAny(array, waitHandles.Length, stop);
+ }
+ }
+
+ //|
+ public static unsafe int WaitAny(WaitHandle[] waitHandles)
+ {
+ SyncHandle[] handles = Thread.CurrentThread.GetSyncHandles(waitHandles.Length);
+ for (int i = 0; i < waitHandles.Length; i++) {
+ handles[i] = waitHandles[i].Handle;
+ }
+ fixed (SyncHandle *array = &handles[0]) {
+ return SyncHandle.WaitAny(array, waitHandles.Length);
+ }
+ }
+
+ //|
+ protected abstract void Dispose(bool explicitDisposing);
+
+ //|
+ public virtual void Close()
+ {
+ Dispose(true);
+ GC.nativeSuppressFinalize(this);
+ }
+
+ //|
+ ///
+ void IDisposable.Dispose()
+ {
+ Dispose(true);
+ GC.nativeSuppressFinalize(this);
+ }
+
+ //|
+ ~WaitHandle()
+ {
+ Dispose(false);
+ }
+
+ public static implicit operator WaitHandle(SyncHandle s) {
+ return new SyncWaitHandle(s);
+ }
+
+ }
+
+ internal class SyncWaitHandle : WaitHandle
+ {
+ private readonly SyncHandle _sync;
+ public SyncWaitHandle(SyncHandle s) {
+ _sync = s;
+ }
+ protected override SyncHandle Handle {
+ get { return _sync; }
+ }
+ public override bool WaitOne(TimeSpan timeout) {
+ return SyncHandle.WaitOne(Handle, timeout);
+ }
+ public override bool WaitOne(SchedulerTime stop) {
+ return SyncHandle.WaitOne(Handle, stop);
+ }
+ public override bool WaitOne() {
+ return SyncHandle.WaitOne(Handle);
+ }
+ protected override void Dispose(bool explicitDisposing) {
+ // todo: implement
+ }
+ }
+
+}
diff --git a/base/Kernel/System/TimeSpan.cs b/base/Applications/Runtime/Full/System/TimeSpan.cs
similarity index 89%
rename from base/Kernel/System/TimeSpan.cs
rename to base/Applications/Runtime/Full/System/TimeSpan.cs
index a4b9e5a..bbc3854 100644
--- a/base/Kernel/System/TimeSpan.cs
+++ b/base/Applications/Runtime/Full/System/TimeSpan.cs
@@ -3,7 +3,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-namespace System {
+namespace System
+{
using System.Text;
using System.Runtime.CompilerServices;
using System;
@@ -99,53 +100,70 @@ namespace System {
//|
public int Days {
+ [NoHeapAllocation]
get { return (int)(_ticks / TicksPerDay); }
}
//|
- public int Hours {
+ public int Hours
+ {
+ [NoHeapAllocation]
get { return (int)((_ticks / TicksPerHour) % 24); }
}
//|
- public int Milliseconds {
+ public int Milliseconds
+ {
+ [NoHeapAllocation]
get { return (int)((_ticks / TicksPerMillisecond) % 1000); }
}
//|
- public int Minutes {
+ public int Minutes
+ {
+ [NoHeapAllocation]
get { return (int)((_ticks / TicksPerMinute) % 60); }
}
//|
- public int Seconds {
+ public int Seconds
+ {
+ [NoHeapAllocation]
get { return (int)((_ticks / TicksPerSecond) % 60); }
}
//|
- public long TotalDays {
+ public long TotalDays
+ {
+ [NoHeapAllocation]
get { return _ticks / TicksPerDay; }
}
//|
- public long TotalHours {
+ public long TotalHours
+ {
+ [NoHeapAllocation]
get { return _ticks / TicksPerHour; }
}
//|
- public long TotalMilliseconds {
- get {
- return _ticks / TicksPerMillisecond;
- }
+ public long TotalMilliseconds
+ {
+ [NoHeapAllocation]
+ get { return _ticks / TicksPerMillisecond; }
}
//|
- public long TotalMinutes {
+ public long TotalMinutes
+ {
+ [NoHeapAllocation]
get { return _ticks / TicksPerMinute; }
}
//|
- public long TotalSeconds {
+ public long TotalSeconds
+ {
+ [NoHeapAllocation]
get { return _ticks / TicksPerSecond; }
}
@@ -176,7 +194,9 @@ namespace System {
// relationship.
//
//|
- public static int Compare(TimeSpan t1, TimeSpan t2) {
+ [NoHeapAllocation]
+ public static int Compare(TimeSpan t1, TimeSpan t2)
+ {
if (t1._ticks > t2._ticks) return 1;
if (t1._ticks < t2._ticks) return -1;
return 0;
@@ -215,12 +235,15 @@ namespace System {
}
//|
- public static bool Equals(TimeSpan t1, TimeSpan t2) {
+ [NoHeapAllocation]
+ public static bool Equals(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks == t2._ticks;
}
//|
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return (int)_ticks ^ (int)(_ticks >> 32);
}
@@ -249,7 +272,7 @@ namespace System {
//|
public TimeSpan Negate() {
- if (_ticks==TimeSpan.MinValue._ticks)
+ if (_ticks == TimeSpan.MinValue._ticks)
throw new OverflowException("Overflow_NegateTwosCompNum");
return new TimeSpan(-_ticks);
}
@@ -279,7 +302,9 @@ namespace System {
}
//|
- public static TimeSpan FromTicks(long value) {
+ [NoHeapAllocation]
+ public static TimeSpan FromTicks(long value)
+ {
return new TimeSpan(value);
}
@@ -325,7 +350,7 @@ namespace System {
//|
public static TimeSpan operator -(TimeSpan t) {
- if (t._ticks==TimeSpan.MinValue._ticks)
+ if (t._ticks == TimeSpan.MinValue._ticks)
throw new OverflowException("Overflow_NegateTwosCompNum");
return new TimeSpan(-t._ticks);
}
@@ -336,7 +361,9 @@ namespace System {
}
//|
- public static TimeSpan operator +(TimeSpan t) {
+ [NoHeapAllocation]
+ public static TimeSpan operator +(TimeSpan t)
+ {
return t;
}
@@ -352,26 +379,35 @@ namespace System {
}
//|
- public static bool operator !=(TimeSpan t1, TimeSpan t2) {
+ [NoHeapAllocation]
+ public static bool operator !=(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks != t2._ticks;
}
//|
- public static bool operator <(TimeSpan t1, TimeSpan t2) {
+ [NoHeapAllocation]
+ public static bool operator <(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks < t2._ticks;
}
//|
- public static bool operator <=(TimeSpan t1, TimeSpan t2) {
+ [NoHeapAllocation]
+ public static bool operator <=(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks <= t2._ticks;
}
//|
- public static bool operator >(TimeSpan t1, TimeSpan t2) {
+ [NoHeapAllocation]
+ public static bool operator >(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks > t2._ticks;
}
//|
+ [NoHeapAllocation]
public static bool operator >=(TimeSpan t1, TimeSpan t2) {
return t1._ticks >= t2._ticks;
}
diff --git a/base/Applications/Runtime/Full/System/Type.cs b/base/Applications/Runtime/Full/System/Type.cs
new file mode 100644
index 0000000..4622424
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Type.cs
@@ -0,0 +1,420 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+// Type is the root of all reflection and the Object that represents
+// a type inside the system. Type is an abstract base class that allows multiple
+// implementations. The system will always provide the subclass __RuntimeType.
+// In Reflection all of the __RuntimeXXX classes are created only once per object
+// in the system and support == comparisons.
+//
+namespace System
+{
+
+ using System;
+ using System.Reflection;
+ using System.Runtime.InteropServices;
+ using System.Runtime.CompilerServices;
+ using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
+
+ //|
+ [AccessedByRuntime("C++ needs to know relationship to RuntimeType")]
+ public abstract partial class Type
+ {
+ //|
+ public static readonly char Delimiter = '.';
+
+ // Prevent from begin created, and allow subclass
+ // to create.
+ //|
+ protected Type() {}
+
+ // GetTypeCode
+ // This method will return a TypeCode for the passed
+ // type.
+ //|
+ [NoHeapAllocation]
+ public static TypeCode GetTypeCode(Type type)
+ {
+ if (type == null)
+ return TypeCode.Empty;
+ return type.GetTypeCodeInternal();
+ }
+
+ [NoHeapAllocation]
+ internal virtual TypeCode GetTypeCodeInternal()
+ {
+ Type type = this;
+
+ if (type != type.UnderlyingSystemType)
+ return Type.GetTypeCode(type.UnderlyingSystemType);
+
+ return TypeCode.Object;
+ }
+
+ //|
+ [Inline]
+ [NoBarriers]
+ [NoHeapAllocation]
+ public static Type GetTypeFromHandle(RuntimeTypeHandle handle)
+ {
+ return RuntimeType.GetTypeFromHandleImpl(handle);
+ }
+
+ // Property representing the name of the Member.
+ //|
+ public abstract String Name {
+ [NoHeapAllocation] get;
+ }
+
+ // Return the fully qualified name. The name does contain the namespace.
+ //|
+ public abstract String FullName {
+ get;
+ }
+
+ // Return the name space of the class.
+ //|
+ public abstract String Namespace {
+ [NoHeapAllocation]
+ get;
+ }
+
+ public abstract Assembly Assembly {
+ [NoHeapAllocation]
+ get;
+ }
+
+ //|
+ public abstract String AssemblyQualifiedName {
+ get;
+ }
+
+ // @TODO: Next integration make this method abstract
+ //|
+ public virtual int GetArrayRank() {
+ throw new NotSupportedException("NotSupported_SubclassOverride");
+ }
+
+ // Returns the base class for a class. If this is an interface or has
+ // no base class null is returned. Object is the only Type that does not
+ // have a base class.
+ //|
+ public abstract Type BaseType {
+ [NoHeapAllocation]
+ get;
+ }
+
+
+ // GetInterfaces
+ // This method will return all of the interfaces implemented by a
+ // class
+ //|
+ abstract public Type[] GetInterfaces();
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Attributes
+ //
+ // The attributes are all treated as read-only properties on a class. Most of
+ // these boolean properties have flag values defined in this class and act like
+ // a bit mask of attributes. There are also a set of boolean properties that
+ // relate to the classes relationship to other classes and to the state of the
+ // class inside the runtime.
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // The attribute property on the Type.
+ //|
+ public TypeAttributes Attributes {
+ [NoHeapAllocation]
+ get {return GetAttributeFlagsImpl();}
+ }
+ //|
+ public bool IsNotPublic {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic);}
+ }
+ //|
+ public bool IsPublic {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public);}
+ }
+ //|
+ public bool IsNestedPublic {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic);}
+ }
+ //|
+ public bool IsNestedPrivate {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate);}
+ }
+ //|
+ public bool IsNestedFamily {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily);}
+ }
+ //|
+ public bool IsNestedFamANDAssem {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem);}
+ }
+ //|
+ public bool IsNestedFamORAssem{
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem);}
+ }
+
+ //|
+ public bool IsAutoLayout {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout);}
+ }
+ //|
+ public bool IsLayoutSequential {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout);}
+ }
+ //|
+ public bool IsExplicitLayout {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout);}
+ }
+
+ //|
+ public bool IsClass {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsSubclassOf(Type.valueType));}
+ }
+ //|
+ public bool IsInterface {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface);}
+ }
+ //|
+ public bool IsValueType {
+ [NoHeapAllocation]
+ get {return IsValueTypeImpl();}
+ }
+
+ //|
+ public bool IsAbstract {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0);}
+ }
+ //|
+ public bool IsSealed {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0);}
+ }
+ //|
+ public bool IsEnum {
+ [NoHeapAllocation]
+ get {return IsSubclassOf(Type.enumType);}
+ }
+ //|
+ public bool IsSpecialName {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0);}
+ }
+ //|
+ public bool IsImport {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0);}
+ }
+
+ //|
+ public bool IsAnsiClass {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass);}
+ }
+ //|
+ public bool IsUnicodeClass {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass);}
+ }
+ //|
+ public bool IsAutoClass {
+ [NoHeapAllocation]
+ get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass);}
+ }
+
+ // These are not backed up by attributes. Instead they are implemented
+ // based internally.
+ //|
+ public bool IsArray {
+ [NoHeapAllocation]
+ get {return IsArrayImpl();}
+ }
+
+ //|
+ public bool IsPrimitive {
+ [NoHeapAllocation]
+ get {return IsPrimitiveImpl();}
+ }
+ //|
+ public bool HasElementType {
+ [NoHeapAllocation]
+ get {return HasElementTypeImpl();}
+ }
+
+ // Protected routine to determine if this class represents a value class
+ //|
+ [NoHeapAllocation]
+ protected virtual bool IsValueTypeImpl() {
+ Type type = this;
+ if (type == Type.valueType || type == Type.enumType) {
+ return false;
+ }
+ return IsSubclassOf(Type.valueType);
+ }
+
+ // Protected routine to get the attributes.
+ //|
+ [NoHeapAllocation]
+ abstract protected TypeAttributes GetAttributeFlagsImpl();
+
+ // Protected routine to determine if this class represents an Array
+ //|
+ [NoHeapAllocation]
+ abstract protected bool IsArrayImpl();
+
+ // Protected routine to determine if this class represents a primitive type
+ //|
+ [NoHeapAllocation]
+ abstract protected bool IsPrimitiveImpl();
+
+ //|
+ [NoHeapAllocation]
+ abstract public Type GetElementType();
+
+ //|
+ [NoHeapAllocation]
+ abstract protected bool HasElementTypeImpl();
+
+ // Return the underlying Type that represents the IReflect Object. For expando object,
+ // this is the (Object) IReflectInstance.GetType(). For Type object it is this.
+ //|
+ public abstract Type UnderlyingSystemType {
+ [NoHeapAllocation]
+ get;
+ }
+
+ // Returns true if this class is a true subclass of c. Everything
+ // else returns false. If this class and c are the same class false is
+ // returned.
+ //
+ //|
+ [NoHeapAllocation]
+ public virtual bool IsSubclassOf(Type c)
+ {
+ Type p = this;
+ if (p == c) {
+ return false;
+ }
+ while (p != null) {
+ if (p == c) {
+ return true;
+ }
+ p = p.BaseType;
+ }
+ return false;
+ }
+
+ // Returns true if an instance of Type c may be assigned
+ // to an instance of this class. Return false otherwise.
+ //
+ //|
+ public virtual bool IsAssignableFrom(Type c)
+ {
+ if (c == null) {
+ return false;
+ }
+
+ // This excludes the TypeBuilder logic since Singularity does not
+ // have TypeBuilder in our fork of the URT sources.
+
+ // Check for interfaces
+ if (IsInterface) {
+ Type[] ifaces = c.GetInterfaces();
+ for (int i=0;i
+ public override String ToString()
+ {
+ return "Type: "+Name;
+ }
+
+ // This method will return an array of classes based upon the array of
+ // types.
+ //|
+ public static Type[] GetTypeArray(Object[] args)
+ {
+ if (args == null) {
+ throw new ArgumentNullException("args");
+ }
+ Type[] cls = new Type[args.Length];
+ for (int i = 0; i < cls.Length; i++) {
+ cls[i] = args[i].GetType();
+ }
+ return cls;
+ }
+
+ //|
+ public override bool Equals(Object o)
+ {
+ if (o == null) {
+ return false;
+ }
+ if (!(o is Type)) {
+ return false;
+ }
+ return (this.UnderlyingSystemType == ((Type) o).UnderlyingSystemType);
+ }
+
+ //|
+ public bool Equals(Type o)
+ {
+ if (o == null) {
+ return false;
+ }
+ return (this.UnderlyingSystemType == o.UnderlyingSystemType);
+ }
+
+ //|
+ public override int GetHashCode()
+ {
+ Type SystemType = UnderlyingSystemType;
+ if (SystemType != this) {
+ return SystemType.GetHashCode();
+ }
+ return base.GetHashCode();
+ }
+
+ // private convenience data
+ private static readonly Type valueType = typeof(System.ValueType);
+ private static readonly Type enumType = typeof(System.Enum);
+
+ public abstract Microsoft.Singularity.V1.Types.SystemType GetSystemType();
+ }
+}
diff --git a/base/Kernel/System/TypeCode.cs b/base/Applications/Runtime/Full/System/TypeCode.cs
similarity index 97%
rename from base/Kernel/System/TypeCode.cs
rename to base/Applications/Runtime/Full/System/TypeCode.cs
index e4b18af..fd6578d 100644
--- a/base/Kernel/System/TypeCode.cs
+++ b/base/Applications/Runtime/Full/System/TypeCode.cs
@@ -21,7 +21,8 @@
// These types of values are instead represented as classes. When the type code
// of an object is TypeCode.Object, a further instance-of check can be used to
// determine if the object is one of these values.
-namespace System {
+namespace System
+{
//|
public enum TypeCode {
//|
diff --git a/base/Applications/Runtime/Full/System/TypeInitializationException.cs b/base/Applications/Runtime/Full/System/TypeInitializationException.cs
new file mode 100644
index 0000000..91845c5
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/TypeInitializationException.cs
@@ -0,0 +1,52 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: TypeInitializationException
+//
+// Purpose: The exception class to wrap exceptions thrown by
+// a type's class initializer (.cctor). This is sufficiently
+// distinct from a TypeLoadException, which means we couldn't
+// find the type.
+//
+//=============================================================================
+using System;
+
+namespace System
+{
+ //|
+ public sealed class TypeInitializationException : SystemException {
+ private String _typeName;
+
+ // This exception is not creatable without specifying the
+ // inner exception.
+ private TypeInitializationException()
+ : base("TypeInitialization_Default") {
+ }
+
+ // This is called from within the runtime. I believe this is necessary
+ // for Interop only, though it's not particularly useful.
+ private TypeInitializationException(String message) : base(message) {
+ }
+
+ //|
+ public TypeInitializationException(String fullTypeName, Exception innerException)
+ : base(String.Format("An exception occurred while initializing the type '{0}'.", fullTypeName), innerException) {
+ _typeName = fullTypeName;
+ }
+
+ //|
+ public String TypeName
+ {
+ get {
+ if (_typeName == null) {
+ return String.Empty;
+ }
+ return _typeName;
+ }
+ }
+ }
+}
diff --git a/base/Kernel/System/UInt16.cs b/base/Applications/Runtime/Full/System/UInt16.cs
similarity index 88%
rename from base/Kernel/System/UInt16.cs
rename to base/Applications/Runtime/Full/System/UInt16.cs
index 71b3d4c..bf3190d 100644
--- a/base/Kernel/System/UInt16.cs
+++ b/base/Applications/Runtime/Full/System/UInt16.cs
@@ -3,19 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: UInt16
-**
-** and Daryl Olander (darylo)
-**
-** Purpose: This class will encapsulate a short and provide an
-** Object representation of it.
-**
-** Date: March 4, 1999
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: UInt16
+//
+// Purpose: This class will encapsulate a short and provide an
+// Object representation of it.
+//
+//===========================================================
+namespace System
+{
using System.Globalization;
using System;
using System.Runtime.CompilerServices;
diff --git a/base/Kernel/System/UInt32.cs b/base/Applications/Runtime/Full/System/UInt32.cs
similarity index 89%
rename from base/Kernel/System/UInt32.cs
rename to base/Applications/Runtime/Full/System/UInt32.cs
index 2a7e434..96b80ee 100644
--- a/base/Kernel/System/UInt32.cs
+++ b/base/Applications/Runtime/Full/System/UInt32.cs
@@ -3,18 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: UInt32
-**
-**
-** Purpose: This class will encapsulate an uint and
-** provide an Object representation of it.
-**
-** Date: March 4, 1999
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: UInt32
+//
+// Purpose: This class will encapsulate an uint and
+// provide an Object representation of it.
+//
+//===========================================================
+namespace System
+{
using System.Globalization;
using System;
using System.Runtime.CompilerServices;
diff --git a/base/Kernel/System/UInt64.cs b/base/Applications/Runtime/Full/System/UInt64.cs
similarity index 88%
rename from base/Kernel/System/UInt64.cs
rename to base/Applications/Runtime/Full/System/UInt64.cs
index 7120a63..ca322a6 100644
--- a/base/Kernel/System/UInt64.cs
+++ b/base/Applications/Runtime/Full/System/UInt64.cs
@@ -3,19 +3,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
-/*============================================================
-**
-** Class: UInt64
-**
-** and Daryl Olander (darylo)
-**
-** Purpose: This class will encapsulate an unsigned long and
-** provide an Object representation of it.
-**
-** Date: March 4, 1999
-**
-===========================================================*/
-namespace System {
+//============================================================
+//
+// Class: UInt64
+//
+// Purpose: This class will encapsulate an unsigned long and
+// provide an Object representation of it.
+//
+//===========================================================
+namespace System
+{
using System.Globalization;
using System;
using System.Runtime.CompilerServices;
diff --git a/base/Kernel/System/UIntPtr.cs b/base/Applications/Runtime/Full/System/UIntPtr.cs
similarity index 96%
rename from base/Kernel/System/UIntPtr.cs
rename to base/Applications/Runtime/Full/System/UIntPtr.cs
index 1904e62..ac9d30d 100644
--- a/base/Kernel/System/UIntPtr.cs
+++ b/base/Applications/Runtime/Full/System/UIntPtr.cs
@@ -4,7 +4,8 @@
//
// ==--==
-namespace System {
+namespace System
+{
using System;
using System.Globalization;
diff --git a/base/Applications/Runtime/Full/System/ValueType.cs b/base/Applications/Runtime/Full/System/ValueType.cs
new file mode 100644
index 0000000..61f046e
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/ValueType.cs
@@ -0,0 +1,48 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Class: ValueType
+//
+// Purpose: Base class for all value classes.
+//
+//===========================================================
+namespace System
+{
+ using System;
+ using System.Runtime.CompilerServices;
+
+ //|
+ [NoCCtor]
+ public abstract class ValueType {
+
+ //|
+ public override bool Equals (Object obj) {
+ throw new Exception("System.ValueType.Equals not implemented in Bartok!");
+ }
+
+ //=================================GetHashCode==================================
+ //Action: Our algorithm for returning the hashcode is a little bit complex. We look
+ // for the first non-static field and get its hashcode. If the type has no
+ // non-static fields, we return the hashcode of the type. We can't take the
+ // hashcode of a static member because if that member is of the same type as
+ // the original type, we'll end up in an infinite loop.
+ //Returns: The hashcode for the type.
+ //Arguments: None.
+ //Exceptions: None.
+ //==============================================================================
+ //|
+ public override int GetHashCode() {
+ throw new Exception("System.ValueType.GetHashCode not implemented in Bartok!");
+ }
+
+ //|
+ public override String ToString() {
+ Type thisType = this.GetType();
+ return thisType.FullName;
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/Version.cs b/base/Applications/Runtime/Full/System/Version.cs
new file mode 100644
index 0000000..6f41785
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/Version.cs
@@ -0,0 +1,295 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//============================================================
+//
+// Purpose:
+//
+//===========================================================
+namespace System
+{
+
+ using System.Runtime.CompilerServices;
+ using CultureInfo = System.Globalization.CultureInfo;
+
+ // A Version object contains four hierarchical numeric components: major, minor,
+ // build and revision. Build and revision may be unspecified, which is represented
+ // internally as a -1. By definition, an unspecified component matches anything
+ // (both unspecified and specified), and an unspecified component is "less than" any
+ // specified component.
+
+ //|
+ public sealed partial class Version : ICloneable, IComparable
+ {
+ private int _Major;
+ private int _Minor;
+ private int _Build = -1;
+ private int _Revision = -1;
+
+ //|
+ public Version(int major, int minor, int build, int revision) {
+ if (major < 0)
+ throw new ArgumentOutOfRangeException("major","ArgumentOutOfRange_Version");
+
+ if (minor < 0)
+ throw new ArgumentOutOfRangeException("minor","ArgumentOutOfRange_Version");
+
+ if (build < 0)
+ throw new ArgumentOutOfRangeException("build","ArgumentOutOfRange_Version");
+
+ if (revision < 0)
+ throw new ArgumentOutOfRangeException("revision","ArgumentOutOfRange_Version");
+
+ _Major = major;
+ _Minor = minor;
+ _Build = build;
+ _Revision = revision;
+ }
+
+ //|
+ public Version(int major, int minor, int build) {
+ if (major < 0)
+ throw new ArgumentOutOfRangeException("major","ArgumentOutOfRange_Version");
+
+ if (minor < 0)
+ throw new ArgumentOutOfRangeException("minor","ArgumentOutOfRange_Version");
+
+ if (build < 0)
+ throw new ArgumentOutOfRangeException("build","ArgumentOutOfRange_Version");
+
+
+ _Major = major;
+ _Minor = minor;
+ _Build = build;
+ }
+
+ //|
+ public Version(int major, int minor) {
+ if (major < 0)
+ throw new ArgumentOutOfRangeException("major","ArgumentOutOfRange_Version");
+
+ if (minor < 0)
+ throw new ArgumentOutOfRangeException("minor","ArgumentOutOfRange_Version");
+
+ _Major = major;
+ _Minor = minor;
+ }
+
+ //|
+ public Version(String version) {
+ if ((Object) version == null)
+ throw new ArgumentNullException("version");
+
+ String[] parsedComponents = version.Split(new char[] {'.'});
+ int parsedComponentsLength = parsedComponents.Length;
+ if ((parsedComponentsLength < 2) || (parsedComponentsLength > 4)) throw new ArgumentException("Arg_VersionString");
+ _Major = Int32.Parse(parsedComponents[0]);
+ if (_Major < 0)
+ throw new ArgumentOutOfRangeException("version","ArgumentOutOfRange_Version");
+
+ _Minor = Int32.Parse(parsedComponents[1]);
+ if (_Minor < 0)
+ throw new ArgumentOutOfRangeException("version","ArgumentOutOfRange_Version");
+
+ parsedComponentsLength -= 2;
+ if (parsedComponentsLength > 0) {
+ _Build = Int32.Parse(parsedComponents[2]);
+ if (_Build < 0)
+ throw new ArgumentOutOfRangeException("build","ArgumentOutOfRange_Version");
+
+ parsedComponentsLength--;
+ if (parsedComponentsLength > 0) {
+ _Revision = Int32.Parse(parsedComponents[3]);
+ if (_Revision < 0)
+ throw new ArgumentOutOfRangeException("revision","ArgumentOutOfRange_Version");
+ }
+ }
+ }
+
+ //|
+ public Version()
+ {
+ _Major = 0;
+ _Minor = 0;
+ }
+
+ // Properties for setting and getting version numbers
+ //|
+ public int Major {
+ get { return _Major; }
+ }
+
+ //|
+ public int Minor {
+ get { return _Minor; }
+ }
+
+ //|
+ public int Build {
+ get { return _Build; }
+ }
+
+ //|
+ public int Revision {
+ get { return _Revision; }
+ }
+
+ //|
+ public Object Clone() {
+ Version v = new Version();
+ v._Major = _Major;
+ v._Minor = _Minor;
+ v._Build = _Build;
+ v._Revision = _Revision;
+ return(v);
+ }
+
+ //|
+ public int CompareTo(Object version)
+ {
+ if (version == null)
+ return 1;
+
+ if (!(version is Version))
+ throw new ArgumentException("Arg_MustBeVersion");
+
+ Version v = (Version) version;
+
+ if (this._Major != v._Major)
+ if (this._Major > v._Major)
+ return 1;
+ else
+ return -1;
+
+ if (this._Minor != v._Minor)
+ if (this._Minor > v._Minor)
+ return 1;
+ else
+ return -1;
+
+ if (this._Build != v._Build)
+ if (this._Build > v._Build)
+ return 1;
+ else
+ return -1;
+
+ if (this._Revision != v._Revision)
+ if (this._Revision > v._Revision)
+ return 1;
+ else
+ return -1;
+
+ return 0;
+ }
+
+ //|
+ public override bool Equals(Object obj) {
+ if (((Object) obj == null) ||
+ (!(obj is Version)))
+ return false;
+
+ Version v = (Version) obj;
+ // check that major, minor, build & revision numbers match
+ if ((this._Major != v._Major) ||
+ (this._Minor != v._Minor) ||
+ (this._Build != v._Build) ||
+ (this._Revision != v._Revision))
+ return false;
+
+ return true;
+ }
+
+ //|
+ public override int GetHashCode()
+ {
+ // Let's assume that most version numbers will be pretty small and just
+ // OR some lower order bits together.
+
+ int accumulator = 0;
+
+ accumulator |= (this._Major & 0x0000000F) << 28;
+ accumulator |= (this._Minor & 0x000000FF) << 20;
+ accumulator |= (this._Build & 0x000000FF) << 12;
+ accumulator |= (this._Revision & 0x00000FFF);
+
+ return accumulator;
+ }
+
+ //|
+ public override String ToString() {
+ if (_Build == -1) return(ToString(2));
+ if (_Revision == -1) return(ToString(3));
+ return(ToString(4));
+ }
+
+ //|
+ public String ToString(int fieldCount) {
+ switch (fieldCount) {
+ case 0:
+ return(String.Empty);
+ case 1:
+ return(String.Concat(_Major));
+ case 2:
+ return(String.Concat(_Major,".",_Minor));
+ default:
+ if (_Build == -1)
+ throw new ArgumentException(String.Format("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "2"), "fieldCount");
+ if (fieldCount == 3)
+ return( _Major + "." + _Minor + "." + _Build );
+
+ if (_Revision == -1)
+ throw new ArgumentException(String.Format("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "3"), "fieldCount");
+
+ if (fieldCount == 4)
+ return( Major + "." + _Minor + "." + _Build + "." + _Revision );
+
+ throw new ArgumentException(String.Format("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "4"), "fieldCount");
+ }
+ }
+
+ //|
+ public static bool operator ==(Version v1, Version v2) {
+ if ((Object) v1 == null) {
+ if ((Object) v2 == null)
+ return true;
+ else
+ return false;
+ }
+ if ((Object) v2 == null)
+ return false;
+
+ return v1.Equals(v2);
+ }
+
+ //|
+ public static bool operator !=(Version v1, Version v2) {
+ return !(v1 == v2);
+ }
+
+ //|
+ public static bool operator <(Version v1, Version v2) {
+ if ((Object) v1 == null)
+ throw new ArgumentNullException("v1");
+ return (v1.CompareTo(v2) < 0);
+ }
+
+ //|
+ public static bool operator <=(Version v1, Version v2) {
+ if ((Object) v1 == null)
+ throw new ArgumentNullException("v1");
+ return (v1.CompareTo(v2) <= 0);
+ }
+
+ //|
+ public static bool operator >(Version v1, Version v2) {
+ return (v2 < v1);
+ }
+
+ //|
+ public static bool operator >=(Version v1, Version v2) {
+ return (v2 <= v1);
+ }
+ }
+}
diff --git a/base/Kernel/System/Void.cs b/base/Applications/Runtime/Full/System/Void.cs
similarity index 91%
rename from base/Kernel/System/Void.cs
rename to base/Applications/Runtime/Full/System/Void.cs
index fe00308..508a2f6 100644
--- a/base/Kernel/System/Void.cs
+++ b/base/Applications/Runtime/Full/System/Void.cs
@@ -8,7 +8,8 @@
// This class represents the void return type
////////////////////////////////////////////////////////////////////////////////
-namespace System {
+namespace System
+{
using System;
//|
diff --git a/base/Applications/Runtime/Full/System/_LocalDataStore.cs b/base/Applications/Runtime/Full/System/_LocalDataStore.cs
new file mode 100644
index 0000000..eff6818
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/_LocalDataStore.cs
@@ -0,0 +1,126 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: LocalDataStore
+//
+// Purpose: Class that stores local data. This class is used in cooperation
+// with the _LocalDataStoreMgr class.
+//
+//=============================================================================
+
+namespace System
+{
+
+ using System;
+
+ internal class LocalDataStore
+ {
+ //=========================================================================
+ // DON'T CHANGE THESE UNLESS YOU MODIFY LocalDataStoreBaseObject in vm\object.h
+ //=========================================================================
+ private Object[] m_DataTable;
+ private LocalDataStoreMgr m_Manager;
+
+ //=========================================================================
+ // Initialize the data store.
+ //=========================================================================
+ public LocalDataStore(LocalDataStoreMgr mgr, int InitialCapacity)
+ {
+ if (null == mgr)
+ throw new ArgumentNullException("mgr");
+
+ // Store the manager of the local data store.
+ m_Manager = mgr;
+
+ // Allocate the array that will contain the data.
+ m_DataTable = new Object[InitialCapacity];
+ }
+
+ //=========================================================================
+ // Retrieves the value from the specified slot.
+ //=========================================================================
+ public Object GetData(LocalDataStoreSlot slot)
+ {
+ Object o = null;
+
+ // Validate the slot.
+ m_Manager.ValidateSlot(slot);
+
+ // Cache the slot index to avoid synchronization issues.
+ int slotIdx = slot.Slot;
+
+ if (slotIdx >= 0) {
+ // Delay expansion of m_DataTable if we can
+ if (slotIdx >= m_DataTable.Length)
+ return null;
+
+ // Retrieve the data from the given slot.
+ o = m_DataTable[slotIdx];
+ }
+
+ // Check if the slot has become invalid.
+ if (!slot.IsValid())
+ throw new InvalidOperationException("InvalidOperation_SlotHasBeenFreed");
+ return o;
+ }
+
+ //=========================================================================
+ // Sets the data in the specified slot.
+ //=========================================================================
+ public void SetData(LocalDataStoreSlot slot, Object data)
+ {
+ // Validate the slot.
+ m_Manager.ValidateSlot(slot);
+
+ // I can't think of a way to avoid the race described in the
+ // LocalDataStoreSlot finalizer method without a lock.
+ lock (m_Manager) {
+ if (!slot.IsValid())
+ throw new InvalidOperationException("InvalidOperation_SlotHasBeenFreed");
+
+ // Do the actual set operation.
+ SetDataInternal(slot.Slot, data, true /*bAlloc*/ );
+ }
+ }
+
+ //=========================================================================
+ // This method does the actual work of setting the data.
+ //=========================================================================
+ internal void SetDataInternal(int slot, Object data, bool bAlloc)
+ {
+ // We try to delay allocate the dataTable (in cases like the manager clearing a
+ // just-freed slot in all stores
+ if (slot >= m_DataTable.Length) {
+ if (!bAlloc)
+ return;
+ SetCapacity(m_Manager.GetSlotTableLength());
+ }
+
+ // Set the data on the given slot.
+ m_DataTable[slot] = data;
+ }
+
+ //=========================================================================
+ // Method used to set the capacity of the local data store.
+ //=========================================================================
+ private void SetCapacity(int capacity)
+ {
+ // Validate that the specified capacity is larger than the current one.
+ if (capacity < m_DataTable.Length)
+ throw new ArgumentException("Argument_ALSInvalidCapacity");
+
+ // Allocate the new data table.
+ Object[] NewDataTable = new Object[capacity];
+
+ // Copy all the objects into the new table.
+ Array.Copy(m_DataTable, NewDataTable, m_DataTable.Length);
+
+ // Save the new table.
+ m_DataTable = NewDataTable;
+ }
+ }
+}
diff --git a/base/Applications/Runtime/Full/System/_LocalDataStoreMgr.cs b/base/Applications/Runtime/Full/System/_LocalDataStoreMgr.cs
new file mode 100644
index 0000000..60dc8a8
--- /dev/null
+++ b/base/Applications/Runtime/Full/System/_LocalDataStoreMgr.cs
@@ -0,0 +1,285 @@
+// ==++==
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ==--==
+//=============================================================================
+//
+// Class: LocalDataStoreMgr
+//
+// Purpose: Class that manages stores of local data. This class is used in
+// cooperation with the LocalDataStore class.
+//
+//=============================================================================
+namespace System
+{
+
+ using System;
+ using System.Collections;
+
+ // This is a cheesy internal helper class that is used to make sure memory
+ // is actually being accessed and not some cached copy of a field in a
+ // register.
+ // WARNING: If we every do type analysis to eliminate virtual functions,
+ // this will break.
+ internal class LdsSyncHelper
+ {
+ internal virtual int Get(ref int slot)
+ {
+ return slot;
+ }
+ }
+
+ // This class is an encapsulation of a slot so that it is managed in a secure fashion.
+ // It is constructed by the LocalDataStoreManager, holds the slot and the manager
+ // and cleans up when it is finalized.
+ //|
+ public sealed class LocalDataStoreSlot
+ {
+ private static LdsSyncHelper m_helper = new LdsSyncHelper();
+
+ private LocalDataStoreMgr m_mgr;
+ private int m_slot;
+
+ // Construct the object to encapsulate the slot.
+ internal LocalDataStoreSlot(LocalDataStoreMgr mgr, int slot)
+ {
+ m_mgr = mgr;
+ m_slot = slot;
+ }
+
+ // Accessors for the two fields of this class.
+ internal LocalDataStoreMgr Manager
+ {
+ get
+ {
+ return m_mgr;
+ }
+ }
+ internal int Slot
+ {
+ get
+ {
+ return m_slot;
+ }
+ }
+
+ // This is used to make sure we are actually reading and writing to
+ // memory to fetch the slot (rather than possibly using a value
+ // cached in a register).
+ internal bool IsValid()
+ {
+ return m_helper.Get(ref m_slot) != -1;
+ }
+
+ // Release the slot reserved by this object when this object goes away.
+ // There is a race condition that can happen in the face of
+ // resurrection where another thread is fetching values or assigning
+ // while the finalizer thread is here. We are counting on the fact
+ // that code that fetches values calls IsValid after fetching a value
+ // and before giving it to anyone. See LocalDataStore for the other
+ // half of this. We are also counting on code that sets values locks
+ // the manager.
+ //|
+ ~LocalDataStoreSlot()
+ {
+ int slot = m_slot;
+
+ // This lock fixes synchronization with the assignment of values.
+ lock (m_mgr) {
+ // Mark the slot as free.
+ m_slot = -1;
+
+ m_mgr.FreeDataSlot(slot);
+ }
+ }
+ }
+
+ internal class LocalDataStoreMgr
+ {
+ private const byte DataSlotOccupied = 0x01;
+
+ private const int InitialSlotTableSize = 64;
+ private const int SlotTableDoubleThreshold = 512;
+ private const int LargeSlotTableSizeIncrease = 128;
+
+ //=========================================================================
+ // Create a data store to be managed by this manager and add it to the
+ // list. The initial size of the new store matches the number of slots
+ // allocated in this manager.
+ //=========================================================================
+ public LocalDataStore CreateLocalDataStore()
+ {
+ // Create a new local data store.
+ LocalDataStore Store = new LocalDataStore(this, m_SlotInfoTable.Length);
+
+ lock (this) {
+ // Add the store to the array list and return it.
+ m_ManagedLocalDataStores.Add(Store);
+ }
+ return Store;
+ }
+
+ //=========================================================================
+ // Remove the specified store from the list of managed stores..
+ //=========================================================================
+ public void DeleteLocalDataStore(LocalDataStore store)
+ {
+ lock (this) {
+ // Remove the store to the array list and return it.
+ m_ManagedLocalDataStores.Remove(store);
+ }
+ }
+
+ //=========================================================================
+ // Allocates a data slot by finding an available index and wrapping it
+ // an object to prevent clients from manipulating it directly, allowing us
+ // to make assumptions its integrity.
+ //=========================================================================
+ public LocalDataStoreSlot AllocateDataSlot()
+ {
+ lock (this) {
+ int i;
+ LocalDataStoreSlot slot;
+
+ // Retrieve the current size of the table.
+ int SlotTableSize = m_SlotInfoTable.Length;
+
+ // Check if there are any slots left.
+ if (m_FirstAvailableSlot < SlotTableSize) {
+ // Save the first available slot.
+ slot = new LocalDataStoreSlot(this, m_FirstAvailableSlot);
+ m_SlotInfoTable[m_FirstAvailableSlot] = DataSlotOccupied;
+
+ // Find the next available slot.
+ for (i = m_FirstAvailableSlot + 1; i < SlotTableSize; ++i)
+ if (0 == (m_SlotInfoTable[i] & DataSlotOccupied))
+ break;
+
+ // Save the new "first available slot".
+ m_FirstAvailableSlot = i;
+
+ // Return the slot index.
+ return slot;
+ }
+
+ // The table is full so we need to increase its size.
+ int NewSlotTableSize;
+ if (SlotTableSize < SlotTableDoubleThreshold) {
+ // The table is still relatively small so double it.
+ NewSlotTableSize = SlotTableSize * 2;
+ }
+ else {
+ // The table is relatively large so simply increase its size by a given amount.
+ NewSlotTableSize = SlotTableSize + LargeSlotTableSizeIncrease;
+ }
+
+ // Allocate the new slot info table.
+ byte[] NewSlotInfoTable = new byte[NewSlotTableSize];
+
+ // Copy the old array into the new one.
+ Array.Copy(m_SlotInfoTable, NewSlotInfoTable, SlotTableSize);
+ m_SlotInfoTable = NewSlotInfoTable;
+
+ // SlotTableSize is the index of the first empty slot in the expanded table.
+ slot = new LocalDataStoreSlot(this, SlotTableSize);
+ m_SlotInfoTable[SlotTableSize] = DataSlotOccupied;
+ m_FirstAvailableSlot = SlotTableSize + 1;
+
+ // Return the selected slot
+ return slot;
+ }
+ }
+
+ //=========================================================================
+ // Allocate a slot and associate a name with it.
+ //=========================================================================
+ public LocalDataStoreSlot AllocateNamedDataSlot(String name)
+ {
+ lock (this) {
+ // Allocate a normal data slot.
+ LocalDataStoreSlot slot = AllocateDataSlot();
+
+ // Insert the association between the name and the data slot number
+ // in the hash table.
+ m_KeyToSlotMap.Add(name, slot);
+ return slot;
+ }
+ }
+
+ //=========================================================================
+ // Retrieve the slot associated with a name, allocating it if no such
+ // association has been defined.
+ //=========================================================================
+ public LocalDataStoreSlot GetNamedDataSlot(String name)
+ {
+ lock (this) {
+ // Lookup in the hashtable to try find a slot for the name.
+ LocalDataStoreSlot slot = (LocalDataStoreSlot) m_KeyToSlotMap[name];
+
+ // If the name is not yet in the hashtable then add it.
+ if (null == slot)
+ return AllocateNamedDataSlot(name);
+
+ // The name was in the hashtable so return the associated slot.
+ return slot;
+ }
+ }
+
+ //=========================================================================
+ // Eliminate the association of a name with a slot. The actual slot will
+ // be reclaimed when the finalizer for the slot object runs.
+ //=========================================================================
+ public void FreeNamedDataSlot(String name)
+ {
+ lock (this) {
+ // Remove the name slot association from the hashtable.
+ m_KeyToSlotMap.Remove(name);
+ }
+ }
+
+ //=========================================================================
+ // Free's a previously allocated data slot on ALL the managed data stores.
+ //=========================================================================
+ internal void FreeDataSlot(int slot)
+ {
+ lock (this) {
+ // Go thru all the managed stores and set the data on the specified slot to 0.
+ for (int i = 0; i < m_ManagedLocalDataStores.Count; i++) {
+ ((LocalDataStore)m_ManagedLocalDataStores[i]).SetDataInternal(
+ slot,
+ null,
+ false);
+ }
+
+ // Mark the slot as being no longer occupied.
+ m_SlotInfoTable[slot] = 0;
+ if (slot < m_FirstAvailableSlot)
+ m_FirstAvailableSlot = slot;
+ }
+ }
+
+ //=========================================================================
+ // Return the number of allocated slots in this manager.
+ //=========================================================================
+ public void ValidateSlot(LocalDataStoreSlot slot)
+ {
+ // Make sure the slot was allocated for this store.
+ if (slot == null || slot.Manager != this)
+ throw new ArgumentException("Argument_ALSInvalidSlot");
+ }
+
+ //=========================================================================
+ // Return the number of allocated slots in this manager.
+ //=========================================================================
+ internal int GetSlotTableLength()
+ {
+ return m_SlotInfoTable.Length;
+ }
+
+ private byte[] m_SlotInfoTable = new byte[InitialSlotTableSize];
+ private int m_FirstAvailableSlot = 0;
+ private ArrayList m_ManagedLocalDataStores = new ArrayList();
+ private Hashtable m_KeyToSlotMap = new Hashtable();
+ }
+}
diff --git a/base/Applications/Runtime/Full/TestApp.csproj b/base/Applications/Runtime/Full/TestApp.csproj
new file mode 100644
index 0000000..ee2bef1
--- /dev/null
+++ b/base/Applications/Runtime/Full/TestApp.csproj
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+ testapp.$(Runtime)
+ Exe
+ $(APPRUNTIMEDIR)
+ C#
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Runtime/testapp.cs b/base/Applications/Runtime/Full/testapp.cs
similarity index 93%
rename from base/Applications/Runtime/testapp.cs
rename to base/Applications/Runtime/Full/testapp.cs
index 8486a53..a0d7621 100644
--- a/base/Applications/Runtime/testapp.cs
+++ b/base/Applications/Runtime/Full/testapp.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: testapp.cs
-//
// Note: This file contains the main entry point for the C#
// portion of Singularity.
//
diff --git a/base/Applications/Runtime/ILHelpers.csproj b/base/Applications/Runtime/ILHelpers.csproj
deleted file mode 100644
index 3ee4ef6..0000000
--- a/base/Applications/Runtime/ILHelpers.csproj
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
- $(APPRUNTIMEDIR)
- $(SINGULARITY_ROOT)\Kernel
- $(OutputPath)\ILHelpers.dll
-
-
-
-
-
-
-
-
-
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Runtime/Singularity/AppRuntime.cs b/base/Applications/Runtime/Singularity/AppRuntime.cs
deleted file mode 100644
index 1cee5b6..0000000
--- a/base/Applications/Runtime/Singularity/AppRuntime.cs
+++ /dev/null
@@ -1,224 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Runtime.cs
-//
-// Note:
-//
-
-using System;
-using System.Collections;
-using System.Reflection;
-using System.Threading;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-using Microsoft.Bartok.Runtime;
-
-#if !MINRUNTIME
- using Microsoft.Singularity.Io;
-#endif
- using Microsoft.Singularity.V1.Services;
-
-[assembly: AssemblyTitle("Microsoft.Singularity")]
-[assembly: AssemblyProduct("Microsoft Research Singularity Runtime")]
-[assembly: AssemblyCompany("Microsoft Corporation")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyKeyFile("public.snk")]
-[assembly: AssemblyDelaySign(true)]
-
-namespace Microsoft.Singularity
-{
-
- [NoCCtor]
- [CLSCompliant(false)]
- public class AppRuntime
- {
- // Note: This function is called by Hal.cpp.
- [AccessedByRuntime("referenced from hal.cpp")]
- public static unsafe int AppStart(Type userClass)
- {
- System.GCs.Transitions.ThreadStart();
-
- int result = 0;
-
- try {
- Tracing.Log(Tracing.Audit, "Runtime.Main()");
-
- // Initialize the primitive runtime, which calls the
- // class constructor for Runtime().
- VTable.Initialize((RuntimeType)typeof(AppRuntime));
- /*VTable.ParseArgs(args);*/
-
- Tracing.Log(Tracing.Audit, "Enabling GC Heap");
- GC.EnableHeap();
-
-#if !MINRUNTIME
- ConsoleOutput.Initialize();
- ConsoleInput.Initialize();
-#endif
-
- SetDebuggerPresence(DebugService.IsDebuggerPresent());
-
- int argCount = 0;
- int argMaxLen = 0;
- for (;; argCount++) {
- int len = ProcessService.GetStartupArg(argCount, null, 0);
- if (len == 0) {
- break;
- }
- if (argMaxLen < len) {
- argMaxLen = len;
- }
- }
- char[] argArray = new char [argMaxLen];
- string[] args = new string[argCount];
- for (int arg = 0; arg < argCount; arg++) {
- fixed (char *argptr = &argArray[0]) {
- int len = ProcessService.GetStartupArg(arg,
- argptr,
- argArray.Length);
- args[arg] = String.StringCTOR(argptr, 0, len);
- }
- }
-
- if (userClass != null) {
- VTable.initType((RuntimeType)userClass);
- }
-
- result = CallMain(args);
- if (!MainReturnsInt()) result = 0;
- Thread.RemoveThread(Thread.CurrentThread.threadIndex);
-
- Thread.JoinAll();
-
-#if !MINRUNTIME
- ConsoleOutput.Finalize();
- ConsoleInput.Finalize();
-#endif
- Tracing.Log(Tracing.Audit, "Main thread exited [{0}]",
- (UIntPtr)unchecked((uint)result));
- }
- catch (Exception e) {
- Tracing.Log(Tracing.Fatal, "Failed with exception {0}.{1}",
- e.GetType().Namespace, e.GetType().Name);
- Tracing.Log(Tracing.Trace, "Exception message was {0}",
- e.ToString());
- DebugStub.WriteLine("Caught {0}", __arglist(e.Message));
- result = -1;
- }
-
- Tracing.Log(Tracing.Audit, "Runtime shutdown started.");
- VTable.Shutdown(result);
- Tracing.Log(Tracing.Audit, "Runtime exiting [{0}]",
- (UIntPtr)unchecked((uint)result));
- return result;
- }
-
- [AccessedByRuntime("output to header : defined in hal.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [StackBound(256)]
- private static extern int CallMain(String[] args);
-
- [AccessedByRuntime("output to header: defined in hal.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [StackBound(256)]
- private static extern bool MainReturnsInt();
-
- [AccessedByRuntime("output to header: defined in hal.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [StackBound(256)]
- private static extern void SetDebuggerPresence(bool debuggerPresent);
-
- internal static void Shutdown(int exitCode)
- {
- //
- // Gracefully close down the process.
- //
- Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0})",
- (UIntPtr)unchecked((uint)exitCode));
-
- DebugStub.WriteLine("Runtime.Shutdown({0})", __arglist(exitCode));
-
- VTable.Shutdown(exitCode);
- Tracing.Log(Tracing.Audit, "Runtime.Shutdown({0}) terminating",
- (UIntPtr)unchecked((uint)exitCode));
- ProcessService.Stop(exitCode);
- }
-
- internal static void Stop(int exitCode)
- {
- //
- // Halt the process immediately.
- //
- Tracing.Log(Tracing.Audit, "Runtime.Stop({0})",
- (UIntPtr)unchecked((uint)exitCode));
-
- DebugStub.WriteLine("Runtime.Stop({0})", __arglist(exitCode));
-
- ProcessService.Stop(exitCode);
- }
-
- //////////////////////////////////////////////////////////////////////
- //
- [NoHeapAllocation]
- public static UIntPtr AddressOf(Object o)
- {
- return Magic.addressOf(o);
- }
-
- [NoHeapAllocation]
- public static UIntPtr SizeOf(Object o)
- {
- return System.GCs.ObjectLayout.Sizeof(o);
- }
-
- public static void InitType(Type ty)
- {
- VTable.initType((RuntimeType) ty);
- }
-
- public static void DumpPageTable()
- {
- System.GCs.PageTable.Dump("PageTable");
- }
-
- //////////////////////////////////////////////////////////////////////
- //
- public static bool EnableGCVerify
- {
- get {
- return VTable.enableGCVerify;
- }
- set {
- VTable.enableGCVerify = value;
- }
- }
-
- public static bool EnableGCAccounting
- {
- get {
- return VTable.enableGCAccounting;
- }
- set {
- VTable.enableGCAccounting = value;
- if (value == true) {
- System.GCs.MemoryAccounting.Initialize(GC.gcType);
- }
- }
- }
-
- public static uint GCPerfCounter
- {
- get {
- return System.GC.perfCounter;
- }
- set {
- System.GC.perfCounter = value;
- }
- }
- }
-}
diff --git a/base/Applications/Runtime/Singularity/DebugStub.cs b/base/Applications/Runtime/Singularity/DebugStub.cs
deleted file mode 100644
index af809b2..0000000
--- a/base/Applications/Runtime/Singularity/DebugStub.cs
+++ /dev/null
@@ -1,337 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Debug.cs
-//
-// Note:
-//
-
-using System;
-using System.Collections;
-using System.Diagnostics;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-
-using Microsoft.Singularity.V1.Services;
-
-namespace Microsoft.Singularity
-{
- [NoCCtor]
- [CLSCompliant(false)]
- public class DebugStub
- {
- /////////////////////////////////////////////////////// Print Methods.
- //
- [NoHeapAllocation]
- public static void Print(byte value)
- {
- Print("{0:x2}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(ushort value)
- {
- Print("{0:x4}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(uint value)
- {
- Print("{0:x8}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(ulong value)
- {
- Print("{0:x}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(UIntPtr value)
- {
- Print("{0:x8}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(sbyte value)
- {
- Print("{0}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(short value)
- {
- Print("{0}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(int value)
- {
- Print("{0}", __arglist(value));
- }
-
- [NoHeapAllocation]
- public static void Print(long value)
- {
- Print("{0}", __arglist(value));
- }
-
- //////////////////////////////////////////////////////////////////////
- //
-
- [NoHeapAllocation]
- public static void Print(String value)
- {
- if (value != null) {
- Print(value, new ArgIterator());
- }
- }
-
- [NoHeapAllocation]
- public static void Print(String format, __arglist)
- {
- Print(format, new ArgIterator(__arglist));
- }
-
-#if PAGING
-[AccessedByRuntime("output to header : defined in debugstub.cpp")]
-[MethodImpl(MethodImplOptions.InternalCall)]
-[StackBound(64)]
-[NoHeapAllocation]
-public static extern void Foo();
-//static int ccc = 0;
-#endif
- [NoHeapAllocation]
- public static unsafe void Print(String format, ArgIterator args)
- {
-#if PAGING
-Foo();
-/*
-if (ccc == 0) {
- DebugStub.Break();
- ccc = 1;
-}
-*/
-#endif
- char *buffer;
- int length;
- int used = 0;
-
- DebugService.PrintBegin(out buffer, out length);
- try {
- if (buffer != null) {
- used = String.LimitedFormatTo(format, args, buffer, length);
- }
- }
- finally {
- DebugService.PrintComplete(buffer, used);
- }
- }
-
- //////////////////////////////////////////////////////////////////////
- //
-
- [NoHeapAllocation]
- public static void Write(String value)
- {
- if (value != null) {
- Write(value, new ArgIterator());
- }
- }
-
- [NoHeapAllocation]
- public static void Write(String format, __arglist)
- {
- Write(format, new ArgIterator(__arglist));
- }
-
- [NoHeapAllocation]
- public static unsafe void Write(String format, ArgIterator args)
- {
- char *buffer;
- int length;
- int used = 0;
-
- DebugService.PrintBegin(out buffer, out length);
- try {
- if (buffer != null) {
- used = String.LimitedFormatTo(format, args, buffer, length);
- }
- }
- finally {
- DebugService.PrintComplete(buffer, used);
- }
- }
-
- //////////////////////////////////////////////////////////////////////
- //
- [NoHeapAllocation]
- public static void WriteLine()
- {
- WriteLine("", new ArgIterator());
- }
-
- [NoHeapAllocation]
- public static void WriteLine(String value)
- {
- if (value != null) {
- WriteLine(value, new ArgIterator());
- }
- }
-
- [NoHeapAllocation]
- public static void WriteLine(String format, __arglist)
- {
- WriteLine(format, new ArgIterator(__arglist));
- }
-
- [NoHeapAllocation]
- public static unsafe void WriteLine(String format, ArgIterator args)
- {
- char *buffer;
- int length;
- int used = 0;
-
- DebugService.PrintBegin(out buffer, out length);
- try {
- if (buffer != null) {
- used = String.LimitedFormatTo(format, args, buffer, length);
- if (used < length) {
- buffer[used++] = '\n';
- }
- }
- }
- finally {
- DebugService.PrintComplete(buffer, used);
- }
- }
-
- ////////////////////////////////////////////////////// Assert Methods.
- //
- [NoHeapAllocation]
- public static void NotImplemented()
- {
- failAssert("Not implemented.");
- }
-
- [NoHeapAllocation]
- public static void NotImplemented(String msg)
- {
- failAssert(/*"Not implemented: "+*/msg);
- }
-
- [Conditional("DEBUG")]
- [NoInline]
- [NoHeapAllocation]
- public static void NotReached()
- {
- failAssert("Unreachable code reached.");
- }
-
- [Conditional("DEBUG")]
- [NoInline]
- [NoHeapAllocation]
- public static void NotReached(String msg)
- {
- failAssert(/*"Unreachable code reached: "+*/msg);
- }
-
- [Conditional("DEBUG")]
- [NoInline]
- [ManualRefCounts]
- [NoHeapAllocation]
- public static void Assert(bool expr)
- {
- if (!expr) {
- failAssert(null);
- }
- }
-
- [Conditional("DEBUG")]
- [NoInline]
- [ManualRefCounts]
- [NoHeapAllocation]
- public static void Deny(bool expr)
- {
- if (expr) {
- failAssert(null);
- }
- }
-
- [Conditional("DEBUG")]
- [NoInline]
- [ManualRefCounts]
- [NoHeapAllocation]
- public static void Assert(bool expr, String s)
- {
- if (!expr) {
- failAssert(s);
- }
- }
-
- [Conditional("DEBUG")]
- [NoInline]
- [NoHeapAllocation]
- public static void Deny(bool expr, String s)
- {
- if (expr) {
- failAssert(s);
- }
- }
-
- [ManualRefCounts]
- [NoHeapAllocation]
- private static void failAssert(String s)
- {
- if (s != null) {
- Print("Assertion failed: {0}", __arglist(s));
- }
- else {
- Print("Assertion failed.");
- }
- Break();
- }
-
- //////////////////////////////////////////////////////////////////////
- //
- [NoHeapAllocation]
- public static ulong ReadPerfCounter(uint which)
- {
- return DebugService.ReadPerfCounter(which);
- }
-
-
- [NoHeapAllocation]
- public static bool WritePerfCounter(uint which, ulong value)
- {
- return DebugService.WritePerfCounter(which, value);
- }
-
- [NoHeapAllocation]
- public static bool AddToPerfCounter(uint which, ulong value)
- {
- return DebugService.AddToPerfCounter(which, value);
- }
-
- /////////////////////////////////////////////////////// State Methods.
- //
-#if true
- [AccessedByRuntime("output to header : defined in halkd.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [StackBound(638)]
- [NoHeapAllocation]
- public static extern void Break();
-#else
- [NoHeapAllocation]
- public static void Break()
- {
- DebugService.Break();
- }
-#endif
- }
-}
diff --git a/base/Applications/Runtime/Singularity/Directory/NameService.sg b/base/Applications/Runtime/Singularity/Directory/NameService.sg
deleted file mode 100644
index 1118e59..0000000
--- a/base/Applications/Runtime/Singularity/Directory/NameService.sg
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: DirectoryService.sg
-//
-// Note:
-//
-// This file provides an implementation of Naming.DirectoryService.NewClientEndpoint
-// that calls through the ABI to retrieve the name-service channel endpoint.
-// This is for use by applications; kernel components can call the "real"
-// DirectoryService class directly.
-//
-
-using Microsoft.Singularity;
-using Microsoft.Singularity.Naming;
-using Microsoft.Singularity.V1.Services;
-
-namespace Microsoft.Singularity.Directory
-{
- public class DirectoryService
- {
- public static unsafe DirectoryServiceContract.Imp!:Ready NewClientEndpoint()
- {
- return (DirectoryServiceContract.Imp!)ProcessService.GetNamespaceEndpoint();
- }
- }
-}
diff --git a/base/Applications/Runtime/Singularity/Io/ConsoleInput.sg b/base/Applications/Runtime/Singularity/Io/ConsoleInput.sg
deleted file mode 100644
index 20d6e19..0000000
--- a/base/Applications/Runtime/Singularity/Io/ConsoleInput.sg
+++ /dev/null
@@ -1,318 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////////
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: ConsoleInput.sg
-//
-// Note: Read a line or a char of the Console
-//
-
-using DirectoryService.Utils;
-using System.GC;
-using System.Runtime.Remoting;
-using System.Threading;
-using System.Collections;
-using System.Diagnostics;
-using Microsoft.Singularity.V1.Services;
-
-
-namespace Microsoft.Singularity.Io {
- using Microsoft.SingSharp;
- using Microsoft.Singularity;
- using Microsoft.Singularity.V1.Services;
- using Microsoft.Singularity.V1.Threads;
- using Microsoft.Singularity.Channels;
- using Microsoft.Singularity.Directory;
-
- using System;
- using System.Text;
- using System.Globalization;
- using System.Runtime.CompilerServices;
-
- using Microsoft.Singularity.Extending;
- using Microsoft.Singularity.Runtime;
- using Microsoft.Singularity.Io;
- using System.Runtime.InteropServices;
-
-
-
- public sealed class ConsoleInput /* : ITracked, ISelectable */
- {
- private static TContainer consoleContainer;
- // protected by TContainer lock.
- private static char[]! readLineBuffer = new char[16];
-
- /*
-
- private char[]! in ExHeap side;
- private UnicodePipeContract.Exp conn;
- private int charCount;
- private int charPos;
-
- private ConsoleInput([Claims] UnicodePipeContract.Exp? pipe)
- {
- this.side = new[ExHeap] char [280];
- this.charCount = 0;
- this.charPos = 0;
- this.conn = pipe;
-
- base();
- }
- */
-
- private ConsoleInput() {}
-
- private static UnicodePipeContract.Exp? GetPipe()
- {
- UnicodePipeContract.Exp con = null;
-
- Endpoint * in ExHeap pipeep = Process.GetStartupEndpoint(0);
- if (pipeep != null) {
- con = pipeep as UnicodePipeContract.Exp;
- if (con == null) {
- // this cannot possibly work! the process is already started
-#if DEBUG
- DebugStub.WriteLine("ConsoleInput: slot 0 is not a pipe.");
-#endif
- Process.RetStartupEndpoint(0,pipeep);
- return null;
- }
- else {
- //DebugStub.WriteLine("ConsoleInput: connected to pipe.");
- return con;
- }
- }
- return null;
- }
-
-
- public static void Initialize()
- {
- UnicodePipeContract.Exp pipe = GetPipe();
- PipeLookAhead bufferedPipe = new PipeLookAhead(pipe, 100);
- ConsoleInput.consoleContainer = new TContainer(bufferedPipe);
- }
-
- /*
- public void Dispose()
- {
- delete this.side;
- delete this.conn;
- }
-
- void ITracked.Acquire() {
- Tracing.Log(Tracing.Debug,"ConsoleInput.Acquire");
- }
- void ITracked.Release() {
- Tracing.Log(Tracing.Debug,"ConsoleInput.Release");
- }
- void ITracked.Expose() {
- Tracing.Log(Tracing.Debug,"ConsoleInput.Expose");
- }
- void ITracked.UnExpose() {
- Tracing.Log(Tracing.Debug,"ConsoleInput.UnExpose");
- }
- */
-
- public static void Finalize()
- {
-#if DEBUG
- DebugStub.WriteLine("consoleInput: finalizer called");
-#endif
- // TContainer chandle = consoleContainer;
- TContainer chandle = consoleContainer;
- consoleContainer = null;
-
- if (chandle == null) return;
-
- PipeLookAhead co = chandle.Acquire();
- co.Dispose();
- }
-
- /*
- private int InternalReadChar()
- {
- expose (this) {
- if (this.conn != null) {
- if (this.charCount == 0) {
- UnicodePipeContract.Exp pipe = this.conn;
-
- tryAgain:
- switch receive {
- case pipe.Write(buffer,a,b):
- if (b == 0) {
- pipe.SendAckWrite(buffer);
- goto tryAgain;
- }
- if (b == 1) {
- int theChar = (int) buffer[a];
- pipe.SendAckWrite(buffer);
- return theChar;
- }
- else {
- // switch our buffer with theirs
- pipe.SendAckWrite(this.side);
- this.side = buffer;
- this.charPos = a+1;
- this.charCount = b-1;
- return (int)buffer[a];
- }
-
- case pipe.ChannelClosed():
- return -1;
- }
- }
- else {
- // there are more chars in the buffer
- int theChar = this.side[this.charPos++];
- this.charCount--;
- return theChar;
- }
- }
- } //expose
- return -1;
- }
- */
-
- public static void Close()
- {
- }
-
- public static int ReadChar()
- {
- if (consoleContainer == null) return -1;
- PipeLookAhead co = consoleContainer.Acquire();
- int key = co.ReadChar();
- if (key == -1) {
- co.Dispose();
- consoleContainer = null;
- return key;
- }
- consoleContainer.Release(co);
- return key;
- } //ReadChar
-
- ////////////////////////////////////////////////////////
- //
- public static string ReadLine()
- {
- if (consoleContainer == null) return null;
- PipeLookAhead bufferedPipe = consoleContainer.Acquire();
-
- int pos = 0;
- int key;
-
- do {
- key = bufferedPipe.ReadChar();
- if (key == -1) {
- bufferedPipe.Dispose();
- consoleContainer = null;
- return null;
- }
- if (key == '\r') {
- // DebugStub.WriteLine("key {0}", key);
- continue;
- }
- if (key == '\n') {
- // DebugStub.WriteLine("key {0}", key);
- break;
- }
- if (pos+1 >= readLineBuffer.Length){
- char[] temp = new char[readLineBuffer.Length *2];
- Array.Copy(readLineBuffer,temp,readLineBuffer.Length);
- readLineBuffer = temp;
- }
- readLineBuffer[pos++] = (char) key;
- if (key > 31 && key < 126) {
- // DebugStub.WriteLine("key {0}", key);
- }
- } while (key != -1 );
-
- string s = new string(readLineBuffer,0,pos);
- //DebugStub.WriteLine("in: count={0}, s=({1})",__arglist(pos, s));
-
- consoleContainer.Release(bufferedPipe);
- return s;
- } //ReadLine
-
- /*
- internal enum ReceiveTag {
- Any = 1,
- GetChar = 2,
- }
-
- [Selectable((int)ReceiveTag.GetChar)]
- public void RecvGetChar(out int key) {
- key = this.InternalReadChar();
- }
-
- ///
- /// Tests if the message at the head of the queue matches the given tag. If so,
- /// returns true.
- ///
- /// If no match is possible in the future given the current message, possible must
- /// be set to false.
- /// Implementations are disallowed from setting possible to true
- /// so that the context can chain them.
- ///
- /// If the underlying object is an endpoint set, it also returns an object that
- /// serves to extract the endpoint having the match from the set later.
- ///
- /// Again, implementations are disallowed from setting match setMatch to null
- /// so that the context can chain the calls.
- ///
- ///
- bool ISelectable.HeadMatches(int tag, ref bool possible, ref object setMatch) {
- // Only handle pipe case
- expose (this) {
- if (this.conn != null) {
- if (this.charCount == 0) {
- UnicodePipeContract.Exp pipe = this.conn;
-
- // negative tag is channel closed
- int pipeTag = (tag < 0)?tag : UnicodePipeContract.Tags.Write;
-
- return pipe.HeadMatches(pipeTag, ref possible, ref setMatch);
- }
- else {
- // there are more chars in the buffer
- if (tag < 0) {
- // not closed
- possible = false;
- return false;
- }
- return true;
- }
- }
- else {
- // no pipe
- possible = false;
- return false;
- }
- } //expose
- }
-
- SyncHandle ISelectable.GetWaitHandle() {
- expose (this) {
- assert(this.conn != null);
- return this.conn.GetWaitHandle();
- }
- }
-
- */
- public static PipeLookAhead! AcquireInput() {
- assert consoleContainer != null;
-
- PipeLookAhead bufferedPipe = consoleContainer.Acquire();
- return bufferedPipe;
- }
-
- public static void ReleaseInput([Claims] PipeLookAhead! bufferedPipe) {
- assert consoleContainer != null;
-
- consoleContainer.Release(bufferedPipe);
- }
-
- } //ConsoleInput
-}//namespace
diff --git a/base/Applications/Runtime/Singularity/Io/ConsoleOutput.sg b/base/Applications/Runtime/Singularity/Io/ConsoleOutput.sg
deleted file mode 100644
index 9fbdeb9..0000000
--- a/base/Applications/Runtime/Singularity/Io/ConsoleOutput.sg
+++ /dev/null
@@ -1,461 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: ConsoleOutput.sg
-//
-// Note: Uses /dev/conout to display console output.
-//
-
-namespace Microsoft.Singularity.Io {
- using Microsoft.SingSharp;
- using Microsoft.Singularity;
- using Microsoft.Singularity.V1.Services;
- using Microsoft.Singularity.Channels;
- using Microsoft.Singularity.Directory;
-
- using System;
- using System.Text;
- using System.Globalization;
- using System.Runtime.CompilerServices;
-
- using System.Runtime.InteropServices;
-
- public sealed class ConsoleOutput : ITracked
- {
- private static TContainer consoleContainer;
-
- private struct PipeData : ITracked {
- public UnicodePipeContract.Imp channel;
- public void Dispose()
- {
- delete channel;
- }
- void ITracked.Acquire() {}
- void ITracked.Release() {}
- public void Expose() {}
- public void UnExpose() {}
-
- public UnicodePipeContract.Imp:READY Swap([Claims] UnicodePipeContract.Imp:READY newPipe) {
- expose (this) {
- UnicodePipeContract.Imp result = this.channel;
- this.channel = newPipe;
- return result;
- }
- }
- }
-
- /*
- private struct DeviceData : ITracked {
- public ConsoleDeviceContract.Imp:Ready channel;
- public void Dispose()
- {
- delete channel;
- }
- void ITracked.Acquire() {}
- void ITracked.Release() {}
- public void Expose() {}
- public void UnExpose() {}
- }
- */
-
- private char[]! in ExHeap side;
- private PipeData pipe;
- /*
- private DeviceData device;
- */
- private ConsoleOutput([Claims] UnicodePipeContract.Imp? pipe)
- {
- this.side = new[ExHeap] char [280];
- this.pipe.channel = pipe;
- }
-
- private static UnicodePipeContract.Imp GetPipe()
- {
- UnicodePipeContract.Imp con = null;
-
- Endpoint* in ExHeap pipeep = Process.GetStartupEndpoint(1);
- if (pipeep != null) {
- con = pipeep as UnicodePipeContract.Imp;
- if (con == null) {
- Process.RetStartupEndpoint(1,pipeep);
- return null;
- }
- return con;
- }
- return null;
- }
-
- public static void Initialize()
- {
- /*
- ConsoleDeviceContract.Imp imp = null;
-
- imp = OpenConsole("/dev/video-text");
- if (imp == null) {
- imp = OpenConsole("/dev/conout");
- if (imp == null) {
- DebugStub.Print("Couldn't open console.\n");
- return;
- }
- }
- */
- UnicodePipeContract.Imp pipe = GetPipe();
- ConsoleOutput co = new ConsoleOutput(pipe);
- consoleContainer = new TContainer(co);
- }
-
- public void Dispose()
- {
- this.pipe.Dispose();
- // this.device.Dispose();
- delete this.side;
- }
-
- void ITracked.Acquire() {
- //Tracing.Log(Tracing.Debug,"ConsoleOutput.Acquire");
- }
- void ITracked.Release() {
- //Tracing.Log(Tracing.Debug,"ConsoleOutput.Release");
- }
- void ITracked.Expose() {
- //Tracing.Log(Tracing.Debug,"ConsoleOutput.Expose");
- }
- void ITracked.UnExpose() {
- //Tracing.Log(Tracing.Debug,"ConsoleOutput.UnExpose");
- }
-
- public static void Finalize()
- {
- TContainer chandle = consoleContainer;
- consoleContainer = null;
-
- if (chandle == null) return;
-
- ConsoleOutput co = chandle.Acquire();
- if (co != null) co.Dispose();
- }
-
- /*
- private static ConsoleDeviceContract.Imp
- OpenConsoleInternal(DirectoryServiceContract.Imp! nsImp,
- [Claims] char[]! in ExHeap deviceName)
- {
- ConsoleDeviceContract.Exp! exp;
- ConsoleDeviceContract.Imp! imp;
- ConsoleDeviceContract.NewChannel(out imp, out exp);
-
- nsImp.SendBind(deviceName, exp);
- switch receive
- {
- case nsImp.AckBind():
- return imp;
- break;
- case nsImp.NakBind(rejectImp, error):
- delete rejectImp;
- delete imp;
- break;
- case nsImp.ChannelClosed():
- throw new Exception("Channel closed during Console bind.");
- delete imp;
- break;
- case nsImp.NakBindReparse(path, rest, linked, backExp):
- assert linked == true;
- assert rest == null;
- delete backExp;
- delete imp;
-
- return OpenConsoleInternal(nsImp, path);
- break;
- }
- return null;
- }
-
- private static ConsoleDeviceContract.Imp OpenConsole(string! devName)
- {
- DirectoryServiceContract.Imp ns = DirectoryService.NewClientEndpoint();
- ConsoleDeviceContract.Imp imp =
- OpenConsoleInternal(ns, Bitter.FromString2(devName));
- delete ns;
-
- if (imp != null) {
- switch receive
- {
- case imp.Success():
- break;
- case imp.ContractNotSupported():
- throw new Exception("ConsoleOutput: ContractNotSupported");
- break;
- case imp.ChannelClosed():
- throw new Exception("ConsoleOutput: ChannelClosed");
- break;
- }
- }
- return imp;
- }
-
- public static void Clear()
- {
- if (consoleContainer == null) return;
-
- ConsoleOutput co = consoleContainer.Acquire();
-
- expose (co) {
- ConsoleDeviceContract.Imp ep = co.device.channel;
- if (ep != null)
- {
- ep.SendClear();
- switch receive
- {
- case ep.AckClear():
- break;
- case ep.NakClear():
- break;
- case ep.ChannelClosed():
- delete ep;
- co.device.channel = null;
- break;
- }
- }
- }
- consoleContainer.Release(co);
- }
-
- public static void CursorFlash()
- {
- if (consoleContainer == null) return;
-
- ConsoleOutput co = consoleContainer.Acquire();
-
- expose (co) {
- ConsoleDeviceContract.Imp ep = co.device.channel;
- if (ep != null)
- {
- ep.SendCursorFlash();
- switch receive
- {
- case ep.AckCursorFlash():
- break;
- case ep.NakCursorFlash():
- break;
- case ep.ChannelClosed():
- delete ep;
- co.device.channel = null;
- break;
- }
- }
- }
- consoleContainer.Release(co);
- }
-
- public static void CursorHide()
- {
- if (consoleContainer == null) return;
-
- ConsoleOutput co = consoleContainer.Acquire();
-
- expose (co) {
- ConsoleDeviceContract.Imp ep = co.device.channel;
- if (ep != null) {
- ep.SendCursorHide();
- switch receive {
- case ep.AckCursorHide():
- break;
- case ep.NakCursorHide():
- break;
- case ep.ChannelClosed():
- delete ep;
- co.device.channel = null;
- break;
- }
- }
- }
- consoleContainer.Release(co);
- }
-
- public static void CursorShow()
- {
- if (consoleContainer == null) return;
-
- ConsoleOutput co = consoleContainer.Acquire();
-
- expose (co) {
- ConsoleDeviceContract.Imp ep = co.device.channel;
- if (ep != null) {
- ep.SendCursorShow();
- switch receive {
- case ep.AckCursorShow():
- break;
- case ep.NakCursorShow():
- break;
- case ep.ChannelClosed():
- delete ep;
- co.device.channel = null;
- break;
- }
- }
- }
- consoleContainer.Release(co);
- }
- */
-
- public static char[]! in ExHeap Write([Claims] char[]! in ExHeap buffer,
- int index, int count)
- {
- if (consoleContainer == null) return buffer;
- ConsoleOutput co = consoleContainer.Acquire();
- try {
- expose (co) {
- if (co.pipe.channel != null) {
- return Write(buffer, index, count, ref co.pipe);
- }
- else {
- return buffer;
- }
- }
- }
- finally {
- consoleContainer.Release(co);
- }
- }
-
- /*
- private static char[]! in ExHeap Write([Claims] char[]! in ExHeap buffer,
- int index, int count,
- ref DeviceData device)
- {
- expose (device) {
- ConsoleDeviceContract.Imp channel = device.channel;
- if (channel != null)
- {
- channel.SendWrite(buffer, index, count);
- switch receive {
- case channel.AckWrite(localside):
- return localside;
-
- case channel.NakWrite(localside):
- return localside;
-
- case channel.ChannelClosed():
- delete channel;
- device.channel = null;
- return new[ExHeap] char[0];
- }
- }
- else {
- return buffer;
- }
- }
- }
- */
-
- private static char[]! in ExHeap Write([Claims] char[]! in ExHeap buffer,
- int index, int count,
- ref PipeData pipe)
- {
- expose (pipe) {
- UnicodePipeContract.Imp channel = pipe.channel;
- if (channel != null) {
- // char[]! in ExHeap buffer=Bitter.FromString2(value);
- channel.SendWrite(buffer, index, count);
- switch receive {
- case channel.AckWrite(i_buffer):
- return i_buffer;
-
- case channel.ChannelClosed():
- delete channel;
- pipe.channel = null;
- return new[ExHeap] char[0];
-
- case unsatisfiable:
- DebugStub.Break();
- throw new Exception("Pipe unsatisfiable ");
- }
- }
- else {
- return buffer;
- }
- }
- }
-
- public static void Write(char[]! buffer, int index, int count)
- {
- if (consoleContainer == null) return;
-
- ConsoleOutput co = consoleContainer.Acquire();
-
- expose (co) {
- char[] in ExHeap side = co.side;
-
- if (side.Length < count) {
- delete side;
- co.side = side = new[ExHeap] char [count];
- }
-
- for (int i = 0; i < count; i++) {
- side[i] = buffer[index + i];
- }
-
- if (co.pipe.channel != null) {
- co.side = Write(side, index, count, ref co.pipe);
- }
- /*
- else {
- co.side = Write(side, index, count, ref co.device);
- }
- */
- }
- consoleContainer.Release(co);
- }
-
- public static void Write(String! value)
- {
- if (consoleContainer == null) return;
-
- ConsoleOutput co = consoleContainer.Acquire();
-
- expose (co) {
-
- char[] in ExHeap side = co.side;
- if (side.Length < value.Length) {
- delete side;
- co.side = side = new[ExHeap] char [value.Length];
- }
-
- for (int i = 0; i < value.Length; i++) {
- side[i] = value[i];
- }
-
- if (co.pipe.channel != null) {
- co.side = Write(side, 0, value.Length, ref co.pipe);
- }
- /*
- else {
- co.side = Write(side, 0, value.Length, ref co.device);
- }
- */
- }
- consoleContainer.Release(co);
- return;
- }
-
- public static UnicodePipeContract.Imp:READY Swap([Claims] UnicodePipeContract.Imp:READY newOutput) {
- if (consoleContainer == null) {
- delete newOutput;
- return null;
- }
-
- ConsoleOutput co = consoleContainer.Acquire();
-
- UnicodePipeContract.Imp result;
- expose(co) {
- result = co.pipe.Swap(newOutput);
- }
- consoleContainer.Release(co);
- return result;
- }
-
- }
-}
diff --git a/base/Applications/Runtime/Singularity/Memory/Stacks.cs b/base/Applications/Runtime/Singularity/Memory/Stacks.cs
deleted file mode 100644
index 5388274..0000000
--- a/base/Applications/Runtime/Singularity/Memory/Stacks.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Stacks.cs - Primitive stack segment manager
-//
-// Note:
-//
-
-namespace Microsoft.Singularity.Memory {
-
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using Microsoft.Singularity;
- using Microsoft.Singularity.X86;
- using Microsoft.Singularity.V1.Services;
-
- [NoCCtor]
- [CLSCompliant(false)]
- [RequiredByBartok]
- internal class Stacks {
-
- internal static unsafe void Initialize()
- {
- DebugStub.Print("Stacks.Initialize() called\n");
- }
-
- internal static unsafe void Finalize()
- {
- DebugStub.Print("Stacks.Finalize() called\n");
- }
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack0(); // Copy 0 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack4(); // Copy 4 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack8(); // Copy 8 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack12(); // Copy 12 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack16(); // Copy 16 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack20(); // Copy 20 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack24(); // Copy 24 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack28(); // Copy 28 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack32(); // Copy 32 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack36(); // Copy 36 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack40(); // Copy 40 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack44(); // Copy 44 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack48(); // Copy 48 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack52(); // Copy 52 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack56(); // Copy 56 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack60(); // Copy 60 bytes of arguments on stack.
-
- [StackBound(64)]
- [NoStackLinkCheck]
- [NoStackOverflowCheck]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RequiredByBartok]
- internal static extern void LinkStack64(); // Copy 64 bytes of arguments on stack.
-
- [ExternalStaticData]
- internal static byte UnlinkStackBegin;
-
- [ExternalStaticData]
- internal static byte UnlinkStackLimit;
- }
-}
diff --git a/base/Applications/Runtime/Singularity/Naming/NameService.sg b/base/Applications/Runtime/Singularity/Naming/NameService.sg
deleted file mode 100644
index c7ecf1f..0000000
--- a/base/Applications/Runtime/Singularity/Naming/NameService.sg
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: DirectoryService.sg
-//
-// Note:
-//
-// This file provides an implementation of Directory.DirectoryService.NewClientEndpoint
-// that calls through the ABI to retrieve the name-service channel endpoint.
-// This is for use by applications; kernel components can call the "real"
-// DirectoryService class directly.
-//
-
-using Microsoft.Singularity;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.V1.Services;
-
-namespace Microsoft.Singularity.Directory
-{
- public class DirectoryService
- {
- public static unsafe DirectoryServiceContract.Imp!:Ready NewClientEndpoint()
- {
- return (DirectoryServiceContract.Imp!)ProcessService.GetNamespaceEndpoint();
- }
- }
-}
diff --git a/base/Applications/Runtime/Singularity/Processor.cs b/base/Applications/Runtime/Singularity/Processor.cs
deleted file mode 100644
index 9ef1c6f..0000000
--- a/base/Applications/Runtime/Singularity/Processor.cs
+++ /dev/null
@@ -1,237 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Processor.cs
-//
-// Note:
-//
-
-namespace Microsoft.Singularity
-{
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Threading;
-
- using Microsoft.Singularity.X86;
- using Microsoft.Singularity.V1.Services;
-
- [CLSCompliant(false)]
- [NoCCtor]
- public class Processor
- {
- public static long CyclesPerSecond
- {
- [NoHeapAllocation]
- get { return ProcessService.GetCyclesPerSecond(); }
- }
-
- public static ulong CycleCount
- {
- [NoHeapAllocation]
- get { return GetCycleCount(); }
- }
-
- //////////////////////////////////////////////////// External Methods.
- //
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [StackBound(32)]
- [NoHeapAllocation]
- public static extern ulong GetCycleCount();
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static unsafe extern UIntPtr GetFrameEip(UIntPtr ebp);
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static unsafe extern UIntPtr GetFrameEbp(UIntPtr ebp);
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static extern UIntPtr GetStackPointer();
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static extern UIntPtr GetFramePointer();
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static unsafe extern ThreadContext * GetCurrentThreadContext();
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static unsafe extern ProcessorContext * GetCurrentProcessorContext();
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static extern Thread GetCurrentThread();
-
- //////////////////////////////////////////////////////////////////////////////
- //
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(16)]
- [NoHeapAllocation]
- public static extern void WriteMsr(uint offset,
- ulong value);
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(16)]
- [NoHeapAllocation]
- public static extern ulong ReadMsr(uint offset);
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(64)]
- [NoHeapAllocation]
- public static extern void ReadCpuid(uint feature,
- out uint v0,
- out uint v1,
- out uint v2,
- out uint v3);
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(16)]
- [NoHeapAllocation]
- public static extern ulong ReadPmc(uint offset);
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(32)]
- [NoHeapAllocation]
- internal static extern void EnterRing3();
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(32)]
- [NoHeapAllocation]
- public static extern bool AtKernelPrivilege();
-
- //////////////////////////////////////////////////////////////////////
- //
- //
- // These methods are currently marked external because they are used
- // by device drivers. We need a tool to verify that device drivers
- // are in fact using them correctly!
- //
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(16)]
- [NoHeapAllocation]
- public static extern bool DisableInterrupts();
-
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(16)]
- [NoHeapAllocation]
- public static extern void RestoreInterrupts(bool enabled);
-
- // Use this method for assertions only!
- [AccessedByRuntime("output to header : defined in Processor.cpp")]
- [MethodImpl(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(16)]
- [NoHeapAllocation]
- public static extern bool InterruptsDisabled();
-
- //////////////////////////////////////////////////////////////////////
- //
- //
- // These methods are public and safe to use from any where provided
- // there's at least 2 call frame on the stack.
- //
- [NoHeapAllocation]
- public static UIntPtr GetCallerEip()
- {
- UIntPtr currentFrame = GetFramePointer();
- UIntPtr callerFrame = GetFrameEbp(currentFrame);
- if (callerFrame == UIntPtr.Zero) {
- return UIntPtr.Zero;
- }
- UIntPtr callersCaller = GetFrameEip(callerFrame);
- return callersCaller;
- }
-
- ///
- /// Provides a mini stack trace starting from the caller of the caller
- /// of this method.
- ///
- [NoHeapAllocation]
- public static void GetStackEips(out UIntPtr pc1, out UIntPtr pc2, out UIntPtr pc3)
- {
- pc1 = UIntPtr.Zero;
- pc2 = UIntPtr.Zero;
- pc3 = UIntPtr.Zero;
-
- UIntPtr currentFrame = GetFramePointer();
- UIntPtr callerFrame = GetFrameEbp(currentFrame);
- if (callerFrame == UIntPtr.Zero) {
- return;
- }
- pc1 = GetFrameEip(callerFrame);
- callerFrame = GetFrameEbp(callerFrame);
- if (callerFrame == UIntPtr.Zero) {
- return;
- }
- pc2 = GetFrameEip(callerFrame);
- callerFrame = GetFrameEbp(callerFrame);
- if (callerFrame == UIntPtr.Zero) {
- return;
- }
- pc3 = GetFrameEip(callerFrame);
- }
-
- ///
- /// Provides the full stack trace starting from the caller of the caller
- /// of this method.
- ///
- /// Eip values in stack array from top to bottom
- [NoHeapAllocation]
- public static void GetStackEips(UIntPtr[] stack)
- {
- if (stack == null) {
- return;
- }
- UIntPtr currentFrame = GetFramePointer();
- UIntPtr callerFrame = GetFrameEbp(currentFrame);
- for (int index = 0; callerFrame != UIntPtr.Zero && index < stack.Length; index++) {
- stack[index] = GetFrameEip(callerFrame);
- callerFrame = GetFrameEbp(callerFrame);
- }
- }
- }
-}
diff --git a/base/Applications/Runtime/System/Console.cs b/base/Applications/Runtime/System/Console.cs
deleted file mode 100644
index 0cd4eb6..0000000
--- a/base/Applications/Runtime/System/Console.cs
+++ /dev/null
@@ -1,319 +0,0 @@
-// ==++==
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// ==--==
-
-namespace System {
- using Microsoft.Singularity;
-#if !MINRUNTIME
- using Microsoft.Singularity.Io;
-#endif
- using System;
- using System.Text;
- using System.Globalization;
- using System.Runtime.CompilerServices;
-
- using System.Runtime.InteropServices;
-
- // Provides static fields for console input and output. Use
- // Console.In for input from the standard input stream (stdin),
- // Console.Out for output to stdout, and Console.Error
- // for output to stderr. If any of those console streams are
- // redirected from the command line, these streams will be redirected.
- // A program can also redirect its own output or input with the
- // SetIn, SetOut, and SetError methods.
- //
- // The distinction between Console.Out and Console.Error is useful
- // for programs that redirect output to a file or a pipe. Note that
- // stdout and stderr can be output to different files at the same
- // time from the DOS command line:
- //
- // someProgram 1> out 2> err
- //
- //|
- public sealed class Console
- {
- private Console()
- {
- throw new NotSupportedException("NotSupported_Constructor");
- }
-
- static Console() {
- }
-
-
- private static void WriteInternal(char[] buffer, int index, int count)
- {
-#if !MINRUNTIME
- ConsoleOutput.Write(buffer, index, count);
-#else
- for (int i = 0; i < count; i++) {
- DebugStub.Print(buffer[index + i]);
- }
-#endif
- }
-
- private static void WriteInternal(String value)
- {
-#if !MINRUNTIME
- ConsoleOutput.Write(value);
-#else
- DebugStub.Print(value);
-#endif
- }
-
- private static void WriteNewLine()
- {
- WriteInternal(Environment.NewLine);
- }
-
- //|
- public static void WriteLine()
- {
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(String value)
- {
- WriteInternal(value);
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(bool value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(char value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(char[] buffer)
- {
- WriteInternal(buffer, 0, buffer.Length);
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(char[] buffer, int index, int count)
- {
- WriteInternal(buffer, index, count);
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(decimal value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(double value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(float value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(int value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- [CLSCompliant(false)]
- public static void WriteLine(uint value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(long value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- [CLSCompliant(false)]
- public static void WriteLine(ulong value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(Object value)
- {
- WriteInternal(value.ToString());
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(String format, Object arg0)
- {
- WriteInternal(String.Format(format, arg0));
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(String format, Object arg0, Object arg1)
- {
- WriteInternal(String.Format(format, arg0, arg1));
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(String format, Object arg0, Object arg1, Object arg2)
- {
- WriteInternal(String.Format(format, arg0, arg1, arg2));
- WriteNewLine();
- }
-
- //|
- public static void WriteLine(String format, params Object[] args)
- {
- WriteInternal(String.Format(format, args));
- WriteNewLine();
- }
-
- //|
- public static void Write(String format, Object arg0)
- {
- WriteInternal(String.Format(format, arg0));
- }
-
- //|
- public static void Write(String format, Object arg0, Object arg1)
- {
- WriteInternal(String.Format(format, arg0, arg1));
- }
-
- //|
- public static void Write(String format, Object arg0, Object arg1, Object arg2)
- {
- WriteInternal(String.Format(format, arg0, arg1, arg2));
- }
-
- //|
- public static void Write(String format, params Object[] args)
- {
- WriteInternal(String.Format(format, args));
- }
-
- //|
- public static void Write(bool value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(char value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(char[] buffer)
- {
- WriteInternal(buffer, 0, buffer.Length);
- }
-
- //|
- public static void Write(char[] buffer, int index, int count)
- {
- WriteInternal(buffer, index, count);
- }
-
- //|
- public static void Write(double value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(decimal value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(float value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(int value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- [CLSCompliant(false)]
- public static void Write(uint value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(long value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- [CLSCompliant(false)]
- public static void Write(ulong value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(Object value)
- {
- WriteInternal(value.ToString());
- }
-
- //|
- public static void Write(String value)
- {
- WriteInternal(value);
- }
-
- public static int Read()
- {
-#if !MINRUNTIME
- return ConsoleInput.ReadChar();
-#else
- return -1;
-#endif
- }
- public static string ReadLine()
- {
-#if !MINRUNTIME
- return ConsoleInput.ReadLine();
-#else
- return "";
-#endif
- }
- }
-}
diff --git a/base/Applications/Runtime/System/Environment.cs b/base/Applications/Runtime/System/Environment.cs
deleted file mode 100644
index 9eb2883..0000000
--- a/base/Applications/Runtime/System/Environment.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-// ==++==
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// ==--==
-/*============================================================
-**
-** Class: Environment
-**
-**
-** Purpose: Provides some basic access to some environment
-** functionality.
-**
-** Date: March 3, 2000
-**
-============================================================*/
-namespace System {
- using System.Globalization;
- using System.Collections;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Reflection;
- using System.Diagnostics;
- using Microsoft.Singularity;
- using Microsoft.Singularity.V1.Services;
-
- //|
- public sealed class Environment {
-
- private Environment() {} // Prevent from begin created
-
- /*==================================TickCount===================================
- **Action: Gets the number of ticks since the system was started.
- **Returns: The number of ticks since the system was started.
- **Arguments: None
- **Exceptions: None
- ==============================================================================*/
- //|
- public static int TickCount {
- get {
- return unchecked((int)(ProcessService.GetUpTime().Ticks / 10000));
- }
- }
-
- /*===================================NewLine====================================
- **Action: A property which returns the appropriate newline string for the given
- ** platform.
- **Returns: \r\n on Win32.
- **Arguments: None.
- **Exceptions: None.
- ==============================================================================*/
- //|
- public static String NewLine {
- get {
- return "\r\n";
- }
- }
-
- //|
- public static void Exit(int exitCode) {
- ProcessService.Stop(exitCode);
- }
-
- //
- public static String StackTrace
- {
- get {
- return "
- [CCtorIsRunDuringStartup]
- [StructLayout(LayoutKind.Sequential)]
- [CLSCompliant(false)]
- [RequiredByBartok]
- public sealed class Thread
- {
- // Singularity specific fields
- // Need CPU context
- // Need stack
-
- // Bartok specific fields
- [RequiredByBartok] // Thread-specific alloc heap
- internal SegregatedFreeList segregatedFreeList;
- [RequiredByBartok] // Thread-specific bump allocator
- internal BumpAllocator bumpAllocator;
-
- internal AutoResetEvent processGcEvent;
-
- private AutoResetEvent autoEvent;
- private ManualResetEvent joinEvent;
-
- internal Thread blockingCctorThread;
-
- // Singularity specific fields
- [AccessedByRuntime("referenced from halforgc.asm")]
- internal unsafe ThreadContext * context;
- internal ThreadHandle threadHandle;
-
- // Most recently thrown exception object that the thread
- // did not catch at all (i.e. that propagated to the bottom
- // of the stack or to a kernel/process boundary without
- // encountering an appropriate catch clause).
- private Exception lastUncaughtException;
-
- private bool ignoredByJoinAll; // for "service" threads
-
- private Object m_ExceptionStateInfo; // Exception info latched to the thread on a thread abort
-
- // Bartok specific fields
- internal Thread nextThread; // Link for linked lists of threads
-
- // This array is of length 1 and contains a queue item for this
- // thread. It allows WaitOne and the scheduler to add this thread
- // to their queues without allocating memory.
- internal ThreadQueueItem[] singleQueueItem;
-
- // MultiUseWord (object header) fields.
- internal UIntPtr externalMultiUseObjAllocListHead;
- internal UIntPtr externalMultiUseObjAllocListTail;
-
- // Bartok specific fields
- internal int threadIndex;
- private ThreadStart threadStart;
- private ThreadState threadState;
- internal int waitingCriticalSectionDepth;
- internal Object waitingObject; // Not used, but useful for debugging
-
- [RequiredByBartok]
- internal TryAllManager tryAllManager;
-
- private static bool closing;
- private static long totalArrayAllocations;
- private static long totalArrayBytesAllocated;
- private static long totalBytes;
- private static long totalStructBytesAllocated;
-
- internal static Thread[] threadTable;
- private static SpinLock threadTableLock;
-
- private static LocalDataStore localDataStore;
-
- internal static Thread initialThread;
-
- // This is used by the Bartok backend. When Bartok tries to generate
- // callback stub for delegate, it checks to see if it is
- // ThreadProc, if it is not, Bartok adds leaveGCSafeState and
- // enterGCSafeState around the delegate call.
- [RequiredByBartok]
- private unsafe delegate uint ThreadProc(void *param);
-
- /*=========================================================================
- ** This manager is responsible for storing the global data that is
- ** shared amongst all the thread local stores.
- =========================================================================*/
- static private LocalDataStoreMgr m_LocalDataStoreMgr;
-
- internal const int maxThreads = 1024; // Must be power of 2 >= 64
- private static int threadIndexGenerator;
-
- /*=========================================================================
- ** Creates a new Thread object which will begin execution at
- ** start.ThreadStart on a new thread when the Start method is called.
- **
- ** Exceptions: ArgumentNullException if start == null.
- =========================================================================*/
- //|
- public unsafe Thread(ThreadStart start)
- {
- Tracing.Log(Tracing.Audit, "Application Thread()");
-
- if (start == null) {
- throw new ArgumentNullException("start");
- }
-
- threadIndex = -1;
- threadState = ThreadState.Unstarted;
- threadStart = start;
-
- // Create the event for the thread to wait upon
- autoEvent = new AutoResetEvent(false);
- joinEvent = new ManualResetEvent(false);
- processGcEvent = new AutoResetEvent(false);
- singleQueueItem = new ThreadQueueItem [1] { new ThreadQueueItem(this) };
-
- // Find a usable entry in the thread table
- bool disabled = Processor.DisableInterrupts();
- Thread.threadTableLock.Acquire(CurrentThread);
- try {
- for (int i = 0; i < threadTable.Length; i++) {
- int index = (threadIndexGenerator + i) % threadTable.Length;
- if (threadTable[index] == null) {
- threadTable[index] = this;
- this.threadIndex = index;
- threadIndexGenerator = index + 1;
- // NB: We call this once, afterwards the GC visitor calls it.
- break;
- }
- }
- } finally {
- Thread.threadTableLock.Release(CurrentThread);
- Processor.RestoreInterrupts(disabled);
- }
-
- VTable.Assert(threadIndex >= 0, "Out of thread slots!");
-
- //MemoryBarrier();
-
- // Must check closing after being insert into table to avoid race condition.
- if (closing) {
- threadState = ThreadState.Stopped;
- joinEvent.Set();
- Tracing.Log(Tracing.Warning, "Aborting: Runtime closing.");
- return;
- }
-
- ThreadHandle handleOnStack;
- UIntPtr threadContext;
- if (!ThreadHandle.Create(threadIndex,
- new ContainerHandle(),
- out handleOnStack,
- out threadContext)) {
- Tracing.Log(Tracing.Warning, "Aborting: ThreadHandle.Create failed.");
- threadState = ThreadState.Stopped;
- joinEvent.Set();
- return;
- }
- this.threadHandle = handleOnStack;
- this.context = (ThreadContext *) threadContext;
- this.context->threadIndex = unchecked((ushort) threadIndex);
- this.context->UpdateAfterGC(this);
- }
-
-
-
- ///
- /// Finalizer is responsible for freeing handle that keeps corresponding
- /// kernel object live.
- ///
- ~Thread() {
- if (this.threadHandle.id != 0) {
- ThreadHandle.Dispose(this.threadHandle);
- this.threadHandle = new ThreadHandle();
- }
- }
-
- /*=========================================================================
- ** Spawns off a new thread which will begin executing at the ThreadStart
- ** method on the IThreadable interface passed in the constructor. Once the
- ** thread is dead, it cannot be restarted with another call to Start.
- **
- ** Exceptions: ThreadStateException if the thread has already been started.
- =========================================================================*/
- //|
- public void Start()
- {
- lock ((Object) this) {
- if (closing) {
- throw new ThreadStateException("Cannot start thread when closing");
- }
-
- ThreadState oldState = threadState;
- if (oldState != ThreadState.Unstarted) {
- throw new ThreadStateException("Cannot start thread in state "+oldState);
- }
-
- threadState = ThreadState.Running;
-
- // Tell the GC that we have created the thread
- GC.NewThreadNotification(this, false);
-
- ThreadHandle.Start(threadHandle);
- GC.KeepAlive(this);
- }
- }
-
- // HalInitContext sets ThreadStub as the first process code to be
- // executed in a new thread context.
- [AccessedByRuntime("referenced from hal.cpp")]
- private static unsafe void ThreadStub(int threadIndex)
- {
- Transitions.ThreadStart();
- GC.ThreadStartNotification(threadIndex);
- Thread currentThread = threadTable[threadIndex];
- if (AddThread(threadIndex)) {
- Tracing.Log(Tracing.Audit, "ThreadStub(atid={0}) Entered",
- (UIntPtr)unchecked((uint)threadIndex));
-
- ThreadStart startFun = currentThread.threadStart;
-
- try {
- startFun();
- } catch (Exception e) {
- DebugStub.WriteLine("Thread {0} failed with exception {1}\n",
- __arglist(threadIndex, e));
- currentThread.lastUncaughtException = e;
- VTable.Assert(e == null, "Thread "+threadIndex+
- " failed with exception "+e);
- }
- Tracing.Log(Tracing.Audit, "ThreadStub(atid={0}) Exiting",
- (UIntPtr)unchecked((uint)threadIndex));
- }
-
- currentThread.joinEvent.Set();
- RemoveThread(threadIndex);
- GC.DeadThreadNotification(currentThread);
-
- bool disabled = Processor.DisableInterrupts();
- // this is a dangerous locking strategy as the transition code
- // may decide it needs to wake up another thread.
- Thread.threadTableLock.Acquire(currentThread);
- try {
- Transitions.ThreadEnd(threadIndex);
- // You may not do any calls out of proc after this point!
- threadTable[threadIndex] = null;
- Transitions.DeadThreadNotification(threadIndex);
- } finally {
- Thread.threadTableLock.Release(currentThread);
- Processor.RestoreInterrupts(disabled);
- }
- }
-
- /*====================================================================
- * Support for service threads. Service threads should not count
- * towards keeping a process alive. When all non-service threads
- * have terminated, the service threads are asked to stop themselves
- * so the process can terminate gracefully.
- *===================================================================*/
-
- // The number of non-service threads running in the process
- private static int threadCount;
- private static Object notificationTableObject;
- private static Object[] notificationTable;
-
- public delegate void StopServiceNotice();
-
- public void MakeServiceThread(StopServiceNotice notification)
- {
- Tracing.Log(Tracing.Audit, "MakeServiceThread {0}",
- (UIntPtr) threadIndex);
- if (this != Thread.CurrentThread) {
- throw new Exception("Only the thread itself may call MakeServiceThread");
- }
- if (notificationTable == null) {
- int tableSize = threadTable.Length;
- Interlocked.CompareExchange(ref notificationTableObject,
- new Object[tableSize],
- null);
- notificationTable = (Object[]) notificationTableObject;
- }
- Tracing.Log(Tracing.Audit, " previous notification: {0:x8}",
- Magic.addressOf(notificationTable[threadIndex]));
- // BUGBUG: Should have been Interlocked.Exchange, but that
- // doesn't work due to a Bartok codegen bug.
- Object oldNotification = notificationTable[threadIndex];
- while (Interlocked.CompareExchange(ref notificationTable[threadIndex], notification, oldNotification) != oldNotification) {
- oldNotification = notificationTable[threadIndex];
- }
- if (oldNotification == null) {
- // We made the thread a service thread for the first time.
- if (Interlocked.Decrement(ref threadCount) == 0) {
- NotifyServiceThreads();
- }
- }
- VTable.Assert(threadCount >= 0);
- }
-
- public void ClearServiceThread(Thread thread)
- {
- Tracing.Log(Tracing.Audit, "ClearServiceThread");
- if (this != Thread.CurrentThread) {
- throw new Exception("Only the thread itself may call ClearServiceThread");
- }
- if (notificationTable == null) {
- return;
- }
- if (Interlocked.Exchange(ref notificationTable[threadIndex],
- null) != null) {
- // We cleared the notification
- Interlocked.Increment(ref threadCount);
- }
- VTable.Assert(threadCount >= 0);
- }
-
- private static bool AddThread(int index)
- {
- Tracing.Log(Tracing.Audit, "AddThread {0} ({1})",
- (UIntPtr) index, (UIntPtr) threadCount);
- VTable.Assert(threadCount >= 0);
- if (Interlocked.Increment(ref threadCount) == 1 &&
- notificationTable != null) {
- // The thread was started after we started sending out
- // notifications, so indicate that the thread should not
- // really be started
- return false;
- } else {
- return true;
- }
- }
-
- internal static void RemoveThread(int index)
- {
- Tracing.Log(Tracing.Audit, "RemoveThread {0} ({1})",
- (UIntPtr) index, (UIntPtr) threadCount);
- if (Interlocked.Decrement(ref threadCount) == 0) {
- NotifyServiceThreads();
- }
- VTable.Assert(threadCount >= 0);
- }
-
- private static void NotifyServiceThreads()
- {
- Tracing.Log(Tracing.Audit, "NotifyServiceThreads");
- if (notificationTable == null) {
- return;
- }
- for (int i = 0; i < notificationTable.Length; i++) {
- if (notificationTable[i] != null) {
- Tracing.Log(Tracing.Audit, " Notifying thread {0}",
- (UIntPtr) i);
- ((StopServiceNotice)notificationTable[i])();
- }
- }
- }
-
-
- /*=========================================================================
- ** Returns true if the thread has been started and is not dead.
- =========================================================================*/
- //|
- public bool IsAlive {
- [NoHeapAllocation]
- get { return (threadState != ThreadState.Unstarted &&
- threadState != ThreadState.Stopped); }
- }
-
-
- /*=========================================================================
- ** Waits for the thread to die.
- **
- ** Exceptions: ThreadStateException if the thread has not been started yet.
- =========================================================================*/
- //|
- public void Join()
- {
- Join(SchedulerTime.MaxValue);
- }
-
- /*=========================================================================
- ** Waits for the thread to die or for timeout milliseconds to elapse.
- ** Returns true if the thread died, or false if the wait timed out.
- **
- ** Exceptions: ArgumentException if timeout < 0.
- ** ThreadStateException if the thread has not been started yet.
- =========================================================================*/
- //|
- public bool Join(TimeSpan timeout)
- {
- if (threadState == ThreadState.Unstarted) {
- throw new ThreadStateException();
- }
- return joinEvent.WaitOne(timeout);
- }
-
- public bool Join(SchedulerTime timeout)
- {
- if (threadState == ThreadState.Unstarted) {
- throw new ThreadStateException();
- }
- return joinEvent.WaitOne(timeout);
- }
-
- internal static bool JoinAll()
- {
- // To avoid races, join all does the following:
- // 1) Wait for all known peer threads to terminate.
- // 2) Set the closing flag to disallow creating of new threads.
- // 3) Wait for any threads that have started in the mean time.
-
- for (uint iteration = 0; iteration < 2; iteration++) {
- for (int i = 0; i < threadTable.Length; i++) {
- Thread thread = null;
-
- bool disabled = Processor.DisableInterrupts();
- Thread.threadTableLock.Acquire(CurrentThread);
- try {
- thread = threadTable[i];
- }
- finally {
- Thread.threadTableLock.Release(CurrentThread);
- Processor.RestoreInterrupts(disabled);
- }
-
- if (thread != null &&
- thread != CurrentThread &&
- thread.threadState != ThreadState.Unstarted &&
- !thread.ignoredByJoinAll) {
- thread.Join();
- }
- }
- closing = true;
- }
- return true;
- }
-
- /*=========================================================================
- ** Suspends the current thread for timeout milliseconds. If timeout == 0,
- ** forces the thread to give up the remainder of its timeslice.
- **
- ** Exceptions: ArgumentException if timeout < 0.
- =========================================================================*/
-
- public static void Sleep(int milliseconds)
- {
- Sleep(TimeSpan.FromMilliseconds(milliseconds));
- }
-
- //|
- public static void Sleep(TimeSpan timeout)
- {
- ThreadHandle.Sleep(timeout);
- }
-
- /* wait for a length of time proportional to 'iterations'. Each iteration is should
- only take a few machine instructions. Calling this API is preferable to coding
- an explicit busy loop because the hardware can be informed that it is busy waiting. */
-
- //|
- [NoHeapAllocation]
- public static void SpinWait(int iterations)
- {
- for (int i = iterations; i > 0; i--) {
- // Ensure that the optimizer doesn't remove this
- NativeNoOp();
- }
- }
-
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void NativeNoOp();
-
- internal static int GetCurrentProcessIndex() {
- return ProcessService.GetCurrentProcessId();
- }
-
- internal bool WaitForMonitor(SchedulerTime timeOut)
- {
- return autoEvent.WaitOne(timeOut);
- }
-
- internal bool WaitForEvent(SchedulerTime timeOut)
- {
- DebugStub.Break();
- return autoEvent.WaitOne(timeOut);
- }
-
- internal bool WaitForEvent(TimeSpan timeout)
- {
- DebugStub.Break();
- return autoEvent.WaitOne(timeout);
- }
-
- internal static unsafe bool WaitForGCEvent(int currentThreadIndex)
- {
- AutoResetEvent are =
- threadTable[currentThreadIndex].processGcEvent;
- // BUGBUG: The restoration of the gcState should be taken
- // care of by the compiler.
- return are.WaitOneNoGC();
- }
-
- internal void SignalMonitor()
- {
- autoEvent.Set();
- }
-
- internal void SignalEvent()
- {
- DebugStub.Break();
- autoEvent.Set();
- }
-
- [Inline]
- internal static void SignalGCEvent(int currentThreadIndex,
- int threadIndex)
- {
- SignalGCEvent(threadIndex);
- }
-
- internal static unsafe void SignalGCEvent(int threadIndex)
- {
- Thread thread = threadTable[threadIndex];
- if (thread == null) {
- return;
- }
- thread.processGcEvent.SetNoGC();
- }
-
- //|
- public static Thread CurrentThread
- {
- [NoHeapAllocation]
- [NoStackLinkCheck]
- get {
- return Processor.GetCurrentThread();
- }
- }
-
- internal ThreadHandle Handle
- {
- [NoHeapAllocation]
- get { return threadHandle; }
- }
-
- [NoStackLinkCheck]
- [RequiredByBartok]
- [NoHeapAllocation]
- private static Thread GetCurrentThreadNative()
- {
- return Processor.GetCurrentThread();
- }
-
- [NoStackLinkCheck]
- [RequiredByBartok]
- [NoHeapAllocation]
- internal static int GetCurrentThreadIndex()
- {
- return Processor.GetCurrentThread().threadIndex;
- }
-
- /*=========================================================================
- ** Return the thread state as a consistent set of bits. This is more
- ** general then IsAlive or IsBackground.
- =========================================================================*/
- //|
- public ThreadState ThreadState
- {
- [NoHeapAllocation]
- get { return threadState; }
- }
-
- [NoHeapAllocation]
- public int GetThreadId()
- {
- return threadIndex;
- }
-
- /*=========================================================================
- ** Allocates an un-named data slot. The slot is allocated on ALL the
- ** threads.
- =========================================================================*/
- //|
- public static LocalDataStoreSlot AllocateDataSlot()
- {
- return m_LocalDataStoreMgr.AllocateDataSlot();
- }
-
- /*=========================================================================
- ** Allocates a named data slot. The slot is allocated on ALL the
- ** threads. Named data slots are "public" and can be manipulated by
- ** anyone.
- =========================================================================*/
- //|
- public static LocalDataStoreSlot AllocateNamedDataSlot(String name)
- {
- return m_LocalDataStoreMgr.AllocateNamedDataSlot(name);
- }
-
- /*=========================================================================
- ** Looks up a named data slot. If the name has not been used, a new slot is
- ** allocated. Named data slots are "public" and can be manipulated by
- ** anyone.
- =========================================================================*/
- //|
- public static LocalDataStoreSlot GetNamedDataSlot(String name)
- {
- return m_LocalDataStoreMgr.GetNamedDataSlot(name);
- }
-
- /*=========================================================================
- ** Frees a named data slot. The slot is allocated on ALL the
- ** threads. Named data slots are "public" and can be manipulated by
- ** anyone.
- =========================================================================*/
- //|
- public static void FreeNamedDataSlot(String name)
- {
- m_LocalDataStoreMgr.FreeNamedDataSlot(name);
- }
-
- /*=========================================================================
- ** Retrieves the value from the specified slot on the current thread.
- =========================================================================*/
- //|
- public static Object GetData(LocalDataStoreSlot slot)
- {
- m_LocalDataStoreMgr.ValidateSlot(slot);
-
- if (localDataStore != null) {
- return localDataStore.GetData(slot);
- }
- return null;
- }
-
- /*=========================================================================
- ** Sets the data in the specified slot on the currently running thread.
- =========================================================================*/
- //|
- public static void SetData(LocalDataStoreSlot slot, Object data)
- {
- // Create new DLS if one hasn't been created for this thread.
- if (localDataStore == null) {
- localDataStore = m_LocalDataStoreMgr.CreateLocalDataStore();
- }
- localDataStore.SetData(slot, data);
- }
-
- /*=============================================================*/
-
- internal Object ExceptionState
- {
- [NoHeapAllocation]
- get { return m_ExceptionStateInfo;}
- [NoHeapAllocation]
- set { m_ExceptionStateInfo = value;}
- }
-
- //
- // This is just designed to prevent compiler warnings.
- // This field is used from native, but we need to prevent the compiler warnings.
- //
-#if _DEBUG
- private void DontTouchThis()
- {
- threadStart = null;
- m_Priority = 0;
- }
-#endif
- /*=========================================================================
- ** Volatile Read & Write and MemoryBarrier methods.
- ** Provides the ability to read and write values ensuring that the values
- ** are read/written each time they are accessed.
- =========================================================================*/
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern byte VolatileRead(ref byte address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern short VolatileRead(ref short address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern int VolatileRead(ref int address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern long VolatileRead(ref long address);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern sbyte VolatileRead(ref sbyte address);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern ushort VolatileRead(ref ushort address);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern uint VolatileRead(ref uint address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern IntPtr VolatileRead(ref IntPtr address);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern UIntPtr VolatileRead(ref UIntPtr address);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern ulong VolatileRead(ref ulong address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern float VolatileRead(ref float address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern double VolatileRead(ref double address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern Object VolatileRead(ref Object address);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref byte address, byte value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref short address, short value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref int address, int value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref long address, long value);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref sbyte address, sbyte value);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref ushort address, ushort value);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref uint address, uint value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref IntPtr address, IntPtr value);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref UIntPtr address, UIntPtr value);
-
- //|
- [CLSCompliant(false)]
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref ulong address, ulong value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref float address, float value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref double address, double value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void VolatileWrite(ref Object address, Object value);
-
- //|
- [Intrinsic]
- [NoHeapAllocation]
- public static extern void MemoryBarrier();
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [GCAnnotation(GCOption.NOGC)]
- [StackBound(12)]
- [NoHeapAllocation]
- private static unsafe extern Thread HalGetThread();
-
- [NoHeapAllocation]
- public static void Yield()
- {
- ThreadHandle.Yield();
- }
-
- [NoHeapAllocation]
- public bool IsStopped()
- {
- return (threadState == ThreadState.Stopped);
- }
-
- [PreInitRefCounts]
- static unsafe Thread()
- {
- threadIndexGenerator = 1;
-
- // Enable Thread.CurrentThread as soon as we can!
- initialThread = Magic.toThread(BootstrapMemory.Allocate(typeof(Thread)));
- initialThread.threadState = ThreadState.Running;
- initialThread.threadIndex = 0;
-
- // Allocate tables for thread management
- threadTable = (Thread[])
- BootstrapMemory.Allocate(typeof(Thread[]), maxThreads);
-
- // Initialize the thread and event tables
- threadTable[initialThread.threadIndex] = initialThread;
- initialThread.context = Processor.GetCurrentThreadContext();
- initialThread.context->threadIndex =
- unchecked((ushort) initialThread.threadIndex);
- initialThread.context->UpdateAfterGC(initialThread);
-
- Tracing.Log(Tracing.Debug, "InitialThread={0:x8}",
- Magic.addressOf(initialThread));
- }
-
- internal static unsafe void FinishInitializeThread()
- {
- int threadIndex = initialThread.threadIndex;
- // Get the GC ready for initialThread
- Transitions.RuntimeInitialized();
- Transitions.ThreadStart();
- initialThread.processGcEvent = new AutoResetEvent(false);
- initialThread.autoEvent = new AutoResetEvent(false);
- initialThread.joinEvent = new ManualResetEvent(false);
- initialThread.singleQueueItem =
- new ThreadQueueItem [1] { new ThreadQueueItem(initialThread) };
- // Use CurrentThread to find our initial handle:
- VTable.Assert(initialThread == CurrentThread);
- initialThread.threadHandle = ThreadHandle.CurrentThread();
- // Instantiate the static variable that needs to be initialized
- m_LocalDataStoreMgr = new LocalDataStoreMgr();
- AddThread(threadIndex);
- }
-
- public TimeSpan ExecutionTime
- {
- get {
- TimeSpan t = ThreadHandle.GetExecutionTime(threadHandle);
- GC.KeepAlive(this);
- return t;
- }
- }
-
- internal static
- void VisitBootstrapData(GCs.NonNullReferenceVisitor visitor)
- {
- visitor.VisitReferenceFields(Thread.initialThread);
- visitor.VisitReferenceFields(Thread.threadTable);
- }
-
- internal static unsafe void UpdateAfterGC()
- {
- // Update all the thread pointers in the thread contexts
- for (int i = 0; i < threadTable.Length; i++) {
- Thread thread = threadTable[i];
- if (thread != null) {
- thread.context->UpdateAfterGC(thread);
- }
- }
- }
-
- // Cache for ABI synchronization
- private SyncHandle[] syncHandles;
- internal SyncHandle[] GetSyncHandles(int length)
- {
- if (syncHandles == null ||
- syncHandles.Length < length) {
-
- syncHandles = new SyncHandle[length + 8];
- }
- return syncHandles;
- }
-
-
- // Caches for Select synchronization
- // We use stacks, because selectable abstractions might
- // internally implement HeadMatches using select receive
- // which is called from within an outer select.
- // NOTE however that internal selects should never block
- // (use timeout)
- private Stack selectBoolsStack;
- private Stack selectObjectsStack;
- private Stack selectSyncHandlesStack;
-
- public bool[] PopSelectBools(int size)
- {
- if (selectBoolsStack == null) {
- selectBoolsStack = new Stack();
- }
- if (selectBoolsStack.Count == 0) {
- return new bool [size];
- }
- bool[] selectBools = (bool[])selectBoolsStack.Pop();
- if (selectBools.Length < size) {
- return new bool [size];
- }
- return selectBools;
- }
-
- public void PushSelectBools(bool[] cache) {
- selectBoolsStack.Push(cache);
- }
-
- public ISelectable[] PopSelectObjects(int size)
- {
- if (selectObjectsStack == null) {
- selectObjectsStack = new Stack();
- }
- if (selectObjectsStack.Count == 0) {
- return new ISelectable [size];
- }
- ISelectable[] selectObjects = (ISelectable[])selectObjectsStack.Pop();
- if (selectObjects.Length < size) {
- return new ISelectable [size];
- }
- return selectObjects;
- }
- public void PushSelectObjects(ISelectable[] cache) {
- selectObjectsStack.Push(cache);
- }
-
- public SyncHandle[] PopSelectSyncHandles(int size)
- {
- if (selectSyncHandlesStack == null) {
- selectSyncHandlesStack = new Stack();
- }
- if (selectSyncHandlesStack.Count == 0) {
- return new SyncHandle [size];
- }
- SyncHandle[] selectSyncHandles = (SyncHandle[])selectSyncHandlesStack.Pop();
- if (selectSyncHandles.Length < size) {
- return new SyncHandle [size];
- }
- return selectSyncHandles;
- }
- public void PushSelectSyncHandles(SyncHandle[] cache) {
- selectSyncHandlesStack.Push(cache);
- }
-
-
-
- // Given a frame's range in memory (its esp/ebp), check whether
- // the frame contains the top transition record. If so,
- // prepare for making a transition from process mode back
- // to kernel mode.
- [AccessedByRuntime("referenced from halasm.asm")]
- [NoStackLinkCheck] // We don't want to throw an exception here;
- // Therefore, we cannot risk allocating stack segments,
- // and we should only call other NoStackLinkCheck functions (XXX).
- internal static unsafe UIntPtr CheckKernelProcessBoundary(UIntPtr esp, UIntPtr ebp, Exception exn)
- {
- ThreadContext *context = Processor.GetCurrentThreadContext();
- CallStack.TransitionRecord *topMarker = context->kernelMarkers;
- CallStack.TransitionRecord *secondMarker = context->stackMarkers;
- UIntPtr topMarkerPtr = (UIntPtr) topMarker;
- // If the top marker is in our frame, we've reached a boundary:
- if (esp < topMarkerPtr && topMarkerPtr <= ebp) {
- context->uncaughtFlag = true;
- Thread.CurrentThread.lastUncaughtException = exn;
- Processor.GetCurrentThreadContext()->SetKernelMode();
- return 1;
- }
- else {
- return 0;
- }
- }
-
- // Most recently thrown exception object that the thread
- // did not catch at all (i.e. that propagated to the bottom
- // of the stack without encountering an appropriate catch clause).
- public Exception LastUncaughtException
- {
- [NoHeapAllocation]
- get {
- return lastUncaughtException;
- }
- }
-
- // Tell JoinAll not to block waiting for this thread to exit.
- // Some special threads (e.g. the finalizer thread) need to run
- // only as long as there are other threads running, and should
- // not be considered by JoinAll.
- [NoHeapAllocation]
- internal void SetIgnoredByJoinAll()
- {
- ignoredByJoinAll = true;
- }
- }
-
- // This class is designed to support queues whose enqueue,
- // dequeue, and remove operations do not allocate memory.
- // This feature is useful when writing code that needs to
- // do such operations with interrupts off.
- [CLSCompliant(false)]
- public class ThreadQueue
- {
- private ThreadQueueItem head = null;
- private ThreadQueueItem tail = null;
-
- [NoHeapAllocation]
- public void Enqueue(ThreadQueueItem item)
- {
- VTable.Assert(item.Next == null);
- VTable.Assert(item.Prev == null);
- VTable.Assert(item.Queue == null);
-
- item.Queue = this;
- item.Prev = tail;
-
- if (tail != null) {
- VTable.Assert(tail.Next == null);
- tail.Next = item;
- } else {
- VTable.Assert(head == null);
- head = item;
- }
-
- tail = item;
- }
-
- [NoHeapAllocation]
- public ThreadQueueItem Dequeue()
- {
- ThreadQueueItem item = head;
-
- if (item != null) {
- Remove(item);
- }
-
- return item;
- }
-
- [NoHeapAllocation]
- public void Remove(ThreadQueueItem item)
- {
- VTable.Assert(item.Queue == this);
-
- if (item.Next != null) {
- item.Next.Prev = item.Prev;
- } else {
- VTable.Assert(item == tail);
- tail = item.Prev;
- }
-
- if (item.Prev != null) {
- item.Prev.Next = item.Next;
- } else {
- VTable.Assert(item == head);
- head = item.Next;
- }
-
- item.Next = null;
- item.Prev = null;
- item.Queue = null;
- }
-
- [NoHeapAllocation]
- public bool IsEmpty()
- {
- return (head == null);
- }
- }
-
- [CLSCompliant(false)]
- public class ThreadQueueItem
- {
- public readonly Thread Thread = null;
-
- public ThreadQueueItem Next = null;
- public ThreadQueueItem Prev = null;
-
- public ThreadQueue Queue = null;
-
- public ThreadQueueItem(Thread thread)
- {
- Thread = thread;
- }
-
- [NoHeapAllocation]
- public void Remove()
- {
- if (Queue != null) {
- Queue.Remove(this);
- }
-
- VTable.Assert(Next == null);
- VTable.Assert(Prev == null);
- VTable.Assert(Queue == null);
- }
- }
-}
diff --git a/base/Applications/Runtime/System/Threading/Timeout.cs b/base/Applications/Runtime/System/Threading/Timeout.cs
deleted file mode 100644
index c670431..0000000
--- a/base/Applications/Runtime/System/Threading/Timeout.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// ==++==
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// ==--==
-
-namespace System.Threading {
- using System.Threading;
- using System;
- // A constant used by methods that take a timeout (Object.Wait, Thread.Sleep
- // etc) to indicate that no timeout should occur.
- //
- // @todo: this should become an enum.
- //|
- public sealed class Timeout
- {
- private Timeout()
- {
- }
-
- //|
- public static readonly TimeSpan Infinite = TimeSpan.Infinite;
- }
-
-}
diff --git a/base/Applications/Runtime/System/Threading/WaitHandle.cs b/base/Applications/Runtime/System/Threading/WaitHandle.cs
deleted file mode 100644
index b2f1b06..0000000
--- a/base/Applications/Runtime/System/Threading/WaitHandle.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-// ==++==
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// ==--==
-/*=============================================================================
-**
-** Class: WaitHandle (this name is NOT definitive)
-**
-**
-** Purpose: Class to represent all synchronization objects in the runtime (that allow multiple wait)
-**
-** Date: August, 1999
-**
-=============================================================================*/
-
-namespace System.Threading {
- using System;
- using System.Threading;
- using System.Runtime.CompilerServices;
- using System.Collections;
- using Microsoft.Singularity;
- using Microsoft.Singularity.V1.Threads;
- using Microsoft.Singularity.V1.Services;
-
- //|
- [CLSCompliant(false)]
- public abstract class WaitHandle : IDisposable
- {
- //|
- public const int WaitTimeout = -1;
-
- protected WaitHandle()
- {
- }
-
- protected abstract SyncHandle Handle{
- get;
- }
-
- //|
- public abstract bool WaitOne(TimeSpan timeout);
-
- //|
- public abstract bool WaitOne(SchedulerTime stop);
-
- [Obsolete("Do not use DateTime for scheduling. It is meaningless. Use SchedulerTime")]
- public bool WaitOne(DateTime stop) {
- SchedulerTime st = SchedulerTime.MinValue + (stop - DateTime.BootTime);
- return WaitOne(st);
- }
-
- //|
- public abstract bool WaitOne();
-
- //|
- public static unsafe int WaitAny(WaitHandle[] waitHandles,
- TimeSpan timeout)
- {
- SyncHandle[] handles = Thread.CurrentThread.GetSyncHandles(waitHandles.Length);
- for (int i = 0; i < waitHandles.Length; i++) {
- handles[i] = waitHandles[i].Handle;
- }
- fixed (SyncHandle *array = &handles[0]) {
- return SyncHandle.WaitAny(array, waitHandles.Length, timeout);
- }
- }
-
- //|
- public static unsafe int WaitAny(WaitHandle[] waitHandles,
- SchedulerTime stop)
- {
- SyncHandle[] handles = Thread.CurrentThread.GetSyncHandles(waitHandles.Length);
- for (int i = 0; i < waitHandles.Length; i++) {
- handles[i] = waitHandles[i].Handle;
- }
- fixed (SyncHandle *array = &handles[0]) {
- return SyncHandle.WaitAny(array, waitHandles.Length, stop);
- }
- }
-
- //|
- public static unsafe int WaitAny(WaitHandle[] waitHandles)
- {
- SyncHandle[] handles = Thread.CurrentThread.GetSyncHandles(waitHandles.Length);
- for (int i = 0; i < waitHandles.Length; i++) {
- handles[i] = waitHandles[i].Handle;
- }
- fixed (SyncHandle *array = &handles[0]) {
- return SyncHandle.WaitAny(array, waitHandles.Length);
- }
- }
-
- //|
- protected abstract void Dispose(bool explicitDisposing);
-
- //|
- public virtual void Close()
- {
- Dispose(true);
- GC.nativeSuppressFinalize(this);
- }
-
- //|
- ///
- void IDisposable.Dispose()
- {
- Dispose(true);
- GC.nativeSuppressFinalize(this);
- }
-
- //|
- ~WaitHandle()
- {
- Dispose(false);
- }
-
- }
-}
diff --git a/base/Applications/Runtime/TestApp.csproj b/base/Applications/Runtime/TestApp.csproj
deleted file mode 100644
index 812cb39..0000000
--- a/base/Applications/Runtime/TestApp.csproj
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
- testapp
- Exe
- $(APPRUNTIMEDIR)
- C#
-
-
-
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/SeattleTrafficProxy/SeattleTrafficProxy.csproj b/base/Applications/SeattleTrafficProxy/SeattleTrafficProxy.csproj
index bd0b639..6c13ed0 100644
--- a/base/Applications/SeattleTrafficProxy/SeattleTrafficProxy.csproj
+++ b/base/Applications/SeattleTrafficProxy/SeattleTrafficProxy.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ dlgchild
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Security/dlg/dlgtest.csproj b/base/Applications/Security/dlg/dlgtest.csproj
new file mode 100644
index 0000000..b25d40e
--- /dev/null
+++ b/base/Applications/Security/dlg/dlgtest.csproj
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+ Exe
+ dlgtest
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Security/security.proj b/base/Applications/Security/security.proj
index 39754cf..8d7fda2 100644
--- a/base/Applications/Security/security.proj
+++ b/base/Applications/Security/security.proj
@@ -1,3 +1,11 @@
+
+
diff --git a/base/Applications/Security/stats/SecStats.sg b/base/Applications/Security/stats/SecStats.sg
index 5a5e0cf..c1e15e5 100644
--- a/base/Applications/Security/stats/SecStats.sg
+++ b/base/Applications/Security/stats/SecStats.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: SecStats.sg
-//
// Note: Singularity micro-benchmark program.
//
using System;
@@ -65,10 +63,12 @@ namespace Microsoft.Singularity.Applications
if (config.doClear) {
sd.ClearStatistics();
Console.Write("Statistics cleared.\n");
- } else if (config.doDisable) {
+ }
+ else if (config.doDisable) {
sd.Disable(true);
Console.Write("Kernel ACL checks disabled.\n");
- } else if (config.doEnable) {
+ }
+ else if (config.doEnable) {
sd.Disable(false);
Console.Write("Kernel ACL checks enabled.\n");
}
diff --git a/base/Applications/Security/stats/stats.csproj b/base/Applications/Security/stats/stats.csproj
index 66c74c0..0c2c0df 100644
--- a/base/Applications/Security/stats/stats.csproj
+++ b/base/Applications/Security/stats/stats.csproj
@@ -1,8 +1,6 @@

-
-
-
-
-
- Exe
- LogBench
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/ServiceManager/Benchmark/LogBenchmark.sg b/base/Applications/ServiceManager/Benchmark/LogBenchmark.sg
deleted file mode 100644
index c878ba6..0000000
--- a/base/Applications/ServiceManager/Benchmark/LogBenchmark.sg
+++ /dev/null
@@ -1,310 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Applications\ServiceManager\Benchmark\LogBenchmark.sg
-//
-// Note:
-//
-using System;
-using System.Text;
-using System.Threading;
-using Microsoft.SingSharp;
-using Microsoft.SingSharp.Reflection;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Applications;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Configuration;
-using Microsoft.Singularity.Diagnostics.Contracts;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.ServiceManager;
-using Microsoft.Singularity.Services;
-[assembly: Transform(typeof(ApplicationResourceTransform))]
-
-namespace Microsoft.Singularity.Applications.ServiceManager
-{
- [ConsoleCategory(HelpMessage="Benchmark client", DefaultAction=true)]
- internal class DefaultConfig
- {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- [Endpoint]
- public readonly TRef processRef;
-
- [Endpoint]
- public readonly TRef memoryRef;
-
- [Endpoint]
- public readonly TRef channelRef;
-
- reflective internal DefaultConfig();
-
- internal int AppMain()
- {
- return LogBenchmark.DefaultMain(this);
- }
- }
-
- internal sealed class BenchmarkServerInfo
- {
- private readonly string! serviceName;
- private readonly string! binaryName;
- private readonly ServiceType type;
-
- internal BenchmarkServerInfo(string! serviceName, string! binaryName,
- ServiceType type)
- {
- this.serviceName = serviceName;
- this.binaryName= binaryName;
- this.type = type;
- }
-
- internal string! ServiceName
- {
- get { return serviceName; }
- private set {}
- }
-
- internal string! BinaryName
- {
- get { return binaryName; }
- private set{}
- }
-
- internal ServiceType Type
- {
- get { return type; }
- private set{}
- }
- }
-
- internal sealed class LogBenchmark
- {
- private BenchmarkServerInfo[] serverList;
-
- private TRef serverControlRef;
- private TRef manageRef;
- private TRef processRef;
- private TRef memoryRef;
- private TRef channelRef;
-
- internal LogBenchmark(BenchmarkServerInfo[] info,
- [Claims]ProcessContract.Imp:Start! pep,
- [Claims]MemoryContract.Imp:Start! mep,
- [Claims]ChannelContract.Imp:Start! cep)
- {
- serverList = info;
- pep.RecvReady();
- processRef = new TRef(pep);
- mep.RecvReady();
- memoryRef = new TRef(mep);
- cep.RecvReady();
- channelRef = new TRef(cep);
- }
-
- internal void Start()
- {
- ServiceControlContract.Imp:Ready! control;
-
- foreach (BenchmarkServerInfo server in serverList) {
- if (server == null) {
- continue;
- }
-
- // Launch the benchmark server
- if (!StartService(server)) {
- return;
- }
-
- // Wait for the server registered.
- Thread.Sleep(2000);
-
- // Start the evaluation
- JobSet.Start(server, serverControlRef);
-
- // shutdown server
- if (!StopService()) {
- return;
- }
- Thread.Sleep(2000);
- }
- }
-
- private bool StartService(BenchmarkServerInfo! info)
- {
- bool success = false;
-
- ServiceInfo* in ExHeap serviceInfo;
- ServiceManagementContract.Imp! ep;
- ServiceControlContract.Imp! client;
- ServiceControlContract.Exp! server;
-
- Console.Write("Starting service: " + info.ServiceName + " ...");
- GetEndpoint(out ep);
- ep.RecvSuccess();
-
- Console.Write(".");
- ServiceControlContract.NewChannel(out client, out server);
- serviceInfo = new [ExHeap] ServiceInfo(0,
- info.ServiceName,
- info.BinaryName,
- info.Type);
- ep.SendBind(serviceInfo, server);
- switch receive {
- case ep.AckBind():
- {
- break;
- }
- case ep.NotFound(rejected):
- {
- delete rejected;
- Console.WriteLine("Doesn't exist.");
- goto exit;
- break;
- }
- case ep.PermissionDenied(rejected):
- {
- delete rejected;
- Console.WriteLine("Permission denied");
- goto exit;
- break;
- }
- }
-
- client.RecvSuccess();
- client.SendStartService();
- switch receive {
- case client.RecvAckStartService():
- {
- Console.WriteLine(" done.");
- success = true;
- break;
- }
- case client.NakStartService(error):
- {
- Console.WriteLine(" error: " + error);
- break;
- }
- case client.ChannelClosed():
- {
- Console.WriteLine(" Channel is closed.");
- break;
- }
- }
-
-exit:
- if (success) {
- serverControlRef =
- new TRef(client);
- manageRef =
- new TRef(ep);
- }
- else {
- delete client;
- delete ep;
- }
- return success;
- }
-
- private bool StopService()
- {
- bool success = false;
- ServiceControlContract.Imp! client;
-
- Console.Write("Stopping service ...");
-
- client = serverControlRef.Acquire();
- client.SendStopService();
- switch receive {
- case client.AckStopService():
- {
- Console.WriteLine(" done.");
- success = true;
- break;
- }
- case client.NakStopService(error):
- {
- Console.WriteLine(" error: " + error);
- break;
- }
- case unsatisfiable:
- {
- break;
- }
- }
- delete client;
- delete manageRef.Acquire();
- return success;
- }
-
- private void GetEndpoint(out ServiceManagementContract.Imp! ep)
- {
- ErrorCode error;
- DirectoryServiceContract.Imp ds;
- ServiceManagementContract.Exp! scServer;
- ServiceManagementContract.NewChannel(out ep, out scServer);
-
- ds = DirectoryService.NewClientEndpoint();
- SdsUtils.Bind(ServiceManagementContract.ModuleName,
- ds,
- scServer, out error);
- delete ds;
- }
-
- internal static int DefaultMain(DefaultConfig! config)
- {
- LogBenchmark bench;
- BenchmarkServerInfo[] serverInfo = new BenchmarkServerInfo[4] {
- new BenchmarkServerInfo("RBench", "RBenchWorker",
- ServiceType.Default),
- new BenchmarkServerInfo("RBench", "RBenchWorker",
- ServiceType.Resilient),
- new BenchmarkServerInfo("RBench", "RBenchHoisted",
- ServiceType.Default),
- new BenchmarkServerInfo("RBench", "RBenchHoisted",
- ServiceType.Resilient),
- };
-
- StringBuilder builder = new StringBuilder();
- ulong[] time = new ulong[4];
- Object obj;
-
- for (int i = 0; i < 4; i++) {
- time[i] = 0;
- }
- for (int i = 0; i < 100; i++) {
- time[0] += Processor.GetCycleCount();
- obj = new Object();
- time[1] += Processor.GetCycleCount();
- obj.ToString();
- time[2] += Processor.GetCycleCount();
- obj.ToString();
- time[3] += Processor.GetCycleCount();
- }
- for (int i = 0; i < 4; i++) {
- time[i] /= 100;
- }
- builder.AppendFormat("New object: {0}\n", time[1] - time[0]);
- builder.AppendFormat("ToString1: {0}\n", time[2] - time[1]);
- builder.AppendFormat("ToString2: {0}\n", time[3] - time[2]);
-
- Console.WriteLine(builder.ToString());
- DebugStub.WriteLine(builder.ToString());
-
- bench = new LogBenchmark(serverInfo,
- config.processRef.Acquire(),
- config.memoryRef.Acquire(),
- config.channelRef.Acquire());
- bench.Start();
-
- return 0;
- }
- }
-}
diff --git a/base/Applications/ServiceManager/Benchmark/Message.sg b/base/Applications/ServiceManager/Benchmark/Message.sg
deleted file mode 100644
index ea3184c..0000000
--- a/base/Applications/ServiceManager/Benchmark/Message.sg
+++ /dev/null
@@ -1,150 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Applications\ServiceManager\Benchmark\Message.sg
-//
-// Note:
-//
-using System;
-using System.Threading;
-using System.Text;
-using Microsoft.SingSharp;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.Services;
-
-namespace Microsoft.Singularity.Applications.ServiceManager
-{
- internal class Message
- {
- private const int MaxArguments = 9;
- private static int[] n = new int[MaxArguments];
-
- static Message()
- {
- Random r = new Random();
- for (int i = 0; i < MaxArguments; i++) {
- n[i] = r.Next();
- }
- }
-
- internal static bool SendReceive(BenchmarkContract.Imp:Ready! ep,
- int num,
- out ulong time1,
- out ulong time2)
- {
- bool success = false;
-
- time1 = 0;
- time2 = 0;
- if (n == null) {
- return false;
- }
-
- switch (num) {
- case 0:
- time1 = Processor.GetCycleCount();
- ep.SendNull();
- break;
- case 1:
- time1 = Processor.GetCycleCount();
- ep.SendOne(n[0]);
- break;
- case 2:
- time1 = Processor.GetCycleCount();
- ep.SendTwo(n[0], n[1]);
- break;
- case 3:
- time1 = Processor.GetCycleCount();
- ep.SendThree(n[0], n[1], n[2]);
- break;
- case 4:
- time1 = Processor.GetCycleCount();
- ep.SendFour(n[0], n[1], n[2], n[3]);
- break;
- case 5:
- time1 = Processor.GetCycleCount();
- ep.SendFive(n[0], n[1], n[2], n[3], n[4]);
- break;
- case 6:
- time1 = Processor.GetCycleCount();
- ep.SendSix(n[0], n[1], n[2], n[3], n[4], n[5]);
- break;
- case 7:
- time1 = Processor.GetCycleCount();
- ep.SendSeven(n[0], n[1], n[2], n[3], n[4], n[5], n[6]);
- break;
- case 8:
- time1 = Processor.GetCycleCount();
- ep.SendEight(n[0], n[1], n[2], n[3], n[4], n[5], n[6],
- n[7]);
- break;
- case 9:
- time1 = Processor.GetCycleCount();
- ep.SendNine(n[0], n[1], n[2], n[3], n[4], n[5], n[6],
- n[7], n[8]);
- break;
- default:
- time1 = 0;
- time2 = 0;
- return false;
- break;
- }
-
- switch receive {
- case ep.AckNull():
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckOne(num1):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckTwo(num1, num2):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckThree(num1, num2, num3):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckFour(num1, num2, num3, num4):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckFive(num1, num2, num3, num4, num5):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckSix(num1, num2, num3, num4, num5, num6):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckSeven(num1, num2, num3, num4, num5, num6, num7):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckEight(num1, num2, num3, num4, num5, num6, num7,
- num8):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.AckNine(num1, num2, num3, num4, num5, num6, num7,
- num8, num9):
- time2 = Processor.GetCycleCount();
- success = true;
- break;
- case ep.ChannelClosed():
- Console.WriteLine("Job: Server channel closed.\n");
- success = false;
- break;
- }
- return success;
- }
-
- } // class
-}
diff --git a/base/Applications/ServiceManager/Benchmark/MultiThreadJob.sg b/base/Applications/ServiceManager/Benchmark/MultiThreadJob.sg
deleted file mode 100644
index 32fac44..0000000
--- a/base/Applications/ServiceManager/Benchmark/MultiThreadJob.sg
+++ /dev/null
@@ -1,325 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Applications\ServiceManager\Benchmark\MultiThreadJob.sg
-//
-// Note:
-//
-using System;
-using System.Collections;
-using System.Text;
-using System.Threading;
-using Microsoft.SingSharp;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.ServiceManager;
-using Microsoft.Singularity.Services;
-
-namespace Microsoft.Singularity.Applications.ServiceManager
-{
- internal sealed class RandomJob : Job
- {
- private readonly int id;
- private bool keepAlive;
- private ulong messageCount;
- private ulong firstHalf;
- private Thread thread;
-
- [ Microsoft.Contracts.NotDelayed ]
- internal RandomJob(BenchmarkServerInfo! info, int tid)
- {
- base(info);
- this.id = tid;
- thread = new Thread(new ThreadStart(this.RunThread));
- }
-
- internal override bool Run()
- {
- thread.Start();
- return true;
- }
-
- internal void Join()
- {
- thread.Join();
- }
-
- internal void Join(int timeout)
- {
- thread.Join(new TimeSpan(0, 0, 0, timeout));
- }
-
- internal void RunThread()
- {
- ulong time1;
- ulong time2;
-
- DebugStub.Print("RandomJob {0} start\n", __arglist(id));
-
- BenchmarkContract.Imp:Ready! imp;
- if (!Bind(out imp)) {
- goto exit;
- }
-
- messageCount = 0;
- keepAlive = true;
- while (keepAlive) {
- imp.SendNull();
- switch receive {
- case imp.AckNull():
- break;
- case unsatisfiable:
- goto exit;
- break;
- }
- messageCount += 2;
- }
-
- /*
- imp.SendEndOfBenchmark();
- switch receive {
- case imp.AckEnd():
- break;
- case imp.ChannelClosed():
- break;
- }
- */
-exit:
- delete imp;
- DebugStub.Print("RandomJob {0} stop\n", __arglist(id));
- }
-
- internal void Stop()
- {
- keepAlive = false;
- }
-
- internal void SwitchRecord()
- {
- firstHalf = messageCount;
- }
-
- internal ulong MessageCount
- {
- get { return messageCount; }
- private set {}
- }
-
- internal ulong FirstHalf
- {
- get { return firstHalf; }
- private set{}
- }
-
- internal ulong SecondHalf
- {
- get {return messageCount - firstHalf; }
- private set{}
- }
- }
-
- internal sealed class MultiThreadJob : Job
- {
- private const int Order = 4;
- private const int NSamples = 10;
- private ulong[,] firstHalf = new ulong[Order, NSamples];
- private ulong[,] totalMessages = new ulong[Order, NSamples];
- private ArrayList jobList;
-
- private TRef serverRef;
-
- internal MultiThreadJob(BenchmarkServerInfo! info,
- TRef! tref)
- {
- base(info);
- this.jobList = new ArrayList();
- this.serverRef = tref;
- }
-
- internal override bool Run()
- {
- bool success = false;
-
- Console.WriteLine("MultiThreadJob start");
- DebugStub.WriteLine("-- MultiThreadJob start");
-
- for (int i = 0; i < Order; i++) {
- for (int j = 0; j < NSamples; j++) {
- CreateJobs(1 << i);
- StartJobs();
- Thread.Sleep(5000);
-
- Start2ndHalf();
- if (base.info.Type == ServiceType.Resilient) {
- success = RestartService();
- }
- else {
- DummyOperation();
- success = true;
- }
- Thread.Sleep(5000);
- DebugStub.WriteLine("Stop jobs...");
- StopJobs();
- CollectResults(i, j);
- DebugStub.WriteLine("Delete jobs...");
- DeleteJobs();
- if (!success) {
- break;
- }
- Thread.Sleep(2000);
- }
- }
- return success;
- }
-
- private void CreateJobs(int numberOfJobs)
- {
- RandomJob job;
-
- for (int i = 0; i < numberOfJobs; i++) {
- job = new RandomJob(base.info, i);
- jobList.Add(job);
- }
- }
-
- private void StartJobs()
- {
- RandomJob job;
-
- foreach (Object obj in jobList) {
- if (obj != null) {
- job = obj as RandomJob;
- if (job != null) {
- job.Run();
- }
- }
- }
- }
-
- private void Start2ndHalf()
- {
- RandomJob job;
-
- foreach (Object obj in jobList) {
- if (obj != null) {
- job = obj as RandomJob;
- if (job != null) {
- job.SwitchRecord();
- }
- }
- }
- }
-
- private void StopJobs()
- {
- RandomJob job;
-
- foreach (Object obj in jobList) {
- if (obj != null) {
- job = obj as RandomJob;
- if (job != null) {
- job.Stop();
- }
- }
- }
-
- foreach (Object obj in jobList) {
- if (obj != null) {
- job = obj as RandomJob;
- if (job != null) {
- job.Join(2000);
- }
- }
- }
- }
-
- private void DeleteJobs()
- {
- jobList.Clear();
- }
-
- private bool RestartService()
- {
- bool success = false;
-
- ServiceControlContract.Imp:Ready! ep;
-
- ep = serverRef.Acquire();
- ep.SendRestartService();
- switch receive {
- case ep.AckRestartService():
- {
- success = true;
- break;
- }
- case ep.ChannelClosed():
- {
- success = false;
- break;
- }
- }
- serverRef.Release(ep);
- return success;
- }
-
- private void DummyOperation()
- {
- ServiceControlContract.Imp:Ready! ep;
- ep = serverRef.Acquire();
- ep.SendStopPoll();
- switch receive {
- case ep.AckStopPoll():
- break;
- case ep.ChannelClosed():
- break;
- }
- serverRef.Release(ep);
- }
-
- private void CollectResults(int order, int sample)
- {
- RandomJob job;
-
- foreach (Object obj in jobList) {
- if (obj != null) {
- job = obj as RandomJob;
- if (job != null) {
- firstHalf[order, sample] = job.FirstHalf;
- totalMessages[order, sample] = job.MessageCount;
- }
- }
- }
- }
-
- public override String! ToString()
- {
- ulong half, total;
- StringBuilder builder = new StringBuilder();
-
- builder.Append("-- MultiThread Test (100 samples for each)");
- builder.Append("(5 seconds for each half) --\n");
- builder.Append("Client(s) FirstHalf SecondHalf Total\n");
- builder.Append("--------- --------- ---------- -------\n");
- for (int i = 0; i < Order; i++) {
- half = 0;
- total = 0;
- for (int j = 0; j < NSamples; j++) {
- half += firstHalf[i, j];
- total += totalMessages[i, j];
- }
- half /= NSamples;
- total /= NSamples;
-
- builder.AppendFormat("{0, -9} {1, 9} {2, 10} {3, 7}\n",
- 1 << i, half, total - half, total);
- }
- builder.Append("\n");
- return builder.ToString();
- }
- }
-}
diff --git a/base/Applications/ServiceManager/Count/Count.csproj b/base/Applications/ServiceManager/Count/Count.csproj
deleted file mode 100644
index 19ab1cc..0000000
--- a/base/Applications/ServiceManager/Count/Count.csproj
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
- Exe
- Count
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/ServiceManager/Count/Count.sg b/base/Applications/ServiceManager/Count/Count.sg
deleted file mode 100644
index b89b678..0000000
--- a/base/Applications/ServiceManager/Count/Count.sg
+++ /dev/null
@@ -1,89 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Applications\ServiceManager\CountUp\CountUp.sg
-//
-// Note:
-//
-using System;
-using System.Threading;
-using Microsoft.SingSharp;
-using Microsoft.SingSharp.Reflection;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Applications;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Configuration;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.Services;
-[assembly: Transform(typeof(ApplicationResourceTransform))]
-
-namespace Microsoft.Singularity.Applications
-{
- [ConsoleCategory(HelpMessage="Counter client", DefaultAction=true)]
- internal class DefaultConfig
- {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- [LongParameter("interval", Position=0, Default=500)]
- internal long interval;
-
- reflective internal DefaultConfig();
-
- internal int AppMain()
- {
- return CountUp.DefaultMain(this);
- }
- }
-
- public class CountUp
- {
- internal static int DefaultMain(DefaultConfig! config)
- {
- bool next;
- ErrorCode error;
- DirectoryServiceContract.Imp ds;
- CounterContract.Imp! ep;
- CounterContract.Exp! server;
- CounterContract.NewChannel(out ep, out server);
-
- ds = DirectoryService.NewClientEndpoint();
- SdsUtils.Bind(CounterContract.ModuleName, ds, server, out error);
-
- ep.RecvSuccess();
-
- Console.WriteLine("Start count");
- ep.SendBeginCount();
- do {
- switch receive {
- case ep.RecvCurrent(number):
- Console.WriteLine("Count: " + number);
- Thread.Sleep((int)config.interval);
- ep.SendNext();
- next = true;
- break;
- case ep.RecvTerminated():
- Console.WriteLine("Terminated...");
- next = false;
- break;
- case ep.ChannelClosed():
- Console.WriteLine("Channel closed...");
- next = false;
- break;
- }
- } while (next);
-
- delete ds;
- delete ep;
-
- return 0;
- }
- }
-}
diff --git a/base/Applications/ServiceManager/Replace/ReplaceGame.csproj b/base/Applications/ServiceManager/Replace/ReplaceGame.csproj
deleted file mode 100644
index 122bc57..0000000
--- a/base/Applications/ServiceManager/Replace/ReplaceGame.csproj
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
- Exe
- ReplaceGame
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/ServiceManager/Replace/ReplaceGame.sg b/base/Applications/ServiceManager/Replace/ReplaceGame.sg
deleted file mode 100644
index 6f2ad8e..0000000
--- a/base/Applications/ServiceManager/Replace/ReplaceGame.sg
+++ /dev/null
@@ -1,399 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Applications\ServiceManager\Replace\ReplaceGame.sg
-//
-// Note:
-//
-using System;
-using System.Threading;
-using Microsoft.SingSharp;
-using Microsoft.SingSharp.Reflection;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Applications;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Configuration;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.ServiceManager;
-using Microsoft.Singularity.Services;
-[assembly: Transform(typeof(ApplicationResourceTransform))]
-
-namespace Microsoft.Singularity.Applications
-{
- [ConsoleCategory(HelpMessage="Replace Game Client", DefaultAction=true)]
- internal class DefaultConfig
- {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- [LongParameter("interval", Default=500)]
- internal long interval;
-
- [BoolParameter("test", Default=true)]
- internal bool test;
-
- reflective internal DefaultConfig();
-
- internal int AppMain()
- {
- return ReplaceGame.DefaultMain(this);
- }
- }
-
- internal sealed class ReplaceGame
- {
- private const int DefaultCount = 50;
- private int count;
- private String![]! names;
- private int self;
- private Random! random;
-
- private const int NumberOfActions = 4;
- private enum Action : int { Overwrite, Protect, Score, Pose };
-
- private static TRef! controlRef;
- private static TRef! manageRef;
-
- internal ReplaceGame(String![]! competitors, int self)
- {
- this.count = DefaultCount;
- this.names = competitors;
- this.self = self;
- Thread.Sleep(1); // To get a different seed
- this.random = new Random();
- }
-
- internal void Run()
- {
- int action;
- GamePlayerContract.Imp! ep;
-
- if (!Connect(out ep)) {
- goto exit;
- }
-
- switch receive {
- case ep.Success():
- break;
- case unsatisfiable:
- goto exit;
- break;
- }
-
- Score(ep);
- Console.WriteLine(names[self] + " start!!");
- try {
- while (count-- > 0) {
- action = random.Next(NumberOfActions);
- switch ((Action)action) {
- case Action.Overwrite:
- Console.WriteLine(names[self] + " overwrite");
- Overwrite(ep);
- break;
- case Action.Protect:
- Console.WriteLine(names[self] + " protect");
- Protect(ep);
- break;
- case Action.Score:
- Console.WriteLine(names[self] + " score");
- Score(ep);
- break;
- case Action.Pose:
- Pose();
- break;
- }
- }
- Console.WriteLine(names[self] + " end!!");
- Score(ep);
- }
- catch (Exception e) {
- DebugStub.Print(e.ToString());
- }
-exit:
- delete ep;
- }
-
- private void Overwrite(GamePlayerContract.Imp:Ready! ep)
- {
- int pos = -1;
- DebugStub.Print("Enter overwrite\n");
-
- ep.SendSearch(Bitter.FromString2(GetSomeone()));
- switch receive {
- case ep.AckSearch(position):
- pos = position;
- break;
- case ep.ChannelClosed():
- //throw new ChannelClosedException();
- break;
- }
-
- if (pos >= 0) {
- ep.SendOverwrite(Bitter.FromString2(names[self]), pos);
- switch receive {
- case ep.AckOverwrite():
- break;
- case ep.ChannelClosed():
- //throw new ChannelClosedException();
- break;
- }
- }
- DebugStub.Print("Exit overwrite\n");
- }
-
- private void Protect(GamePlayerContract.Imp:Ready! ep)
- {
- int pos = -1;
- ep.SendSearch(Bitter.FromString2(names[self]));
- switch receive {
- case ep.AckSearch(position):
- pos = position;
- break;
- case ep.ChannelClosed():
- //throw new ChannelClosedException();
- break;
- }
- if (pos >= 0) {
- ep.SendProtect(pos);
- switch receive {
- case ep.AckProtect():
- break;
- case ep.ChannelClosed():
- //throw new ChannelClosedException();
- break;
- }
- }
- }
-
- private void Score(GamePlayerContract.Imp:Ready! ep)
- {
- ep.SendScore(Bitter.FromString2(names[self]));
- switch receive {
- case ep.AckScore(score):
- Console.Write("{0, -10} : {1}\n", names[self], score);
- break;
- case ep.ChannelClosed():
- //throw new ChannelClosedException();
- break;
- }
- }
-
- private void Pose()
- {
- Thread.Sleep(100);
- }
-
- private String! GetSomeone()
- {
- int index;
- do {
- index = random.Next(names.Length);
- } while (index == self);
- return names[index];
- }
-
- internal bool Connect(out GamePlayerContract.Imp! ep)
- {
- DirectoryServiceContract.Imp! ds;
- GamePlayerContract.Imp! imp;
- GamePlayerContract.Exp! exp;
- ErrorCode error;
-
- ds = DirectoryService.NewClientEndpoint();
- GamePlayerContract.NewChannel(out imp, out exp);
- SdsUtils.Bind(GamePlayerContract.ModuleName, ds, exp, out error);
- ep = imp;
- delete ds;
- return (error == ErrorCode.NoError);
- }
-
- //--------------------------------------------------------------------
- // Test Code
- //--------------------------------------------------------------------
-
- private static bool StartService()
- {
- bool success = false;
-
- ServiceInfo* in ExHeap serviceInfo;
- ServiceManagementContract.Imp! ep;
- ServiceControlContract.Imp! imp;
- ServiceControlContract.Exp! exp;
-
- Console.Write("Starting service: " +
- GamePlayerContract.ModuleName + " ...");
- GetEndpoint(out ep);
- ep.RecvSuccess();
-
- ServiceControlContract.NewChannel(out imp, out exp);
- serviceInfo = new [ExHeap] ServiceInfo(0,
- GamePlayerContract.ModuleName,
- GamePlayerContract.ModuleName,
- ServiceType.Resilient);
- ep.SendBind(serviceInfo, exp);
- switch receive {
- case ep.AckBind():
- {
- break;
- }
- case ep.NotFound(rejected):
- {
- delete rejected;
- Console.WriteLine("Doesn't exist.");
- goto exit;
- break;
- }
- case ep.PermissionDenied(rejected):
- {
- delete rejected;
- Console.WriteLine("Permission denied");
- goto exit;
- break;
- }
- }
-
- imp.RecvSuccess();
- imp.SendStartService();
- switch receive {
- case imp.RecvAckStartService():
- {
- Console.WriteLine(" done.");
- success = true;
- break;
- }
- case imp.NakStartService(error):
- {
- Console.WriteLine(" error: " + error);
- break;
- }
- case imp.ChannelClosed():
- {
- Console.WriteLine(" Channel is closed.");
- break;
- }
- }
-
-exit:
- if (success) {
- controlRef =
- new TRef(imp);
- manageRef =
- new TRef(ep);
- }
- else {
- delete imp;
- delete ep;
- }
- return success;
- }
-
- private static bool RestartService()
- {
- bool success = false;
- ServiceControlContract.Imp:Ready! ep;
-
- ep = controlRef.Acquire();
- ep.SendRestartService();
- switch receive {
- case ep.AckRestartService():
- {
- success = true;
- break;
- }
- case ep.ChannelClosed():
- {
- success = false;
- break;
- }
- }
- controlRef.Release(ep);
- return success;
- }
-
- private static bool StopService()
- {
- bool success = false;
- ServiceControlContract.Imp:Ready! ep;
-
- Console.Write("Stopping service ...");
-
- ep = controlRef.Acquire();
- ep.SendStopService();
- switch receive {
- case ep.AckStopService():
- {
- Console.WriteLine(" done.");
- success = true;
- break;
- }
- case ep.NakStopService(error):
- {
- Console.WriteLine(" error: " + error);
- break;
- }
- }
- delete ep;
- delete manageRef.Acquire();
- return success;
- }
-
- private static void GetEndpoint(out ServiceManagementContract.Imp! ep)
- {
- ErrorCode error;
- DirectoryServiceContract.Imp ds;
- ServiceManagementContract.Exp! scServer;
- ServiceManagementContract.NewChannel(out ep, out scServer);
-
- DebugStub.Print("GetEndpoint\n");
- ds = DirectoryService.NewClientEndpoint();
- SdsUtils.Bind(ServiceManagementContract.ModuleName, ds, scServer,
- out error);
- DebugStub.Print("GetEndpoint: {0}\n", __arglist((int)error));
- delete ds;
- }
-
-
- internal static int DefaultMain(DefaultConfig! config)
- {
- // bang! bang! bang!
- String![]! names = new String![4] {"Microsoft", "Google", "Yahoo", "Apple"};
- ReplaceGame![]! game = new ReplaceGame![4];
- Thread![]! players = new Thread![4];
-
- if (config.test) {
- StartService();
- Thread.Sleep(2000);
- }
-
- for (int i = 0; i < 4; i++) {
- game[i] = new ReplaceGame(names, i);
- players[i] = new Thread(new ThreadStart(game[i].Run));
- }
- foreach (Thread! player in players) {
- player.Start();
- }
-
- if (config.test) {
- Thread.Sleep(8000);
- RestartService();
- }
-
- foreach (Thread! player in players) {
- player.Join();
- }
-
- if (config.test) {
- StopService();
- }
-
- return 0;
- }
- }
-}
diff --git a/base/Applications/ServiceManager/SMSClient/SMSClient.cs b/base/Applications/ServiceManager/SMSClient/SMSClient.cs
index ae62b40..2e0d83c 100644
--- a/base/Applications/ServiceManager/SMSClient/SMSClient.cs
+++ b/base/Applications/ServiceManager/SMSClient/SMSClient.cs
@@ -4,11 +4,11 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Applications\ServiceManager\SMSClient\SMSClient.sg
-//
// Note: Service Manager client program
//
using System;
+using System.Threading;
+
using Microsoft.SingSharp;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity;
@@ -36,7 +36,8 @@ namespace Microsoft.Singularity.Applications.ServiceManager
internal int AppMain()
{
- return SMSClient.DefaultMain(this);
+ Console.WriteLine("Use -? for help.");
+ return 0;
}
}
@@ -50,44 +51,21 @@ namespace Microsoft.Singularity.Applications.ServiceManager
public readonly TRef Stdout;
[StringParameter("service", Mandatory=true, Position=0)]
- internal string service;
+ internal string serviceName;
- [StringParameter("type", Mandatory=false, Position=1)]
- internal string type;
+ // [BoolParameter("w", Mandatory=false, HelpMessage="Wait for service to start.")]
+ public bool wait;
reflective internal StartConfig();
internal int AppMain()
{
- return SMSClient.StartService(this);
+ return SMSClient.StartService((!)serviceName, wait);
}
}
[ConsoleCategory(Action="stop", HelpMessage="Stop a service")]
- internal class StopConfig
- {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- //[StringParameter("service", Mandatory=true, Position=0)]
- //internal string service;
-
- [LongParameter("id", Mandatory=true, Position=0)]
- internal long id;
-
- reflective internal StopConfig();
-
- internal int AppMain()
- {
- return SMSClient.StopService(this);
- }
- }
-
- [ConsoleCategory(Action="restart", HelpMessage="Restart a service")]
- internal class RestartConfig
+ internal class StopServiceCommand
{
[InputEndpoint("data")]
public readonly TRef Stdin;
@@ -96,13 +74,16 @@ namespace Microsoft.Singularity.Applications.ServiceManager
public readonly TRef Stdout;
[StringParameter("service", Mandatory=true, Position=0)]
- internal string service;
+ internal string serviceName;
- reflective internal RestartConfig();
+ // [BoolParameter("w", Mandatory=false, HelpMessage="Wait for service to stop.")]
+ public bool wait;
+
+ reflective internal StopServiceCommand();
internal int AppMain()
{
- return SMSClient.RestartService(this);
+ return SMSClient.StopService((!)serviceName, wait);
}
}
@@ -123,191 +104,789 @@ namespace Microsoft.Singularity.Applications.ServiceManager
}
}
+ [ConsoleCategory(Action="show", HelpMessage="Show details about a specific service.")]
+ internal class ShowServiceParameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("service", Position=0, Mandatory=true, HelpMessage="The service to examine.")]
+ public string ServiceName;
+
+ reflective internal ShowServiceParameters();
+
+ internal int AppMain()
+ {
+ if (ServiceName == null) {
+ Console.WriteLine("The 'service' parameter is required, but has not been provided.");
+ return -1;
+ }
+
+ ServiceManagerContract.Imp! svmanager = SMSClient.ConnectServiceManager();
+ try {
+ ServiceError error = SMSClient.SelectService(svmanager, this.ServiceName);
+ if (error != ServiceError.None)
+ return -1;
+
+ bool errors = false;
+
+ svmanager.SendQueryServiceConfig();
+ switch receive {
+ case svmanager.CurrentServiceConfig(config):
+ SMSClient.ShowConfigDetailed(config);
+ config.Dispose();
+ break;
+
+ case svmanager.RequestFailed(err):
+ if (err == ServiceError.ServiceNotFound) {
+ Console.WriteLine("There is no service with name '{0}'.", this.ServiceName);
+ return -1;
+ }
+
+ Console.WriteLine("Failed to query service configuration.");
+ SMSClient.ShowServiceError(err);
+ errors = true;
+ break;
+
+ case svmanager.ChannelClosed():
+ Console.WriteLine("The Service Manager closed its channel unexpectedly.");
+ return -1;
+ }
+
+ svmanager.SendQueryServiceStatus();
+ switch receive {
+ case svmanager.CurrentServiceStatus(status):
+ Console.WriteLine();
+ SMSClient.ShowStatusDetailed(status);
+ status.Dispose();
+ break;
+
+ case svmanager.RequestFailed(err):
+ Console.WriteLine("Failed to query service status.");
+ SMSClient.ShowServiceError(err);
+ errors = true;
+ break;
+
+ case svmanager.ChannelClosed():
+ Console.WriteLine("The Service Manager closed its channel unexpectedly.");
+ return -1;
+ }
+
+ if (errors)
+ return -1;
+ else
+ return 0;
+
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+ }
+
+ [ConsoleCategory(Action="watch", HelpMessage="Watch the status of a service")]
+ internal class WatchConfig
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("service", Mandatory=true, Position=0)]
+ internal string serviceName;
+
+ reflective internal WatchConfig();
+
+ internal int AppMain()
+ {
+ return SMSClient.WatchService((!)serviceName);
+ }
+ }
+
+ [ConsoleCategory(Action="watchall", HelpMessage="Watch the status of the Service Manager")]
+ internal class WatchAllConfig
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+#if false
+ [BoolParameter("c", Mandatory=false, HelpMessage="Watch all service configuration changes")]
+ public bool watchConfigChanges;
+
+ [BoolParameter("s", Mandatory=false, HelpMessage="Watch all service status changes")]
+ public bool watchStatusChanges;
+#endif
+
+ reflective internal WatchAllConfig();
+
+ internal int AppMain()
+ {
+#if false
+ ServiceManagerEventMask desiredEvents = 0;
+
+ if (watchConfigChanges)
+ desiredEvents |= ServiceManagerEventMask.AnyServiceConfig;
+
+ if (watchStatusChanges)
+ desiredEvents |= ServiceManagerEventMask.AnyServiceStatus;
+
+ if (desiredEvents == 0)
+ desiredEvents = ServiceManagerEventMask.AnyServiceConfig | ServiceManagerEventMask.AnyServiceStatus;
+#else
+ ServiceManagerEventMask desiredEvents = ServiceManagerEventMask.AnyServiceConfig | ServiceManagerEventMask.AnyServiceStatus;
+#endif
+
+ ServiceManagerContract.Imp! svmanager = SMSClient.ConnectServiceManager();
+
+ svmanager.SendWatchServiceManager(desiredEvents);
+
+ switch receive {
+ case svmanager.Ok():
+ break;
+
+ case svmanager.RequestFailed(error):
+ Console.WriteLine("The Service Manager rejected the subscription request.");
+ SMSClient.ShowServiceError(error);
+ delete svmanager;
+ return -1;
+ }
+
+ Console.WriteLine("Watching Service Manager...");
+
+ for (;;) {
+ Console.WriteLine("Sending WaitNextServiceManagerChange");
+ svmanager.SendWaitNextServiceManagerChange();
+
+ Console.WriteLine("switch-receive");
+
+ switch receive {
+ case svmanager.ServiceManagerChanged(events):
+ Console.WriteLine("Service Manager events fired: {0:x8}", ((uint)events));
+ break;
+ }
+ }
+ }
+ }
+
+ [ConsoleCategory(Action="create", HelpMessage="Create a new service entry")]
+ internal class CreateServiceCommand
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("service", Mandatory=true, Position=0)]
+ internal string serviceName;
+
+ [StringParameter("exe", Mandatory=false, HelpMessage="Executable to use; if omitted, uses service name.")]
+ public string executableName;
+
+ [StringParameter("display", Mandatory=false, HelpMessage="Display name to use; if omitted, uses service name.")]
+ public string displayName;
+
+ [BoolParameter("disabled", Mandatory=false, HelpMessage="Create in a disabled state.")]
+ public bool isAdministrativelyDisabled;
+
+ reflective internal CreateServiceCommand();
+
+ internal int AppMain()
+ {
+ assert serviceName != null;
+ if (serviceName.Length == 0) {
+ Console.WriteLine("Invalid service name.");
+ return -1;
+ }
+
+ if (executableName == null || executableName.Length == 0)
+ executableName = serviceName;
+
+ if (displayName == null || displayName.Length == 0)
+ displayName = serviceName;
+
+ ServiceManagerContract.Imp! svmanager = SMSClient.ConnectServiceManager();
+ try {
+
+ ServiceConfig config = new ServiceConfig();
+ config.ServiceName = Bitter.FromString2(serviceName);
+ config.ExecutableName = Bitter.FromString2(executableName);
+ config.DisplayName = Bitter.FromString2(displayName);
+ config.IsAdministrativelyDisabled = isAdministrativelyDisabled;
+ config.MinProcesses = 0;
+ config.MaxProcesses = 1;
+ config.MaxClientsPerProcess = ServiceConfig.UnlimitedClientsPerProcess;
+ config.MaxProcessAgeInSeconds = ServiceConfig.UnlimitedProcessAge;
+
+ svmanager.SendCreateService(config);
+
+ switch receive {
+ case svmanager.Ok():
+ Console.WriteLine("Service was successfully created.");
+ return 0;
+
+ case svmanager.RequestFailed(error):
+ Console.WriteLine("Failed to create service.");
+ SMSClient.ShowServiceError(error);
+ return -1;
+ }
+
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+ }
+
+ [ConsoleCategory(Action="delete", HelpMessage="Delete an existing service")]
+ internal class DeleteServiceCommand
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("service", Mandatory=true, Position=0)]
+ internal string serviceName;
+
+ reflective internal DeleteServiceCommand();
+
+ internal int AppMain()
+ {
+ assert serviceName != null;
+ if (serviceName.Length == 0) {
+ Console.WriteLine("Invalid service name.");
+ return -1;
+ }
+
+ ServiceManagerContract.Imp! svmanager = SMSClient.ConnectServiceManager();
+ try {
+
+ ServiceError error = SMSClient.SelectService(svmanager, serviceName);
+ if (error != ServiceError.None)
+ return -1;
+
+ svmanager.SendDeleteService();
+
+ switch receive {
+ case svmanager.Ok():
+ Console.WriteLine("Service was successfully deleted.");
+ return 0;
+
+ case svmanager.RequestFailed(err):
+ Console.WriteLine("Failed to delete service.");
+ SMSClient.ShowServiceError(err);
+ return -1;
+ }
+
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+ }
+
+ [ConsoleCategory(Action="enable", HelpMessage="Enable a service")]
+ internal class EnableServiceCommand
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("service", Mandatory=true, Position=0)]
+ internal string serviceName;
+
+ reflective internal EnableServiceCommand();
+
+ internal int AppMain()
+ {
+ assert serviceName != null;
+ if (serviceName.Length == 0) {
+ Console.WriteLine("Invalid service name.");
+ return -1;
+ }
+
+ ServiceManagerContract.Imp! svmanager = SMSClient.ConnectServiceManager();
+ try {
+
+ ServiceError error = SMSClient.SelectService(svmanager, serviceName);
+ if (error != ServiceError.None)
+ return -1;
+
+ svmanager.SendEnableService(true);
+
+ switch receive {
+ case svmanager.Ok():
+ Console.WriteLine("Service was successfully enabled.");
+ return 0;
+
+ case svmanager.RequestFailed(err):
+ Console.WriteLine("Failed to enable service.");
+ SMSClient.ShowServiceError(err);
+ return -1;
+ }
+
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+ }
+
+ [ConsoleCategory(Action="disable", HelpMessage="Disable a service")]
+ internal class DisableServiceCommand
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("service", Mandatory=true, Position=0)]
+ internal string serviceName;
+
+ reflective internal DisableServiceCommand();
+
+ internal int AppMain()
+ {
+ assert serviceName != null;
+ if (serviceName.Length == 0) {
+ Console.WriteLine("Invalid service name.");
+ return -1;
+ }
+
+ ServiceManagerContract.Imp! svmanager = SMSClient.ConnectServiceManager();
+ try {
+
+ ServiceError error = SMSClient.SelectService(svmanager, serviceName);
+ if (error != ServiceError.None)
+ return -1;
+
+ svmanager.SendEnableService(false);
+
+ switch receive {
+ case svmanager.Ok():
+ Console.WriteLine("Service was successfully disabled.");
+ return 0;
+
+ case svmanager.RequestFailed(err):
+ Console.WriteLine("Failed to disable service.");
+ SMSClient.ShowServiceError(err);
+ return -1;
+ }
+
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+ }
+
+ [ConsoleCategory(Action="kill", HelpMessage="Terminate the process(es) of a service.")]
+ internal class TerminateServiceCommand
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [StringParameter("service", Mandatory=true, Position=0)]
+ internal string serviceName;
+
+ [LongParameter("pid", Mandatory=false, Position=1, Default=-1)]
+ internal long processId;
+
+ reflective internal TerminateServiceCommand();
+
+ internal int AppMain()
+ {
+ assert serviceName != null;
+ if (serviceName.Length == 0) {
+ Console.WriteLine("Invalid service name.");
+ return -1;
+ }
+
+ ServiceManagerContract.Imp! svmanager = SMSClient.ConnectServiceManager();
+ try {
+
+ ServiceError error = SMSClient.SelectService(svmanager, serviceName);
+ if (error != ServiceError.None)
+ return -1;
+
+ if (processId != -1)
+ svmanager.SendTerminateServiceProcess((int)processId);
+ else
+ svmanager.SendTerminateServiceAllProcesses();
+
+ switch receive {
+ case svmanager.Ok():
+ return 0;
+
+ case svmanager.RequestFailed(err):
+ SMSClient.ShowServiceError(err);
+ return -1;
+ }
+
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+ }
+
+
public class SMSClient
{
- private static void GetEndpoint(out ServiceManagementContract.Imp! ep)
+ internal static ServiceManagerContract.Imp! ConnectServiceManager()
{
- ErrorCode error;
- DirectoryServiceContract.Imp ds;
- ServiceManagementContract.Exp! scServer;
- ServiceManagementContract.NewChannel(out ep, out scServer);
+ using (ImpatientWatcher watcher = new ImpatientWatcher("ConnectServiceManager", "create channel", 250)) {
+ ErrorCode error;
+ ServiceManagerContract.Imp! manager_imp;
+ ServiceManagerContract.Exp! manager_exp;
+ ServiceManagerContract.NewChannel(out manager_imp, out manager_exp);
- ds = DirectoryService.NewClientEndpoint();
- SdsUtils.Bind(ServiceManagementContract.ModuleName, ds,
- scServer, out error);
- delete ds;
+ watcher.NextStep("NewClientEndpoint", 250);
+
+ DirectoryServiceContract.Imp! rootds = DirectoryService.NewClientEndpoint();
+ try {
+ watcher.NextStep("SdsUtils.Bind", 1000);
+ if (SdsUtils.Bind(ServiceManagerContract.ModuleName, rootds, manager_exp, out error)) {
+ watcher.NextStep("RecvSuccess", 250);
+ manager_imp.RecvSuccess();
+ return manager_imp;
+ }
+ else {
+ delete manager_imp;
+ Console.WriteLine("Failed to contact the Service Manager. Error: " + SdsUtils.ErrorCodeToString(error));
+ throw new Exception("Failed to connect to Service Manager.");
+ }
+ }
+ finally {
+ delete rootds;
+ }
+ }
}
- internal static int StartService(StartConfig! config)
+ internal static ServiceError SelectService(ServiceManagerContract.Imp! svmanager, string! serviceName)
{
- int res = 1;
- ServiceType type = ServiceType.Unknown;
- ServiceInfo* in ExHeap info;
- ServiceManagementContract.Imp! ep;
- ServiceControlContract.Imp! client;
- ServiceControlContract.Exp! server;
-
- switch (config.type)
- {
- case "Resilient":
- type = ServiceType.Resilient;
- break;
- case "Default":
- type = ServiceType.Default;
- break;
- default:
- type = ServiceType.Default;
- break;
- }
-
- Console.Write("Starting service: " + config.service + " ... ");
- GetEndpoint(out ep);
- ep.RecvSuccess();
-
- ServiceControlContract.NewChannel(out client, out server);
- info = new[ExHeap] ServiceInfo(0, config.service, config.service,
- type);
- ep.SendBind(info, server);
+ svmanager.SendSelectService(Bitter.FromString2(serviceName));
switch receive {
- case ep.AckBind():
- break;
- case ep.NotFound(rejected):
- delete rejected;
- Console.WriteLine("Doesn't exist.");
- goto exit;
- break;
- case ep.PermissionDenied(rejected):
- delete rejected;
- Console.WriteLine("Permission denied");
- goto exit;
- break;
- }
+ case svmanager.Ok():
+ // Console.WriteLine("Successfully selected service '{0}'.", serviceName);
+ return ServiceError.None;
- client.RecvSuccess();
- client.SendStartService();
- switch receive {
- case client.RecvAckStartService():
- Console.WriteLine("done.");
- res = 0;
- break;
- case client.NakStartService(error):
- Console.WriteLine("Error code: " + error);
- break;
- case client.ChannelClosed():
- Console.WriteLine("Channel is closed.");
- break;
+ case svmanager.RequestFailed(error):
+ Console.WriteLine("Failed to select service '{0}'.", serviceName);
+ ShowServiceError(error);
+ return error;
+
+ case svmanager.ChannelClosed():
+ throw new Exception("Service Manager closed channel before responding.");
}
-exit:
- delete client;
- delete ep;
- return res;
}
- internal static int StopService(StopConfig! config)
+ internal static void ShowServiceError(ServiceError error)
{
- int res = 1;
- ServiceManagementContract.Imp! ep;
- ServiceControlContract.Imp! client;
- ServiceControlContract.Exp! server;
-
- Console.Write("Stopping service: " + config.id + " ... ");
- GetEndpoint(out ep);
- ep.RecvSuccess();
-
- ServiceControlContract.NewChannel(out client, out server);
- ep.SendGetControl((int)config.id, server);
- switch receive {
- case ep.RecvAckGetControl():
- break;
- case ep.NotFound(rejected):
- delete rejected;
- Console.WriteLine("Doesn't exist.");
- goto exit;
- break;
- case ep.PermissionDenied(rejected):
- delete rejected;
- Console.WriteLine("Permission denied");
- goto exit;
- break;
- case ep.TryAgain(rejected):
- delete rejected;
- Console.WriteLine("Busy!");
- goto exit;
- break;
- }
-
- client.RecvSuccess();
- client.SendStopService();
- switch receive {
- case client.AckStopService():
- Console.WriteLine("done.");
- res = 0;
- break;
- case client.NakStopService(error):
- Console.WriteLine("Error code: " + error);
- break;
- }
-exit:
- delete client;
- delete ep;
- return res;
+ Console.WriteLine("ServiceError: " + ServiceEnums.ToString(error));
}
- internal static int RestartService(RestartConfig! config)
+ static internal int StartService(string! serviceName, bool wait)
{
- Console.WriteLine("-- Sorry, not implemented yet.");
- return 1;
+ ServiceManagerContract.Imp! svmanager = ConnectServiceManager();
+
+ try {
+
+ ServiceError error = SelectService(svmanager, serviceName);
+ if (error != ServiceError.None) {
+ return -1;
+ }
+
+ if (wait) {
+ svmanager.SendStartServiceWait();
+
+ for (;;) {
+ switch receive {
+ case svmanager.RequestFailed(err):
+ ShowServiceError(err);
+ return -1;
+
+ case svmanager.ServiceStarting():
+ Console.WriteLine("Service Manager accepted request to start service '{0}'.", serviceName);
+ return 0;
+
+ case timeout(TimeSpan.FromSeconds(10)):
+ Console.WriteLine("waiting...");
+ break;
+ }
+ }
+ }
+ else {
+ svmanager.SendStartServiceNoWait();
+
+ switch receive {
+ case svmanager.RequestFailed(err):
+ ShowServiceError(err);
+ return -1;
+
+ case svmanager.ServiceStarting():
+ Console.WriteLine("Service Manager accepted request to start service '{0}'.", serviceName);
+ return 0;
+ }
+ }
+ }
+ finally {
+ delete svmanager;
+ }
}
+ internal static int StopService(string! serviceName, bool wait)
+ {
+ ServiceManagerContract.Imp! svmanager = ConnectServiceManager();
+
+ try {
+
+ ServiceError error = SelectService(svmanager, serviceName);
+ if (error != ServiceError.None)
+ return -1;
+
+ if (wait) {
+ svmanager.SendStopServiceWait();
+
+ for (;;) {
+ switch receive {
+ case svmanager.RequestFailed(err):
+ ShowServiceError(err);
+ if (err == ServiceError.CannotStopService) {
+ Console.WriteLine("If this service is an 'always active' service, then the stop command cannot be used.");
+ Console.WriteLine("Instead, use the 'disable' command.");
+ }
+ return -1;
+
+ case svmanager.ServiceStopping():
+ Console.WriteLine("Service Manager accepted request to stop service '{0}'.", serviceName);
+ return 0;
+
+ case timeout(TimeSpan.FromSeconds(10)):
+ Console.WriteLine("waiting...");
+ break;
+ }
+ }
+ }
+ else {
+ svmanager.SendStopServiceNoWait();
+
+ switch receive {
+ case svmanager.RequestFailed(err):
+ ShowServiceError(err);
+ return -1;
+
+ case svmanager.ServiceStopping():
+ Console.WriteLine("Service Manager accepted request to stop service '{0}'.", serviceName);
+ return 0;
+ }
+ }
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+
+ internal static int WatchService(string! serviceName)
+ {
+ ServiceManagerContract.Imp! svmanager = ConnectServiceManager();
+
+ try {
+
+ ServiceError error = SelectService(svmanager, serviceName);
+ if (error != ServiceError.None) {
+ return -1;
+ }
+
+ svmanager.SendWatchServiceStatus();
+
+ switch receive {
+ case svmanager.RequestFailed(err):
+ ShowServiceError(err);
+ return -1;
+
+ case svmanager.Ok():
+ Console.WriteLine("Service Manager accepted request to watch service '{0}'.", serviceName);
+ break;
+ }
+
+ for (;;) {
+ svmanager.SendWaitServiceChange();
+
+ switch receive {
+ case svmanager.ServiceStatusChanged(ServiceStatus status, bool missedChange):
+ Console.WriteLine("Status changed: ");
+ Console.WriteLine(" State: " + ServiceEnums.ToString(status.State));
+ if (missedChange) {
+ Console.WriteLine(" Note: At least one status change was missed.");
+ }
+ break;
+
+ case svmanager.RequestFailed(err):
+ Console.WriteLine("Request failed.");
+ ShowServiceError(err);
+ return -1;
+
+ case svmanager.ChannelClosed():
+ Console.WriteLine("Service Manager closed channel!");
+ return -1;
+ }
+ }
+
+ }
+ finally {
+ delete svmanager;
+ }
+ }
+
+ const string ListServiceFormat = "{0,-20} {1,-10} {2,-6} {3}";
+
internal static int ListServices(ListConfig! config)
{
- bool next = false;
- int count = 0;
- ServiceManagementContract.Imp! ep;
+ ServiceManagerContract.Imp! svmanager = ConnectServiceManager();
- GetEndpoint(out ep);
- ep.RecvSuccess();
- ep.SendBeginEnumeration();
- Console.WriteLine();
- Console.WriteLine("PID Task Name");
- Console.WriteLine("=== ===================");
- do {
- switch receive {
- case ep.RecvCurrent(info):
- ++count;
- Console.WriteLine("{0,3} {1,-19}",
- info->Id, info->Name);
- delete info;
- ep.SendMoveNext();
- next = true;
- break;
- case ep.RecvEnumerationTerminated():
- next = false;
- break;
- case ep.ChannelClosed():
- next = false;
- break;
+ try {
+ Console.WriteLine(ListServiceFormat, "Name", "State", "PID", "Display Name");
+ Console.WriteLine(ListServiceFormat,
+ new String('-', 20),
+ new String('-', 10),
+ new String('-', 6),
+ new String('-', 30));
+
+ ServiceInfo[]! in ExHeap first_entries = new[ExHeap] ServiceInfo[40];
+ svmanager.SendEnumerateServices(first_entries);
+
+ for (;;) {
+ switch receive {
+ case svmanager.EnumerationTerminated(entries, count):
+ ListServices(entries, count);
+ delete entries;
+ return 0;
+
+ case svmanager.NextServiceInfo(entries, count):
+ ListServices(entries, count);
+ svmanager.SendEnumerateServices(entries);
+ break;
+
+ case svmanager.ChannelClosed():
+ Console.WriteLine("Service Manager channel closed");
+ return -1;
+
+ }
}
- } while (next);
- Console.WriteLine();
- Console.WriteLine(count + " services are found.");
-
- delete ep;
- return 0;
+ }
+ finally {
+ delete svmanager;
+ }
}
- internal static int DefaultMain(DefaultConfig! config)
+ static void ListServices(ServiceInfo[]! in ExHeap entries, int count)
{
- Console.WriteLine("Usage: svconf [name] [type]");
- Console.WriteLine(" @start Start the service");
- Console.WriteLine(" @stop Stop the service");
- //Console.WriteLine(" @restart Restart the service");
- Console.WriteLine(" @list Show a list of running services");
- Console.WriteLine(" type: Default or Resilient");
+ for (int i = 0; i < count; i++) {
+ expose(entries[i])
+ {
+ string! serviceName = ToString(entries[i].Config.ServiceName);
+ string! displayName = ToString(entries[i].Config.DisplayName);
+ string! stateString = ServiceEnums.ToString(entries[i].Status.State);
+ string! processIdString = entries[i].Status.ProcessId != -1 ?
+ (!)entries[i].Status.ProcessId.ToString() : "";
+ Console.WriteLine(ListServiceFormat, serviceName, stateString, processIdString, displayName);
+ }
+ }
+ }
- return 0;
+ public static string! ToString(char[] in ExHeap str)
+ {
+ if (str != null)
+ return Bitter.ToString2(str);
+ else
+ return "";
+ }
+
+ public static void ShowConfigDetailed(ServiceConfig config)
+ {
+ if (config.ServiceName == null) {
+ Console.WriteLine("Error: A ServiceConfig structure had a null ServiceName field.");
+ return;
+ }
+ string! serviceName = Bitter.ToString2(config.ServiceName);
+
+ string! executableName = config.ExecutableName != null ? Bitter.ToString2(config.ExecutableName) : "";
+ string! displayName = config.DisplayName != null ? Bitter.ToString2(config.DisplayName) : "";
+
+ Console.WriteLine("Service Configuration");
+ Console.WriteLine("---------------------");
+ Console.WriteLine();
+ Console.WriteLine(DetailFormat, "Service Name", serviceName);
+ Console.WriteLine(DetailFormat, "Executable", executableName);
+ Console.WriteLine(DetailFormat, "Display Name", displayName);
+ Console.WriteLine(DetailFormat, "Activation Mode", ServiceEnums.ToString(config.ActivationMode));
+ Console.WriteLine(DetailFormat, "Is Disabled?", config.IsAdministrativelyDisabled.ToString());
+
+ Console.WriteLine(DetailFormat, "Min/Max Processes", String.Format("min {0} / {1}",
+ config.MinProcesses,
+ config.MaxProcesses == ServiceConfig.UnlimitedProcesses ? "no max" : "max " + config.MaxProcesses));
+
+ string! max_age_text;
+ if (config.MaxProcessAgeInSeconds == ServiceConfig.UnlimitedProcessAge)
+ max_age_text = "unlimited";
+ else {
+ TimeSpan limit = TimeSpan.FromSeconds(config.MaxProcessAgeInSeconds);
+ max_age_text = (!)limit.ToString();
+ }
+ Console.WriteLine(DetailFormat, "Max Process Age", max_age_text);
+
+ string clients_per_process_text;
+ if (config.MaxClientsPerProcess == ServiceConfig.UnlimitedClientsPerProcess) {
+ clients_per_process_text = "unlimited";
+ }
+ else {
+ clients_per_process_text = config.MaxClientsPerProcess.ToString();
+ }
+ Console.WriteLine(DetailFormat, "Max Clients per Process", clients_per_process_text);
+
+ }
+
+ const string DetailFormat = "{0,-25}: {1}";
+
+ public static void ShowStatusDetailed(ServiceStatus status)
+ {
+ Console.WriteLine("Service Status");
+ Console.WriteLine("--------------");
+ Console.WriteLine();
+ Console.WriteLine(DetailFormat, "State", ServiceEnums.ToString(status.State));
+ if (status.State != ServiceState.Stopped) {
+ Console.WriteLine(DetailFormat, "Process ID", status.ProcessId);
+ }
+
+ // This is not yet accurate.
+ // Console.WriteLine(DetailFormat, "Total Active Clients", status.TotalActiveClients);
+
+ Console.WriteLine(DetailFormat, "Total Active Processes", status.TotalActiveProcesses);
+ Console.WriteLine(DetailFormat, "Connect Queue Length", status.ConnectQueueLength);
+
+ Console.WriteLine(DetailFormat, "Last Process Start", status.LastStartFailed ? "FAILED" : "Succeeded");
+ if (status.LastStartFailed) {
+ Console.WriteLine(DetailFormat, "Last Start Error", ServiceEnums.ToString(status.LastStartError));
+ }
}
}
+
}
diff --git a/base/Applications/ServiceManager/SMSClient/SMSClient.csproj b/base/Applications/ServiceManager/SMSClient/SMSClient.csproj
index 8f459c7..57d374b 100644
--- a/base/Applications/ServiceManager/SMSClient/SMSClient.csproj
+++ b/base/Applications/ServiceManager/SMSClient/SMSClient.csproj
@@ -1,8 +1,6 @@

+
diff --git a/base/Applications/ServiceManager/TryEnter/Main.sg b/base/Applications/ServiceManager/TryEnter/Main.sg
deleted file mode 100644
index c5d18f7..0000000
--- a/base/Applications/ServiceManager/TryEnter/Main.sg
+++ /dev/null
@@ -1,110 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-
-using System;
-using System.Threading;
-using Microsoft.SingSharp;
-using Microsoft.SingSharp.Reflection;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Applications;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Configuration;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.Io;
-
-[assembly: Transform(typeof(ApplicationResourceTransform))]
-
-namespace Microsoft.Singularity.Applications.ServiceManager
-{
- [ConsoleCategory(HelpMessage="TryEnter Test", DefaultAction=true)]
- internal class DefaultConfig
- {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- reflective internal DefaultConfig();
-
- internal int AppMain()
- {
- return Main.AppMain(this);
- }
- }
-
-
- internal class Worker
- {
- private Main! parent;
- private int id;
-
- internal Worker(Main! parent, int id)
- {
- this.parent = parent;
- this.id = id;
- }
-
- internal void Run()
- {
- Console.WriteLine("Thread {0} start\n", id);
- for (int i = 0; i < 10; i++) {
- parent.Enter(id);
- Thread.Sleep(100);
- }
- Console.WriteLine("Thread {0} end\n", id);
- }
- }
-
- internal class Main
- {
- private Object! mutex = new Object();
- private int count = 0;
-
- public void Start(int number)
- requires number >= 0;
- {
- Thread![] thread = new Thread![number];
- Worker[] worker = new Worker[number];
-
- for (int i = 0; i < number; i++) {
- worker[i] = new Worker(this, i);
- thread[i] = new Thread(new ThreadStart(worker[i].Run));
- }
-
- for (int i = 0; i < number; i++) {
- thread[i].Start();
- }
-
- for (int i = 0; i < number; i++) {
- thread[i].Join();
- }
- }
-
- internal void Enter(int id)
- {
- assert mutex != null;
-
- Console.WriteLine("{0} try enter", id);
- if (!Monitor.TryEnter(mutex)) {
- // Never reached here
- Console.WriteLine("{0} couldn't get monitor", id);
- ++count;
- return;
- }
- Console.WriteLine("{0} got monitor", id);
- Thread.Sleep(1000);
- Monitor.Exit(mutex);
- Console.WriteLine("{0} exit (count: {1})", id, count);
- }
-
- internal static int AppMain(DefaultConfig! config)
- {
- new Main().Start(4);
-
- return 0;
- }
- }
-}
diff --git a/base/Applications/ServiceManager/TryEnter/TryEnterTest.csproj b/base/Applications/ServiceManager/TryEnter/TryEnterTest.csproj
deleted file mode 100644
index 594c18d..0000000
--- a/base/Applications/ServiceManager/TryEnter/TryEnterTest.csproj
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
- Exe
- TryEnterTest
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Shell/Breaker.cs b/base/Applications/Shell/Breaker.cs
index 91921c7..ff03bd9 100644
--- a/base/Applications/Shell/Breaker.cs
+++ b/base/Applications/Shell/Breaker.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Breaker.cs
-//
// Note:
//
diff --git a/base/Applications/Shell/Manifest.sg b/base/Applications/Shell/Manifest.sg
deleted file mode 100644
index 165ef5a..0000000
--- a/base/Applications/Shell/Manifest.sg
+++ /dev/null
@@ -1,292 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: Manifest.cs
-//
-// Note: Creates and binds endpoints using a manifest.
-//
-
-using System;
-using System.Text;
-using System.Collections;
-
-using Microsoft.SingSharp;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Directory;
-using Microsoft.Singularity.Extending;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.Memory;
-using Microsoft.Singularity.Xml;
-
-namespace Microsoft.Singularity.Applications
-{
-
- ///
- /// This is a placeholder class for an application's manifest.
- /// At present the application manifest is represented by a hashtable.
- /// The hashtable has several important properties:
- /// - name: the name of the application
- /// - path: path to the application executable
- ///
- public class Manifest
- {
- ///
- /// We treat the application manifest as a collection of
- /// key, value pairs.
- ///
-
-
- private Hashtable! data = new Hashtable();
- private const string pipeContract = "Microsoft.Singularity.Io.UnicodePipeContract";
-
- private string name;
- private string path;
-
- private readonly XmlNode! applicationNode;
- private readonly XmlNode! processNode;
- private readonly XmlNode actionNode;
- private readonly XmlNode categoriesNode;
- private readonly XmlNode stringParametersNode;
- private readonly XmlNode stringArrayParametersNode;
- private readonly XmlNode longParametersNode;
- private readonly XmlNode boolParametersNode;
- private static StringBuilder sb;
-
- ///
- /// Create a manifest object from the given xml representation
- ///
-
- [Microsoft.Contracts.NotDelayed]
- public Manifest(byte[] xml)
- {
- XmlReader! reader = new XmlReader(xml);
- XmlNode! doc = (!)reader.Parse();
-
- this(doc);
- }
-
- [Microsoft.Contracts.NotDelayed]
- private Manifest(XmlNode! doc)
- {
- XmlNode app = (!)doc.GetChild("application");
- name = app["name"];
- XmlNode proc = null;
- foreach (XmlNode! process in app.Children) {
- if (process.Name != "process") {
- continue;
- }
- if (process.GetAttribute("main", "false") == "true") {
- path = process["path"];
- proc = process;
- break;
- }
- }
- applicationNode = (!)app;
- XmlNode! processNode = this.processNode = (!)proc;
- base();
-
- categoriesNode = processNode.GetChild("categories");
-
- if (categoriesNode != null) {
- return;
- }
- else {
- DebugStub.WriteLine("::: no category");
- }
- }
-
- public XmlNode GetCategoriesNode()
- {
- return categoriesNode;
- }
-
-
- public void SetProperty(object! name, object value)
- {
- data[name] = value;
- }
-
- public string Name
- {
- get {
- return name;
- }
- }
-
- public string Path
- {
- get {
- return path;
- }
- }
-
- public string GetHelpMessage(XmlNode categoryNode)
- {
- return categoryNode == null? null : categoryNode.GetAttribute("HelpMessage", null);
- }
-
-
- // given an action find the corresponding category node
- public XmlNode GetCategoryNode(string actionName) {
- if (categoriesNode == null) {
- //Console.WriteLine("GetCategoryNode: no categories!");
- return null;
- }
- if (actionName == null) {
- // return the 1st one if there is one
- //Console.WriteLine("GetCategoryNode: Selecting default!");
- XmlNode n = categoriesNode.GetChild("category");
- if (n == null) {
- return null;
- }
- else return n;
- }
- else {
- foreach (XmlNode! c in categoriesNode.Children) {
- string a = c.GetAttribute("Action",null);
- //Console.WriteLine("action= {0}.",a);
- if ( a != null && a == actionName) {
- //Console.WriteLine("found a match for action {0}",actionName);
- return c;
- }
- }
- return null;
- }
- }
-
- public XmlNode GetBoolParameterNode(XmlNode! category)
- {
- return category.GetChild("BoolParameters");
- }
-
- public XmlNode GetStringArrayParameterNode(XmlNode! category)
- {
- return category.GetChild("StringArrayParameters");
- }
-
- public XmlNode GetStringParameterNode(XmlNode! category)
- {
- return category.GetChild("StringParameters");
- }
-
- public XmlNode GetLongParameterNode(XmlNode! category)
- {
- return category.GetChild("LongParameters");
- }
-
- public bool HasParameters()
- {
- return (categoriesNode != null);
- }
-
-#if false
- public void ShowParameters()
- {
- if (categoryNode == null) {
- Console.WriteLine("::: no category");
- return;
- }
- if (stringParametersNode == null) {
- Console.WriteLine("::: no strings");
- }
- if (longParametersNode == null) {
- Console.WriteLine("::: no integers");
- }
- }
-#endif
- public int SetEndpoints(Process process, string action, bool show)
- {
- // walk the XmlTree looking endpoints
- // these will be used by the binder to setup and transfer to
- // the starting process much like what is done for drivers
-
- XmlNode categoryNode = GetCategoryNode(action);
- //Console.WriteLine(" Set endpoints");
- if (categoryNode == null) {
- Console.WriteLine("No endpoints in console app!");
- //DebugStub.Break();
- return 0;
- }
-
- XmlNode endpoints = categoryNode.GetChild("endpoints");
- if (endpoints == null) {
- //DebugStub.Break();
- return 0;
- }
- int endpointCount = endpoints.GetAttribute("length", 0);
- if (endpointCount == 0) {
- DebugStub.Break();
- return 0;
- }
-
- //fill in ep set
- foreach (XmlNode! endpoint in endpoints.Children) {
- string! contract
- = (!)endpoint.GetAttribute("contractName", "");
- int index = endpoint.GetAttribute("id", -1);
-
- if (endpoint.Name == "endpoint") {
- // FIXFIX -- if it is a pipe ignore it for now
- if (show) {
- Console.WriteLine(" endpoint: {0}", contract);
- }
- else {
- if (contract != pipeContract) {
- // get a pre-bound generic endpoint to a service from the
- // resource tracker
- if (process == null) {
- throw new Exception("Process arg was null.");
- }
- if (!Binder.BindServiceUser(process, index, contract, endpoint)) {
- return -1;
- }
- }
- else {
- DebugStub.WriteLine("shell.manifest.SetEndpoints: skipping pipe at {0}", __arglist(index));
- }
- }
- }
- }
- return endpointCount;
- }
-
-#if false
- public override string! ToString()
- {
- StringBuilder sb = new StringBuilder();
-
- sb.AppendFormat("", Name);
-
- // the main executable
- sb.AppendFormat("", Path);
-
- foreach(DataItem item in data.Values) {
- if (item.Directory == null) {
- sb.AppendFormat("",
- item.Name, item.Value);
- }
- else {
- sb.AppendFormat("",
- item.Directory, item.Name, item.Value);
- }
- }
-
- sb.Append("");
- sb.Append("");
- sb.Append("");
- sb.Append("");
-
- return sb.ToString();
- }
-
- public byte[] Serialize()
- {
- return (new UTF8Encoding()).GetBytes(ToString());
- }
-#endif
- }
-}
diff --git a/base/Applications/Shell/Parser.cs b/base/Applications/Shell/Parser.cs
index 83311d2..ef04dc8 100644
--- a/base/Applications/Shell/Parser.cs
+++ b/base/Applications/Shell/Parser.cs
@@ -1,10 +1,8 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
+// ----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-///////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
using System;
using System.Collections;
@@ -13,15 +11,15 @@ using Microsoft.Contracts;
namespace Microsoft.Singularity.Applications
{
- /**
- * This is a general lr parser driver.
- * Parses the programming by first lexing it into a number
- * of tokens for a token stack. Then parser then pops tokens off
- * this stack, consults the parse tables and push the corresponding
- * nonterminals and states on the operand stack. This is the same
- * algorithm from the dragon book with some tweaks to support optional
- * tokens (i.e. newlines).
- **/
+ ///
+ // This is a general lr parser driver.
+ // Parses the programming by first lexing it into a number
+ // of tokens for a token stack. Then parser then pops tokens off
+ // this stack, consults the parse tables and push the corresponding
+ // nonterminals and states on the operand stack. This is the same
+ // algorithm from the dragon book with some tweaks to support optional
+ // tokens (i.e. newlines).
+ //
abstract class Parser
{
private const int END_INPUT_MARKER_ID = 2;
@@ -66,16 +64,18 @@ namespace Microsoft.Singularity.Applications
leftStack.Push(st);
leftStack.Push(tok);
leftStack.Push(new State(action.stateOrProduction));
- } else if (action.type == ActionType.REDUCE) {
+ }
+ else if (action.type == ActionType.REDUCE) {
Production production = (!)ProductionTable[action.stateOrProduction];
Object value = production.Reduction(leftStack);
StackElement topLeft = (StackElement)leftStack.Pop();
State previousState;
if (topLeft is State) {
previousState = (State)topLeft;
- } else {
+ }
+ else {
leftStack.Push(topLeft);
- previousState = st; /* took an epsilon transition */
+ previousState = st; // took an epsilon transition
}
State nextState = GotoTable[previousState.id, production.NonterminalType];
if (nextState == null) throw new Exception("missing state");
@@ -83,7 +83,8 @@ namespace Microsoft.Singularity.Applications
leftStack.Push(new Nonterminal(production.NonterminalType, value));
leftStack.Push(nextState);
rightStack.Push(tok);
- } else if (action.type == ActionType.ACCEPT) {
+ }
+ else if (action.type == ActionType.ACCEPT) {
break;
}
}
@@ -121,7 +122,8 @@ namespace Microsoft.Singularity.Applications
spec.Lexer(token);
if (token.value != null)
tokens.Add(token);
- } else {
+ }
+ else {
tokens.Add(new Token(spec.Type, match.Value, lineNumber, charIndex));
}
int lastIndex;
@@ -129,7 +131,8 @@ namespace Microsoft.Singularity.Applications
if (occurrences > 0) {
lineNumber += occurrences;
charIndex = match.Value.Length - (lastIndex + 1);
- } else {
+ }
+ else {
charIndex += match.Value.Length;
}
goto outer;
@@ -159,10 +162,13 @@ namespace Microsoft.Singularity.Applications
public readonly int id;
public Object value;
public StackElement(int id) { this.id = id; }
+#if false
+ // Error: Bartok can not handle complicated override pattern of System.Object.ToString. [Specifically, it was overridden via a MethodImpl or replaced via interface method reimplementation, effectively merging two virtual slots. Then the original slot was overridden by Microsoft.Singularity.Applications.Parser.Token.ToString, effectively splitting the slots again. Bartok currently can not analyze the split.]
public override string! ToString()
{
return id.ToString();
}
+#endif
}
public class State : StackElement
{
@@ -183,10 +189,13 @@ namespace Microsoft.Singularity.Applications
this.optional = optional;
}
+#if false
+ // Error: Bartok can not handle complicated override pattern of System.Object.ToString. [Specifically, it was overridden via a MethodImpl or replaced via interface method reimplementation, effectively merging two virtual slots. Then the original slot was overridden by Microsoft.Singularity.Applications.Parser.Token.ToString, effectively splitting the slots again. Bartok currently can not analyze the split.]
public override string! ToString()
{
return value + ":" + id;
}
+#endif
}
private class Nonterminal : StackElement
{
diff --git a/base/Applications/Shell/ScriptEngine.cs b/base/Applications/Shell/ScriptEngine.cs
index cf7005f..d4d29ef 100644
--- a/base/Applications/Shell/ScriptEngine.cs
+++ b/base/Applications/Shell/ScriptEngine.cs
@@ -1,14 +1,11 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
+// ----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-///////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
using System;
using System.Collections;
-using System.IO;
using System.Text.RegularExpressions;
using System.Text;
using Microsoft.Singularity;
@@ -17,25 +14,25 @@ using Microsoft.Contracts;
namespace Microsoft.Singularity.Applications
{
- /**
- * Provides a reasonable script engine implementation.
- * This engine is composed of two distinct parts: the parser
- * and the interpreter. Parser.cs and ScriptParser.cs provide
- * the parsing functionality. Parser.cs is the general handwritten slr
- * driver while ScriptParser contains the automatically generated
- * parse tables and semantic action functions for productions
- * and lex operations of this specific scripting language. This file
- * provides the interpretation mechanism that runs over an ast produced
- * by the parser.
- **/
+ ///
+ // Provides a reasonable script engine implementation.
+ // This engine is composed of two distinct parts: the parser
+ // and the interpreter. Parser.cs and ScriptParser.cs provide
+ // the parsing functionality. Parser.cs is the general handwritten slr
+ // driver while ScriptParser contains the automatically generated
+ // parse tables and semantic action functions for productions
+ // and lex operations of this specific scripting language. This file
+ // provides the interpretation mechanism that runs over an ast produced
+ // by the parser.
+ //
class ScriptEngine
{
private String script;
private Block parsedScript;
public const String LAST_COMMAND_EXIT_SYMBOL = "?";
public const String NUM_ARGUMENTS_SYM = "#";
- public delegate int CommandLineRunner(ShellControl! shellControl,
- String[] commandLine,
+ public delegate int CommandLineRunner(ShellControl! shellControl,
+ String[] commandLine,
bool isBackground);
private CommandLineRunner runner;
@@ -52,21 +49,26 @@ namespace Microsoft.Singularity.Applications
ScriptEngine engine = new ScriptEngine(script, runner);
try {
engine.Parse();
- } catch (Parser.ParseException e) {
+ }
+ catch (Parser.ParseException e) {
Console.WriteLine(e.Message);
return -1;
- } catch (Exception e) {
+ }
+ catch (Exception e) {
Console.WriteLine(e.Message);
return -1;
}
try {
return engine.Run(shellControl, arguments);
- } catch (Interpretation.InterpretationException e) {
+ }
+ catch (Interpretation.InterpretationException e) {
Console.WriteLine(e.Message);
- } catch (ScriptException e) {
+ }
+ catch (ScriptException e) {
Console.WriteLine(e.Message);
- } catch (Exception e) {
+ }
+ catch (Exception e) {
Console.WriteLine(e.Message);
}
return -1;
@@ -123,8 +125,10 @@ namespace Microsoft.Singularity.Applications
{
get {
Object exitCode = LookupSymbol(LAST_COMMAND_EXIT_SYMBOL);
- if (exitCode == null) { return 0; }
- return (Int32) exitCode;
+ if (exitCode == null) {
+ return 0;
+ }
+ return (Int32) exitCode;
}
set { SetSymbol(LAST_COMMAND_EXIT_SYMBOL, value); }
}
@@ -178,7 +182,7 @@ namespace Microsoft.Singularity.Applications
public DivideByZeroException() : base("Division by zero undefined.") { }
}
-
+
}
public abstract class Element { }
@@ -219,9 +223,11 @@ namespace Microsoft.Singularity.Applications
Object value = GetValue(interp);
if (value is String) {
return Int32.Parse((String)value);
- } else if (value is Int32) {
+ }
+ else if (value is Int32) {
return (int)value;
- } else if (value is bool) {
+ }
+ else if (value is bool) {
return ((bool)value) ? 1 : 0;
}
throw new Interpretation.UnknownTypeException(value.GetType().ToString());
@@ -233,14 +239,17 @@ namespace Microsoft.Singularity.Applications
if (value is String) {
try {
return Boolean.Parse((String)value);
- } catch (FormatException) {
+ }
+ catch (FormatException) {
throw new Interpretation.TypeConversionException((String)value, "bool");
}
- } else if (value is Int32) {
+ }
+ else if (value is Int32) {
return ((int)value) == 0 ? true : false;
- } else if (value is Boolean) {
+ }
+ else if (value is Boolean) {
return (bool)value;
}
throw new Interpretation.UnknownTypeException(value.GetType().ToString());
@@ -369,15 +378,21 @@ namespace Microsoft.Singularity.Applications
private static int CompareTo(Object left, Expression e, Interpretation! interp)
{
if (left == null) {
- if (e == null) { return 0; }
+ if (e == null) {
+ return 0;
+ }
return -1;
}
- if (e == null) { return 1; }
+ if (e == null) {
+ return 1;
+ }
if (left is String) {
return ((String)left).CompareTo(e.StringValue(interp));
- } else if (left is int) {
+ }
+ else if (left is int) {
return ((int)left).CompareTo(e.IntValue(interp));
- } else if (left is Boolean) {
+ }
+ else if (left is Boolean) {
return ((Boolean)left).CompareTo(e.BoolValue(interp));
}
throw new Interpretation.UnknownTypeException("unsupported type");
@@ -477,7 +492,8 @@ namespace Microsoft.Singularity.Applications
String value = StringValue(interp);
try {
return Int32.Parse(value);
- } catch (FormatException) {
+ }
+ catch (FormatException) {
throw new Interpretation.TypeConversionException(value, "String");
}
}
@@ -487,7 +503,8 @@ namespace Microsoft.Singularity.Applications
String value = StringValue(interp);
try {
return Boolean.Parse(value);
- } catch (FormatException) {
+ }
+ catch (FormatException) {
throw new Interpretation.TypeConversionException(value, "String");
}
}
@@ -504,7 +521,7 @@ namespace Microsoft.Singularity.Applications
ArrayList chunks = new ArrayList();
char last = (char) -1;
int lastIndex = 0;
- for (int i = 0; i < interpolation.Length; last = interpolation[i], ++i) {
+ for (int i = 0; i < interpolation.Length; last = interpolation[i], ++i) {
if (interpolation[i] == '$' && last != '\\') {
chunks.Add(interpolation.Substring(lastIndex, i - lastIndex));
lastIndex = i + 1;
@@ -535,7 +552,8 @@ namespace Microsoft.Singularity.Applications
}
var = split_i.Substring(1, index - 1);
rest = index + 1 < split_i.Length ? split_i.Substring(index + 1) : "";
- } else {
+ }
+ else {
Match m = whitespace.Match(split_i);
assert m != null;
int index = m.Success ? m.Index : split_i.Length;
@@ -637,7 +655,8 @@ namespace Microsoft.Singularity.Applications
{
if (condition.BoolValue(interp)) {
trueBlock.Interpret(shellControl, interp);
- } else {
+ }
+ else {
falseBlock.Interpret(shellControl, interp);
}
}
@@ -706,19 +725,25 @@ namespace Microsoft.Singularity.Applications
try {
int exitCode = Int32.Parse(arguments[1]);
interp.ExitCode = exitCode;
- } catch (FormatException) {
+ }
+ catch (FormatException) {
throw new Interpretation.TypeConversionException((String)arguments[1], "integer");
}
}
interp.Exit = true;
- } else {
- try {
- int exitCode = interp.runner(shellControl, arguments, async);
- interp.ExitCode = exitCode;
- }
- catch (FileNotFoundException) {
- interp.Exit = true;
- }
+ }
+ else if (false) {
+ //
+ //arguments[0].Trim() == "read") {
+ //string input = Console.ReadLine();
+ //String[] split = whitespace.Split(input);
+ //for (int j = 1, k = 0; j < arguments.Length && k < split.Length; ++j, ++k) {
+ //interp.SetSymbol(arguments[j], split[k]);
+ //
+ }
+ else {
+ int exitCode = interp.runner(shellControl, arguments, async);
+ interp.ExitCode = exitCode;
}
}
}
diff --git a/base/Applications/Shell/Shell.csproj b/base/Applications/Shell/Shell.csproj
index f3c3159..df9ece1 100644
--- a/base/Applications/Shell/Shell.csproj
+++ b/base/Applications/Shell/Shell.csproj
@@ -1,8 +1,6 @@
-
-
-
-
-
- Exe
- Sleep
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Sleep/sleep.csproj b/base/Applications/Sleep/sleep.csproj
new file mode 100644
index 0000000..ce4cf3d
--- /dev/null
+++ b/base/Applications/Sleep/sleep.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ Exe
+ sleep
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Slides/DemoDeck.pdf b/base/Applications/Slides/DemoDeck.pdf
new file mode 100644
index 0000000..650e3a8
Binary files /dev/null and b/base/Applications/Slides/DemoDeck.pdf differ
diff --git a/base/Applications/Slides/DemoDeck.ppt b/base/Applications/Slides/DemoDeck.ppt
deleted file mode 100644
index 016306a..0000000
Binary files a/base/Applications/Slides/DemoDeck.ppt and /dev/null differ
diff --git a/base/Applications/Slides/Resources.cpp b/base/Applications/Slides/Resources.cpp
index 65e4917..8596b5d 100644
--- a/base/Applications/Slides/Resources.cpp
+++ b/base/Applications/Slides/Resources.cpp
@@ -1,7 +1,8 @@
-///////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
+// ----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////
//
diff --git a/base/Applications/Slides/Slide.bmp b/base/Applications/Slides/Slide.bmp
deleted file mode 100644
index 42f8b89..0000000
Binary files a/base/Applications/Slides/Slide.bmp and /dev/null differ
diff --git a/base/Applications/Slides/Slides.csproj b/base/Applications/Slides/Slides.csproj
index d5bf87c..d1317f4 100644
--- a/base/Applications/Slides/Slides.csproj
+++ b/base/Applications/Slides/Slides.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ StartProcess
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/SysInfo/SysInfo.cs b/base/Applications/SysInfo/SysInfo.cs
new file mode 100644
index 0000000..5ab118d
--- /dev/null
+++ b/base/Applications/SysInfo/SysInfo.cs
@@ -0,0 +1,235 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Utility program to query the system information
+//
+using System;
+using System.Diagnostics;
+using System.Net.IP;
+using System.Text.RegularExpressions;
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+using Microsoft.SingSharp;
+using NetStack.Contracts;
+using NetStack.Channels.Public;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Eventing;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications
+{
+
+ [ConsoleCategory(HelpMessage="Test utility application", DefaultAction=true)]
+ internal class DefaultConfig
+ {
+ [Endpoint]
+ public readonly TRef Stdin;
+
+ [Endpoint]
+ public readonly TRef Stdout;
+
+ [StringParameter( "S", Mandatory=false, HelpMessage="Source filter")]
+ internal string SourceFilter;
+
+ [BoolParameter( "a", Default=false, HelpMessage="display all events")]
+ internal bool DumpAll;
+
+ reflective internal DefaultConfig();
+
+ internal int AppMain() {
+ return SysInfo.DefaultMain(this);
+ }
+ }
+
+ public class SysInfo
+ {
+
+ static string SourceFilter;
+ static bool DumpAll;
+
+ [CLSCompliant(false)]
+ static internal bool ActiveEntryDelegate(UIntPtr sourceHandle,
+ int index,
+ EventDescriptor descriptor,
+ QueryBuffer entryBuffer,
+ ref EnumerationContext context)
+ {
+ if (!DumpAll) {
+
+ return false;
+ }
+
+ if (descriptor != null) {
+ Console.Write("{0:d5}", index);
+ descriptor.EnumerateFields(new QueryFieldDelegate(ActiveFieldDelegate), entryBuffer, ref context);
+ Console.WriteLine("");
+ }
+
+ return true;
+ }
+
+ static internal bool TableHeadDelegate(FieldDescriptor fieldDescriptor,
+ object obj,
+ ref EnumerationContext ctx)
+ {
+ if (fieldDescriptor != null) {
+ Console.Write(" {0}", fieldDescriptor.Name);
+ }
+ return true;
+ }
+
+ static internal bool ActiveFieldDelegate(FieldDescriptor fieldDescriptor,
+ object obj,
+ ref EnumerationContext ctx)
+ {
+ if (obj != null) {
+
+ Console.Write(" {0}", obj.ToString());
+ }
+ return true;
+ }
+
+ static internal bool SourceDelegate(UIntPtr sourceHandle,
+ UIntPtr storageHandle,
+ UIntPtr eventType,
+ UInt16 count,
+ string bufferName,
+ EventDescriptor descriptor,
+ ref EnumerationContext context)
+ {
+ if (SourceFilter != null) {
+
+ if (!Regex.IsMatch(bufferName, SourceFilter)) {
+
+ return true;
+ }
+ }
+
+ if (descriptor != null) {
+ Console.WriteLine("Source: \"{0}\". {1} entries of type {2}",
+ bufferName, count, descriptor.GetName());
+
+ if (DumpAll) {
+ Console.Write("Index");
+ descriptor.EnumerateFields(new QueryFieldDelegate(TableHeadDelegate), null, ref context);
+ Console.WriteLine("");
+ Console.Write("-----");
+
+ for (int i = 0; i < descriptor.GetFieldsCount(); i++) {
+ Console.Write("----------");
+ }
+ Console.WriteLine("");
+ }
+
+ } else {
+ Console.WriteLine("Source: \"{0}\". Storage handle ={1}",
+ bufferName, sourceHandle);
+ }
+ return true;
+ }
+
+ static internal bool fieldDelegate(FieldDescriptor fieldDescriptor,
+ object obj,
+ ref EnumerationContext context)
+ {
+ if ((fieldDescriptor != null) && (obj != null)) {
+
+ Console.WriteLine(" {0}:{1}:{2} = {3}",
+ fieldDescriptor.Offset,
+ fieldDescriptor.GetTypeName(),
+ fieldDescriptor.Name,
+ obj.ToString());
+ }
+
+ return true;
+ }
+
+
+ static internal bool EntryDelegate(EventDescriptor currentEntry,
+ QueryBuffer buffer,
+ ref EnumerationContext context)
+ {
+ if (!DumpAll) {
+
+ return false;
+ }
+
+ if ((currentEntry != null) && (buffer != null)) {
+
+ currentEntry.EnumerateFields(new QueryFieldDelegate(fieldDelegate), buffer, ref context);
+ }
+
+ return true;
+ }
+
+ public static void ListActiveSources()
+ {
+ Controller hostController = Controller.GetSystemController();
+ EnumerationContext ctx = new EnumerationContext();
+
+ if ((hostController == null) || (ctx == null)) {
+ return;
+ }
+
+ LoadEventTypes(hostController);
+
+ hostController.EnumerateActiveSources(
+ new QuerySourceDelegate(SourceDelegate),
+ new ActiveSourceEntryDelegate(ActiveEntryDelegate),
+ new QueryEntryDelegate(EntryDelegate),
+ 0,
+ ref ctx);
+ }
+
+ public static void LoadEventTypes(Controller! hostController)
+ {
+ int currentSize = 100;
+ UIntPtr [] eventTypeArray = new UIntPtr[currentSize];
+
+ if (eventTypeArray != null) {
+
+ QuerySession.FlushCaches();
+
+ int eventTypeCount = hostController.QueryEventTypeList(eventTypeArray, currentSize);
+
+ while (eventTypeCount > currentSize) {
+
+ eventTypeArray = new UIntPtr[eventTypeCount];
+ eventTypeCount = hostController.QueryEventTypeList(eventTypeArray, currentSize);
+ }
+
+ for (int i = 0; i < eventTypeCount; i++) {
+
+
+ EventDescriptor descriptor = QuerySession.GetEventDescriptor(hostController,
+ eventTypeArray[i]);
+
+ if (descriptor != null) {
+
+ Console.WriteLine("Event type \"{0}\"", descriptor.GetName());
+ }
+
+ }
+ }
+ }
+
+
+ internal static int DefaultMain(DefaultConfig! config)
+ {
+ SourceFilter = config.SourceFilter;
+ DumpAll = config.DumpAll;
+
+ ListActiveSources();
+ return 0;
+ }
+ } // end class SysInfo
+}
diff --git a/base/Applications/SysInfo/SysInfo.csproj b/base/Applications/SysInfo/SysInfo.csproj
new file mode 100644
index 0000000..c7462b7
--- /dev/null
+++ b/base/Applications/SysInfo/SysInfo.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ Exe
+ SysInfo
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/TaskList/TaskList.csproj b/base/Applications/TaskList/TaskList.csproj
index ce0f69e..a590330 100644
--- a/base/Applications/TaskList/TaskList.csproj
+++ b/base/Applications/TaskList/TaskList.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ TestUtil
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tester/TestDriver.sg b/base/Applications/Tester/TestDriver.sg
new file mode 100644
index 0000000..7f44ec8
--- /dev/null
+++ b/base/Applications/Tester/TestDriver.sg
@@ -0,0 +1,747 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+//using System.Threading;
+using Microsoft.SingSharp;
+using Microsoft.Singularity;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Test.Contracts;
+using Microsoft.Singularity.Xml;
+
+using FileSystem.Utils;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Io;
+//using System.Collections;
+
+using Microsoft.Singularity.V1.Services;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Applications;
+using Microsoft.Contracts;
+using Microsoft.Singularity.Configuration;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Test
+{
+
+ [ConsoleCategory(HelpMessage="Test harness", DefaultAction=true)]
+ internal sealed class Parameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [StringParameter("TestProfile", Mandatory=true, Position=0,
+ HelpMessage="Name of test profile to run") ]
+ internal string profileName;
+
+ [BoolParameter("FailFast", Default=false,
+ HelpMessage="Terminate testing on first failure")]
+ public bool failFast;
+
+ [BoolParameter("Verbose", Default=false,
+ HelpMessage="Report assertions even when they pass")]
+ public bool reportAssertions;
+
+ [BoolParameter("Timings", Default=false,
+ HelpMessage="Prepend a fixed profix and timing information")]
+ public bool reportTimes;
+
+ [LongParameter("TestTimeout", Default=60000L,
+ HelpMessage="Default timeout in millisecond for each test (default=60 seconds)")]
+ public long defaultTimeout;
+
+ [LongParameter("Iterations", Default=1L,
+ HelpMessage="Number of times to run the profiles (default = 1)")]
+ public long iterations;
+
+ [LongParameter("Pass", Default=0L,
+ HelpMessage="Only run tests from the profile that are designated for this pass (default Pass 0).")]
+ public long testPass;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ try {
+ return TestDriver.AppMain(this);
+ }
+ catch (Exception e) {
+ Console.WriteLine("Execution failed: {0}", e);
+ return -1;
+ }
+ }
+ }
+
+ [ConsoleCategory(HelpMessage="Run a single test case", Action="manual")]
+ internal sealed class SingleParameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [StringParameter("Module", Mandatory=true, Position=0, HelpMessage="Name of test module") ]
+ internal string moduleName;
+ [StringParameter("Suite", Mandatory=true, Position=1, HelpMessage="Name of test suite") ]
+ internal string suiteName;
+ [StringArrayParameter("Tests", Mandatory=false, HelpMessage="Names of tests to run") ]
+ internal string[] testNames;
+
+ [BoolParameter("FailFast", Default=false,
+ HelpMessage="Terminate testing on first failure.")]
+ public bool failFast;
+
+ [BoolParameter("Verbose", Default=false,
+ HelpMessage="Report assertions even when they pass")]
+ public bool reportAssertions;
+
+ [BoolParameter("Timings", Default=false,
+ HelpMessage="Prepend a fixed profix and timing information")]
+ public bool reportTimes;
+
+ [LongParameter("TestTimeout", Default=60000L,
+ HelpMessage="Default timeout in millisecond for each test (default=60 seconds)")]
+ public long defaultTimeout;
+
+ [LongParameter("Iterations", Default=1L,
+ HelpMessage="Number of times to run the profiles (default = 1)")]
+ public long iterations;
+
+ reflective internal SingleParameters();
+
+ internal int AppMain() {
+ try {
+ return TestDriver.SingleMain(this);
+ }
+ catch (Exception e) {
+ Console.WriteLine("Execution failed: {0}", e);
+ return -1;
+ }
+ }
+ }
+
+ internal struct Progress
+ {
+ public readonly int passed;
+ public readonly int skipped;
+ public readonly int failures;
+ public readonly int knownFailures;
+
+ public Progress(int p, int s, int f, int k) {
+ passed = p;
+ skipped = s;
+ failures = f;
+ knownFailures = k;
+ }
+ }
+
+ public class TestDriver
+ {
+ internal const long CYCLE_ADJUST = 10000;
+ // 3 second delay for a process to stop
+ private readonly TimeSpan CHILD_STOP_WAIT = new TimeSpan(3000);
+ internal const string PASSED = "PASSED";
+ internal const string FAILED = "FAILED";
+ internal const string SKIPPED = "SKIPPED";
+ internal const string PARTIAL = "PARTIAL";
+
+ private const string INFO = "INFO";
+ private const string CHANNEL_CLOSED = "CONNECTION CLOSED";
+ private const string TIMED_OUT = "test timed out";
+ private const string STOP_TIMED_OUT = "MODULE SHUTDOWN TIMED OUT";
+ private const string PREVIOUS_FAILURE = "previous failures";
+ private const string SETUP_FAILED = "previous setup failure";
+ private const string SETUP_SKIPPED = "previous setup skipped";
+ private const string ASSERT_FAILED = "ASSERTION FAILED";
+
+ internal const string BEGIN = "BEGIN";
+ internal const string END = "END";
+ internal const string INIT = "INIT";
+ internal const string CLEANUP = "CLEANUP";
+
+ internal const string PROFILE = "PROFILE";
+ internal const string MODULE = "MODULE";
+ internal const string SUITE = "SUITE";
+ internal const string TEST = "TEST";
+
+ private const string DEFAULT_FOLDER = "/init/";
+ private const string DEFAULT_EXT = ".tst";
+
+ // STATE ////////////////////////////////////////////
+
+ private bool m_reportAsserts;
+ private bool m_failFast;
+ private int m_testPass;
+
+ private XmlNode! m_profile;
+ private TestContext! m_root;
+
+ private int m_passed;
+ private int m_failures;
+ private int m_knownFailures;
+ private int m_skipped;
+
+ // CREATION //////////////////////////////////////
+ public TestDriver(string! profileName,
+ XmlNode! node,
+ long timeout,
+ bool failFast,
+ bool reportAll,
+ bool reportTimes,
+ int testPass)
+ {
+ m_root = new TestContext((!)node.GetAttribute("Name", profileName),
+ node,
+ TimeSpan.FromMilliseconds(timeout),
+ reportTimes);
+ m_profile = node;
+ m_failFast = failFast;
+ m_reportAsserts = reportAll;
+ m_testPass = testPass;
+ }
+
+ // QUERIES /////////////////////////////////////////
+
+ internal Progress SoFar
+ {
+ get {
+ return new Progress(m_passed, m_skipped, m_failures, m_knownFailures);
+ }
+ }
+
+ // OPERATIONS //////////////////////////////////////
+
+ internal static int AppMain(Parameters! config)
+ {
+ DirectoryServiceContract.Imp ds = config.nsRef.Acquire();
+ if (ds == null) {
+ throw new Exception("Unable to acquire handle to the Directory Service root");
+ }
+ ds.RecvSuccess();
+
+ string! name;
+ string! fname = PathAndName(config.profileName, out name);
+ XmlReader reader = new XmlReader();
+ XmlNode! root;
+ try {
+ root = (!) reader.Parse(fname);
+ }
+ catch (Exception ex) {
+ Console.WriteLine(ex.ToString());
+ throw new Exception("Unable to load test profile: " + config.profileName);
+ }
+
+ PipeMultiplexer outputMux = MuxOut();
+ if (outputMux == null) {
+ delete ds;
+ return -1;
+ }
+
+ int problems = 0;
+ try {
+ for (int i = 0; config.iterations == -1 || i < config.iterations; i++) {
+ TestDriver driver =
+ new TestDriver(name,
+ root,
+ config.defaultTimeout,
+ config.failFast,
+ config.reportAssertions,
+ config.reportTimes,
+ (int)config.testPass);
+ driver.RunProfile(ds, outputMux);
+ problems += driver.m_failures + driver.m_skipped;
+ }
+ }
+ catch (Exception ex) {
+ Console.WriteLine(ex.ToString());
+ throw;
+ }
+ finally {
+ outputMux.Dispose();
+ delete ds;
+ }
+ return problems;
+ }
+
+ internal static int SingleMain(SingleParameters! config)
+ {
+ DirectoryServiceContract.Imp ds = config.nsRef.Acquire();
+ if (ds == null) {
+ throw new Exception("Unable to acquire handle to the Directory Service root");
+ }
+ ds.RecvSuccess();
+ PipeMultiplexer outputMux = MuxOut();
+
+ XmlNode! root = new XmlNode("");
+ XmlNode! profile = new XmlNode("Profile");
+ root.AddAttribute("Name", "manual");
+ root.AddChild(profile);
+ XmlNode! module = new XmlNode("Module");
+ module.AddAttribute("Name", config.moduleName);
+ profile.AddChild(module);
+ XmlNode! suite = new XmlNode("Suite");
+ suite.AddAttribute("Name", config.suiteName);
+ module.AddChild(suite);
+ foreach (string! t in config.testNames) {
+ XmlNode! tx = new XmlNode("Test");
+ tx.AddAttribute("Name", t);
+ suite.AddChild(tx);
+ }
+
+ int problems = 0;
+ try {
+ for (int i = 0; config.iterations == -1 || i < config.iterations; i++) {
+ TestDriver driver =
+ new TestDriver("manual",
+ root,
+ config.defaultTimeout,
+ config.failFast,
+ config.reportAssertions,
+ config.reportTimes,
+ 0);
+ driver.RunProfile(ds, outputMux);
+ problems += driver.m_failures + driver.m_skipped;
+ }
+ }
+ catch (Exception ex) {
+ Console.WriteLine(ex.ToString());
+ throw;
+ }
+ finally {
+ outputMux.Dispose();
+ delete ds;
+ }
+ return problems;
+ }
+
+ // Redirect our standard output into a multiplexer so we can interleave
+ // output from child processes
+ static private PipeMultiplexer! MuxOut()
+ {
+ // Swap our real stdOut with a newly created one
+ UnicodePipeContract.Exp! newOutputExp;
+ UnicodePipeContract.Imp! newOutputImp;
+ UnicodePipeContract.NewChannel(out newOutputImp, out newOutputExp);
+ UnicodePipeContract.Imp stdOut = ConsoleOutput.Swap(newOutputImp);
+ if (stdOut == null) {
+ // TODO may not require stdout once we report to debugStub
+ delete newOutputExp;
+ throw new Exception("test expects a STDOUT pipe");
+ }
+ // Use a mux to splice our own output together with the child
+ // processes we will run.
+ return PipeMultiplexer.Start(stdOut, newOutputExp);
+ }
+
+ // return a full path, and output the core name (without extension or path)
+ static private string! PathAndName(string! arg, out string! name)
+ {
+ string! res = arg.StartsWith("/") ? arg : DEFAULT_FOLDER + arg;
+ int ext = res.LastIndexOf('.');
+ if (ext == -1) {
+ ext = res.Length;
+ res += DEFAULT_EXT;
+ }
+ int nStart = res.LastIndexOf("/") + 1;
+ name = res.Substring(nStart, ext - nStart);
+ return res;
+ }
+
+ internal void RunProfile(DirectoryServiceContract.Imp! ds,
+ PipeMultiplexer! outputMux)
+ {
+ Progress current = SoFar;
+ m_root.Nest(INIT, m_root.Node).Report(BEGIN, PROFILE);
+ foreach (XmlNode p in (!) m_root.Node.Children) {
+ if (p != null && p.Name == "Profile") {
+ foreach (XmlNode child in (!) p.Children) {
+ if (child != null && child.Name == "Module") {
+ SpawnModule(m_root.Nest(child), ds, outputMux);
+ if (m_failures > 0 && m_failFast) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ ReportEnd(m_root, PROFILE, current);
+ // TODO do we want to count the tests skipped?
+ //if (skips > 0) {
+ // Report(SKIPPED, skips + FAIL_SKIPS);
+ // m_skipped += skips;
+ // }
+ // TODO
+ // Report(SKIPPED, skips + FAIL_SKIPS);
+
+ }
+
+ internal void SpawnModule(TestContext! ctx,
+ DirectoryServiceContract.Imp! ds,
+ PipeMultiplexer! outputMux)
+ {
+ TestContext setupCtx = ctx.Nest(INIT, ctx.Node);
+ setupCtx.Report(BEGIN, MODULE);
+
+ // This is a test app, so we expect to run it with the
+ // "test" action. If that doesn't work, something is wrong
+ // REVIEW: how is failure signaled?
+ string name = ctx.Name;
+ string[] args = new string[2];
+ args[0] = name;
+ args[1] = "@test";
+
+ Manifest manifest;
+ Process child = Binder.CreateProcess(ds, args, outputMux, out manifest);
+ if (null == child) {
+ ctx.Report(SKIPPED, "Test module or manifest missing: " + ctx.Name);
+ // TODO count the number of tests skipped
+ return;
+ }
+
+ // Make a channel for the test module
+ // The child gets the pipe that goes into our output MUX
+ ModuleTesterContract.Exp! testerExp;
+ ModuleTesterContract.Imp! tester;
+ ModuleTesterContract.NewChannel(out tester, out testerExp);
+ // Make a channel for the test module
+ LogContract.Exp! logExp;
+ LogContract.Imp! log;
+ LogContract.NewChannel(out log, out logExp);
+
+ Debug("Setting slot 2 in test SIP", name);
+ child.SetStartupEndpoint(2, testerExp);
+ Debug("Starting test SIP", name);
+ child.Start();
+ Debug("Started test SIP", name);
+ Progress current = SoFar;
+ string! summary = MODULE;
+ try {
+ tester.RecvGetLogger();
+ Debug("Sending logger", name);
+ tester.SendLogger(logExp, m_reportAsserts);
+
+ Debug("Beginning Test", name);
+ if (WaitResult(setupCtx, tester, log)) {
+ RunSuites(ctx, tester, log);
+ CleanupModule(ctx.Nest(CLEANUP, ctx.Node), tester, log);
+ }
+ }
+ catch (Exception ex) {
+ summary = (!) ex.ToString();
+ }
+ finally {
+ delete tester;
+ delete log;
+ if (! child.Join(CHILD_STOP_WAIT)) {
+ // TODO count this as a failure m_failures++;
+ ctx.Report(INFO, STOP_TIMED_OUT);
+ child.Stop();
+ }
+ Debug("Terminating test sip", name);
+ ReportEnd(ctx, summary, current);
+ }
+ }
+
+ private static void Debug(string msg, string data)
+ {
+#if DEBUG_TEST_SETUP
+ DebugStub.WriteLine("{0} [{1}]", __arglist(msg, data));
+#endif
+ }
+
+ internal void CleanupModule(TestContext! ctx,
+ ModuleTesterContract.Imp:DO_MODULE! tester,
+ LogContract.Imp! log)
+ {
+ tester.SendCleanupModule();
+ WaitResult(ctx, tester, log);
+ }
+
+ internal void RunSuites(TestContext! ctx,
+ ModuleTesterContract.Imp:DO_MODULE! tester,
+ LogContract.Imp! log)
+ {
+ foreach (XmlNode n in (!) ctx.Node.Children) {
+ if (n != null && n.Name == "Suite") {
+ RunSuite(ctx.Nest(n), tester, log);
+ if (m_failures > 0 && m_failFast) {
+ break;
+ }
+ }
+ }
+ // TODO do we want to count the tests skipped?
+ //if (skips > 0) {
+ // Report(SKIPPED, skips + FAIL_SKIPS);
+ // m_skipped += skips;
+ // }
+ }
+
+ internal void RunSuite(TestContext! ctx,
+ ModuleTesterContract.Imp:DO_MODULE! tester,
+ LogContract.Imp! log)
+ {
+ TestContext setupCtx = ctx.Nest(INIT, ctx.Node);
+ setupCtx.Report(BEGIN, SUITE);
+ Progress current = SoFar;
+ bool setup = setupCtx.SkipReason == null;
+ if (setup) {
+ tester.SendInitSuite(Bitter.FromString2(ctx.Name));
+ if (!WaitResult(setupCtx, tester, log)) {
+ setup = false;
+ ctx.StartSkipping(SETUP_FAILED);
+ }
+ }
+ else {
+ setupCtx.Report(SKIPPED, ctx.SkipReason);
+ }
+ // We will at least visit each test, and perhaps just report
+ // skipping it there
+ RunTests(ctx, tester, log);
+ if (setup) {
+ //only cleanup if we actually setup
+ CleanupSuite(ctx.Nest(CLEANUP, ctx.Node), tester, log);
+ }
+ ReportEnd(ctx, SUITE, current);
+ }
+
+ internal void CleanupSuite(TestContext! ctx,
+ ModuleTesterContract.Imp:DO_MODULE! tester,
+ LogContract.Imp! log)
+ {
+ tester.SendCleanupSuite();
+ WaitResult(ctx, tester, log);
+ }
+
+ internal void RunTests(TestContext! suite,
+ ModuleTesterContract.Imp:DO_MODULE! tester,
+ LogContract.Imp! log)
+ {
+ foreach (XmlNode n in (!) suite.Node.Children) {
+ if (n != null && n.Name == "Test") {
+ RunTest(suite.Nest(n), tester, log);
+ }
+ }
+ }
+
+ internal void RunTest(TestContext! ctx,
+ ModuleTesterContract.Imp:DO_SUITE! tester,
+ LogContract.Imp! log)
+ {
+ if (ctx.Pass != m_testPass) {
+ // Ignore the test entry
+ return;
+ }
+ if (ctx.SkipReason != null) {
+ m_skipped++;
+ // TODO should this support fail recursion as well?
+ ctx.Report(SKIPPED, ctx.SkipReason);
+ return;
+ }
+ ctx.Nest(INIT, ctx.Node).Report(BEGIN, TEST);
+ tester.SendRunTest(Bitter.FromString2(ctx.Name));
+ WaitResult(ctx, tester, log);
+ }
+
+ internal bool WaitResult(TestContext! ctx,
+ ModuleTesterContract.Imp:DO_SUITE! tester,
+ LogContract.Imp! log)
+ {
+ while (true) {
+ switch receive {
+ case log.Log(char[]! in ExHeap msg, long atCycle, long atTime):
+ // TODO decide whether to check the report flag
+ ctx.Report(INFO, Bitter.ToString2(msg), atCycle, atTime);
+ delete msg;
+ log.SendOK();
+ break;
+
+ case tester.Passed(long cycles, long duration):
+ ctx.Report(PASSED, "", cycles, duration);
+ m_passed++;
+ return true;
+
+ case tester.Failed(char[]! in ExHeap error, long cycles, long duration):
+ string err = Bitter.ToString2(error);
+ delete error;
+ ctx.Report(FAILED, PrepareFailure(ctx, err), cycles, duration);
+ FailFast();
+ return false;
+
+ case tester.Skipped(char[]! in ExHeap why):
+ // TODO does this also need to handle known failures?
+ ctx.Report(SKIPPED, Bitter.ToString2(why));
+ delete why;
+ m_skipped++;
+ return false;
+
+ case tester.ChannelClosed():
+ ctx.Report(FAILED, PrepareFailure(ctx, CHANNEL_CLOSED));
+ throw new ChannelClosedException();
+ case timeout(ctx.Timeout):
+ ctx.Report(FAILED, PrepareFailure(ctx, TIMED_OUT));
+ throw new Exception(TIMED_OUT);
+ }
+ }
+ }
+
+ private string! PrepareFailure(TestContext! ctx, string! msg)
+ {
+ if (ctx.KnownFailure == null) {
+ m_failures++;
+ return msg;
+ }
+ else {
+ m_knownFailures++;
+ return string.Format("KNOWN FAILURE({0}): {1}", ctx.KnownFailure, msg);
+ }
+ }
+
+ private string! PrepareSkip(TestContext! ctx, string! msg)
+ {
+ if (ctx.KnownFailure == null) {
+ m_skipped++;
+ return msg;
+ }
+ else {
+ m_knownFailures++;
+ return string.Format("KNOWN FAILURE({0}): {1}", ctx.KnownFailure, msg);
+ }
+ }
+
+ /// Throw if we are supposed to abort after the first failure
+ internal void FailFast() {
+ if (m_failFast && m_failures > 0) {
+ throw new Exception("Test Failed");
+ }
+ }
+
+ private void ReportEnd(TestContext! ctx, string! tag, Progress before)
+ {
+ // TODO deal with skipped
+ int passed = m_passed - before.passed;
+ int failed = m_failures - before.failures;
+ int known = m_knownFailures - before.knownFailures;
+ int skipped = m_skipped - before.skipped;
+ string fmt = known > 0
+ ? "{0} Passed: {1} Skipped: {2} Failed: {3} +{4} known failure"
+ : "{0} Passed: {1} Skipped: {2} Failed: {3}";
+ string msg = string.Format(fmt, tag, passed, skipped, failed, known);
+ string status = failed > 0 ? FAILED : (skipped + known > 0) ? PARTIAL : PASSED;
+ ctx.Report(status, msg);
+ }
+ }
+
+ internal class TestContext
+ {
+ internal TimeSpan Timeout;
+ internal int Pass;
+ internal string! Name;
+ internal string! Current;
+ internal XmlNode! Node;
+ // If non-null, then tests should be skipped for that reason
+ internal string SkipReason;
+ internal string KnownFailure;
+ private bool m_reportTimes;
+
+ public TestContext(string! name, XmlNode! node, TimeSpan timeout, bool reportTimes)
+ {
+ Timeout = timeout;
+ Current = name;
+ Name = name;
+ Node = node;
+ SkipReason = null;
+ KnownFailure = node.GetAttribute("KnownFailure", null);
+ m_reportTimes = reportTimes;
+ }
+ private TestContext(string! name, XmlNode! node, TestContext! prev)
+ {
+ Node = node;
+ Name = name;
+ Current = prev.Current + ":" + name;
+ Timeout = TimeSpan.FromMilliseconds(node.GetAttribute("Timeout", prev.Timeout.TotalMilliseconds));
+ Pass = node.GetAttribute("Pass", prev.Pass);
+ SkipReason = prev.SkipReason;
+ KnownFailure = node.GetAttribute("KnownFailure", prev.KnownFailure);
+ m_reportTimes = prev.m_reportTimes;
+ }
+
+ // QUERIES ///////////////////////////////////////////////////
+ public static long CycleCount
+ {
+ get {
+#if AFFINITY_SCHEDULER
+ return Processor.CycleCount;
+#else
+ // If we're not using the affinity scheduler, substitute
+ // TickCount for CycleCount. TickCount will be consistent
+ // across processors.
+ return (long) Environment.TickCount;
+#endif
+ }
+ }
+
+ public static long Ticks
+ {
+ get { return DateTime.Now.Ticks; }
+ }
+
+ public TestContext! Nest(string! sub, XmlNode! node)
+ {
+ return new TestContext(sub, node, this);
+ }
+
+ public TestContext! Nest(XmlNode! node)
+ {
+ return Nest((!) node.GetAttribute("Name", "unknown"), node);
+ }
+
+ override public string! ToString()
+ {
+ return Current;
+ }
+
+ public void Report(string tag, string msg, long cycles, long time)
+ {
+ DateTime t = new DateTime(time);
+ // HACK Singularity doesn't support string formats
+ // string ts = t.ToString("yyyy/MM/ddTHH:mm:ss:fff");
+ string ts = String.Format("{0:d04}/{1:d02}/{2:d02}T{3:d02}:{4:d02}:{5:d02}:{6:d03}",
+ t.Year, t.Month, t.Day, t.Hour, t.Minute, t.Second, t.Millisecond);
+ string fmt = m_reportTimes ? "TEST>{3}# {4} {0} {1} {2}"
+ : "{0} {1} {2}";
+ // show on console for any fail/skip or for END of a non INIT/CLEANUP
+ if ((tag != TestDriver.PASSED && tag != TestDriver.BEGIN) ||
+ (tag != TestDriver.BEGIN && Name != TestDriver.INIT && Name != TestDriver.CLEANUP))
+ {
+ Console.WriteLine(fmt, tag, Current.Substring(Current.IndexOf(":")+1), msg, cycles, ts);
+ }
+
+ DebugStub.WriteLine("");
+ DebugStub.WriteLine(fmt, __arglist(tag, Current, msg, cycles, ts));
+ }
+
+ public void Report(string tag, string msg)
+ {
+ Report(tag, msg, CycleCount, Ticks);
+ }
+
+ // OPERATIONS ////////////////////////////////////////////////
+ public void StartSkipping(string! reason)
+ {
+ SkipReason = reason;
+ }
+
+ }
+}
diff --git a/base/Applications/Tester/Tester.csproj b/base/Applications/Tester/Tester.csproj
new file mode 100644
index 0000000..ef89825
--- /dev/null
+++ b/base/Applications/Tester/Tester.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ SingUnit
+ Exe
+ true
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/AdjustTest/AdjustTest.cs b/base/Applications/Tests/AdjustTest/AdjustTest.cs
new file mode 100644
index 0000000..b8ca4bc
--- /dev/null
+++ b/base/Applications/Tests/AdjustTest/AdjustTest.cs
@@ -0,0 +1,41 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+
+namespace Microsoft.Singularity.AdjustTest
+{
+ public struct Holder : IDisposable
+ {
+ int handle;
+ public Holder(int i)
+ {
+ handle = i;
+ }
+ public void Dispose()
+ {
+ Console.WriteLine("Disposed {0}", handle);
+ }
+ }
+
+ public class Test
+ {
+ public static Holder Hold(int i)
+ {
+ return new Holder(i);
+ }
+
+ //[ShellCommand("adjusttest", "Test code rewriting.")]
+ public static void Main()
+ {
+ Console.WriteLine("starting");
+ using (Hold(3)) {
+ Console.WriteLine("using");
+ }
+ Console.WriteLine("used");
+ }
+ }
+}
diff --git a/base/Applications/Tests/AdjustTest/AdjustTest.csproj b/base/Applications/Tests/AdjustTest/AdjustTest.csproj
new file mode 100644
index 0000000..83afdcb
--- /dev/null
+++ b/base/Applications/Tests/AdjustTest/AdjustTest.csproj
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+ Exe
+ AdjustTest
+
+ Full
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/Bartok/Bug00013/Bug00013.cs b/base/Applications/Tests/Bartok/Bug00013/Bug00013.cs
index f368011..d4a006f 100644
--- a/base/Applications/Tests/Bartok/Bug00013/Bug00013.cs
+++ b/base/Applications/Tests/Bartok/Bug00013/Bug00013.cs
@@ -1,5 +1,5 @@
//
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Some sort of threads/locking test.
@@ -16,7 +16,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace MarmotBugs {
+namespace MarmotBugs
+{
[ConsoleCategory(HelpMessage="Show attributes associated with a file", DefaultAction=true)]
internal class Parameters {
@@ -37,7 +38,8 @@ namespace MarmotBugs {
}
}
- class DebugPrintSpin {
+ class DebugPrintSpin
+ {
private static Object locker = new Object();
public static void Lock() {
// Class_java_lang_Thread *currentThread = CurrentThread();
@@ -52,7 +54,8 @@ namespace MarmotBugs {
}
}
- class Bug00013 { //: Runnable {
+ class Bug00013
+ { //: Runnable {
static int totalThreads = Int32.MaxValue;
@@ -79,7 +82,7 @@ namespace MarmotBugs {
Assert(b, "Assertion failed");
}
private static void Assert(bool b, String s) {
- if(!b) {
+ if (!b) {
DebugPrintSpin.Lock();
Console.WriteLine(s);
Console.WriteLine("Failed Bug00013");
@@ -239,13 +242,14 @@ namespace MarmotBugs {
Console.WriteLine(newThread.GetHashCode());
DebugPrintSpin.Unlock();
- /*
- new WatchDog().start();
- try {
- Thread.sleep(1000);
- } catch(InterruptedException e) {
- }
- /**/
+ //
+ //new WatchDog().start();
+ //try {
+ // Thread.sleep(1000);
+ //}
+ //catch (InterruptedException e) {
+ //}
+ ///*
newThread.Start();
@@ -267,7 +271,8 @@ namespace MarmotBugs {
+ " deadman expired");
DebugDumpThreadAnchorTable(4);
DebugBreak();
- } else {
+ }
+ else {
Console.WriteLine();
Console.Write(" ?<0,");
Console.Write(numThreadsAlive);
@@ -291,12 +296,12 @@ namespace MarmotBugs {
links = new Bug00013[maxLinks];
}
- /*
- public override String ToString() {
- if (nodename != null) return(nodename);
- return(base.ToString());
- }
- */
+ //
+ //public override String ToString() {
+ // if (nodename != null) return(nodename);
+ // return(base.ToString());
+ //}
+ //
public void run() {
int myNumThreadsAlive;
@@ -329,7 +334,8 @@ namespace MarmotBugs {
lock (this) {
if (random == null) {
random = new Random();
- } else {
+ }
+ else {
conflict = true;
}
}
@@ -340,10 +346,10 @@ namespace MarmotBugs {
Bug00013 node = new Bug00013();
anchor.addLink(this, node);
- for (int i=0; i= 0);
if (traversalsLeft > traversalLimit) {
traversalsLeft = traversalLimit;
@@ -449,7 +455,8 @@ namespace MarmotBugs {
break;
}
}
- } else {
+ }
+ else {
pendingQueue = this;
}
}
@@ -542,7 +549,7 @@ namespace MarmotBugs {
checkConsistency();
if (last.numLinks < maxLinks) {
lastLinked = true;
- for (int i=0; i0, "addlink() last.numLinks should be > 0");
last.numLinks--;
- for (int i=0; ii; j--) {
+ for (int j = numUndeadThreadids; j > i; j--) {
undeadThreadids[j] = undeadThreadids[j-1];
}
undeadThreadids[i] = threadid;
@@ -631,7 +638,7 @@ namespace MarmotBugs {
static void DebugPrintUndead() {
char sep = ':';
- for (int i=0; i> 8) & 0xfff;
int v = (n >> 8) & Config.KEY_SPACE_MASK;
@@ -106,19 +107,16 @@ namespace Test {
RBNode temp = root;
RBNode parent = null;
- while(temp != sentinelNode)
- { // find Parent
+ while (temp != sentinelNode) {
+ // find Parent
parent = temp;
- if ( key == temp.Value)
- {
+ if (key == temp.Value) {
return false;
}
- else if (key > temp.Value)
- {
+ else if (key > temp.Value) {
temp = temp.Right;
}
- else
- {
+ else {
temp = temp.Left;
}
}
@@ -131,10 +129,8 @@ namespace Test {
node.Right = sentinelNode;
// insert node into tree starting at parent's location
- if(node.Parent != null)
- {
- if (node.Value > node.Parent.Value)
- {
+ if (node.Parent != null) {
+ if (node.Value > node.Parent.Value) {
node.Parent.Right = node;
}
else
@@ -157,19 +153,15 @@ namespace Test {
bool result = false;
// traverse tree until node is found
- while(node != sentinelNode)
- {
- if (key == node.Value)
- {
+ while (node != sentinelNode) {
+ if (key == node.Value) {
result = true;
break;
}
- else if (key < node.Value)
- {
+ else if (key < node.Value) {
node = node.Left;
}
- else
- {
+ else {
node = node.Right;
}
}
@@ -186,23 +178,19 @@ namespace Test {
RBNode node;
node = root;
- while(node != sentinelNode)
- {
- if (key == node.Value)
- {
+ while (node != sentinelNode) {
+ if (key == node.Value) {
break;
}
- else if (key < node.Value)
- {
+ else if (key < node.Value) {
node = node.Left;
}
- else
- {
+ else {
node = node.Right;
}
}
- if(node == sentinelNode)
+ if (node == sentinelNode)
return false; // key not found
Delete(node);
@@ -228,22 +216,21 @@ namespace Test {
// find the replacement node (the successor to x) - the node one with
// at *most* one child.
- if(z.Left == sentinelNode || z.Right == sentinelNode)
+ if (z.Left == sentinelNode || z.Right == sentinelNode)
y = z; // node has sentinel as a child
- else
- {
+ else {
// z has two children, find replacement node which will
// be the leftmost node greater than z
y = z.Right; // traverse right subtree
- while(y.Left != sentinelNode) // to find next node in sequence
+ while (y.Left != sentinelNode) // to find next node in sequence
y = y.Left;
}
- // at this point, y contains the replacement node. Its content will be copied
+ // at this point, y contains the replacement node. it's content will be copied
// to the values in the node to be deleted
// x (y's only child) is the node that will be linked to y's old parent.
- if(y.Left != sentinelNode)
+ if (y.Left != sentinelNode)
x = y.Left;
else
x = y.Right;
@@ -252,7 +239,7 @@ namespace Test {
// link x to proper subtree in parent
// this removes y from the chain
x.Parent = y.Parent;
- if(y.Parent != null)
+ if (y.Parent != null)
if(y == y.Parent.Left)
y.Parent.Left = x;
else
@@ -262,12 +249,11 @@ namespace Test {
// copy the values from y (the replacement node) to the node being deleted.
// note: this effectively deletes the node.
- if(y != z)
- {
+ if (y != z) {
z.Value = y.Value;
}
- if(y.Color == Color.BLACK)
+ if (y.Color == Color.BLACK)
RestoreAfterDelete(x);
}
@@ -283,13 +269,12 @@ namespace Test {
RBNode y;
- while(x != root && x.Color == Color.BLACK)
- {
- if(x == x.Parent.Left) // determine sub tree from parent
+ while (x != root && x.Color == Color.BLACK) {
+ if (x == x.Parent.Left) // determine sub tree from parent
{
y = x.Parent.Right; // y is x's sibling
- if(y.Color == Color.RED)
- { // x is black, y is red - make both black and rotate
+ if (y.Color == Color.RED) {
+ // x is black, y is red - make both black and rotate
y.Color = Color.BLACK;
x.Parent.Color = Color.RED;
RotateLeft(x.Parent);
@@ -301,10 +286,8 @@ namespace Test {
y.Color = Color.RED; // change parent to red
x = x.Parent; // move up the tree
}
- else
- {
- if(y.Right.Color == Color.BLACK)
- {
+ else {
+ if (y.Right.Color == Color.BLACK) {
y.Left.Color = Color.BLACK;
y.Color = Color.RED;
RotateRight(y);
@@ -317,11 +300,10 @@ namespace Test {
x = root;
}
}
- else
- { // right subtree - same as code above with right and left swapped
+ else {
+ // right subtree - same as code above with right and left swapped
y = x.Parent.Left;
- if(y.Color == Color.RED)
- {
+ if (y.Color == Color.RED) {
y.Color = Color.BLACK;
x.Parent.Color = Color.RED;
RotateRight (x.Parent);
@@ -333,10 +315,8 @@ namespace Test {
y.Color = Color.RED;
x = x.Parent;
}
- else
- {
- if(y.Left.Color == Color.BLACK)
- {
+ else {
+ if (y.Left.Color == Color.BLACK) {
y.Right.Color = Color.BLACK;
y.Color = Color.RED;
RotateLeft(y);
@@ -358,14 +338,13 @@ namespace Test {
RBNode y;
// maintain red-black tree properties after adding x
- while(x != root && x.Parent.Color == Color.RED)
- {
+ while (x != root && x.Parent.Color == Color.RED) {
// Parent node is .Colored red;
- if(x.Parent == x.Parent.Parent.Left) // determine traversal path
+ if (x.Parent == x.Parent.Parent.Left) // determine traversal path
{ // is it on the Left or Right subtree?
y = x.Parent.Parent.Right; // get uncle
- if(y!= null && y.Color == Color.RED)
- { // uncle is red; change x's Parent and uncle to black
+ if (y != null && y.Color == Color.RED) {
+ // uncle is red; change x's Parent and uncle to black
x.Parent.Color = Color.BLACK;
y.Color = Color.BLACK;
// grandparent must be red. Why? Every red node that is not
@@ -373,11 +352,10 @@ namespace Test {
x.Parent.Parent.Color = Color.RED;
x = x.Parent.Parent; // continue loop with grandparent
}
- else
- {
+ else {
// uncle is black; determine if x is greater than Parent
- if(x == x.Parent.Right)
- { // yes, x is greater than Parent; rotate Left
+ if (x == x.Parent.Right) {
+ // yes, x is greater than Parent; rotate Left
// make x a Left child
x = x.Parent;
RotateLeft(x);
@@ -388,21 +366,18 @@ namespace Test {
RotateRight(x.Parent.Parent); // rotate right
}
}
- else
- { // x's Parent is on the Right subtree
+ else {
+ // x's Parent is on the Right subtree
// this code is the same as above with "Left" and "Right" swapped
y = x.Parent.Parent.Left;
- if(y!= null && y.Color == Color.RED)
- {
+ if (y != null && y.Color == Color.RED) {
x.Parent.Color = Color.BLACK;
y.Color = Color.BLACK;
x.Parent.Parent.Color = Color.RED;
x = x.Parent.Parent;
}
- else
- {
- if(x == x.Parent.Left)
- {
+ else {
+ if (x == x.Parent.Left) {
x = x.Parent;
RotateRight(x);
}
@@ -431,25 +406,25 @@ namespace Test {
x.Right = y.Left; // y's Left child's becomes x's Right child
// modify parents
- if(y.Left != sentinelNode)
+ if (y.Left != sentinelNode)
y.Left.Parent = x; // sets y's Left Parent to x
- if(y != sentinelNode)
+ if (y != sentinelNode)
y.Parent = x.Parent; // set y's Parent to x's Parent
- if(x.Parent != null)
- { // determine which side of its Parent x was on
- if(x == x.Parent.Left)
+ if (x.Parent != null) {
+ // determine which side of it's Parent x was on
+ if (x == x.Parent.Left)
x.Parent.Left = y; // set Left Parent to y
else
x.Parent.Right = y; // set Right Parent to y
}
- else
+ else
root = y; // at root, set it to y
// link x and y
y.Left = x; // put x on y's Left
- if(x != sentinelNode) // set y as x's Parent
+ if (x != sentinelNode) // set y as x's Parent
x.Parent = y;
}
@@ -469,25 +444,25 @@ namespace Test {
x.Left = y.Right; // y's Right child becomes x's Left child
// modify parents
- if(y.Right != sentinelNode)
+ if (y.Right != sentinelNode)
y.Right.Parent = x; // sets y's Right Parent to x
- if(y != sentinelNode)
+ if (y != sentinelNode)
y.Parent = x.Parent; // set y's Parent to x's Parent
- if(x.Parent != null) // null=root, could also have used root
+ if (x.Parent != null) // null = root, could also have used root
{ // determine which side of its Parent x was on
- if(x == x.Parent.Right)
+ if (x == x.Parent.Right)
x.Parent.Right = y; // set Right Parent to y
else
x.Parent.Left = y; // set Left Parent to y
}
- else
+ else
root = y; // at root, set it to y
// link x and y
y.Right = x; // put x on y's Right
- if(x != sentinelNode) // set y as x's Parent
+ if (x != sentinelNode) // set y as x's Parent
x.Parent = y;
}
@@ -522,20 +497,16 @@ namespace Test {
// Check left side
RBNode left = root.Left;
- if (sentinelNode != left)
- {
- if (left.Color == Color.RED && rootcolor == Color.RED)
- {
+ if (sentinelNode != left) {
+ if (left.Color == Color.RED && rootcolor == Color.RED) {
Console.WriteLine("Two consecutive red nodes!");
return;
}
- if (left.Value >= root.Value)
- {
+ if (left.Value >= root.Value) {
Console.WriteLine("Tree values out of order!");
return;
}
- if (left.Marked)
- {
+ if (left.Marked) {
Console.WriteLine("Cycle in tree structure!");
return;
}
@@ -544,20 +515,16 @@ namespace Test {
// Check right side
RBNode right = root.Right;
- if (sentinelNode != right)
- {
- if (right.Color == Color.RED && rootcolor == Color.RED)
- {
+ if (sentinelNode != right) {
+ if (right.Color == Color.RED && rootcolor == Color.RED) {
Console.WriteLine("Two consecutive red nodes!");
return;
}
- if (right.Value <= root.Value)
- {
+ if (right.Value <= root.Value) {
Console.WriteLine("Tree values out of order!");
return;
}
- if (right.Marked)
- {
+ if (right.Marked) {
Console.WriteLine("Cycle in tree structure!");
return;
}
@@ -565,10 +532,8 @@ namespace Test {
}
// Check black node count
- if (sentinelNode == root.Left || sentinelNode == root.Right)
- {
- if (soFar != blackNodes)
- {
+ if (sentinelNode == root.Left || sentinelNode == root.Right) {
+ if (soFar != blackNodes) {
Console.WriteLine("Variable number of black nodes to leaves!");
return;
}
@@ -580,7 +545,7 @@ namespace Test {
public class RBNode
{
- /** creates new tree node **/
+ /// creates new tree node *
internal int Value = 0;
internal Color Color = Color.RED;
internal bool Marked;
@@ -590,7 +555,8 @@ namespace Test {
}
}
- class STMTest {
+ class STMTest
+ {
static Object o = new Object();
@@ -602,7 +568,7 @@ namespace Test {
int i;
try {
- for (i = 0 ; ((Config.OP_COUNT == -1) || (i < Config.OP_COUNT)); i ++) {
+ for (i = 0; ((Config.OP_COUNT == -1) || (i < Config.OP_COUNT)); i ++) {
int n = random.Next();
int v = (n >> 8) & Config.KEY_SPACE_MASK;
@@ -611,43 +577,70 @@ namespace Test {
if (Config.KIND == RunKind.Atomic) {
try {
r = t.Contains(v);
- } catch (AtomicFakeException) { }
- } else if (Config.KIND == RunKind.TryAll) {
+ }
+ catch (AtomicFakeException) {
+
+ }
+ }
+ else if (Config.KIND == RunKind.TryAll) {
try {
r = t.Contains(v);
- } catch (TryAllFakeException) { }
- } else {
+ }
+ catch (TryAllFakeException) {
+
+ }
+ }
+ else {
r = t.Contains(v);
}
- } else if ((n & 0xff) < (Config.LOOKUP_FRAC + Config.REMOVE_FRAC)) {
+ }
+ else if ((n & 0xff) < (Config.LOOKUP_FRAC + Config.REMOVE_FRAC)) {
if (Config.KIND == RunKind.Atomic) {
try {
r = t.Remove(v);
- } catch (AtomicFakeException) { }
- } else if (Config.KIND == RunKind.TryAll) {
+ }
+ catch (AtomicFakeException) {
+
+ }
+ }
+ else if (Config.KIND == RunKind.TryAll) {
try {
r = t.Remove(v);
- } catch (TryAllFakeException) { }
- } else {
+ }
+ catch (TryAllFakeException) {
+
+ }
+ }
+ else {
r = t.Remove(v);
}
if (r) my_shadow -= v;
- } else {
+ }
+ else {
if (Config.KIND == RunKind.Atomic) {
try {
r = t.Insert(v);
- } catch (AtomicFakeException) { }
- } else if (Config.KIND == RunKind.TryAll) {
+ }
+ catch (AtomicFakeException) {
+
+ }
+ }
+ else if (Config.KIND == RunKind.TryAll) {
try {
r = t.Insert(v);
- } catch (TryAllFakeException) { }
- } else {
+ }
+ catch (TryAllFakeException) {
+
+ }
+ }
+ else {
r = t.Insert(v);
}
if (r) my_shadow += v;
}
}
- } catch (Exception e) {
+ }
+ catch (Exception e) {
lock (o) {
Console.WriteLine("Failed with " + e);
}
@@ -692,14 +685,16 @@ namespace Test {
private static int NextArgInt(string[] args, ref int nextArg, int min) {
try {
int x = Int32.Parse(NextArg(args, ref nextArg));
- if(x < min) {
+ if (x < min) {
Usage("parameter " + (nextArg-1) + " should be >= " + min);
}
return x;
- } catch(FormatException) {
+ }
+ catch (FormatException) {
Usage("illegal format in parameter " + (nextArg-1));
return 0;
- } catch(OverflowException) {
+ }
+ catch (OverflowException) {
Usage("overflow in parameter " + (nextArg-1));
return 0;
}
@@ -712,7 +707,7 @@ namespace Test {
}
int argIndex = 0;
- if(argIndex < args.Length) {
+ if (argIndex < args.Length) {
if ((String.Compare(args[0], "tree", true) == 0)
|| (String.Compare(args[0], "tree.exe", true) == 0)
|| (String.Compare(args[0], "tree.x86", true) == 0)) {
@@ -800,7 +795,8 @@ namespace Test {
if (Config.DETERMINISTIC) {
Console.WriteLine("Shadow - Actual = " + (s - a));
- } else {
+ }
+ else {
Console.WriteLine("Shadow = " + s);
Console.WriteLine("Actual = " + a);
}
diff --git a/base/Applications/Tests/CLink/CLink.sg b/base/Applications/Tests/CLink/CLink.sg
index d99162f..bf73d0a 100644
--- a/base/Applications/Tests/CLink/CLink.sg
+++ b/base/Applications/Tests/CLink/CLink.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: CLink.sg
-//
// Note: Simple ping-pong second child process
//
@@ -53,7 +51,7 @@ namespace Microsoft.Singularity.Applications
cin.SendPongReady();
try {
- while(true) {
+ while (true) {
switch receive {
case cin.Ping(int data):
Console.WriteLine("CLink{0,2}: Ping({1}) to Ping...", id, data);
diff --git a/base/Applications/Tests/CPing/CPing.sg b/base/Applications/Tests/CPing/CPing.sg
index 5d29262..64d957c 100644
--- a/base/Applications/Tests/CPing/CPing.sg
+++ b/base/Applications/Tests/CPing/CPing.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: CPing.sg
-//
// Note: Simple ping-pong test child app #1
//
@@ -46,7 +44,7 @@ namespace Microsoft.Singularity.Applications
Console.WriteLine("CPing : Starting cpong.");
string[] cargs = new string[1];
- cargs[0] = "CPong.x86";
+ cargs[0] = "CPong";
Process child = new Process(cargs, null, 1);
child.SetStartupEndpoint(0, (Endpoint * in ExHeap)pongExp);
child.Start();
@@ -60,7 +58,7 @@ namespace Microsoft.Singularity.Applications
Console.WriteLine("CPing : Starting clink[{0}].", i);
cargs = new string[2];
- cargs[0] = "CLink.x86";
+ cargs[0] = "CLink";
cargs[1] = i.ToString();
child = new Process(cargs, null, 2);
diff --git a/base/Applications/Tests/CPong/CPong.sg b/base/Applications/Tests/CPong/CPong.sg
index 40e1fe3..9565dfb 100644
--- a/base/Applications/Tests/CPong/CPong.sg
+++ b/base/Applications/Tests/CPong/CPong.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: CPong.sg
-//
// Note: Simple ping-pong second child process
//
@@ -36,7 +34,7 @@ namespace Microsoft.Singularity.Applications
conn.SendPongReady();
try {
- while(true) {
+ while (true) {
switch receive {
case conn.Ping(int data):
Console.WriteLine("CPong : Ping({0}) to Pong...", data);
diff --git a/base/Applications/Tests/Cast/Cast.cs b/base/Applications/Tests/Cast/Cast.cs
index 6fb0ab5..e33245a 100644
--- a/base/Applications/Tests/Cast/Cast.cs
+++ b/base/Applications/Tests/Cast/Cast.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Cast.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -18,7 +16,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/ChannelDemo/ChannelDemo.csproj b/base/Applications/Tests/ChannelDemo/ChannelDemo.csproj
index 480c35d..995bd4f 100644
--- a/base/Applications/Tests/ChannelDemo/ChannelDemo.csproj
+++ b/base/Applications/Tests/ChannelDemo/ChannelDemo.csproj
@@ -5,8 +5,6 @@ Microsoft Research Singularity
Copyright (c) Microsoft Corporation. All rights reserved.
-File: Applications\Tests\ChannelDemo\ChannelDemo.csproj
-
Note: Tests channel I/O
##############################################################################
diff --git a/base/Applications/Tests/ChannelDemo/ChannelDemo.sg b/base/Applications/Tests/ChannelDemo/ChannelDemo.sg
index 4ec717b..3095871 100644
--- a/base/Applications/Tests/ChannelDemo/ChannelDemo.sg
+++ b/base/Applications/Tests/ChannelDemo/ChannelDemo.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ChannelDemo.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -20,7 +18,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/ChannelPerf/ChannelPerf.sg b/base/Applications/Tests/ChannelPerf/ChannelPerf.sg
index 3a22208..01454f1 100644
--- a/base/Applications/Tests/ChannelPerf/ChannelPerf.sg
+++ b/base/Applications/Tests/ChannelPerf/ChannelPerf.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ChannelPerf.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -93,11 +92,9 @@ namespace Microsoft.Singularity.Applications {
for (int i = 0; i < num; i++) {
arg = i;
e2.SendReq(arg);
- switch receive
- {
+ switch receive {
case e2.Resp(reply):
- if (doAlloc)
- {
+ if (doAlloc) {
foo = new byte[20000];
foo[1] = 0x3; // keep the compiler happy
}
diff --git a/base/Applications/Tests/ClockTest/ClockTest.cs b/base/Applications/Tests/ClockTest/ClockTest.cs
index ecb655c..faaf1b4 100644
--- a/base/Applications/Tests/ClockTest/ClockTest.cs
+++ b/base/Applications/Tests/ClockTest/ClockTest.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ClockTest.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/Collect/Collect.cs b/base/Applications/Tests/Collect/Collect.cs
index 1a7b1ad..fd882b6 100644
--- a/base/Applications/Tests/Collect/Collect.cs
+++ b/base/Applications/Tests/Collect/Collect.cs
@@ -4,22 +4,20 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Collect.cs
-//
// Note: Simple Singularity test program.
//
using System;
using Microsoft.Singularity.V1.Services;
using Microsoft.Contracts;
using Microsoft.Singularity.Channels;
-using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -52,12 +50,10 @@ namespace Microsoft.Singularity.Applications {
prev = _prev;
value = i;
- if (i <= 1)
- {
+ if (i <= 1) {
next = null;
}
- else
- {
+ else {
next = new LinkedList(i - 1, this);
}
data = new byte [24576 + 1024 * i];
@@ -84,8 +80,7 @@ namespace Microsoft.Singularity.Applications {
{
Console.WriteLine(" Value = {0} [Next] {1}, {2} bytes payload",
value, next.value, data.Length);
- if (next.value != _value)
- {
+ if (next.value != _value) {
next.PrintNext(_value);
}
}
@@ -100,16 +95,14 @@ namespace Microsoft.Singularity.Applications {
requires prev != null;
{
Console.WriteLine(" Value = {0} [Prev] {1}", value, prev.value);
- if (prev.value != _value)
- {
+ if (prev.value != _value) {
prev.PrintPrev(_value);
}
}
private LinkedList! Last()
{
- if (next != null)
- {
+ if (next != null) {
return next.Last();
}
return this;
diff --git a/base/Applications/Tests/ConsoleDemo/ConsoleDemo.sg b/base/Applications/Tests/ConsoleDemo/ConsoleDemo.sg
index 6dae956..590b04c 100644
--- a/base/Applications/Tests/ConsoleDemo/ConsoleDemo.sg
+++ b/base/Applications/Tests/ConsoleDemo/ConsoleDemo.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ChannelDemo.cs
-//
// Note: Simple Singularity test program.
//
@@ -21,11 +19,11 @@ using Microsoft.Singularity.Channels;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
-using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications.Tests {
+namespace Microsoft.Singularity.Applications.Tests
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -52,8 +50,7 @@ namespace Microsoft.Singularity.Applications.Tests {
ConsoleDeviceContract.NewChannel(out imp, out exp);
nsImp.SendBind(deviceName, exp);
- switch receive
- {
+ switch receive {
case nsImp.AckBind():
return imp;
break;
@@ -85,8 +82,7 @@ namespace Microsoft.Singularity.Applications.Tests {
delete ns;
if (imp != null) {
- switch receive
- {
+ switch receive {
case imp.Success():
break;
case imp.ContractNotSupported():
@@ -166,7 +162,7 @@ namespace Microsoft.Singularity.Applications.Tests {
int cc = columns / 2;
int cr = rows / 2;
int edge = Math.Min(cc, cr);
- for (int i = 0 ; i < edge; i++) {
+ for (int i = 0; i < edge; i++) {
DrawLine(imp, cc - i, cr - i, cc - i, cr + i, '*');
DrawLine(imp, cc - i, cr + i, cc + i, cr + i, '*');
DrawLine(imp, cc + i, cr + i, cc + i, cr - i, '*');
@@ -187,7 +183,7 @@ namespace Microsoft.Singularity.Applications.Tests {
int cr = rows / 2;
int r = 2 * Math.Min(cc, cr) / 3;
double tau = 2 * Math.PI / twoPiSteps;
- for (int i = 0 ; i < 5 * twoPiSteps; i++) {
+ for (int i = 0; i < 5 * twoPiSteps; i++) {
double theta = i * tau;
int x = (int)(r * Math.Sin(theta));
int y = (int)(r * Math.Cos(theta));
diff --git a/base/Applications/Tests/DumpPages/DumpPages.cs b/base/Applications/Tests/DumpPages/DumpPages.cs
deleted file mode 100644
index b38a6d4..0000000
--- a/base/Applications/Tests/DumpPages/DumpPages.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: DumpPages.cs
-//
-// Note: Simple Singularity test program.
-//
-using System;
-
-namespace Microsoft.Singularity.Applications
-{
- public class DumpPages
- {
- //[ShellCommand("dump", "Dump page table")]
- public static int Main(String[] args)
- {
- AppRuntime.DumpPageTable();
- return 0;
- }
- }
-}
diff --git a/base/Applications/Tests/DumpPages/DumpPages.csproj b/base/Applications/Tests/DumpPages/DumpPages.csproj
deleted file mode 100644
index 3b29a89..0000000
--- a/base/Applications/Tests/DumpPages/DumpPages.csproj
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
- DumpPages
- Exe
- true
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Tests/GcStress/GcStress.sg b/base/Applications/Tests/GcStress/GcStress.sg
index afedb9d..188e9ba 100644
--- a/base/Applications/Tests/GcStress/GcStress.sg
+++ b/base/Applications/Tests/GcStress/GcStress.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: GcStress.sg
-//
// Note: Simple Singularity test program.
//
using System;
@@ -23,7 +21,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -54,15 +53,13 @@ namespace Microsoft.Singularity.Applications {
{
const int ARGS_START = 1;
- if (!config.doKernelTest)
- {
+ if (!config.doKernelTest) {
new GcStress().Run();
}
else {
DirectoryServiceContract.Imp! epNS = DirectoryService.NewClientEndpoint();
- try
- {
+ try {
StressContract.Imp! imp;
StressContract.Exp! exp;
StressContract.NewChannel(out imp, out exp);
@@ -73,15 +70,13 @@ namespace Microsoft.Singularity.Applications {
Console.Write("failure on lookup of name " + StressContract.ModuleName
+ "reason: " + SdsUtils.ErrorCodeToString(errorOut));
delete imp;
- if (errorOut == ErrorCode.ChannelClosed)
- {
+ if (errorOut == ErrorCode.ChannelClosed) {
throw new Exception("Encountered a ChannelClosed");
}
return 1;
}
else {
- switch receive
- {
+ switch receive {
case imp.Ready() :
break;
case imp.ContractNotSupported() :
@@ -94,10 +89,8 @@ namespace Microsoft.Singularity.Applications {
return 1;
}
imp.SendGcStress();
- while (true)
- {
- switch receive
- {
+ while (true) {
+ switch receive {
case imp.Print(char[] in ExHeap s) :
Console.Write(Bitter.ToString(s));
imp.SendAckPrint();
@@ -114,60 +107,55 @@ namespace Microsoft.Singularity.Applications {
}
}
}
-/*
-// epNS.SendBind(Bitter.FromString2(StressContract.ModuleName), exp);
-
- switch receive
- {
- case epNS.NakBind(rejected, error) :
- // failure
- Console.Write("failure on lookup of name " + StressContract.ModuleName);
- delete imp;
- delete rejected;
- return 1;
-
- case epNS.AckBind() :
- // success
- switch receive
- {
- case imp.Ready() :
- break;
- case imp.ContractNotSupported() :
- Console.Write("failure: contract not supported");
- delete imp;
- return 1;
- case imp.ChannelClosed() :
- Console.Write("failure: channel closed prematurely");
- delete imp;
- return 1;
- }
- imp.SendGcStress();
- while (true)
- {
- switch receive
- {
- case imp.Print(char[] in ExHeap s) :
- Console.Write(Bitter.ToString(s));
- imp.SendAckPrint();
- delete s;
- break;
-
- case imp.GcStressDone() :
- delete imp;
- return 0;
-
- case imp.ChannelClosed() :
- delete imp;
- return 0;
- }
- }
- case epNS.ChannelClosed() :
- throw new Exception("epNS channel closed");
- }
-*/
+//
+//// epNS.SendBind(Bitter.FromString2(StressContract.ModuleName), exp);
+//
+// switch receive {
+// case epNS.NakBind(rejected, error) :
+// // failure
+// Console.Write("failure on lookup of name " + StressContract.ModuleName);
+// delete imp;
+// delete rejected;
+// return 1;
+//
+// case epNS.AckBind() :
+// // success
+// switch receive {
+// case imp.Ready() :
+// break;
+// case imp.ContractNotSupported() :
+// Console.Write("failure: contract not supported");
+// delete imp;
+// return 1;
+// case imp.ChannelClosed() :
+// Console.Write("failure: channel closed prematurely");
+// delete imp;
+// return 1;
+// }
+// imp.SendGcStress();
+// while (true) {
+// switch receive {
+// case imp.Print(char[] in ExHeap s) :
+// Console.Write(Bitter.ToString(s));
+// imp.SendAckPrint();
+// delete s;
+// break;
+//
+// case imp.GcStressDone() :
+// delete imp;
+// return 0;
+//
+// case imp.ChannelClosed() :
+// delete imp;
+// return 0;
+// }
+// }
+// case epNS.ChannelClosed() :
+// throw new Exception("epNS channel closed");
+// }
+//
}
- finally
- {
+ finally {
delete epNS;
}
}
diff --git a/base/Applications/Tests/Hog/Hog.cs b/base/Applications/Tests/Hog/Hog.cs
index d7820cf..3297a39 100644
--- a/base/Applications/Tests/Hog/Hog.cs
+++ b/base/Applications/Tests/Hog/Hog.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Hog.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/IoTestApp/IoTestApp.csproj b/base/Applications/Tests/IoTestApp/IoTestApp.csproj
new file mode 100644
index 0000000..25ba2d3
--- /dev/null
+++ b/base/Applications/Tests/IoTestApp/IoTestApp.csproj
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ Exe
+ IoTestApp
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/IoTestApp/IoTestApp.sg b/base/Applications/Tests/IoTestApp/IoTestApp.sg
new file mode 100644
index 0000000..831a7d9
--- /dev/null
+++ b/base/Applications/Tests/IoTestApp/IoTestApp.sg
@@ -0,0 +1,246 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+// This is the top level unit/iotest driver that sends and receives I/O
+// on the IoTest device drivers contract.
+//
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Channels;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Configuration;
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications
+{
+ [ConsoleCategory(HelpMessage="IoTest Application for IoTest driver", DefaultAction=true)]
+ internal class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ //[StringParameter( "device", Mandatory=true, Position=0 , HelpMessage="Device name for test (usually /dev/iotest0)")]
+ [StringParameter( "device", Default="/dev/iotest0", Position=0 , HelpMessage="Device name for test (usually /dev/iotest0)")]
+ internal string deviceName;
+
+ [LongParameter( "size", Default=4096, HelpMessage="Size for each I/O Transaction")]
+ internal long chunksize;
+
+ [LongParameter( "count", Default=50000, HelpMessage="Repetition count.")]
+ internal long count;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return IoTest.AppMain(this);
+ }
+ }
+
+ public class IoTest
+ {
+ public static IoTestContract.Imp:Ready OpenDevice(String! devname)
+ {
+ IoTestContract.Exp! exp;
+ IoTestContract.Imp! imp;
+ IoTestContract.NewChannel(out imp, out exp);
+ DirectoryServiceContract.Imp ns;
+
+ // get NS endpoint
+ ns = DirectoryService.NewClientEndpoint();
+ bool success = false;
+ ErrorCode error;
+ success = SdsUtils.Bind(devname, ns, exp, out error);
+ if (!success) {
+ Console.WriteLine("Bind of {0} failed\n", devname);
+ delete imp;
+ delete ns;
+ return null;
+ }
+ switch receive {
+ case imp.Success():
+ break;
+ case imp.ContractNotSupported():
+ Console.WriteLine("{0} does not support IoTestDevice", devname);
+ delete imp;
+ delete ns;
+ return null;
+ case imp.ChannelClosed():
+ Console.WriteLine("IoTestDevice channel to {0} closed unexpectedly", devname);
+ delete imp;
+ delete ns;
+ return null;
+ }
+
+ delete ns;
+ return imp;
+ }
+
+ private static void DisplayPerf(long ticksDelta, long ticksPerSecond, long iters, long chunkSize)
+ {
+ long numBytes = iters * chunkSize;
+ long opsPerSec = ticksDelta == 0 ? long.MaxValue : iters * ticksPerSecond / ticksDelta;
+ long bytesPerSec = ticksDelta == 0 ? long.MaxValue : numBytes * ticksPerSecond / ticksDelta;
+ long mbPerSec = bytesPerSec / (1024*1024);
+ long elapsedSeconds = ticksDelta / ticksPerSecond;
+
+ Console.WriteLine("Ops/s: {0} MB/s: {1} Bytes/Sec {2} Elapsed: {3}",
+ opsPerSec, mbPerSec, bytesPerSec, elapsedSeconds);
+ }
+
+ internal static int AppMain(Parameters! config)
+ {
+ long chunkSize = config.chunksize;
+ long iters = config.count;
+
+ IoTestContract.Imp imp;
+ string! devName = (!)config.deviceName;
+
+ imp = OpenDevice(devName);
+ if (null == imp) {
+ return 1;
+ }
+
+ DateTime startDateTime = ProcessService.GetUtcTime();
+ long startIrqCount = ProcessService.GetKernelInterruptCount();
+ long startSwitchCount = ProcessService.GetContextSwitchCount();
+ long startKernelGcCount = ProcessService.GetKernelGcCount();
+ int startGcCount;
+ long startGcMillis;
+ long startGcBytes;
+ GC.PerformanceCounters(out startGcCount,
+ out startGcMillis,
+ out startGcBytes);
+
+ // Allocate an exchange heap buffer for write
+ byte[] in ExHeap writeBuffer = new [ExHeap] byte [chunkSize];
+
+ // Set a known pattern for comparison on readback
+ for (int i = 0; i < writeBuffer.Length; i++) {
+ writeBuffer[i] = (byte)i;
+ }
+
+ // Allocate an exchange heap buffer for read
+ byte[] in ExHeap readBuffer = new [ExHeap] byte [chunkSize];
+
+ // Clear the read buffer
+ for (int i = 0; i < readBuffer.Length; i++) {
+ readBuffer[i] = 0;
+ }
+
+ for (long count = 0; count < iters; count++) {
+ ulong lengthWritten;
+ ulong lengthRead;
+
+ // Declare a reference to an output buffer from the exchange heap
+ byte[]! in ExHeap outWriteBuffer;
+ byte[]! in ExHeap outReadBuffer;
+
+ // First do a write, we lose ownership of buffer
+ imp.SendWrite(writeBuffer, 0, (ulong)chunkSize);
+
+ // Receive the write ack, we receive ownership of outBuffer
+ imp.RecvAckWrite(out outWriteBuffer, out lengthWritten); // Fix writeOut, not needed???
+
+ // What happens if the real response is RecvNakWrite()?
+ // (an exception occurs)
+
+ if (lengthWritten != (ulong)chunkSize) {
+ Console.WriteLine("Error: lengthWritten {0} does not match request size {1}",
+ lengthWritten, chunkSize);
+ }
+
+ // Compare the pattern
+ for (int i = 0; i < outWriteBuffer.Length; i++) {
+ if (outWriteBuffer[i] != (byte)i) {
+ Console.WriteLine("Error: returned buffer pattern mismatch on Write! index={0}, value={1}, sb={2}",
+ i, outWriteBuffer[i], (byte)i);
+ }
+ }
+
+ writeBuffer = outWriteBuffer;
+
+ // Clear the read buffer
+ for (int i = 0; i < readBuffer.Length; i++) {
+ readBuffer[i] = 0;
+ }
+
+ // Send the Read
+ imp.SendRead(readBuffer, 0, (ulong)chunkSize);
+
+ // Receive the Ack for the read
+ imp.RecvAckRead(out outReadBuffer, out lengthRead);
+
+ // What happens if the real response is RecvNakRead()?
+ // (an exception occurs)
+
+ if (lengthRead != (ulong)chunkSize) {
+ Console.WriteLine("Error: lengthRead {0} does not match request size {1}",
+ lengthRead, chunkSize);
+ }
+
+ // Compare the pattern
+ for (int i = 0; i < outReadBuffer.Length; i++) {
+ if (outReadBuffer[i] != (byte)i) {
+ Console.WriteLine("Error: returned buffer pattern mismatch on Read! index={0}, value={1}, sb={2}",
+ i, outReadBuffer[i], (byte)i);
+ }
+ }
+
+ readBuffer = outReadBuffer;
+ }
+
+ int endGcCount;
+ long endGcMillis;
+ long endGcBytes;
+ long endCycleCount;
+
+ DateTime endDateTime = ProcessService.GetUtcTime();
+
+ GC.PerformanceCounters(out endGcCount,
+ out endGcMillis,
+ out endGcBytes);
+
+ long ticksDelta = endDateTime.Ticks - startDateTime.Ticks;
+
+ double elapsedSeconds;
+
+ DisplayPerf(ticksDelta, DateTime.TicksPerSecond, iters, chunkSize);
+
+ Console.WriteLine("[AppGC :- cnt {0} bytes {1} Kern: ints {2} swi {3} gcs {4}]",
+ endGcCount - startGcCount,
+ endGcBytes - startGcBytes,
+ ProcessService.GetKernelInterruptCount() - startIrqCount,
+ ProcessService.GetContextSwitchCount() - startSwitchCount,
+ ProcessService.GetKernelGcCount() - startKernelGcCount);
+
+ // Rundown exchange heap buffers
+ delete readBuffer;
+ delete writeBuffer;
+
+ // Rundown endpoints
+ delete imp;
+
+ return 0;
+ }
+ }
+}
diff --git a/base/Applications/Tests/KPTest/KPTest.csproj b/base/Applications/Tests/KPTest/KPTest.csproj
deleted file mode 100644
index 679c07a..0000000
--- a/base/Applications/Tests/KPTest/KPTest.csproj
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
- KPTest
- Exe
- true
- true
- true
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Tests/KPTest/KPTest.sg b/base/Applications/Tests/KPTest/KPTest.sg
deleted file mode 100644
index 0a61118..0000000
--- a/base/Applications/Tests/KPTest/KPTest.sg
+++ /dev/null
@@ -1,223 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: KPTest.sg
-//
-// Note: Tests the kernel-process boundary.
-//
-// Feel free to add more commands to this file.
-
-using System;
-using System.Collections;
-using System.Threading;
-using Microsoft.SingSharp;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Memory;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.V1.Services;
-using Microsoft.Singularity.Stress.Contracts;
-
-using Microsoft.Singularity.Channels;
-using Microsoft.Contracts;
-using Microsoft.SingSharp.Reflection;
-using Microsoft.Singularity.Applications;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.Configuration;
-[assembly: Transform(typeof(ApplicationResourceTransform))]
-
-namespace Microsoft.Singularity.Applications {
- [ConsoleCategory(DefaultAction=true)]
- internal class Parameters {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- [BoolParameter( "help", Default=false, HelpMessage="Display Extended help message.")]
- internal bool doHelp;
-
- [StringArrayParameter( "args", HelpMessage="arg bucket")]
- internal string[] args;
-
- reflective internal Parameters();
-
- internal int AppMain() {
- return KPTest.AppMain(this);
- }
- }
-
- public class KPTest : Microsoft.Singularity.Stress.KPTestBase
- {
- static Hashtable! processes = new Hashtable(); // maps strings to Processes
-
- internal static int AppMain(Parameters! config)
- {
- assume config.args != null;
- string[] args;
- if(config.doHelp) {
- Console.WriteLine("usage:");
- Console.WriteLine(" kptest command1 ... commandn");
- Console.WriteLine("where each command is one of:");
- Console.WriteLine(" print s {print s; ...remaining commands...;}");
- Console.WriteLine(" print- s {...remaining commands...; print s}");
- Console.WriteLine(" print^ s {print s; ...remaining commands...; print s}");
- Console.WriteLine(" catch s {try {...remaining commands...} catch(Exception) {print s}}");
- Console.WriteLine(" finally s {try {...remaining commands...} finally {print s}}");
- Console.WriteLine(" break {break; ...remaining commands...; break}");
- Console.WriteLine(" kernel {enter kernel; ...remaining commands...; leave kernel");
- Console.WriteLine(" frames n {make n stack frames; ...remaining commands...; free frames}");
- Console.WriteLine(" throw {throw ArgumentException}");
- Console.WriteLine(" throwstop {throw ProcessStopException} (kernel only)");
- Console.WriteLine(" delay n {for i=1 to n {compute} ...remaining commands...}");
- Console.WriteLine(" sleep n {sleep n milliseconds ...remaining commands...}");
- Console.WriteLine(" yield {yield; ...remaining commands...}");
- Console.WriteLine(" wall {block forever}");
- Console.WriteLine(" (* n ... ) {repeat n {...}; ...remaining commands...}}");
- Console.WriteLine(" (| ... ) {new thread(...); ...remaining commands...}} (process only)");
- Console.WriteLine(" (& s ... ) {new proc s(...); ...remaining commands...}} (process only)");
- Console.WriteLine(" suspend s {suspend proc s; ...remaining commands...} (process only)");
- Console.WriteLine(" resume s {resume proc s; ...remaining commands...} (process only)");
- Console.WriteLine(" stop s {stop proc s; ...remaining commands...} (process only)");
- Console.WriteLine("where s is any string and n is any nonnegative integer");
- Console.WriteLine("example: kptest print hello catch foo frames 1000 kernel finally bar throw");
- Console.WriteLine("example: kptest print 1 (& p print hi delay 100 print bye ) delay 50 stop p");
- Console.WriteLine("example: kptest 'print 1 (& p print hi delay 100 print bye ) delay 50 stop p'");
- return 0;
- }
- else if (config.args.Length == 1) {
- // Turn a single quoted string into a list of arguments.
- // Beware: this doesn't handle multiple spaces between commands.
- string foo = config.args[0] ;
- assert foo != null;
- args = foo.Split(new char[] {' '});
- }
- else args = config.args;
-
- Console.WriteLine("return value: {0:x}", new KPTest().Go(args, 0));
- return 0;
- }
-
- public KPTest()
- {
- }
-
- private string[] args;
-
- private KPTest(String[]! args)
- {
- this.args = args;
- }
-
- private void Run()
- requires this.args != null;
- {
- Console.WriteLine("new thread running");
- Console.WriteLine("thread return value: {0:x}", Go(args, 0));
- }
-
- public override uint Go(string[]! args, int i)
- {
- if (i >= args.Length) return 0x12345678;
- string arg = args[i];
- if (arg == "kernel" || arg == "_kernel")
- {
- ArgList* in ExHeap exArgs = null;
- for(int j = args.Length - 1; j >= 0; j--)
- {
- exArgs = new[ExHeap] ArgList(Bitter.FromString(args[j]), exArgs);
- }
-
- if (arg == "kernel")
- {
- Console.WriteLine("calling kernel");
- }
- unsafe
- {
- uint r = Microsoft.Singularity.V1.Stress.StressDirect.KPTest((SharedHeapService.Allocation*) exArgs, i + 1);
- if (arg == "kernel")
- {
- Console.WriteLine("returned from kernel");
- }
- return r;
- }
- }
- else if (arg == "(|")
- {
- int rParen = FindClosingRParen((!) args, i + 1);
- string[] before = new string[rParen - (i + 1)];
- Array.Copy(args, i + 1, before, 0, before.Length);
- string[] after = new string[args.Length - (rParen + 1)];
- Array.Copy(args, rParen + 1, after, 0, after.Length);
- new Thread(new ThreadStart(new KPTest(before).Run)).Start();
- return Go(after, 0);
- }
- else if (arg == "(&")
- {
- string! name = (!)args[i + 1];
- int rParen = FindClosingRParen((!) args, i + 2);
- string[] before = new string[rParen - (i + 2) + 1];
- before[0] = "kptest";
- Array.Copy(args, i + 2, before, 1, before.Length - 1);
- string[] after = new string[args.Length - (rParen + 1)];
- Array.Copy(args, rParen + 1, after, 0, after.Length);
- Process p = new Process(before);
- processes[name] = p;
- p.Start();
- return Go(after, 0);
- }
- else if (arg == "suspend" || arg == "_suspend")
- {
- string! name = (!)args[i + 1];
- Process! p = (!)(processes[name] as Process);
- if (arg == "suspend")
- {
- Console.WriteLine("suspending " + name);
- }
- p.Suspend(false);
- if (arg == "suspend")
- {
- Console.WriteLine("suspended " + name);
- }
- return Go(args, i + 2);
- }
- else if (arg == "resume" || arg == "_resume")
- {
- string! name = (!)args[i + 1];
- Process! p = (!)(processes[name] as Process);
- if (arg == "resume")
- {
- Console.WriteLine("resuming " + name);
- }
- p.Resume(false);
- if (arg == "resume")
- {
- Console.WriteLine("resumed " + name);
- }
- return Go(args, i + 2);
- }
- else if (arg == "stop" || arg == "_stop")
- {
- string! name = (!)args[i + 1];
- Process! p = (!)(processes[name] as Process);
- if (arg == "stop")
- {
- Console.WriteLine("stopping " + name);
- }
- p.Stop();
- if (arg == "stop")
- {
- Console.WriteLine("stopped " + name);
- }
- return Go(args, i + 2);
- }
- else
- {
- return base.Go(args, i);
- }
- }
- }
-}
diff --git a/base/Applications/Tests/KPTest/StressLib.cs b/base/Applications/Tests/KPTest/StressLib.cs
deleted file mode 100644
index 1f7162d..0000000
--- a/base/Applications/Tests/KPTest/StressLib.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: KPTest.sg
-//
-// Note: Tests the kernel-process boundary.
-//
-// Feel free to add more commands to this file.
-
-using System;
-using Microsoft.SingSharp;
-using Microsoft.Singularity;
-using Microsoft.Singularity.Stress;
-using Microsoft.Singularity.Memory;
-using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.V1.Services;
-using System.Runtime.CompilerServices;
-
-namespace Microsoft.Singularity.Stress
-{
- public class StressDirect
- {
- [OutsideGCDomain]
- [MethodImpl(MethodImplOptions.InternalCall)]
- public static extern unsafe uint KPTest(SharedHeapService.Allocation* sharedArgs, int i);
- }
-}
diff --git a/base/Applications/Tests/Keys/Keys.sg b/base/Applications/Tests/Keys/Keys.sg
index edbc2bc..bb31aa2 100644
--- a/base/Applications/Tests/Keys/Keys.sg
+++ b/base/Applications/Tests/Keys/Keys.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Keys.sg
-//
// Note: Simple Singularity test program.
//
@@ -36,8 +34,7 @@ namespace Microsoft.Singularity.Applications
int y;
uint key = 0;
keyboard.SendGetKey();
- switch receive
- {
+ switch receive {
case keyboard.AckKey(ikey):
key = ikey;
break;
@@ -82,8 +79,7 @@ namespace Microsoft.Singularity.Applications
KeyboardDeviceContract.NewChannel(out keyImp, out keyExp);
nsImp.SendBind(devName, keyExp);
- switch receive
- {
+ switch receive {
case nsImp.AckBind():
return keyImp;
break;
@@ -123,8 +119,7 @@ namespace Microsoft.Singularity.Applications
return null;
}
- switch receive
- {
+ switch receive {
case imp.Success():
break;
case imp.ContractNotSupported():
diff --git a/base/Applications/Tests/MathTest/MathTest.cs b/base/Applications/Tests/MathTest/MathTest.cs
index 5507df3..ad4e76f 100644
--- a/base/Applications/Tests/MathTest/MathTest.cs
+++ b/base/Applications/Tests/MathTest/MathTest.cs
@@ -4,8 +4,7 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: MathTest.cs
-//
+
using System;
namespace Microsoft.Singularity.Applications
diff --git a/base/Applications/Tests/MemStress/MemStress.cs b/base/Applications/Tests/MemStress/MemStress.cs
new file mode 100644
index 0000000..1dbc45b
--- /dev/null
+++ b/base/Applications/Tests/MemStress/MemStress.cs
@@ -0,0 +1,384 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Perform short (bvt) and long running stress of OutOfMemory
+// behavior of the system.
+//
+
+//
+// Tests to support:
+//
+// - Overcommit of heap memory within a SIP
+//
+// Create lots of managed array objects until the OS can no
+// longer satisfy the request and terminates the SIP.
+//
+//
+// - Overcommit of stack memory within a SIP
+//
+// Implement a recursive function that results in stack overflow
+// and termination of the SIP.
+//
+// - Overcommit of heap memory within the kernel
+//
+// Since we can't directly allocate kernel heap memory,
+// we do this by creating lots of kernel objects that occupy
+// the heap (such as new threads)
+//
+// - Overcommit kernel heap memory from within the kernel in multiple
+// threads to find races in any resource reservation strategies that
+// may be timing dependent.
+//
+
+using System;
+using System.Threading;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.UnitTest;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications
+{
+
+ [ConsoleCategory(DefaultAction=true)]
+ internal class Parameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [BoolParameter( "sip_so", Default=false, HelpMessage="Create Stack Overflow in SIP")]
+ internal bool sipSo;
+
+ [BoolParameter( "sip_oom", Default=false, HelpMessage="Create Out Of Memory in SIP")]
+ internal bool sipOom;
+
+ [BoolParameter( "kernel_oom", Default=false, HelpMessage="Create Kernel Out Of Memory")]
+ internal bool kernelOom;
+
+ [BoolParameter( "kernel_oom_stress", Default=false, HelpMessage="Create Kernel Out Of Memory Stress")]
+ internal bool kernelOomStress;
+
+ //
+ // The noProcess parameter runs the test without creating a sub-process.
+ //
+ // Since success for this test is running out of memory and having the SIP
+ // die, there is no way to return a success status to a top level test script.
+ // The script thinks that the SIP failure due to OOM is a failure of the test.
+ //
+ // So by default, the tests are run in a sub-process which we can then monitor
+ // and return a proper result to the top level test script.
+ //
+ // This parameter allows the same executable to be used for both parts
+ // of the test.
+ //
+ [BoolParameter( "noprocess", Default=false, HelpMessage="Run directly without a sub-process")]
+ internal bool noProcess;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return MemStress.AppMain(this);
+ }
+ }
+
+ public class MemStress
+ {
+ internal static int AppMain(Parameters! config)
+ {
+
+#if PAGING
+ if (true) {
+ Console.WriteLine("MemStress does not work on PAGING builds");
+ return -1;
+ }
+#endif
+ DumpMemInfo();
+
+ SipMemoryStresser sipms = new SipMemoryStresser();
+
+ if (!config.noProcess) {
+ if (config.sipSo) {
+ sipms.RunTestAsProcess(config, "-sip_so");
+ }
+ else if (config.sipOom) {
+ sipms.RunTestAsProcess(config, "-sip_oom");
+ }
+ else if (config.kernelOom) {
+ sipms.RunTestAsProcess(config, "-kernel_oom");
+ }
+ else if (config.kernelOomStress) {
+ sipms.RunTestAsProcess(config, "-kernel_oom_stress");
+ }
+ else {
+ Console.WriteLine("Usage: MemStress [-sip_oom] [-sip_so] [-kernel_oom] [-kernel_oom_stress]");
+ Console.WriteLine("Must pick one option");
+ }
+ }
+ else {
+ if (config.sipSo) {
+ sipms.RunSOTest();
+ }
+ else if (config.sipOom) {
+ sipms.RunOOMTest();
+ }
+ else if (config.kernelOom) {
+ sipms.KernelOOMTest();
+ }
+ else if (config.kernelOomStress) {
+ sipms.KernelOOMStress();
+ }
+ else {
+ Console.WriteLine("Usage: MemStress [-sip_oom] [-sip_so] [-kernel_oom] [-kernel_oom_stress]");
+ Console.WriteLine("Must pick one option");
+ }
+ }
+
+ return 0;
+ }
+
+ public static void DumpMemInfo()
+ {
+ int result;
+
+ ulong totalMemoryFree = 0;
+ ulong totalMemoryInUse = 0;
+ ulong kernelHeapInUse = 0;
+ ulong kernelStackInUse = 0;
+ ulong totalSIPHeapInUse = 0;
+ ulong totalSIPStackInUse = 0;
+ ulong kernelStackReservation = 0;
+ ulong kernelHeapReservation = 0;
+
+ result = MemoryInfoService.MemoryUsageInfo(
+ out totalMemoryFree,
+ out totalMemoryInUse,
+ out kernelHeapInUse,
+ out kernelStackInUse,
+ out totalSIPHeapInUse,
+ out totalSIPStackInUse,
+ out kernelStackReservation,
+ out kernelHeapReservation
+ );
+
+ // TODO: Use standard ErrorCode's
+ if (result != 0) {
+ Console.WriteLine("Error {0} retrieving MemoryUsageInfo");
+ }
+ else {
+ Console.WriteLine("TotalMemoryFree 0x{0:x8}, TotalMemoryInUse {1:x8}", totalMemoryFree, totalMemoryInUse);
+ Console.WriteLine("KernelHeapInUse {0:x8}, KernelStackInUse {1:x8}", kernelHeapInUse, kernelStackInUse);
+ Console.WriteLine("TotalSIPHeapInUse {0:x8}, TotalSIPStackInUse {1:x8}", totalSIPHeapInUse, totalSIPStackInUse);
+ Console.WriteLine("KernelStackReservation {0:x8}, KernelHeapReservation {1:x8}", kernelStackReservation, kernelHeapReservation);
+ Console.WriteLine("");
+ }
+ }
+ }
+
+ public class SipMemoryStresser
+ {
+ //
+ // Run out of memory test, eventually terminates the SIP due
+ // to fail fast.
+ //
+ internal void RunTestAsProcess(Parameters! config, string test) {
+
+ Process p = null;
+
+ //
+ // Create a subprocess run of "memstress -testparameter"
+ //
+ string[] args = new string[3];
+ args[0] = "memstress";
+ args[1] = test;
+ args[2] = "-noprocess";
+
+ Console.WriteLine("Creating subprocess memstress {0} -noprocess", test);
+
+ try {
+ p = ProcessLauncher.CreateSubProcess(config, args);
+ }
+ catch (Exception e) {
+ Console.WriteLine("Exception from CreateSubProcess: " + e.Message);
+ return;
+ }
+
+ if (p == null) {
+ Console.WriteLine("Error creating process");
+ return;
+ }
+
+ Console.WriteLine("Process returned with ExitCode={0}", p.ExitCode);
+ }
+
+ public void RunOOMTest() {
+
+ object[] TopLevel;
+ object[] tmp;
+
+ TopLevel = new Object[1];
+
+ //
+ // Currrently the test handles the OOM exception showing
+ // that this works. Additional testing should create multiple
+ // threads and have OOM failures at random places in the runtime
+ // without try/except handlers so we can test the case when
+ // the exception bubbles up to the top of the stack.
+ //
+ try {
+ for (int count = 65535;; count *= 2) {
+
+ tmp = new object[count];
+
+ tmp[0] = TopLevel;
+ TopLevel = tmp;
+
+ for (int i = 1; i < count; i++) {
+ TopLevel[i] = new object[count];
+ }
+
+ MemStress.DumpMemInfo();
+ }
+ }
+ catch (OutOfMemoryException e) {
+ e=e;
+ //Thread.CurrentProcess.Stop(1);
+ return;
+ }
+ }
+
+ // Run stack overflow test, terminates the SIP
+ public void RunSOTest() {
+
+ // Test the fail fast path directly
+ //Microsoft.Singularity.V1.Services.StackService.StackOverflow();
+
+ RunSOTest();
+ }
+
+ //
+ // Invoke a kernel heap out of memory condition by creating
+ // lots of kernel objects
+ //
+ public void KernelOOMTest() {
+
+ IdleThread[] threads;
+
+ int threadCount = 1000;
+
+ while (true) {
+
+ System.Console.WriteLine("Creating {0} threads", threadCount);
+
+ threads = new IdleThread[threadCount];
+ if (threads == null) {
+ System.Console.WriteLine("Error allocating Thread[]");
+ return;
+ }
+
+ for (int i = 0; i < threadCount; i++) {
+ threads[i] = new IdleThread(i);
+ if (threads[i] == null) {
+ System.Console.WriteLine("Error creating thread");
+ return;
+ }
+ }
+
+ // Start them running
+ for (int i = 0; i < threadCount; i++) {
+ ((!)threads[i]).RunThread();
+ }
+ }
+ }
+
+ //
+ // Use multiple threads to stress the system and induce
+ // kernel heap OOM to test the ability for the system
+ // to remain running.
+ //
+ public void KernelOOMStress() {
+ Console.WriteLine("Not implemented yet");
+ return;
+ }
+ }
+
+ // Generic class that creates the thread
+ public class ThreadRunner
+ {
+ private Thread thread;
+
+ public ThreadRunner() {
+ }
+
+ public Thread Thread {
+ get {
+ return thread;
+ }
+ }
+
+ // Creates thread, returns with it running
+ public Thread RunThread() {
+
+ thread = new Thread(new ThreadStart(ThreadMain));
+
+ thread.Start();
+
+ return thread;
+ }
+
+ public virtual void ThreadMain() {
+
+ // This exits the thread
+ return;
+ }
+ }
+
+ //
+ // Implementation classes represent different thread creation
+ // parameters, and actions
+ //
+
+ //
+ // This creates an idle thread that just waits.
+ //
+ // The goal is to create lots of kernel objects and use up
+ // memory, not jam the system with many threads until
+ // it stalls.
+ //
+ public class IdleThread : ThreadRunner
+ {
+ private long argValue;
+
+ public IdleThread(long arg) : base() {
+ argValue = arg;
+ }
+
+ public override void ThreadMain() {
+
+ // Wait for ever
+ while (true) {
+ Thread.Sleep(60*60*1000);
+ }
+
+ // This exits the thread
+ return;
+ }
+ }
+}
+
+
diff --git a/base/Applications/Tests/MemStress/MemStress.csproj b/base/Applications/Tests/MemStress/MemStress.csproj
new file mode 100644
index 0000000..5d17adf
--- /dev/null
+++ b/base/Applications/Tests/MemStress/MemStress.csproj
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ MemStress
+ Exe
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/MemStress/SubProcess.sg b/base/Applications/Tests/MemStress/SubProcess.sg
new file mode 100644
index 0000000..f5bfd3a
--- /dev/null
+++ b/base/Applications/Tests/MemStress/SubProcess.sg
@@ -0,0 +1,94 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+ using System;
+//using System.Threading;
+using Microsoft.SingSharp;
+using Microsoft.Singularity;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Test.Contracts;
+using Microsoft.Singularity.Xml;
+
+using FileSystem.Utils;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Io;
+//using System.Collections;
+
+using Microsoft.Singularity.V1.Services;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Directory;
+using Microsoft.Contracts;
+
+namespace Microsoft.Singularity.Applications
+{
+
+ public class ProcessLauncher {
+
+ internal static Process CreateSubProcess(
+ Parameters! config,
+ string[] args
+ )
+ {
+ DirectoryServiceContract.Imp ds = config.nsRef.Acquire();
+ if (ds == null) {
+ throw new Exception("Unable to acquire handle to the Directory Service root");
+ }
+ ds.RecvSuccess();
+
+ PipeMultiplexer outputMux = MuxOut();
+ if (outputMux == null) {
+ delete ds;
+ return null;
+ }
+
+ Manifest manifest;
+
+ Process child = Binder.CreateProcess(ds, args, outputMux, out manifest);
+ if (child == null) {
+ Console.WriteLine("Error creating process");
+ DebugStub.Print("Error creating process");
+ outputMux.Dispose();
+ delete ds;
+ return null;
+ }
+
+ child.Start();
+
+ child.Join();
+
+ outputMux.Dispose();
+ delete ds;
+
+ if (null == child) {
+ return null;
+ }
+
+ // Allow the caller to the get childs exit status
+ return child;
+ }
+
+ // Redirect our standard output into a multiplexer so we can interleave
+ // output from child processes
+ static private PipeMultiplexer MuxOut()
+ {
+ // Swap our real stdOut with a newly created one
+ UnicodePipeContract.Exp! newOutputExp;
+ UnicodePipeContract.Imp! newOutputImp;
+ UnicodePipeContract.NewChannel(out newOutputImp, out newOutputExp);
+ UnicodePipeContract.Imp stdOut = ConsoleOutput.Swap(newOutputImp);
+ if (stdOut == null) {
+ // TODO may not require stdout once we report to debugStub
+ Console.WriteLine("test expects a STDOUT pipe");
+ delete newOutputExp;
+ return null;
+ }
+ // Use a mux to splice our own output together with the child
+ // processes we will run.
+ return PipeMultiplexer.Start(stdOut, newOutputExp);
+ }
+ }
+}
+
diff --git a/base/Applications/Tests/MonitorTest/MonitorTest.cs b/base/Applications/Tests/MonitorTest/MonitorTest.cs
deleted file mode 100644
index ce98728..0000000
--- a/base/Applications/Tests/MonitorTest/MonitorTest.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-// Microsoft Research Singularity
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// File: MonitorTest.cs
-//
-// Note: Some basic tests of the monitor code.
-//
-
-using System;
-using System.Threading;
-
-using Microsoft.Singularity.UnitTest;
-
-using Microsoft.Singularity.Channels;
-using Microsoft.Contracts;
-using Microsoft.SingSharp.Reflection;
-using Microsoft.Singularity.Applications;
-using Microsoft.Singularity.Io;
-using Microsoft.Singularity.Configuration;
-[assembly: Transform(typeof(ApplicationResourceTransform))]
-
-namespace Microsoft.Singularity.Applications {
- [ConsoleCategory(DefaultAction=true)]
- internal class Parameters {
- [InputEndpoint("data")]
- public readonly TRef Stdin;
-
- [OutputEndpoint("data")]
- public readonly TRef Stdout;
-
- reflective internal Parameters();
-
- internal int AppMain() {
- return MonitorTest.AppMain(this);
- }
- }
-
- public class MonitorTest
- {
- internal static int AppMain(Parameters! config)
- {
- for (int i = 0; i < 2; i++) {
- UnitTest.Add("Many Threads PulseAll",
- new UnitTest.TestDelegate(PulseAllTest.ManyThreadsTest));
-
- UnitTest.Add("Few Threads Pulse",
- new UnitTest.TestDelegate(PulseAllTest.FewThreadsTest));
-
- UnitTest.Add("Low-density Pulse",
- new UnitTest.TestDelegate(PulseTest.LowDensityTest));
- UnitTest.Add("Medium-density Pulse",
- new UnitTest.TestDelegate(PulseTest.MediumDensityTest));
- UnitTest.Add("High-density Pulse",
- new UnitTest.TestDelegate(PulseTest.HighDensityTest));
- }
- return ((UnitTest.Run(true) == UnitTest.Result.Passed) &&
- Assert.Failures == 0) ? 0 : 1;
- }
- }
-}
diff --git a/base/Applications/Tests/MonitorTest/MonitorTest.csproj b/base/Applications/Tests/MonitorTest/MonitorTest.csproj
index 24f633c..b4a0e42 100644
--- a/base/Applications/Tests/MonitorTest/MonitorTest.csproj
+++ b/base/Applications/Tests/MonitorTest/MonitorTest.csproj
@@ -5,32 +5,26 @@ Microsoft Research Singularity
Copyright (c) Microsoft Corporation. All rights reserved.
-File: Applications\Tests\MonitorTest\MonitorTest.csproj
-
-Note: MonitorTest test
+Note:
##############################################################################
-->
-
+
MonitorTest
Exe
- true
+
+ true
true
-
-
-
-
-
-
+
diff --git a/base/Applications/Tests/MonitorTest/PulseAllTest.cs b/base/Applications/Tests/MonitorTest/PulseAllTest.cs
index 3216b04..5a86174 100644
--- a/base/Applications/Tests/MonitorTest/PulseAllTest.cs
+++ b/base/Applications/Tests/MonitorTest/PulseAllTest.cs
@@ -4,14 +4,13 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: PulseTest.cs
-//
// Note:
//
using System;
using System.Threading;
+using Microsoft.Singularity;
using Microsoft.Singularity.UnitTest;
namespace Microsoft.Singularity.Applications
@@ -20,8 +19,26 @@ namespace Microsoft.Singularity.Applications
/// A test of Monitor.PulseAll. A collection of threads waits on
/// a single monitor for a pulse all.
///
- internal sealed class PulseAllTest
+ [TestClass]
+ public class PulseAllTest : TestClass
{
+ [TestMethod]
+ public void FewThreadsTest()
+ {
+ (new Pulser(8, 2, Expect)).RunTest();
+ }
+
+ [TestMethod]
+ public void ManyThreadsTest()
+ {
+ (new Pulser(50, 2, Expect)).RunTest();
+ }
+ }
+
+ internal sealed class Pulser
+ {
+ TestLog Expect;
+
int waiterCount = 50;
int timeoutSeconds = 2;
@@ -37,6 +54,15 @@ namespace Microsoft.Singularity.Applications
object! monitor = new object();
bool []! visited;
+
+ public Pulser(int threadCount, int timeoutSeconds, TestLog expect)
+ {
+ this.waiterCount = threadCount;
+ this.visited = new bool [threadCount];
+ this.timeoutSeconds = timeoutSeconds;
+ this.Expect = expect;
+ }
+
private static void Yield()
{
#if SINGULARITY
@@ -48,7 +74,7 @@ namespace Microsoft.Singularity.Applications
public void WatchdogThreadMain()
{
- TimeSpan delta = TimeSpan.FromSeconds(timeoutSeconds);
+ TimeSpan delta = TimeSpan.FromMilliseconds(500);
int now = this.generation;
int last = 0;
@@ -59,18 +85,15 @@ namespace Microsoft.Singularity.Applications
}
Yield();
now = this.generation;
- } while (last != now);
-
- DebugStub.Break();
-
- this.timedOut = true;
+ Expect.NotEqual(last, now, "progress was made in the last cycle");
+ } while (true);
}
public void ControllerThreadMain()
{
const int iterations = 1000;
- const int YieldFudge = 50;
+ const int YieldFudge = 150;
// Signal worker threads to start
controllerReady.Set();
@@ -78,13 +101,6 @@ namespace Microsoft.Singularity.Applications
for (int i = 1; i <= iterations; i++) {
barrierEvent.WaitOne();
- // There is a potential
- // race between the last thread reaching the barrier
- // setting the barrierEvent and reaching the Monitor.Wait
- // call. By yielding a few times we should give the
- // thread enough time to get there.
- for (int n = 0; n < YieldFudge; n++)
- Yield();
lock (this.monitor) {
// Reset check state
this.passedBarrier = 0;
@@ -107,19 +123,18 @@ namespace Microsoft.Singularity.Applications
while (!stop) {
Monitor.Enter(this.monitor);
try {
- Assert.True(waiterRunning == false,
- "Two waiters have monitor.");
+ Expect.False(waiterRunning, "Only one waiter is in the monitor");
waiterRunning = true;
- Assert.False(this.visited[this.passedBarrier],
- "Thread already reached barrier.");
+ Expect.False(this.visited[this.passedBarrier],
+ "Thread is before the barrier");
this.visited[this.passedBarrier] = true;
this.passedBarrier++;
this.generation++;
- Assert.LessOrEqual(this.passedBarrier, waiterCount,
- "More waiters passed barrier than expected.");
+ Expect.LessOrEqual(this.passedBarrier, waiterCount,
+ "Not too many waiters passed the barrier");
if (this.passedBarrier == this.waiterCount) {
barrierEvent.Set();
@@ -153,26 +168,9 @@ namespace Microsoft.Singularity.Applications
}
while (!controller.Join(TimeSpan.FromMilliseconds(100))) {
- Assert.False(this.timedOut, "Timed out!");
+ Expect.False(this.timedOut, "Completed before timeout");
}
watchdog.Join();
}
-
- public PulseAllTest(int threadCount, int timeoutSeconds)
- {
- this.waiterCount = threadCount;
- this.timeoutSeconds = timeoutSeconds;
- this.visited = new bool [threadCount];
- }
-
- public static void FewThreadsTest()
- {
- (new PulseAllTest(8, 2)).RunTest();
- }
-
- public static void ManyThreadsTest()
- {
- (new PulseAllTest(50, 2)).RunTest();
- }
}
}
diff --git a/base/Applications/Tests/MonitorTest/PulseTest.cs b/base/Applications/Tests/MonitorTest/PulseTest.cs
index 94f4f6a..f541eca 100644
--- a/base/Applications/Tests/MonitorTest/PulseTest.cs
+++ b/base/Applications/Tests/MonitorTest/PulseTest.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: PulseTest.cs
-//
// Note:
//
@@ -23,22 +21,75 @@ namespace Microsoft.Singularity.Applications
/// a collection of threads then enters, spins, pulses, and exits.
///
///
- internal sealed class PulseTest
+ [TestClass]
+ public class PulseTest : TestClass
{
- internal class Node
+ [ClassInitialize]
+ public void Init()
+ {
+ // HACK
+ PulseHelper.Expect = Expect;
+ }
+
+ [TestMethod]
+ public void LowDensityTest()
+ {
+ PulseHelper p = new PulseHelper(128, 17, 20);
+ p.Initialize();
+ p.RunTest();
+ }
+
+ [TestMethod]
+ public void MediumDensityTest()
+ {
+ PulseHelper p = new PulseHelper(32, 32, 20);
+ p.Initialize();
+ p.RunTest();
+ }
+
+ [TestMethod]
+ public void HighDensityTest()
+ {
+ PulseHelper p = new PulseHelper(4, 128, 20);
+ p.Initialize();
+ p.RunTest();
+ }
+ }
+
+ internal sealed class PulseHelper
+ {
+
+ public static TestLog Expect;
+
+ internal PulseHelper(int numberOfNodes, int numberOfThreads, int iterations)
+ {
+ this.nodes = new Node[numberOfNodes];
+ this.threadCount = numberOfThreads;
+ this.maxCycles = iterations;
+ this.startedCount = 0;
+ this.finishedCount = 0;
+ this.finishedEvent = new ManualResetEvent(false);
+ }
+
+ internal class Node
{
volatile bool inVisit = false;
+ // workaround Phoenix MSIL/PDB reader bug 1083
+ public Node()
+ {
+ }
+
internal void BeginVisit()
{
Monitor.Enter(this);
- Assert.False(inVisit, "Node is visited by two threads");
+ Expect.False(inVisit, "This is the first thread into the node");
inVisit = true;
}
internal void EndVisit()
{
- Assert.True(inVisit, "Unpaired visit ending");
+ Expect.True(inVisit, "EndVisit has a corresponding BeginVisit");
Monitor.Pulse(this);
inVisit = false;
Monitor.Exit(this);
@@ -74,7 +125,7 @@ namespace Microsoft.Singularity.Applications
int r = this.path[n];
this.remainLength--;
- this.path[r] = this.path[this.remainLength];
+ this.path[n] = this.path[this.remainLength];
this.path[this.remainLength] = r;
if (this.remainLength == 0) {
@@ -127,8 +178,9 @@ namespace Microsoft.Singularity.Applications
// Yield up to number of threads to give other
// threads a chance to run
int yieldCount = rng.Next(this.threadCount);
- while (yieldCount-- > 0)
+ while (yieldCount-- > 0) {
Yield();
+ }
n.EndVisit();
// Console.Write("[{0}]", threadNumber);
@@ -146,28 +198,28 @@ namespace Microsoft.Singularity.Applications
private void WatchdogThreadMain()
{
int last = this.generation;
+
+ // give the visitor threads a chance to initialize
+ const int maxInitializationTime = 120;
+ int loopCount = 0;
+ while (startedCount != this.threadCount && ++loopCount < maxInitializationTime) {
+ Thread.Sleep(1000);
+ }
+
for (;;) {
Thread.Sleep(TimeSpan.FromSeconds(5));
if (this.finishedCount == this.threadCount) {
return;
}
int now = this.generation;
- Assert.True(last != now, "Deadlock detected.");
+ if (last == now) {
+ DebugStub.Break();
+ }
last = now;
}
}
- internal PulseTest(int numberOfNodes, int numberOfThreads, int iterations)
- {
- this.nodes = new Node[numberOfNodes];
- this.threadCount = numberOfThreads;
- this.maxCycles = iterations;
- this.startedCount = 0;
- this.finishedCount = 0;
- this.finishedEvent = new ManualResetEvent(false);
- }
-
- private void Initialize()
+ internal void Initialize()
{
for (int i = 0; i < nodes.Length; i++) {
nodes[i] = new Node();
@@ -184,28 +236,6 @@ namespace Microsoft.Singularity.Applications
finishedEvent.WaitOne();
watchdog.Join();
- Assert.True(Assert.Failures == 0, "Failures within threads.");
- }
-
- internal static void LowDensityTest()
- {
- PulseTest p = new PulseTest(128, 17, 20);
- p.Initialize();
- p.RunTest();
- }
-
- internal static void MediumDensityTest()
- {
- PulseTest p = new PulseTest(32, 32, 20);
- p.Initialize();
- p.RunTest();
- }
-
- internal static void HighDensityTest()
- {
- PulseTest p = new PulseTest(4, 128, 20);
- p.Initialize();
- p.RunTest();
}
}
}
diff --git a/base/Applications/Tests/MpStress/MpStress.cs b/base/Applications/Tests/MpStress/MpStress.cs
new file mode 100644
index 0000000..b2b4d5f
--- /dev/null
+++ b/base/Applications/Tests/MpStress/MpStress.cs
@@ -0,0 +1,294 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Perform short (bvt) and long running stress of multiprocessor
+// sensitive areas of the system. Used MonitorTest.cs as an
+// application template
+//
+
+using System;
+using System.Threading;
+
+using Microsoft.Singularity.UnitTest;
+
+using Microsoft.Singularity.Channels;
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications
+{
+ [ConsoleCategory(DefaultAction=true)]
+ internal class Parameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [LongParameter("cpucount", Default=2, HelpMessage="CPU Count for test")]
+ internal long cpuCount;
+
+ [LongParameter("passcount", Default=10, HelpMessage="Pass Count for test")]
+ internal long passCount;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return MpStress.AppMain(this);
+ }
+ }
+
+ public class MpStress
+ {
+ internal static int AppMain(Parameters! config)
+ {
+ int result;
+
+ Console.WriteLine("Running MpStress for CPU Count {0}", config.cpuCount);
+
+ ThreadTest tt = new ThreadTest();
+
+ result = tt.RunTest(config.cpuCount, config.passCount);
+ if (result != 0) {
+ return result;
+ }
+
+ return 0;
+ }
+ }
+
+ public class ThreadTest
+ {
+
+ public int RunTest(long cpuCount, long passCount) {
+
+ // Start the thread create/destroy test
+ //ThreadTestsThread threadTests = new ThreadTestsThread(cpuCount);
+
+ // Run pulse tests
+ PulseTestsThread pulseTests = new PulseTestsThread(cpuCount, passCount);
+ pulseTests.RunThread();
+
+ // Start the background threads
+ //threadTests.RunThread();
+
+ // Wait for pulse tests to complete
+ ((!)pulseTests.Thread).Join();
+
+ return 0;
+ }
+ }
+
+ //
+ // Implementation classes represent different thread creation
+ // parameters, and actions
+ //
+
+ public class PrintThread : ThreadRunner
+ {
+ private long argValue;
+
+ public PrintThread(long arg) : base() {
+ argValue = arg;
+ }
+
+ public override void ThreadMain() {
+
+ //System.Console.WriteLine("PrintThread: Thread {0}, ThreadIndex {1}\n", Thread.CurrentThread.GetThreadId(), argValue);
+
+ // Call some additional "interesting" system calls here in order to disturb
+ // the system state, cause lock contention, flesh out races and unprotected code
+ // regions, etc.
+ //
+
+ // This exits the thread
+ //Console.Write("-");
+ return;
+ }
+ }
+
+ public class ThreadTestsThread : ThreadRunner
+ {
+ private long cpuCount;
+
+ public ThreadTestsThread(long cpuCount) : base() {
+ this.cpuCount = cpuCount;
+ }
+
+ public override void ThreadMain() {
+
+ const long Timeout = 1000 * 10; // 10 seconds
+ long threadCount = 0;
+ PrintThread[] threads;
+
+ threadCount = cpuCount * 2;
+
+ //
+ // Run forever, process will exit when the ApMain thread
+ // is done with the test sequence
+ //
+ for (;;) {
+
+ //Console.Write(".");
+
+ threads = new PrintThread[threadCount];
+ if (threads == null) {
+ System.Console.WriteLine("Error allocating Thread[]");
+ return;
+ }
+
+ for (int i = 0; i < threadCount; i++) {
+ threads[i] = new PrintThread(i);
+ if (threads[i] == null) {
+ System.Console.WriteLine("Error creating thread");
+ return;
+ }
+ }
+
+ // Start them running
+ for (int i = 0; i < threadCount; i++) {
+ ((!)threads[i]).RunThread();
+ }
+
+ TimeSpan timeout = TimeSpan.FromMilliseconds(Timeout);
+
+ for (int i = 0; i < threadCount; i++) {
+ if (!((!)(((!)threads[i]).Thread)).Join(timeout)) {
+ Console.WriteLine("Timeout waiting for thread exit");
+ return;
+ }
+ //Console.Write("+");
+ }
+ }
+ }
+ }
+
+ public class PulseTestsThread : ThreadRunner
+ {
+ private long cpuCount;
+ private long passes;
+ private int threadCount;
+ private int maxThreadCount;
+ private const int threadsPerCpu = 64;
+
+ public PulseTestsThread(long cpuCount, long passes) : base() {
+ this.cpuCount = cpuCount;
+ this.passes = passes;
+ maxThreadCount = threadsPerCpu * (int)cpuCount;
+
+ // Limit max threads, otherwise we will overflow the kernel's thread table
+ if (maxThreadCount > 512) {
+ maxThreadCount = 512;
+ }
+ }
+
+ public override void ThreadMain() {
+
+ System.Console.WriteLine("Running PulseTests: Thread {0}\n", Thread.CurrentThread.GetThreadId());
+ Console.Write("passes={0}", passes);
+ Console.WriteLine(" cpuCount={0}", cpuCount);
+
+ for (int pass = 0; pass < passes; pass++) {
+
+ Console.WriteLine("pass={0}", pass);
+
+ UnitTest.Clear();
+ threadCount = 0;
+
+ for (int i = 0; i < cpuCount; i++) {
+
+ // 50 threads
+ if (!CheckMaxThreads(50)) {
+ UnitTest.Add("Many Threads PulseAll",
+ new UnitTest.TestDelegate(PulseAllTest.ManyThreadsTest));
+ }
+
+ // 8 threads
+ if (!CheckMaxThreads(8)) {
+ UnitTest.Add("Few Threads PulseAll",
+ new UnitTest.TestDelegate(PulseAllTest.FewThreadsTest));
+ }
+
+ // 17 threads
+ if (!CheckMaxThreads(17)) {
+ UnitTest.Add("Low-density Pulse",
+ new UnitTest.TestDelegate(PulseTest.LowDensityTest));
+ }
+
+ // 32 threads
+ if (!CheckMaxThreads(32)) {
+ UnitTest.Add("Medium-density Pulse",
+ new UnitTest.TestDelegate(PulseTest.MediumDensityTest));
+ }
+
+ // 128 threads
+ if (!CheckMaxThreads(128)) {
+ UnitTest.Add("High-density Pulse",
+ new UnitTest.TestDelegate(PulseTest.HighDensityTest));
+ }
+ }
+
+ Console.WriteLine("{0} PulseThreads", threadCount);
+
+ // Wait for the sub-threads to run
+ if (UnitTest.Run(true) != UnitTest.Result.Passed) {
+ Console.WriteLine("PulseTest failed!\n");
+ }
+ }
+
+ // This exits the thread
+ return;
+ }
+
+ // We must keep total thread count at a reasonable level
+ // otherwise we overflow the kernel thread table that is
+ // hardcoded at 1024. We will set 512 max threads for now.
+ private bool CheckMaxThreads(int count)
+ {
+ if ((count + threadCount) <= maxThreadCount) {
+ threadCount += count;
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ // Generic class that creates the thread
+ public class ThreadRunner
+ {
+ private Thread thread;
+
+ public ThreadRunner() {
+ }
+
+ public Thread Thread {
+ get {
+ return thread;
+ }
+ }
+
+ // Creates thread, returns with it running
+ public Thread RunThread() {
+
+ thread = new Thread(new ThreadStart(ThreadMain));
+
+ thread.Start();
+
+ return thread;
+ }
+
+ public virtual void ThreadMain() {
+
+ // This exits the thread
+ return;
+ }
+ }
+}
diff --git a/base/Applications/Tests/MpStress/MpStress.csproj b/base/Applications/Tests/MpStress/MpStress.csproj
new file mode 100644
index 0000000..c8346eb
--- /dev/null
+++ b/base/Applications/Tests/MpStress/MpStress.csproj
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+ MpStress
+ Exe
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/MpStress/PulseAllTest.cs b/base/Applications/Tests/MpStress/PulseAllTest.cs
new file mode 100644
index 0000000..016e3eb
--- /dev/null
+++ b/base/Applications/Tests/MpStress/PulseAllTest.cs
@@ -0,0 +1,174 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+
+using System;
+using System.Threading;
+
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ ///
+ /// A test of Monitor.PulseAll. A collection of threads waits on
+ /// a single monitor for a pulse all.
+ ///
+ internal sealed class PulseAllTest
+ {
+ int waiterCount = 50;
+ int timeoutSeconds = 2;
+
+ int passedBarrier = 0;
+ bool waiterRunning = false;
+ volatile bool timedOut = false;
+ volatile bool stop = false;
+ volatile int generation = 0;
+
+ ManualResetEvent controllerReady = new ManualResetEvent(false);
+ ManualResetEvent finishedEvent = new ManualResetEvent(false);
+ AutoResetEvent barrierEvent = new AutoResetEvent(false);
+ object monitor = new object();
+ bool [] visited;
+
+ private static void Yield()
+ {
+#if SINGULARITY
+ Thread.Yield();
+#else
+ Thread.Sleep(0);
+#endif
+ }
+
+ public void WatchdogThreadMain()
+ {
+ TimeSpan delta = TimeSpan.FromSeconds(timeoutSeconds);
+
+ int now = this.generation;
+ int last = 0;
+ do {
+ last = now;
+ if (finishedEvent.WaitOne(delta)) {
+ return;
+ }
+ Yield();
+ now = this.generation;
+ if (last == now)
+ DebugStub.Break(); // break if we made no progress
+ } while (true);
+ }
+
+ public void ControllerThreadMain()
+ {
+ const int iterations = 1000;
+
+ const int YieldFudge = 50;
+
+ // Signal worker threads to start
+ controllerReady.Set();
+ Yield();
+
+ for (int i = 1; i <= iterations; i++) {
+ barrierEvent.WaitOne();
+ // There is a potential
+ // race between the last thread reaching the barrier
+ // setting the barrierEvent and reaching the Monitor.Wait
+ // call. By yielding a few times we should give the
+ // thread enough time to get there.
+ for (int n = 0; n < YieldFudge; n++)
+ Yield();
+ lock (this.monitor) {
+ // Reset check state
+ this.passedBarrier = 0;
+ for (int j = 0; j < visited.Length; j++) {
+ visited[j] = false;
+ }
+
+ // Set stop flag if end is reached
+ this.stop = (i == iterations);
+
+ // Wake up waiters
+ Monitor.PulseAll(this.monitor);
+ }
+ }
+ finishedEvent.Set();
+ }
+
+ public void WaiterThreadMain()
+ {
+ while (!stop) {
+ Monitor.Enter(this.monitor);
+ try {
+ Assert.True(waiterRunning == false,
+ "Two waiters have monitor.");
+ waiterRunning = true;
+
+ Assert.False(this.visited[this.passedBarrier],
+ "Thread already reached barrier.");
+ this.visited[this.passedBarrier] = true;
+
+ this.passedBarrier++;
+ this.generation++;
+
+ Assert.LessOrEqual(this.passedBarrier, waiterCount,
+ "More waiters passed barrier than expected.");
+
+ if (this.passedBarrier == this.waiterCount) {
+ barrierEvent.Set();
+ }
+
+ this.waiterRunning = false;
+ Monitor.Wait(this.monitor);
+ this.waiterRunning = true;
+ }
+ finally {
+ this.waiterRunning = false;
+ Monitor.Exit(this.monitor);
+ }
+ }
+ }
+
+ public void RunTest()
+ {
+ Thread watchdog =
+ new Thread(new ThreadStart(WatchdogThreadMain));
+ Thread controller =
+ new Thread(new ThreadStart(ControllerThreadMain));
+
+ watchdog.Start();
+ controller.Start();
+
+ controllerReady.WaitOne();
+ for (int i = 0; i < waiterCount; i++) {
+ Thread t = new Thread(new ThreadStart(WaiterThreadMain));
+ t.Start();
+ }
+
+ while (!controller.Join(TimeSpan.FromMilliseconds(100))) {
+ Assert.False(this.timedOut, "Timed out!");
+ }
+ watchdog.Join();
+ }
+
+ public PulseAllTest(int threadCount, int timeoutSeconds)
+ {
+ this.waiterCount = threadCount;
+ this.timeoutSeconds = timeoutSeconds;
+ this.visited = new bool [threadCount];
+ }
+
+ public static void FewThreadsTest()
+ {
+ (new PulseAllTest(8, 500)).RunTest();
+ }
+
+ public static void ManyThreadsTest()
+ {
+ (new PulseAllTest(50, 500)).RunTest();
+ }
+ }
+}
diff --git a/base/Applications/Tests/MpStress/PulseTest.cs b/base/Applications/Tests/MpStress/PulseTest.cs
new file mode 100644
index 0000000..27eaa46
--- /dev/null
+++ b/base/Applications/Tests/MpStress/PulseTest.cs
@@ -0,0 +1,210 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note:
+//
+
+using System;
+using System.Threading;
+
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ ///
+ /// A class for testing Monitor.Pulse.
+ ///
+ /// This class creates a group of monitors (Node class) that
+ /// a collection of threads then enters, spins, pulses, and exits.
+ ///
+ ///
+ internal sealed class PulseTest
+ {
+ internal class Node
+ {
+ volatile bool inVisit = false;
+
+ internal void BeginVisit()
+ {
+ Monitor.Enter(this);
+ Assert.False(inVisit, "Node is visited by two threads");
+ inVisit = true;
+ }
+
+ internal void EndVisit()
+ {
+ Assert.True(inVisit, "Unpaired visit ending");
+ Monitor.Pulse(this);
+ inVisit = false;
+ Monitor.Exit(this);
+ }
+ }
+
+ internal sealed class VisitPath
+ {
+ int [] path;
+ int remainLength;
+ int cycles;
+
+ internal VisitPath(int pathLength)
+ {
+ this.path = new int[pathLength];
+ this.remainLength = pathLength;
+ this.cycles = 0;
+ }
+
+ internal void Initialize()
+ {
+ // This is a separate method so
+ // we can compile compatibly on Win32. SGC wants
+ // the Sing# specific NonDelayed attribute otherwise.
+ for (int i = 0; i < this.remainLength; i++) {
+ this.path[i] = i;
+ }
+ }
+
+ internal int Pick(int randomNumber)
+ {
+ int n = randomNumber % this.remainLength;
+ int r = this.path[n];
+
+ this.remainLength--;
+ this.path[n] = this.path[this.remainLength];
+ this.path[this.remainLength] = r;
+
+ if (this.remainLength == 0) {
+ this.cycles++;
+ this.remainLength = this.path.Length;
+ }
+ return r;
+ }
+
+ internal int Cycles { get { return this.cycles; } }
+ }
+
+ private Node[] nodes;
+ private readonly int threadCount;
+ private readonly int maxCycles;
+ private volatile int startedCount;
+ private volatile int finishedCount;
+ private volatile int generation;
+ private ManualResetEvent finishedEvent;
+
+ private static void Yield()
+ {
+#if SINGULARITY
+ Thread.Yield();
+#else
+ Thread.Sleep(0);
+#endif
+ }
+
+ internal void VisitorThreadMain()
+ {
+ // Wait until all other threads have started
+ int threadNumber;
+ lock (this) {
+ threadNumber = startedCount++;
+ }
+ while (startedCount != this.threadCount) {
+ Yield();
+ }
+
+ Random rng = new Random(threadNumber);
+ VisitPath path = new VisitPath(this.nodes.Length);
+ path.Initialize();
+
+ while (path.Cycles != this.maxCycles) {
+ // Select a node previously unvisited in this cycle
+ Node/*!*/ n = /*^(!)^*/ nodes[path.Pick(rng.Next())];
+ n.BeginVisit();
+
+ // Yield up to number of threads to give other
+ // threads a chance to run
+ int yieldCount = rng.Next(this.threadCount);
+ while (yieldCount-- > 0)
+ Yield();
+
+ n.EndVisit();
+ // Console.Write("[{0}]", threadNumber);
+ this.generation++;
+ }
+
+ lock (this) {
+ this.finishedCount++;
+ if (this.finishedCount == this.threadCount) {
+ this.finishedEvent.Set();
+ }
+ }
+ }
+
+ private void WatchdogThreadMain()
+ {
+ int last = this.generation;
+ for (;;) {
+ Thread.Sleep(TimeSpan.FromSeconds(500));
+ if (this.finishedCount == this.threadCount) {
+ return;
+ }
+ int now = this.generation;
+ if (last == now)
+ DebugStub.Break();
+ last = now;
+ }
+ }
+
+ internal PulseTest(int numberOfNodes, int numberOfThreads, int iterations)
+ {
+ this.nodes = new Node[numberOfNodes];
+ this.threadCount = numberOfThreads;
+ this.maxCycles = iterations;
+ this.startedCount = 0;
+ this.finishedCount = 0;
+ this.finishedEvent = new ManualResetEvent(false);
+ }
+
+ private void Initialize()
+ {
+ for (int i = 0; i < nodes.Length; i++) {
+ nodes[i] = new Node();
+ }
+ }
+
+ internal void RunTest()
+ {
+ for (int i = 0; i < this.threadCount; i++) {
+ (new Thread(new ThreadStart(VisitorThreadMain))).Start();
+ }
+ Thread watchdog = new Thread(new ThreadStart(WatchdogThreadMain));
+ watchdog.Start();
+
+ finishedEvent.WaitOne();
+ watchdog.Join();
+ Assert.True(Assert.Failures == 0, "Failures within threads.");
+ }
+
+ internal static void LowDensityTest()
+ {
+ PulseTest p = new PulseTest(128, 17, 20);
+ p.Initialize();
+ p.RunTest();
+ }
+
+ internal static void MediumDensityTest()
+ {
+ PulseTest p = new PulseTest(32, 32, 20);
+ p.Initialize();
+ p.RunTest();
+ }
+
+ internal static void HighDensityTest()
+ {
+ PulseTest p = new PulseTest(4, 128, 20);
+ p.Initialize();
+ p.RunTest();
+ }
+ }
+}
diff --git a/base/Applications/Tests/Ntlm/NtlmUnitTest.csproj b/base/Applications/Tests/Ntlm/NtlmUnitTest.csproj
index 0340e5b..72664eb 100644
--- a/base/Applications/Tests/Ntlm/NtlmUnitTest.csproj
+++ b/base/Applications/Tests/Ntlm/NtlmUnitTest.csproj
@@ -1,26 +1,24 @@

-
+
{3F9845B1-E3A1-40DD-96E5-AFD900858FA4}
Exe
NtlmUnitTest
4
- true
-
+
+
@@ -28,8 +26,8 @@
-
+
-
+
diff --git a/base/Applications/Tests/Ntlm/NtlmUnitTest.sg b/base/Applications/Tests/Ntlm/NtlmUnitTest.sg
index 8fec4a9..6fa2a56 100644
--- a/base/Applications/Tests/Ntlm/NtlmUnitTest.sg
+++ b/base/Applications/Tests/Ntlm/NtlmUnitTest.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: NtlmSupplicant.cs
-//
// Note:
//
// This app is a unit test for the NTLM authentication library. It can
@@ -113,7 +111,8 @@ internal class DefaultCommand
if (failureCount == 0) {
WriteLine("All computed responses match known good values. Test passes.");
return 0;
- } else {
+ }
+ else {
WriteLine("Failures: " + failureCount);
return -1;
}
@@ -281,8 +280,7 @@ class Util
public static string! ByteArrayToString(byte[]! buffer, int index, int length)
{
StringBuilder sb = new StringBuilder(length * 2);
- for (int i = 0; i < length; i++)
- {
+ for (int i = 0; i < length; i++) {
byte b = buffer[index + i];
sb.Append(HexDigits[b >> 4]);
sb.Append(HexDigits[b & 0xf]);
@@ -354,17 +352,18 @@ internal class RemoteAuthTestCommand
internal int AppMain()
{
// Split the username into domain\username, if the user has specified domain name.
- string! username = this.UserName;
+ string! username = (!)this.UserName;
string! domain;
int index = username.IndexOf('\\');
if (index != -1) {
domain = username.Substring(0, index);
username = username.Substring(index + 1);
- } else {
+ }
+ else {
domain = ".";
}
- string! password = this.Password;
+ string! password = (!)this.Password;
// First, connect to BVT test server.
// The sole purpose of the server is to test NTLMSSP messages.
@@ -372,10 +371,10 @@ internal class RemoteAuthTestCommand
try {
// Bartok is failing on Dns.GetLocalHostAddresses
- /*
- IPHostEntry! he = (!)Dns.GetHostByName(this.ServerName);
- IPAddress[]! addresses = (!)he.AddressList;
- */
+ //
+ //IPHostEntry! he = (!)Dns.GetHostByName(this.ServerName);
+ //IPAddress[]! addresses = (!)he.AddressList;
+ //
IPv4 addr = IPv4.Parse(this.ServerName);
IPAddress[]! addresses = { new IPAddress(addr) };
@@ -403,7 +402,8 @@ internal class RemoteAuthTestCommand
socket.Connect(ep);
Console.WriteLine("Connected.");
connected = true;
- } catch(Exception ex) {
+ }
+ catch (Exception ex) {
Console.WriteLine("Connection failed.");
Util.ShowException(ex);
connected = false;
@@ -429,8 +429,8 @@ internal class RemoteAuthTestCommand
byte[]! negotiate = NtlmSupplicant.GetNegotiate(
NtlmNegotiateFlags.None,
- this.ClientMachineDomainName,
- this.Workstation);
+ (!)this.ClientMachineDomainName,
+ (!)this.Workstation);
NtlmUnitTestProtocol.SendMessage(socket, TestMessageType.Negotiate, negotiate);
@@ -459,12 +459,14 @@ internal class RemoteAuthTestCommand
if (result.Succeeded != 0) {
Console.WriteLine(" Succeeded = TRUE");
- } else {
+ }
+ else {
Console.WriteLine(" Succeeded = FALSE");
}
Console.WriteLine(" Message: " + resulttext);
- } catch(Exception ex) {
+ }
+ catch (Exception ex) {
Console.WriteLine("Exception occurred during test.");
Util.ShowException(ex);
}
@@ -473,7 +475,8 @@ internal class RemoteAuthTestCommand
}
return 0;
- } catch(Exception ex) {
+ }
+ catch (Exception ex) {
Console.WriteLine("Exception occurred during test.");
Util.ShowException(ex);
return -1;
@@ -511,15 +514,15 @@ internal class RemoteAuthTestCredMgrCommand
// First, connect to BVT test server.
// The sole purpose of the server is to test NTLMSSP messages.
- string! credentialsName = this.CredentialsName;
+ string! credentialsName = (!)this.CredentialsName;
string! credentialsTag = this.CredentialsTag != null ? this.CredentialsTag : "";
try {
// Bartok is failing on Dns.GetLocalHostAddresses
- /*
- IPHostEntry! he = (!)Dns.GetHostByName(this.ServerName);
- IPAddress[]! addresses = (!)he.AddressList;
- */
+ //
+ //IPHostEntry! he = (!)Dns.GetHostByName(this.ServerName);
+ //IPAddress[]! addresses = (!)he.AddressList;
+ //
IPv4 addr = IPv4.Parse(this.ServerName);
IPAddress[]! addresses = { new IPAddress(addr) };
@@ -547,7 +550,8 @@ internal class RemoteAuthTestCredMgrCommand
socket.Connect(ep);
Console.WriteLine("Connected.");
connected = true;
- } catch(Exception ex) {
+ }
+ catch (Exception ex) {
Console.WriteLine("Connection failed.");
Util.ShowException(ex);
connected = false;
@@ -640,16 +644,19 @@ internal class RemoteAuthTestCredMgrCommand
if (result.Succeeded != 0) {
Console.WriteLine(" Succeeded = TRUE");
- } else {
+ }
+ else {
Console.WriteLine(" Succeeded = FALSE");
}
Console.WriteLine(" Message: " + resulttext);
- } finally {
+ }
+ finally {
delete supplicant;
}
- } catch(Exception ex) {
+ }
+ catch (Exception ex) {
Console.WriteLine("Exception occurred during test.");
Util.ShowException(ex);
}
@@ -658,7 +665,8 @@ internal class RemoteAuthTestCredMgrCommand
}
return 0;
- } catch(Exception ex) {
+ }
+ catch (Exception ex) {
Console.WriteLine("Exception occurred during test.");
Util.ShowException(ex);
return -1;
diff --git a/base/Applications/Tests/Null/Null.cs b/base/Applications/Tests/Null/Null.cs
index 66a5507..fde15cf 100644
--- a/base/Applications/Tests/Null/Null.cs
+++ b/base/Applications/Tests/Null/Null.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Null.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/RamDiskTest/RamDiskTest.cs b/base/Applications/Tests/RamDiskTest/RamDiskTest.cs
new file mode 100644
index 0000000..a7b5b91
--- /dev/null
+++ b/base/Applications/Tests/RamDiskTest/RamDiskTest.cs
@@ -0,0 +1,414 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Perform short test of some RamDisk and RamDiskClientManager operations.
+// Used MemStress.cs as an application template.
+//
+
+using System;
+using System.Collections;
+using System.Threading;
+
+using Microsoft.Singularity.UnitTest;
+using Microsoft.Singularity.V1.Services;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Io;
+
+using Microsoft.Singularity.Services.RamDisk;
+using Microsoft.Singularity.Services.RamDisk.Contracts;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications
+{
+ [ConsoleCategory(DefaultAction=true)]
+ internal class Parameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ return RamDiskTest.AppMain(this);
+ }
+ }
+
+ public class RamDiskTest
+ {
+ internal static int AppMain(Parameters! config)
+ {
+ const int diskBytes = 2000000 /*bytes*/;
+
+ RamDiskControlContract.Imp managerImp = null;
+ DirectoryServiceContract.Imp dsImp = null;
+ DiskDeviceContract.Imp diskImp = null;
+ try {
+ managerImp = ConnectToRamDiskClientManager();
+
+ string! diskPath = CreateTest(managerImp, diskBytes);
+ dsImp = DirectoryService.NewClientEndpoint();
+ diskImp = OpenDevice(dsImp, diskPath);
+
+ int lastSector = (diskBytes - 1 + RamDisk.SECTOR_SIZE - 1)/RamDisk.SECTOR_SIZE;
+ BasicReadWriteTest(diskImp, 0/*sector*/, RamDisk.SECTOR_SIZE);
+ BasicReadWriteTest(diskImp, lastSector, RamDisk.SECTOR_SIZE);
+ BasicReadWriteTest(diskImp, lastSector/2, RamDisk.SECTOR_SIZE);
+ for (int size = RamDisk.SECTOR_SIZE; size < diskBytes; size *= 2) {
+ BasicReadWriteTest(diskImp, 0/*sector*/, size);
+ }
+ BasicReadWriteTest(diskImp, 0/*sector*/, diskBytes);
+
+ BasicReadWriteErrorTest(diskImp, lastSector + 1, RamDisk.SECTOR_SIZE);
+ BasicReadWriteErrorTest(diskImp, lastSector, 2*RamDisk.SECTOR_SIZE);
+ BasicReadWriteErrorTest(diskImp, 0/*sector*/, diskBytes + RamDisk.SECTOR_SIZE);
+ BasicReadWriteErrorTest(diskImp, lastSector/2, (lastSector + 1 - lastSector/2 + 1) * RamDisk.SECTOR_SIZE);
+
+ RandomReadWriteTest(diskImp, diskBytes);
+
+ EnsureDestroyFailsWithInUse(managerImp, diskPath);
+
+ delete diskImp;
+ diskImp = null;
+
+ Destroy(managerImp, diskPath, false/*force*/);
+ EnsureDoesNotExist(dsImp, diskPath);
+
+ OutOfMemoryTest(managerImp);
+ }
+ catch (Exception ex) {
+ Console.WriteLine("Error: " + ex.Message + "\n" + ex.StackTrace);
+ }
+ finally {
+ delete managerImp;
+ delete dsImp;
+ delete diskImp;
+ }
+ return 0;
+ }
+
+ private static void BasicReadWriteTest(DiskDeviceContract.Imp:Ready! diskImp,
+ int sector,
+ int size)
+ {
+ byte[] in ExHeap data = null;
+ try {
+ data = new[ExHeap] byte[size];
+ for (int i = 0; i < data.Length; i++) {
+ data[i] = (byte)i;
+ }
+ data = Write(diskImp, 0, data);
+
+ delete data;
+ data = new[ExHeap] byte[size];
+
+ data = Read(diskImp, 0, data);
+ for (int i = 0; i < data.Length; i++) {
+ if (data[i] != (byte)i) {
+ throw new Exception(String.Format("Data did not match after write-read sequence: at byte {0} got {1}, expected {2}",
+ i, data[i], (byte)i));
+ }
+ }
+ }
+ finally {
+ delete data;
+ }
+ }
+
+ private static void BasicReadWriteErrorTest(DiskDeviceContract.Imp:Ready! imp,
+ int sector,
+ int size)
+ {
+ byte[] in ExHeap data = new[ExHeap] byte[size];
+ imp.SendRead(data, 0, (ulong)size, (ulong)sector);
+ switch receive {
+ case imp.AckRead(outBuffer):
+ delete outBuffer;
+ throw new Exception("RamDisk read operation succeeded where expected to fail");
+ case imp.NakRead():
+ break;
+ case imp.ChannelClosed():
+ throw new Exception("RamDisk closed channel prematurely");
+ }
+
+ data = new[ExHeap] byte[size];
+ imp.SendWrite(data, 0, (ulong)size, (ulong)sector);
+ switch receive {
+ case imp.AckWrite(outBuffer):
+ throw new Exception("RamDisk write operation succeeded where expected to fail");
+ case imp.NakWrite():
+ break;
+ case imp.ChannelClosed():
+ throw new Exception("RamDisk closed channel prematurely");
+ }
+ }
+
+ private static void RandomReadWriteTest(DiskDeviceContract.Imp:Ready! diskImp,
+ int diskBytes)
+ {
+ const int seed = 840799514; // Just an arbitrary value
+ const int sectorsToWrite = 1000;
+ int numSectors = (diskBytes - 1 + RamDisk.SECTOR_SIZE - 1)/RamDisk.SECTOR_SIZE + 1;
+ Random r = new Random(seed);
+ ArrayList! visitedSectors = new ArrayList();
+
+ byte[]! in ExHeap data = new[ExHeap] byte[RamDisk.SECTOR_SIZE];
+ try {
+ byte[]! gcData = new byte[RamDisk.SECTOR_SIZE];
+ for (int i = 0; i < sectorsToWrite; i++) {
+ int sectorNum = r.Next(numSectors);
+ if (visitedSectors.Contains(sectorNum)) {
+ continue;
+ }
+ else {
+ visitedSectors.Add(sectorNum);
+ }
+
+ r.NextBytes(gcData);
+
+ Bitter.FromByteArray(data, 0, RamDisk.SECTOR_SIZE, gcData, 0);
+ data = Write(diskImp, (ulong)sectorNum, data);
+ }
+
+ visitedSectors.Clear();
+
+ r = new Random(seed);
+ for (int i = 0; i < sectorsToWrite; i++) {
+ int sectorNum = r.Next(numSectors);
+ if (visitedSectors.Contains(sectorNum)) {
+ continue;
+ }
+ else {
+ visitedSectors.Add(sectorNum);
+ }
+
+ r.NextBytes(gcData);
+
+ data = Read(diskImp, (ulong)sectorNum, data);
+ for (int byteNum = 0; byteNum < data.Length; byteNum++) {
+ if (data[byteNum] != gcData[byteNum]) {
+ throw new Exception(
+ String.Format("Data did not match after write-read sequence: at sector {0}, byte {1}, got {2}, expected {3}",
+ sectorNum, byteNum, data[byteNum], gcData[byteNum]));
+ }
+ }
+ }
+ }
+ finally {
+ delete data;
+ }
+ }
+
+ private static RamDiskControlContract.Imp! ConnectToRamDiskClientManager()
+ {
+ DirectoryServiceContract.Imp! dsExp =
+ DirectoryService.NewClientEndpoint();
+
+ RamDiskControlContract.Imp! fccImp;
+ RamDiskControlContract.Exp! fccExp;
+ RamDiskControlContract.NewChannel(out fccImp, out fccExp);
+ try {
+ dsExp.SendBind(
+ Bitter.FromString2(
+ RamDiskControlContract.ManagerControlPath
+ ),
+ fccExp);
+
+ switch receive {
+ case dsExp.AckBind():
+ switch receive {
+ case fccImp.Success():
+ return fccImp;
+ case fccImp.ChannelClosed():
+ throw new Exception("RamDisk client manager closed channel prematurely");
+ }
+ // unreached
+ case dsExp.NakBind(exp, errorCode):
+ delete exp;
+ delete fccImp;
+ throw new Exception("RamDisk client manager rejected bind");
+
+ case dsExp.ChannelClosed():
+ delete fccImp;
+ throw new Exception("RamDisk client manager closed channel prematurely");
+ }
+ }
+ finally {
+ delete dsExp;
+ }
+ }
+
+ private static void OutOfMemoryTest(RamDiskControlContract.Imp! controller)
+ {
+ controller.SendCreate(1000000000000L);
+
+ switch receive {
+ case controller.CreateSuccess(diskPath):
+ delete diskPath;
+ throw new Exception("Creation of very large disk succeeded where expected to fail with out of memory");
+ case controller.Fail(error):
+ if (error != RamDiskContractErrorCode.OutOfMemory) {
+ throw new Exception("Creation of very large disk failed with unexpected error code " + error + ", expected to fail with out of memory");
+ }
+ return;
+ case controller.ChannelClosed():
+ throw new Exception("RamDisk client manager closed channel prematurely");
+ }
+ }
+
+ private static string! CreateTest(RamDiskControlContract.Imp! controller,
+ ulong diskSizeBytes)
+ {
+ controller.SendCreate(diskSizeBytes);
+
+ switch receive {
+ case controller.CreateSuccess(diskPath):
+ string result = Bitter.ToString2(diskPath);
+ delete diskPath;
+ return result;
+ case controller.Fail(error):
+ throw new Exception("Create disk failed with error code " + error);
+ case controller.ChannelClosed():
+ throw new Exception("RamDisk client manager closed channel prematurely");
+ }
+ }
+
+ private static DiskDeviceContract.Imp:Ready!
+ OpenDevice(DirectoryServiceContract.Imp:Ready! nsImp,
+ string! deviceName)
+ {
+ DiskDeviceContract.Exp! diskExp;
+ DiskDeviceContract.Imp! diskImp;
+ DiskDeviceContract.NewChannel(out diskImp, out diskExp);
+
+ nsImp.SendBind(Bitter.FromString2(deviceName), diskExp);
+ switch receive {
+ case nsImp.AckBind():
+ switch receive {
+ case diskImp.Success():
+ return diskImp;
+ case diskImp.ContractNotSupported():
+ delete diskImp;
+ throw new Exception("RamDisk does not support disk contract");
+ case diskImp.ChannelClosed():
+ delete diskImp;
+ throw new Exception("RamDisk closed channel prematurely");
+ }
+ // unreached
+ case nsImp.NakBind(badExp, errorCode):
+ delete diskImp;
+ delete badExp;
+ throw new Exception("Failed to bind disk '" + deviceName + "' with error code " + errorCode);
+ case nsImp.ChannelClosed():
+ delete diskImp;
+ throw new Exception("Directory Service closed channel prematurely");
+ }
+ }
+
+ private static void EnsureDoesNotExist(DirectoryServiceContract.Imp:Ready! nsImp,
+ string! fileName)
+ {
+ DiskDeviceContract.Exp! fileExp;
+ DiskDeviceContract.Imp! fileImp;
+ DiskDeviceContract.NewChannel(out fileImp, out fileExp);
+
+ nsImp.SendBind(Bitter.FromString2(fileName), fileExp);
+ switch receive {
+ case nsImp.AckBind():
+ throw new Exception("File expected to be missing exists");
+ case nsImp.NakBind(badExp, errorCode):
+ delete fileImp;
+ delete badExp;
+ if (errorCode != ErrorCode.NotFound) {
+ throw new Exception("Failed to bind file '" + fileName + "' expected to be missing with unexpected error code " + errorCode);
+ }
+ return;
+ case nsImp.ChannelClosed():
+ delete fileImp;
+ throw new Exception("Directory Service closed channel prematurely");
+ }
+ }
+
+ private static byte[]! in ExHeap Read(DiskDeviceContract.Imp:Ready! imp,
+ ulong sectorId,
+ [Claims] byte[]! in ExHeap data)
+
+ {
+ ulong dataLength = (ulong)data.Length;
+ imp.SendRead(data, 0, dataLength, sectorId);
+ switch receive {
+ case imp.AckRead(outBuffer):
+ return outBuffer;
+ case imp.NakRead():
+ throw new Exception("RamDisk rejected read operation");
+ case imp.ChannelClosed():
+ throw new Exception("RamDisk closed channel prematurely");
+ }
+ }
+
+ private static byte[]! in ExHeap Write(DiskDeviceContract.Imp:Ready! imp,
+ ulong sectorId,
+ [Claims] byte[]! in ExHeap data)
+ {
+ imp.SendWrite(data, 0, (ulong)data.Length, sectorId);
+ switch receive {
+ case imp.AckWrite(outBuffer):
+ return outBuffer;
+ case imp.NakWrite():
+ throw new Exception("RamDisk rejected write operation");
+ case imp.ChannelClosed():
+ throw new Exception("RamDisk closed channel prematurely");
+ }
+ }
+
+ private static void EnsureDestroyFailsWithInUse(RamDiskControlContract.Imp! controller,
+ string! diskPath)
+ {
+ char[] in ExHeap diskPathExHeap = Bitter.FromString2(diskPath);
+ controller.SendDestroy(diskPathExHeap, false/*force*/);
+
+ switch receive {
+ case controller.Success():
+ throw new Exception("Destroy disk succeeded where expected to fail with in-use error");
+ case controller.Fail(errorCode):
+ if (errorCode != RamDiskContractErrorCode.IsInUse) {
+ throw new Exception("Destroy disk failed with unexpected error code " + errorCode + ", expected in-use");
+ }
+ return;
+ case controller.ChannelClosed():
+ throw new Exception("RamDisk client manager closed channel prematurely");
+ }
+ }
+
+ private static void Destroy(RamDiskControlContract.Imp! controller,
+ string! diskPath,
+ bool force)
+ {
+ char[] in ExHeap diskPathExHeap = Bitter.FromString2(diskPath);
+ controller.SendDestroy(diskPathExHeap, force);
+
+ switch receive {
+ case controller.Success():
+ return;
+ case controller.Fail(error):
+ throw new Exception("Destroy disk failed with error code " + error);
+ case controller.ChannelClosed():
+ throw new Exception("RamDisk client manager closed channel prematurely");
+ }
+ }
+ }
+}
+
+
diff --git a/base/Applications/Tests/RamDiskTest/RamDiskTest.csproj b/base/Applications/Tests/RamDiskTest/RamDiskTest.csproj
new file mode 100644
index 0000000..3cb3631
--- /dev/null
+++ b/base/Applications/Tests/RamDiskTest/RamDiskTest.csproj
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ RamDiskTest
+ Exe
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/Recursion/Recursion.cs b/base/Applications/Tests/Recursion/Recursion.cs
index a899560..ce8b466 100644
--- a/base/Applications/Tests/Recursion/Recursion.cs
+++ b/base/Applications/Tests/Recursion/Recursion.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Recursion.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/SDSTest/SDSTest.csproj b/base/Applications/Tests/SDSTest/SDSTest.csproj
deleted file mode 100644
index 469edf6..0000000
--- a/base/Applications/Tests/SDSTest/SDSTest.csproj
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
- SDSTest
- Exe
- true
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Tests/SDSTest/SDSTest.sg b/base/Applications/Tests/SDSTest/SDSTest.sg
index f9c0355..ac3061b 100644
--- a/base/Applications/Tests/SDSTest/SDSTest.sg
+++ b/base/Applications/Tests/SDSTest/SDSTest.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: SDSTest.sg
-//
// Note:
//
@@ -73,7 +71,7 @@ namespace Microsoft.Singularity.Applications
public int failCount;
private bool nakLoaded;
private bool dspLoaded;
- private bool doDebug;
+ private bool doDebug;
public DirectoryServiceTests (bool nakLoaded, bool dspLoaded, bool doDebug)
{
@@ -97,8 +95,8 @@ namespace Microsoft.Singularity.Applications
SdsUtils.ErrorCodeToString(actual),
ok ? "true" : "false"
);
- Console.WriteLine(s);
- if (doDebug) DebugStub.WriteLine(s);
+ Console.WriteLine(s);
+ if (doDebug) DebugStub.WriteLine(s);
//DebugStub.Break();
}
else {
@@ -109,8 +107,8 @@ namespace Microsoft.Singularity.Applications
SdsUtils.ErrorCodeToString(expected),
ok ? "true" : "false"
);
- Console.WriteLine(s);
- if (doDebug) DebugStub.WriteLine(s);
+ Console.WriteLine(s);
+ if (doDebug) DebugStub.WriteLine(s);
}
}
@@ -168,7 +166,7 @@ namespace Microsoft.Singularity.Applications
bool ok = SdsUtils.GetLinkValue(path, ds, out linkValue, out errorOut);
CheckError("GetLinkValue", path, expected, errorOut, ok);
if (ok) {
- if (expectedValue != linkValue){
+ if (expectedValue != linkValue) {
Console.WriteLine(" expected({0}) got({1})", expectedValue, linkValue);
}
}
@@ -239,6 +237,8 @@ namespace Microsoft.Singularity.Applications
CheckError("GetAttributes", path, expected, errorOut, ok);
}
+ private readonly string testpeExecutableName = "/init/testpe/testpe" + DirectoryService.ExecutableExtension;
+
public void AttributesTests(DirectoryServiceContract.Imp! ds)
{
DoCreateDirectory(ds, "/d1", ErrorCode.NoError);
@@ -248,8 +248,8 @@ namespace Microsoft.Singularity.Applications
DoGetAttributes(ds, "/d1", ErrorCode.NoError, NodeType.Directory);
DoGetAttributes(ds, "/d1/Link1", ErrorCode.NoError, NodeType.SymLink);
- DoGetAttributes(ds, "/init/testpe/testpe.x86", ErrorCode.NoError, NodeType.IoMemory);
- DoGetAttributes(ds, "/stress", ErrorCode.NoError, NodeType.ServiceProvider);
+ DoGetAttributes(ds, testpeExecutableName, ErrorCode.NoError, NodeType.IoMemory);
+ DoGetAttributes(ds, "/service/stress", ErrorCode.NoError, NodeType.ServiceProvider);
DoGetAttributes(ds, "/d1/Link1/d2", ErrorCode.NoError, NodeType.Directory);
DoGetAttributes(ds, "/d1/garbage", ErrorCode.NotFound, NodeType.BadNode);
@@ -339,7 +339,7 @@ namespace Microsoft.Singularity.Applications
// Attempt to delete non directories
//service provider
- DoDeleteDirectory(ds, "/stress", ErrorCode.NotDirectory);
+ DoDeleteDirectory(ds, "/service/stress", ErrorCode.NotDirectory);
//link
DoDeleteDirectory(ds, "/d2/Link1", ErrorCode.NotDirectory);
//IoMemory
@@ -404,20 +404,21 @@ namespace Microsoft.Singularity.Applications
Dummy.Exp! dS;
FileContract.NewChannel(out fc, out fs);
- DoBind(ds,"/init/testpe/testpe.x86",fs,ErrorCode.NoError);
+ DoBind(ds,testpeExecutableName,fs,ErrorCode.NoError);
delete fc;
Dummy.NewChannel(out dC, out dS);
- DoBind(ds,"/init/testpe/testpe.x86",dS,ErrorCode.ContractNotSupported);
+ DoBind(ds,testpeExecutableName,dS,ErrorCode.ContractNotSupported);
delete dC;
DirectoryServiceContract.NewChannel(out imp , out exp);
- DoBind(ds,"/init/testpe/testpe.x86",exp,ErrorCode.ContractNotSupported);
+ DoBind(ds,testpeExecutableName,exp,ErrorCode.ContractNotSupported);
delete imp;
DoCreateLink(ds, "/link", "/init", ErrorCode.NoError);
FileContract.NewChannel(out fc, out fs);
- DoBind(ds,"/link/testpe/testpe.x86",fs,ErrorCode.NoError);
+ DoBind(ds,"/link/testpe/testpe"+DirectoryService.ExecutableExtension,
+ fs,ErrorCode.NoError);
delete fc;
DoDeleteLink(ds, "/link", ErrorCode.NoError);
@@ -428,7 +429,7 @@ namespace Microsoft.Singularity.Applications
FileContract.NewChannel(out fc, out fs);
//bind to ServiceProvider with File
- DoBind(ds,"/FsCtrl",fs,ErrorCode.ContractNotSupported);
+ DoBind(ds,"/service/fs",fs,ErrorCode.ContractNotSupported);
delete fc;
FileContract.NewChannel(out fc, out fs);
@@ -495,10 +496,10 @@ namespace Microsoft.Singularity.Applications
Process dsp = null;
ErrorCode errorOut;
- if (config.nsRef == null) {
- throw new Exception("Unable to acquire handle to the Directory Service root");
- }
- DirectoryServiceContract.Imp ds = config.nsRef.Acquire();
+ if (config.nsRef == null) {
+ throw new Exception("Unable to acquire handle to the Directory Service root");
+ }
+ DirectoryServiceContract.Imp ds = config.nsRef.Acquire();
ds.RecvSuccess();
@@ -507,7 +508,7 @@ namespace Microsoft.Singularity.Applications
bool ok;
///
- /// FIXFIX SdsUtils FlushCache needs to be re-implemented
+ /// TODO: FIXFIX SdsUtils FlushCache needs to be re-implemented
/// in order for us to be able to wait for NakService termination
///
@@ -515,16 +516,16 @@ namespace Microsoft.Singularity.Applications
DirectoryServiceContract.Exp! dspExp;
DirectoryServiceContract.NewChannel(out dspImp, out dspExp);
- string dspMountPoint = config.mountPoint;
+ string dspMountPoint = (!)config.mountPoint;
ok = SdsUtils.Bind(dspMountPoint, ds, dspExp, out errorOut);
delete dspImp;
bool dspLoaded = false;
if (!ok) {
- Console.WriteLine(" unable to bind to {0}. Reason={1}",
+ Console.WriteLine(" unable to bind to {0}. Reason={1}",
dspMountPoint, SdsUtils.ErrorCodeToString(errorOut));
delete ds;
- return 1;
+ return 1;
}
else dspLoaded = true;
diff --git a/base/Applications/Tests/Scheduler/RMAPI/RMAPI.cs b/base/Applications/Tests/Scheduler/RMAPI/RMAPI.cs
new file mode 100644
index 0000000..d8f87da
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/RMAPI/RMAPI.cs
@@ -0,0 +1,123 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Threading;
+
+using Microsoft.Contracts;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.UnitTest;
+using Microsoft.Singularity.V1.Services;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications
+{
+ [ConsoleCategory(HelpMessage="Utility to test Resource Management APIs. Run selected tests.",
+ DefaultAction=true)]
+ internal class Parameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ [BoolParameter("ProcessWithOutput", Default = false,
+ HelpMessage="Run process creation test with children output to console.")]
+ public bool runProcessWithOutput;
+
+ [BoolParameter("ProcessNoOutputLoop", Default = false,
+ HelpMessage="Run process creation test where children don't output to console. Run in infinit loop")]
+ public bool runProcessWithOutputLoop;
+
+ [BoolParameter("ProcessNoOutput", Default = false,
+ HelpMessage="Run process creation test where children don't output to console.")]
+ public bool runProcessNoOutput;
+
+ reflective internal Parameters();
+
+ internal int AppMain() {
+ TestsToRun testsToRun = TestsToRun.None;
+ if (runProcessWithOutput) {
+ testsToRun |= TestsToRun.ProcessWithOutput;
+ }
+ if (runProcessNoOutput) {
+ testsToRun |= TestsToRun.ProcessNoOutput;
+ }
+ if (runProcessWithOutputLoop) {
+ testsToRun |= TestsToRun.ProcessNoOutputLoop;
+ }
+ return RMAPI.AppMain(testsToRun);
+ }
+ }
+
+ [ConsoleCategory(HelpMessage="Utility to test Resource Management APIs. Run all tests.",
+ Action="all")]
+ internal class AllTestsParameters {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [Endpoint]
+ public readonly TRef nsRef;
+
+ reflective internal AllTestsParameters();
+
+ internal int AppMain() {
+ return RMAPI.AppMain(TestsToRun.All);
+ }
+ }
+
+ [Flags]
+ internal enum TestsToRun
+ {
+ None = 0x0,
+ ProcessWithOutput = 0x1,
+ ProcessNoOutput = 0x2,
+ ProcessNoOutputLoop = 0x4,
+ All = 0xF,
+ }
+
+ internal sealed class RMAPI
+ {
+ internal static int AppMain(TestsToRun testsToRun)
+ {
+ // Run test cases where the child processes don't output to the console
+ if ((testsToRun & TestsToRun.ProcessNoOutput) != 0) {
+ TestProcessCreation.RunWithNoChildOutput();
+ }
+
+ // Run test cases where the child processes output to the console
+ if ((testsToRun & TestsToRun.ProcessWithOutput) != 0) {
+ TestProcessCreation.RunWithChildOutput();
+ }
+
+ // Run test cases where the child processes don't output to the console
+ if ((testsToRun & TestsToRun.ProcessNoOutputLoop) != 0) {
+ for (int i = 0; ; i++) {
+ Console.Write(i);
+ Console.Write('.');
+ TestProcessCreation.RunWithNoChildOutput();
+ Thread.Sleep(1000);
+ }
+ }
+
+ return 0;
+ }
+ }
+}
+
+
diff --git a/base/Applications/Tests/Scheduler/RMAPI/RMAPI.csproj b/base/Applications/Tests/Scheduler/RMAPI/RMAPI.csproj
new file mode 100644
index 0000000..1ec6353
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/RMAPI/RMAPI.csproj
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+ RMAPITest
+ Exe
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/Scheduler/RMAPI/TestProcessCreation.cs b/base/Applications/Tests/Scheduler/RMAPI/TestProcessCreation.cs
new file mode 100644
index 0000000..8301bb4
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/RMAPI/TestProcessCreation.cs
@@ -0,0 +1,366 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Diagnostics;
+using System.Collections;
+using System.Threading;
+using Microsoft.SingSharp;
+using Microsoft.Singularity.UnitTest;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Channels;
+
+namespace Microsoft.Singularity.Applications
+{
+ ///
+ /// Test cases for creating processes in parallel.
+ ///
+ internal sealed class TestProcessCreation
+ {
+ private const int numThreads = 16;
+ private const int iterations = 16;
+ private const string commandLine = "fib";
+ private static int idGenerator;
+ private static ManualResetEvent evtGate;
+
+ ///
+ /// Run test to create processes. The child processes don't output
+ /// to the console. Instead, we swallow their output with a null pipe.
+ ///
+ internal static void RunWithNoChildOutput()
+ {
+ Console.Write(" test parallel process creation with no child output... ");
+
+ evtGate = new ManualResetEvent(false);
+
+ // Start the worker threads
+ Thread[] threads = new Thread[numThreads];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(ProcessCreationMainWithNoOutput));
+ ((!)threads[i]).Start();
+ Thread.Yield();
+ }
+
+ // Give the worker threads a bit time to initialize
+ // then signal the start
+ Thread.Sleep(1000);
+ evtGate.Set();
+
+ // Wait for all worker threads to finish
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+
+ // If we didn't crash, then this test is successful.
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Run test to create processes in parallel. The child
+ /// processes output to the console through PipeMultiplexer.
+ ///
+ internal static void RunWithChildOutput()
+ {
+ Console.Write(" test parallel process creation with child output... ");
+
+ evtGate = new ManualResetEvent(false);
+
+ // Start the worker threads
+ WorkerThread[] threads = new WorkerThread[numThreads];
+ for (int i = 0; i < threads.Length; i++) {
+ PipeMultiplexer! mux = CreatePipeMultiplexer();
+ WorkerThread worker = new WorkerThread(mux);
+ worker.thread = new Thread(worker.ThreadRoutine);
+ threads[i] = worker;
+ }
+
+ // We want to create all of the muxes first, then create
+ // all of the threads, then start them.
+
+ foreach (WorkerThread! worker in threads) {
+ worker.thread.Start();
+ Thread.Yield();
+ }
+
+ // Give the worker threads a bit time to initialize
+ // then signal the start
+ Thread.Sleep(1000);
+ evtGate.Set();
+
+ // Wait for all worker threads to finish
+ foreach (WorkerThread! worker in threads) {
+ worker.thread.Join();
+ }
+
+ foreach (WorkerThread! worker in threads) {
+ PipeMultiplexer! mux = worker.muxRef.Acquire();
+ delete mux;
+ }
+
+ // If we didn't crash, then this test is successful.
+ Console.WriteLine();
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Thread main function that creates processes. The child
+ /// processes don't output to the console. Instead, we swallow
+ /// their output with a null pipe.
+ ///
+ private static void ProcessCreationMainWithNoOutput()
+ {
+ int id = Interlocked.Increment(ref idGenerator) - 1;
+
+ NullPipeControl.Imp:START! control = StartNullPipe();
+ DirectoryServiceContract.Imp! directoryService =
+ DirectoryService.NewClientEndpoint();
+
+ // Wait for the signal
+ evtGate.WaitOne();
+
+ // Create many processes
+ Process[] children = new Process[iterations];
+ try {
+ for (int i = 0; i < iterations; i++) {
+ UnicodePipeContract.Imp! childStdInImp;
+ UnicodePipeContract.Exp! childStdInExp;
+ UnicodePipeContract.NewChannel(out childStdInImp, out childStdInExp);
+
+ UnicodePipeContract.Imp! childStdOutImp = CreateNullPipeClient(control);
+
+ //Manifest manifest;
+ children[i] = Binder.CreateProcess(directoryService,
+ new string[1]{commandLine}, childStdInExp, childStdOutImp);
+ delete childStdInImp;
+ if (children[i] == null) {
+ throw new ProcessCreateException("Failed to create process");
+ }
+
+ ((!)children[i]).Start();
+ if (id == 0) {
+ Console.Write('.');
+ }
+ }
+ }
+ finally {
+ delete directoryService;
+ delete control;
+ }
+
+ // Wait for all children to finish
+ for (int i = 0; i < children.Length; i++) {
+ ((!)children[i]).Join();
+ }
+ }
+
+ private contract NullPipeControl
+ {
+ in message NewInput(UnicodePipeContract.Exp:EXPMOVABLE! client);
+ out message Ack();
+
+ state START: NewInput? -> Ack! -> START;
+ }
+
+ private static UnicodePipeContract.Imp:READY! CreateNullPipeClient(
+ NullPipeControl.Imp:START! control)
+ {
+ UnicodePipeContract.Imp! client;
+ UnicodePipeContract.Exp! exp;
+ UnicodePipeContract.NewChannel(out client, out exp,
+ UnicodePipeContract.EXPMOVABLE.Value);
+ control.SendNewInput(exp);
+ switch receive {
+ case control.Ack():
+ switch receive {
+ case client.Moved():
+ return client;
+
+ case client.ChannelClosed():
+ throw new ProcessCreateException(
+ "Failed to create null pipe: client receve");
+ }
+
+ case control.ChannelClosed():
+ throw new ProcessCreateException(
+ "Failed to create null pipe: control receive");
+ }
+ }
+
+ private static NullPipeControl.Imp:START! StartNullPipe()
+ {
+ NullPipeControl.Imp! controlImp;
+ NullPipeControl.Exp! controlExp;
+ NullPipeControl.NewChannel(out controlImp, out controlExp);
+
+ NullPipeThread pipeThread = new NullPipeThread(controlExp);
+
+ Thread t = new Thread(new ThreadStart(pipeThread.PumpMessage));
+ t.Start();
+ return controlImp;
+ }
+
+ private class NullPipeThread
+ {
+ TRef! controlExp;
+
+ internal NullPipeThread([Claims] NullPipeControl.Exp:START! control)
+ {
+ this.controlExp = new TRef(control);
+ }
+
+ internal void PumpMessage()
+ {
+ NullPipeControl.Exp:START! control = this.controlExp.Acquire();
+ ESet clients =
+ new ESet();
+
+ bool done = false;
+
+ try {
+ while (!done) {
+ switch receive {
+
+ case control.NewInput(client):
+ client.SendMoved();
+ clients.Add(client);
+ control.SendAck();
+ break;
+
+ case control.ChannelClosed():
+ done = true;
+ break;
+
+ case client.Write(buffer, index, count) in clients:
+ client.SendAckWrite(buffer);
+ clients.Add(client);
+ continue;
+
+ case client.ChannelClosed() in clients:
+ delete client;
+ continue;
+ }
+ }
+ }
+ finally {
+ clients.Dispose();
+ delete control;
+ }
+ }
+ }
+
+ private class WorkerThread
+ {
+ public WorkerThread([Claims]PipeMultiplexer! mux)
+ {
+ this.muxRef = new TContainer(mux);
+ }
+
+ public TContainer! muxRef;
+
+ public Thread thread;
+
+ public void ThreadRoutine()
+ {
+ int totalProcessesCreated = 0;
+ int goalCountProcessesCreated = 0x100;
+ int maxActiveProcesses = 0x10;
+
+ ArrayList processes = new ArrayList();
+
+ PipeMultiplexer! mux = muxRef.Acquire();
+
+ DirectoryServiceContract.Imp! rootdir = DirectoryService.NewClientEndpoint();
+
+ try {
+
+ for (;;) {
+ Thread.Yield();
+
+ // scan child processes and remove dead ones
+ int i = 0;
+ while (i < processes.Count) {
+ Process! process = (Process!)processes[i];
+ if (process.Join(TimeSpan.Zero)) {
+ // oooo, it's dead.
+ // Debug.WriteLine(String.Format("yay, process {0} died", process.Id));
+ process.Dispose(true);
+ processes.RemoveAt(i);
+ }
+ else {
+ // process not dead yet
+ i++;
+ }
+ }
+
+
+ bool canCreateProcess = (processes.Count < maxActiveProcesses
+ && totalProcessesCreated < goalCountProcessesCreated);
+
+ if (canCreateProcess) {
+ string[] childArgs = new string[1]{ commandLine };
+ Process process = Binder.CreateProcess(rootdir, childArgs, mux);
+ if (process == null) {
+ Debug.WriteLine("FAILED to create child process.");
+ Debugger.Break();
+ break;
+ }
+ processes.Add(process);
+ process.Start();
+ // Debug.WriteLine(String.Format("created child process (id {0}), this is {1}/{2}", process.Id, totalProcessesCreated, goalCountProcessesCreated));
+ totalProcessesCreated++;
+ }
+
+ if (!canCreateProcess) {
+ // Debug.WriteLine("snore");
+ Thread.Sleep(250);
+ }
+
+ if (processes.Count == 0 && totalProcessesCreated == goalCountProcessesCreated) {
+ Debug.WriteLine("goal has been created. worker thread terminating.");
+ break;
+ }
+ }
+
+ foreach (Process! process in processes) {
+ Debug.WriteLine("Terminating child process: " + process.Id);
+ process.Stop();
+ }
+ foreach (Process! process in processes) {
+ Debug.WriteLine("Waiting for child process: " + process.Id);
+ process.Join();
+ process.Dispose(true);
+ }
+ processes.Clear();
+ }
+ finally {
+ delete rootdir;
+ muxRef.Release(mux);
+ }
+ }
+ }
+
+ // Redirect our standard output into a multiplexer so we can interleave
+ // output from child processes
+ private static PipeMultiplexer! CreatePipeMultiplexer()
+ {
+ // Swap our real stdOut with a newly created one
+ UnicodePipeContract.Exp! newOutputExp;
+ UnicodePipeContract.Imp! newOutputImp;
+ UnicodePipeContract.NewChannel(out newOutputImp, out newOutputExp);
+ UnicodePipeContract.Imp stdOut = ConsoleOutput.Swap(newOutputImp);
+ if (stdOut == null) {
+ throw new Exception("test expects a STDOUT pipe");
+ }
+ // Use a mux to splice our own output together with the child
+ // processes we will run.
+ return PipeMultiplexer.Start(stdOut, newOutputExp);
+ }
+
+ }
+}
diff --git a/base/Applications/Tests/Scheduler/Threading/TestAutoResetEvent.cs b/base/Applications/Tests/Scheduler/Threading/TestAutoResetEvent.cs
new file mode 100644
index 0000000..3d0d18b
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/Threading/TestAutoResetEvent.cs
@@ -0,0 +1,504 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Threading;
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ ///
+ /// Test cases for auto reset event class
+ ///
+ internal sealed class TestAutoResetEvent
+ {
+ internal static TestLog Expect;
+ private const int MaxWaiters = 16;
+ private static AutoResetEvent evt, evt1, evt2, evt3, evt4;
+ private static ManualResetEvent evtGate;
+ private static readonly TimeSpan trivialTestWaitTime = TimeSpan.FromMilliseconds(100);
+ private static int counter;
+ private static int readyCount;
+
+ internal static void Run()
+ {
+ TestTrivialReset();
+ TestTrivialSet();
+ TestThreadSet();
+ TestThreadReset();
+ TestMultipleWaitOne();
+ TestSetAll();
+ TestDeadlock();
+
+ ///TODO: harden kernel code so it doesn't crash on this test, then enable the test
+ //TestDispose();
+ }
+
+ ///
+ /// After the event is reset, test to make sure WaitOne timeout in the same thread
+ ///
+ private static void TestTrivialReset()
+ {
+ Console.Write(" test trivial reset ");
+
+ //
+ // reset by constructor
+ //
+ evt = new AutoResetEvent(false);
+ Console.Write('.');
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // reset by constructor and Reset()
+ //
+ evt = new AutoResetEvent(false);
+ evt.Reset();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // set by constructor and then explicitly Reset()
+ //
+ evt = new AutoResetEvent(true);
+ evt.Reset();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // Set() and Reset() several times
+ //
+ evt = new AutoResetEvent(true);
+ evt.Set();
+ evt.Reset();
+ evt.Set();
+ evt.Reset();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// After the event is set, test to make sure WaitOne succeed in the same thread
+ ///
+ private static void TestTrivialSet()
+ {
+ Console.Write(" test Trivial set ");
+
+ //
+ // set by constructor
+ //
+ evt = new AutoResetEvent(true);
+ Console.Write('.');
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ evt.Close();
+
+ //
+ // set by constructor then explicitly Set()
+ //
+ evt = new AutoResetEvent(true);
+ evt.Set();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ evt.Close();
+
+ //
+ // reset by constructor then explicitly Set()
+ //
+ evt = new AutoResetEvent(false);
+ evt.Set();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ evt.Close();
+
+ //
+ // reset and set several times
+ //
+ evt = new AutoResetEvent(false);
+ evt.Set();
+ evt.Reset();
+ evt.Set();
+ evt.Reset();
+ evt.Set();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ evt.Close();
+
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Set the event, and then WaitOne from different thread. The wait should succeed.
+ ///
+ private static void TestThreadSet()
+ {
+ Console.Write(" test thread set ");
+ evt = new AutoResetEvent(true);
+
+ Thread t = new Thread(new ThreadStart(WaiterMain));
+ t.Start();
+ t.Join();
+
+ Console.Write('.');
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Reset the event and then WaitOne from different thread. The wait should timeout
+ ///
+ private static void TestThreadReset()
+ {
+ Console.Write(" test thread reset ");
+ evt = new AutoResetEvent(false);
+ counter = 0;
+
+ Thread t = new Thread(new ThreadStart(NoSignalWaiterMain));
+ t.Start();
+ Console.Write('.');
+ t.Join();
+
+ // wait should timeout and therefore counter should be 1
+ if (Thread.VolatileRead(ref counter) != 1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+
+ Console.Write('.');
+ evt.Set();
+ evt.WaitOne();
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// multiple threads WaitOne on a reset auto reset event and master thread
+ /// calls SetAll. all waiters should be unblocked by it.
+ ///
+ private static void TestSetAll()
+ {
+ Console.Write(" test set all ");
+ readyCount = 0;
+ counter = 0;
+
+ //
+ // multiple threads WaitOne on a reset auto reset event and master thread
+ // calls SetAll. all waiters should be unblocked by it.
+ //
+ Console.Write('.');
+ evt = new AutoResetEvent(false);
+ Thread[] threads = new Thread[MaxWaiters];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(WaiterMain));
+ ((!)threads[i]).Start();
+ Thread.Yield();
+ }
+
+ // wait for all threads to be ready
+ for (int t = 0; t < 50; t++) {
+ if (Thread.VolatileRead(ref readyCount) == MaxWaiters) {
+ break;
+ }
+ Thread.Sleep(100);
+ }
+ evt.SetAll();
+
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+ if (Thread.VolatileRead(ref counter) != MaxWaiters) {
+ Expect.Fail("unexpected counter");
+ return;
+ }
+ evt.Close();
+
+ //
+ // now multiple threads wait on the same event after SetAll, they should
+ // all timeout except one
+ //
+ Console.Write('.');
+ counter = 0;
+ evt = new AutoResetEvent(false);
+ evt.SetAll();
+ threads = new Thread[MaxWaiters];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(NoSignalWaiterMain));
+ ((!)threads[i]).Start();
+ Thread.Yield();
+ }
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+
+ // all waiter except one should timeout, therefore counter should be
+ // number of waiters minus one
+ if (Thread.VolatileRead(ref counter) != (MaxWaiters - 1)) {
+ Expect.Fail("unexpected counter");
+ return;
+ }
+ evt.Close();
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// test multiple threads WaitOne() on the same event while the master
+ /// thread call Set one at a time.
+ ///
+ private static void TestMultipleWaitOne()
+ {
+ Console.Write(" test multiple wait one ");
+ evt = new AutoResetEvent(true);
+
+ for (int n = 1; n < MaxWaiters; n++) {
+ // reset counter
+ counter = 0;
+ int previousCounter = 0;
+ int numSet = 0;
+ bool timeout = true;
+ evt.Set();
+
+ for (int i = 0; i < n; i++) {
+ new Thread(new ThreadStart(WaiterMain)).Start();
+ }
+
+ // Call Set() one at a time after observing a change in the counter
+ for (int t = 0; t < 50; t++) {
+ int currentCounter = Thread.VolatileRead(ref counter);
+ if (currentCounter == n) {
+ if (numSet != n - 1) {
+ Expect.Fail(string.Format(
+ "unexpected number of Set() with {0} threads", n));
+ return;
+ }
+ timeout = false;
+ Console.Write('.');
+ break;
+ }
+ else if (previousCounter != currentCounter) {
+ previousCounter = currentCounter;
+ evt.Set();
+ numSet++;
+ Thread.Yield();
+ }
+ else {
+ Thread.Sleep(100);
+ }
+ }
+
+ if (timeout) {
+ Expect.Fail(string.Format("timed out with {0} threads", n));
+ return;
+ }
+ }
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Test dead lock situation where two threads each waits the other to set an event
+ ///
+ private static void TestDeadlock()
+ {
+ Console.Write(" test deadlock ...");
+ evtGate = new ManualResetEvent(false);
+ evt3 = new AutoResetEvent(false);
+ evt4 = new AutoResetEvent(false);
+ counter = 0;
+ Thread t1 = new Thread(new ThreadStart(DeadlockMain1));
+ Thread t2 = new Thread(new ThreadStart(DeadlockMain2));
+ t1.Start();
+ t2.Start();
+
+ evt3.WaitOne();
+ evt4.WaitOne();
+ evtGate.Set();
+
+ t1.Join();
+ t2.Join();
+
+ // wait in both thread should timeout, therefore the counter should be 2
+ if (Thread.VolatileRead(ref counter) != 2) {
+ Expect.Fail("expecting deadlock");
+ return;
+ }
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Test the scenario where we dispose an event object then wait on it.
+ ///
+ private static void TestDispose()
+ {
+ Console.Write(" test dispose ");
+ evt = new AutoResetEvent(false);
+ evt.Close();
+ try {
+ evt.WaitOne();
+ }
+ catch (Exception ex) {
+ Console.WriteLine(ex.ToString());
+ return;
+ }
+ Expect.Fail("expecting exception on disposed object");
+ }
+
+ ///
+ /// Thread entry point to test waiting on an event.
+ /// increment the counter only if the wait timeout
+ ///
+ private static void NoSignalWaiterMain()
+ {
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ // increment counter if the wait timeout
+ Interlocked.Increment(ref counter);
+ }
+ }
+
+ ///
+ /// Thread entry point to test waiting on an event.
+ /// increment readyCount before wait begins and increment counter after wait succeeds
+ ///
+ private static void WaiterMain()
+ {
+ Interlocked.Increment(ref readyCount);
+ evt.WaitOne();
+ Interlocked.Increment(ref counter);
+ }
+
+ ///
+ /// Thread entry point to test dead lock
+ /// increment counter if wait timeout
+ ///
+ private static void DeadlockMain1()
+ {
+ evt1 = new AutoResetEvent(false);
+ evt3.Set();
+ evtGate.WaitOne();
+ bool ret = evt2.WaitOne(TimeSpan.FromSeconds(1));
+ if (!ret) {
+ // increment counter if the wait timeout
+ Interlocked.Increment(ref counter);
+ }
+ }
+
+ ///
+ /// Thread entry point to test dead lock
+ /// increment counter if wait timeout
+ ///
+ private static void DeadlockMain2()
+ {
+ evt2 = new AutoResetEvent(false);
+ evt4.Set();
+ evtGate.WaitOne();
+ bool ret = evt1.WaitOne(TimeSpan.FromSeconds(1));
+ if (!ret) {
+ // increment counter if the wait timeout
+ Interlocked.Increment(ref counter);
+ }
+ }
+ }
+}
diff --git a/base/Applications/Tests/Scheduler/Threading/TestManualResetEvent.cs b/base/Applications/Tests/Scheduler/Threading/TestManualResetEvent.cs
new file mode 100644
index 0000000..8792f9a
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/Threading/TestManualResetEvent.cs
@@ -0,0 +1,455 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Threading;
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ ///
+ /// Test cases for manual reset event class
+ ///
+ internal sealed class TestManualResetEvent
+ {
+ internal static TestLog Expect;
+ private const int MaxWaiters = 16;
+ private static ManualResetEvent evt, evt1, evt2, evt3, evt4;
+ private static readonly TimeSpan trivialTestWaitTime = TimeSpan.FromMilliseconds(100);
+ private static int counter;
+ private static int readyCount;
+
+ internal static void Run()
+ {
+ TestTrivialReset();
+ TestTrivialSet();
+ TestThreadSet();
+ TestThreadReset();
+ TestMultipleWaitOneWithInitialSet();
+ TestMultipleWaitOneWithInitialReset();
+ TestDeadlock();
+
+ ///TODO: harden kernel code so it doesn't crash on this test, then enable the test
+ //TestDispose();
+ }
+
+ ///
+ /// After the event is reset, test to make sure WaitOne timeout in the same thread
+ ///
+ private static void TestTrivialReset()
+ {
+ Console.Write(" test trivial reset");
+
+ //
+ // reset by constructor
+ //
+ evt = new ManualResetEvent(false);
+ Console.Write('.');
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // reset by constructor and Reset()
+ //
+ evt = new ManualResetEvent(false);
+ evt.Reset();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // set by constructor and then explicitly Reset()
+ //
+ evt = new ManualResetEvent(true);
+ evt.Reset();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // Set() and Reset() several times
+ //
+ evt = new ManualResetEvent(true);
+ evt.Set();
+ evt.Reset();
+ evt.Set();
+ evt.Reset();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout again");
+ return;
+ }
+ evt.Close();
+
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// After the event is set, test to make sure WaitOne succeed in the same thread
+ ///
+ private static void TestTrivialSet()
+ {
+ Console.Write(" test Trivial set ");
+
+ //
+ // set by constructor
+ //
+ evt = new ManualResetEvent(true);
+ Console.Write('.');
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // set by constructor then explicitly Set()
+ //
+ evt = new ManualResetEvent(true);
+ evt.Set();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // reset by constructor then explicitly Set()
+ //
+ evt = new ManualResetEvent(false);
+ evt.Set();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed again");
+ return;
+ }
+ evt.Close();
+
+ //
+ // reset and set several times
+ //
+ evt = new ManualResetEvent(false);
+ evt.Set();
+ evt.Reset();
+ evt.Set();
+ evt.Reset();
+ evt.Set();
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed");
+ return;
+ }
+ Console.Write('.');
+ ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ Expect.Fail("wait should succeed again");
+ return;
+ }
+ evt.Close();
+
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Set the event, and then WaitOne from different thread. The wait should succeed.
+ ///
+ private static void TestThreadSet()
+ {
+ Console.Write(" test thread set ");
+ evt = new ManualResetEvent(true);
+
+ Thread t = new Thread(new ThreadStart(WaiterMain));
+ t.Start();
+ t.Join();
+
+ Console.Write('.');
+ evt.WaitOne();
+ evt.Reset();
+
+ Console.Write('.');
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (ret) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Reset the event and then WaitOne from different thread. The wait should timeout
+ ///
+ private static void TestThreadReset()
+ {
+ Console.Write(" test thread reset ");
+ evt = new ManualResetEvent(false);
+ counter = 0;
+
+ Thread t = new Thread(new ThreadStart(NoSignalWaiterMain));
+ t.Start();
+ Console.Write('.');
+ t.Join();
+
+ // wait should timeout and therefore the counter should be 1
+ if (Thread.VolatileRead(ref counter) != 1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+
+ Console.Write('.');
+ evt.Set();
+ evt.WaitOne();
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// test multiple threads WaitOne() on the same event which is initially set
+ ///
+ private static void TestMultipleWaitOneWithInitialSet()
+ {
+ Console.Write(" test multiple wait one with initial set ");
+ evt = new ManualResetEvent(true);
+
+ for (int n = 1; n < MaxWaiters; n++) {
+ Console.Write('.');
+ Thread[] threads = new Thread[n];
+ for (int i = 0; i < n; i++) {
+ threads[i] = new Thread(new ThreadStart(WaiterMain));
+ ((!)threads[i]).Start();
+ }
+ for (int i = 0; i < n; i++) {
+ ((!)threads[i]).Join();
+ }
+ }
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// test multiple threads WaitOne() on the same event which is initially reset
+ /// the master thread then
+ ///
+ private static void TestMultipleWaitOneWithInitialReset()
+ {
+ Console.Write(" test multiple wait one with initial reset ");
+ evt = new ManualResetEvent(false);
+
+ for (int n = 1; n < MaxWaiters; n++) {
+ // reset counter
+ counter = 0;
+ readyCount = 0;
+ // reset event
+ evt.Reset();
+
+ Console.Write('.');
+ Thread[] threads = new Thread[n];
+ for (int i = 0; i < n; i++) {
+ threads[i] = new Thread(new ThreadStart(WaiterMain));
+ ((!)threads[i]).Start();
+ Thread.Yield();
+ }
+
+ // wait for all threads to be ready
+ while (true) {
+ if (Thread.VolatileRead(ref readyCount) == n) {
+ break;
+ }
+ Thread.Yield();
+ }
+
+ // make sure no wait leaking
+ Expect.Equal(Thread.VolatileRead(ref counter), 0,
+ "Detected event wait leaking!");
+
+ evt.Set();
+ for (int i = 0; i < n; i++) {
+ ((!)threads[i]).Join();
+ }
+ }
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Test dead lock situation where two threads each waits the other to set an event
+ ///
+ private static void TestDeadlock()
+ {
+ Console.Write(" test deadlock ...");
+ evt = new ManualResetEvent(false);
+ evt3 = new ManualResetEvent(false);
+ evt4 = new ManualResetEvent(false);
+ counter = 0;
+ Thread t1 = new Thread(new ThreadStart(DeadlockMain1));
+ Thread t2 = new Thread(new ThreadStart(DeadlockMain2));
+ t1.Start();
+ t2.Start();
+
+ evt3.WaitOne();
+ evt4.WaitOne();
+ evt.Set();
+
+ t1.Join();
+ t2.Join();
+
+ // wait in both thread should timeout, therefore the counter should be 2
+ if (Thread.VolatileRead(ref counter) != 2) {
+ Expect.Fail("expecting deadlock");
+ return;
+ }
+
+ evt.Close();
+ evt = null;
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Test the scenario where we dispose an event object then wait on it.
+ ///
+ private static void TestDispose()
+ {
+ Console.Write(" test dispose ");
+ evt = new ManualResetEvent(false);
+ evt.Close();
+ try {
+ evt.WaitOne();
+ }
+ catch (Exception ex) {
+ Console.WriteLine(ex.ToString());
+ return;
+ }
+ Expect.Fail("expecting exception on disposed object");
+ }
+
+ ///
+ /// Thread entry point to test waiting on an event.
+ /// increment the counter only if the wait timeout
+ ///
+ private static void NoSignalWaiterMain()
+ {
+ bool ret = evt.WaitOne(trivialTestWaitTime);
+ if (!ret) {
+ // increment counter if the wait timeout
+ Interlocked.Increment(ref counter);
+ }
+ }
+
+ ///
+ /// Thread entry point to test waiting on an event.
+ /// increment readyCount before wait begins and increment counter after wait succeeds
+ ///
+ private static void WaiterMain()
+ {
+ Interlocked.Increment(ref readyCount);
+ evt.WaitOne();
+ Interlocked.Increment(ref counter);
+ }
+
+ ///
+ /// Thread entry point to test dead lock
+ /// increment counter if wait timeout
+ ///
+ private static void DeadlockMain1()
+ {
+ evt1 = new ManualResetEvent(false);
+ evt3.Set();
+ evt.WaitOne();
+ bool ret = evt2.WaitOne(TimeSpan.FromSeconds(1));
+ if (!ret) {
+ // increment counter if the wait timeout
+ Interlocked.Increment(ref counter);
+ }
+ }
+
+ ///
+ /// Thread entry point to test dead lock
+ /// increment counter if wait timeout
+ ///
+ private static void DeadlockMain2()
+ {
+ evt2 = new ManualResetEvent(false);
+ evt4.Set();
+ evt.WaitOne();
+ bool ret = evt1.WaitOne(TimeSpan.FromSeconds(1));
+ if (!ret) {
+ // increment counter if the wait timeout
+ Interlocked.Increment(ref counter);
+ }
+ }
+ }
+}
diff --git a/base/Applications/Tests/Scheduler/Threading/TestMutex.cs b/base/Applications/Tests/Scheduler/Threading/TestMutex.cs
new file mode 100644
index 0000000..910770a
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/Threading/TestMutex.cs
@@ -0,0 +1,300 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Threading;
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ internal sealed class TestMutex
+ {
+ internal static TestLog Expect;
+ private static readonly TimeSpan waitTimeout = TimeSpan.FromMilliseconds(100);
+ private static Mutex mutex;
+ private static ManualResetEvent evtGate;
+ private const int numRoundsInContention = 65536;
+ private static int counter;
+ private static volatile int sum;
+
+ internal static void Run()
+ {
+ ///TODO: harden kernel code so it doesn't crash on this then enable the test
+ //TestIncorrectRelease();
+
+ TestCtor();
+
+ ///TODO: currently mutex supports recursion in kernel but not in applications,
+ /// add support then enable this test case
+ //TestRecursion();
+
+ TestContention();
+
+ // there are other mutex related test cases e.g. Tests\MonitorTest that provide more
+ // test coverage.
+ }
+
+ ///
+ /// Test two threads both running busy loops grabbing and releasing the same mutex
+ ///
+ private static void TestContention()
+ {
+ Console.Write(" test contention ");
+
+ mutex = new Mutex();
+ evtGate = new ManualResetEvent(false);
+ Thread t1 = new Thread(new ThreadStart(ContentionThreadMain));
+ Thread t2 = new Thread(new ThreadStart(ContentionThreadMain));
+ t1.Start();
+ Thread.Yield();
+ t2.Start();
+ Thread.Yield();
+
+ evtGate.Set();
+ t1.Join();
+ t2.Join();
+
+ Cleanup();
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Thread entry point for contention test. Run a tight loop which acquires the mutex,
+ /// does a little work, then releases it
+ ///
+ private static void ContentionThreadMain()
+ {
+ evtGate.WaitOne();
+ for (int i = 0; i < numRoundsInContention; i++) {
+ mutex.AcquireMutex();
+ Thread.Yield();
+ for (int j = 0; j < 1000; j++) {
+ // sum is volatile so this won't be optimized away
+ sum = unchecked(sum + i * j * j / 23);
+ }
+ if (i % 10000 == 0) {
+ Console.Write('.');
+ }
+ Thread.Yield();
+ mutex.ReleaseMutex();
+ Thread.Yield();
+ }
+ }
+
+ ///
+ /// Test the situation where we release the mutex without acquiring it first
+ ///
+ private static void TestIncorrectRelease()
+ {
+ Console.Write(" test incorrect release ");
+ mutex = new Mutex();
+ try {
+ mutex.ReleaseMutex();
+ }
+ catch (InvalidOperationException) {
+ Cleanup();
+ Console.WriteLine("OK");
+ return;
+ }
+ Expect.Fail("expecting exception");
+ }
+
+ ///
+ /// Test the constructor of Mutex
+ ///
+ private static void TestCtor()
+ {
+ Console.Write(" test constructor ");
+
+ //
+ // default ctor: initially owned = false
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex();
+ Thread thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 1) {
+ Expect.Fail("expecting wait to succeed");
+ return;
+ }
+
+ //
+ // explicit ctor: initially owned = false
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex(false);
+ thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 1) {
+ Expect.Fail("expecting wait to succeed");
+ return;
+ }
+
+ //
+ // explicit ctor: initially owned = true
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex(true);
+ thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 0) {
+ Expect.Fail("expecting wait to timeout");
+ return;
+ }
+
+ //
+ // explicit ctor: initially owned = true, then explicitly release
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex(true);
+ mutex.ReleaseMutex();
+ thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 1) {
+ Expect.Fail("expecting wait to succeed");
+ return;
+ }
+
+ //
+ // explicit ctor: initially owned = false, then explicitly acquire
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex(false);
+ mutex.WaitOne();
+ thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 0) {
+ Expect.Fail("expecting wait to timeout");
+ return;
+ }
+
+ Cleanup();
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Mutex supports recursion: the same thread can Acquire the same mutex
+ /// multiple times successfully
+ ///
+ private static void TestRecursion()
+ {
+ Console.Write(" test recursion ");
+
+ //
+ // same number of acquire and release
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex();
+ mutex.AcquireMutex();
+ mutex.AcquireMutex();
+ mutex.AcquireMutex();
+ mutex.ReleaseMutex();
+ mutex.ReleaseMutex();
+ mutex.ReleaseMutex();
+ Thread thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 1) {
+ Expect.Fail("expecting wait to succeed");
+ return;
+ }
+
+ //
+ // same number of acquire and release, with the explicit ctor count as 1
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex(true);
+ mutex.AcquireMutex();
+ mutex.AcquireMutex();
+ mutex.ReleaseMutex();
+ mutex.ReleaseMutex();
+ mutex.ReleaseMutex();
+ thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 1) {
+ Expect.Fail("expecting wait to succeed");
+ return;
+ }
+
+ //
+ // acquire without release, the other thread will wait and timeout
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex();
+ mutex.AcquireMutex();
+ mutex.AcquireMutex();
+ mutex.AcquireMutex();
+ thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 0) {
+ Expect.Fail("expecting wait to timeout");
+ return;
+ }
+
+ //
+ // less release than acquire, the other thread will wait and timeout
+ //
+ Cleanup();
+ Console.Write('.');
+ mutex = new Mutex();
+ mutex.AcquireMutex();
+ mutex.AcquireMutex();
+ mutex.AcquireMutex();
+ mutex.ReleaseMutex();
+ mutex.ReleaseMutex();
+ thread = new Thread(new ThreadStart(TimeoutWaitMain));
+ thread.Start();
+ thread.Join();
+ if (Thread.VolatileRead(ref counter) != 0) {
+ Expect.Fail("expecting wait to timeout");
+ return;
+ }
+
+ Cleanup();
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// The thread entry point for the waiter.
+ /// increment counter only if the wait is successful
+ ///
+ private static void TimeoutWaitMain()
+ {
+ bool ret = mutex.WaitOne(waitTimeout);
+ if (ret) {
+ Interlocked.Increment(ref counter);
+ }
+ }
+
+ ///
+ /// Dispose the mutex, reset the counter
+ ///
+ private static void Cleanup()
+ {
+ if (mutex != null) {
+ mutex.Close();
+ mutex = null;
+ }
+ counter = 0;
+ }
+ }
+}
diff --git a/base/Applications/Tests/Scheduler/Threading/TestSynchronize.cs b/base/Applications/Tests/Scheduler/Threading/TestSynchronize.cs
new file mode 100644
index 0000000..7fcebb3
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/Threading/TestSynchronize.cs
@@ -0,0 +1,126 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Threading;
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ internal sealed class TestSynchronize
+ {
+ private static Mutex! mutex;
+ private static AutoResetEvent! autoResetEvent;
+ private static ManualResetEvent! manualResetEvent;
+ private static AutoResetEvent! syncEvent;
+ private static Mutex! consoleLock;
+
+ private static void SyncThread()
+ {
+ Write("[2] Acquiring mutex...");
+ mutex.WaitOne();
+ Write("[2] Mutex acquired!");
+ mutex.ReleaseMutex();
+ Write("[2] Mutex released.");
+
+ Thread.Yield();
+ Thread.Yield();
+ Thread.Yield();
+ Thread.Yield();
+ Thread.Yield();
+
+ Write("[2] Setting event.");
+ autoResetEvent.Set();
+
+ Thread.Yield();
+ Thread.Yield();
+ Thread.Yield();
+ Thread.Yield();
+ Thread.Yield();
+
+ Write("[2] Waiting for notification...");
+ syncEvent.WaitOne();
+
+ Write("[2] Setting event.");
+ autoResetEvent.Set();
+
+ Write("[2] Waiting for notification...");
+ syncEvent.WaitOne();
+
+ Write("[2] Setting manual event.");
+ manualResetEvent.Set();
+ }
+
+ internal static void Run()
+ {
+ mutex = new Mutex();
+ autoResetEvent = new AutoResetEvent(false);
+ manualResetEvent = new ManualResetEvent(true);
+ syncEvent = new AutoResetEvent(false);
+ consoleLock = new Mutex();
+
+ Thread t1 = new Thread(new ThreadStart(SyncThread));
+ t1.Start();
+
+ Write("[1] Acquiring mutex...");
+ mutex.WaitOne();
+ Write("[1] Mutex acquired!");
+ Write("[1] Releasing mutex...");
+ mutex.ReleaseMutex();
+ Write("[1] Mutex released.");
+
+ Write("[1] Acquiring mutex...");
+ mutex.WaitOne();
+ Write("[1] Mutex acquired!");
+ Write("[1] Yielding (1/3).");
+ Thread.Yield();
+ Write("[1] Yielding (2/3).");
+ Thread.Yield();
+ Write("[1] Yielding (3/3).");
+ Thread.Yield();
+ Write("[1] Releasing mutex...");
+ mutex.ReleaseMutex();
+ Write("[1] Mutex released.");
+
+ Write("[1] Waiting on event.");
+ autoResetEvent.WaitOne();
+ Write("[1] Event set!");
+
+ Write("[1] Setting sync event.");
+ syncEvent.Set();
+
+ Write("[1] Waiting on event.");
+ autoResetEvent.WaitOne();
+ Write("[1] Event set!");
+
+ Write("[1] Waiting on manual event.");
+ manualResetEvent.WaitOne();
+ Write("[1] Event set!");
+
+ Write("[1] Resetting manual event.");
+ manualResetEvent.Reset();
+
+ Write("[1] Setting sync event.");
+ syncEvent.Set();
+
+ Write("[1] Waiting on manual event.");
+ manualResetEvent.WaitOne();
+ Write("[1] Event set!");
+
+ Write("[1] Waiting on manual event.");
+ manualResetEvent.WaitOne();
+ Write("[1] Event set!");
+ }
+
+ private static void Write(string text)
+ {
+ consoleLock.WaitOne();
+ Console.Write(" " + text);
+ consoleLock.ReleaseMutex();
+ }
+ }
+}
diff --git a/base/Applications/Tests/Scheduler/Threading/TestWaitAny.cs b/base/Applications/Tests/Scheduler/Threading/TestWaitAny.cs
new file mode 100644
index 0000000..0b8e77d
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/Threading/TestWaitAny.cs
@@ -0,0 +1,614 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Threading;
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ ///
+ /// Test cases for WaitHandle.WaitAny()
+ ///
+ internal sealed class TestWaitAny
+ {
+ internal static TestLog Expect;
+ private const int numHandles = 7;
+ private const int numHandlesStress = 72;
+ private static readonly TimeSpan waitTimeout = TimeSpan.FromMilliseconds(100);
+ private static WaitHandle[] handles;
+ private static ManualResetEvent evtGate;
+ private static int counter;
+ private static int readyCount;
+
+ internal static void Run()
+ {
+ ///TODO: harden code path and then enable this test case
+ //TestNullArray();
+
+ TestTrivialTimeout();
+ TestTrivialSameHandleArray();
+ TestTrivialEachPosition();
+ TestThreadTimeout();
+ TestThreadEachPosition();
+ TestThreadMultipleWaitAny();
+ TestThreadMixtureSyncObjects();
+ }
+
+ ///
+ /// WaitAny on a mixture of AutoResetEvent, ManualResetEvent, and Mutex
+ ///
+ private static void TestThreadMixtureSyncObjects()
+ {
+ Console.Write(" test thread mixture of sync objects ");
+
+ Cleanup();
+ Console.Write('.');
+ evtGate = new ManualResetEvent(false);
+ handles = new WaitHandle[numHandlesStress];
+ for (int i = 0; i < handles.Length; i++) {
+ switch(i % 3) {
+ case 0:
+ // auto reset events, half set and half reset
+ handles[i] = new AutoResetEvent(i % 6 == 0);
+ break;
+ case 1:
+ // mutexes, half initially owned and half not initially owned
+ handles[i] = new Mutex(i % 6 != 1);
+ break;
+ case 2:
+ // manual reset events, all reset
+ handles[i] = new ManualResetEvent(false);
+ break;
+ }
+ }
+
+ Thread[] threads = new Thread[numHandlesStress];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(TimeoutWaitMain));
+ ((!)threads[i]).Start();
+ Thread.Yield();
+ }
+
+ // wait for all waiter threads to be ready
+ while (true) {
+ if (Thread.VolatileRead(ref readyCount) == numHandlesStress) {
+ break;
+ }
+ Thread.Yield();
+ }
+
+ // let the waiter threads go
+ evtGate.Set();
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+
+ // half of the mutexes, half of the auto reset events, and all manual reset events
+ // should timeout. therefore the counter is
+ // numHandlesStress - (numHandlesStress + 3) / 6 * 2
+ if (Thread.VolatileRead(ref counter) !=
+ numHandlesStress - (numHandlesStress + 3) / 6 * 2) {
+ Expect.Fail(string.Format("unexpected counter {0}", counter));
+ return;
+ }
+ Cleanup();
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Multiple threads call WaitAny() on an array of wait handles of the same type
+ ///
+ private static void TestThreadMultipleWaitAny()
+ {
+ Console.Write(" test thread multiple wait any ");
+
+ //
+ // wait on multiple mutexes
+ //
+ Cleanup();
+ Console.Write('.');
+ evtGate = new ManualResetEvent(false);
+ handles = new WaitHandle[numHandlesStress];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new Mutex();
+ }
+ Thread[] threads = new Thread[numHandlesStress];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(TimeoutWaitMain));
+ ((!)threads[i]).Start();
+ Thread.Yield();
+ }
+ // wait for all waiter threads to be ready
+ while (true) {
+ if (Thread.VolatileRead(ref readyCount) == numHandlesStress) {
+ break;
+ }
+ Thread.Yield();
+ }
+ evtGate.Set();
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+
+ if (Thread.VolatileRead(ref counter) != 0) {
+ Expect.Fail("unexpected counter");
+ return;
+ }
+
+ //
+ // wait on multiple auto reset events
+ //
+ Cleanup();
+ Console.Write('.');
+ evtGate.Reset();
+ handles = new WaitHandle[numHandlesStress];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new AutoResetEvent(false);
+ }
+ threads = new Thread[numHandlesStress];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(TimeoutWaitMain));
+ ((!)threads[i]).Start();
+ Thread.Yield();
+ }
+ // set half of the events
+ for (int i = 0; i < handles.Length; i += 2) {
+ ((AutoResetEvent!)handles[i]).Set();
+ }
+
+ // wait for all waiter threads to be ready
+ while (true) {
+ if (Thread.VolatileRead(ref readyCount) == numHandlesStress) {
+ break;
+ }
+ Thread.Yield();
+ }
+ evtGate.Set();
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+
+ // half of the events are set, the rest should timeout, therefore the counter
+ // should be numHandlesStress - numHandlesStress / 2
+ if (Thread.VolatileRead(ref counter) != numHandlesStress - numHandlesStress / 2) {
+ Expect.Fail("unexpected counter");
+ return;
+ }
+ Cleanup();
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// poke each position of WaitAny handles to make sure we don't have blind spot.
+ ///
+ private static void TestTrivialEachPosition()
+ {
+ Console.Write(" test trivial each position ");
+ int ret;
+
+ //
+ // initialize an array of auto reset events, all set, and call WaitAny
+ // multiple times, it should cycle through the array, after the array is
+ // thoroughly walked, the next WaitAny should timeout
+ //
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new AutoResetEvent(true);
+ }
+ for (int i = 0; i < handles.Length; i++) {
+ Console.Write('.');
+ ret = WaitHandle.WaitAny(handles);
+ if (ret != i) {
+ Expect.Fail(string.Format("expect wait succeed on handles[{0}]", i));
+ return;
+ }
+ }
+ Console.Write('.');
+ ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+ //
+ // now start with an array of auto reset events all reset,
+ // then poke each position at a time, WaitAny should success on that position
+ //
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new AutoResetEvent(false);
+ }
+ for (int i = handles.Length-1; i >= 0; i--) {
+ ((AutoResetEvent!)handles[i]).Set();
+ Console.Write('.');
+ ret = WaitHandle.WaitAny(handles);
+ if (ret != i) {
+ Expect.Fail(string.Format("expect wait succeed on handles[{0}]", i));
+ return;
+ }
+ }
+ Console.Write('.');
+ ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// poke each position of WaitAny handles and call WaitAny on a different thread
+ ///
+ private static void TestThreadEachPosition()
+ {
+ Console.Write(" test thread each position ");
+ Cleanup();
+
+ //
+ // initialize an array of auto reset events, all set, and call WaitAny
+ // on multiple threads, they should cycle through the array, after the array is
+ // thoroughly walked, the next WaitAny should timeout
+ //
+ Console.Write('.');
+ evtGate = new ManualResetEvent(false);
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new AutoResetEvent(true);
+ }
+ Thread[] threads = new Thread[numHandles];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(WaitMain));
+ ((!)threads[i]).Start();
+ }
+ evtGate.Set();
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+
+ // all wait should be successful, therefore counter is 1+2+...+numHandles
+ if (Thread.VolatileRead(ref counter) != numHandles * (numHandles + 1) / 2) {
+ Expect.Fail("unexpected counter");
+ return;
+ }
+ Console.Write('.');
+ int ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+ //
+ // now start with an array of auto reset events all reset,
+ // then poke each position at a time, WaitAny should success on that position
+ //
+ Console.Write('.');
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new AutoResetEvent(false);
+ }
+ threads = new Thread[numHandles];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(WaitMain));
+ ((!)threads[i]).Start();
+ }
+ evtGate.Set();
+
+ for (int i = handles.Length-1; i >= 0; i--) {
+ ((AutoResetEvent!)handles[i]).Set();
+ Thread.Yield();
+ }
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+ // all wait should be successful, therefore counter is 1+2+...+numHandles
+ if (Thread.VolatileRead(ref counter) != numHandles * (numHandles + 1) / 2) {
+ Expect.Fail("unexpected counter");
+ return;
+ }
+
+ Console.Write('.');
+ ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Thread entry point of the waiter thread.
+ /// Counter is incremented by the successful wait position plus one
+ ///
+ private static void WaitMain()
+ {
+ evtGate.WaitOne();
+ int ret = WaitHandle.WaitAny(handles);
+
+ // there is no Interlocked.Add on int :( Do it the hard way
+ int oldValue, newValue;
+ do {
+ oldValue = Thread.VolatileRead(ref counter);
+ newValue = oldValue + (ret + 1);
+ }
+ while (oldValue != Interlocked.CompareExchange(ref counter, newValue, oldValue));
+ }
+
+ ///
+ /// WaitAny on an array of handles where all elements are referening the same instance
+ ///
+ private static void TestTrivialSameHandleArray()
+ {
+ Console.Write(" test trivial same handle array ");
+
+ //
+ // same instance of manual reset event
+ //
+ Console.Write('.');
+ ManualResetEvent mevt = new ManualResetEvent(true);
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = mevt;
+ }
+ int ret = WaitHandle.WaitAny(handles);
+ if (ret != 0) {
+ Expect.Fail("expect wait succeed on handles[0]");
+ return;
+ }
+ ret = WaitHandle.WaitAny(handles);
+ if (ret != 0) {
+ Expect.Fail("expect wait succeed on handles[0] again");
+ return;
+ }
+ Cleanup();
+
+ //
+ // same instance of auto reset event
+ //
+ Console.Write('.');
+ AutoResetEvent aevt = new AutoResetEvent(true);
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = aevt;
+ }
+ ret = WaitHandle.WaitAny(handles);
+ if (ret != 0) {
+ Expect.Fail("expect wait succeed on handles[0]");
+ return;
+ }
+ ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Test WaitAny on an array with is null or contains null elements
+ ///
+ private static void TestNullArray()
+ {
+ Console.Write(" test null array ");
+
+ Console.Write('.');
+ handles = null;
+ bool exception = false;
+ try {
+ WaitHandle.WaitAny(handles);
+ }
+ catch (ArgumentNullException) {
+ exception = true;
+ }
+ if (!exception) {
+ Expect.Fail("expecting exception");
+ return;
+ }
+
+ Console.Write('.');
+ handles = new WaitHandle[3] { null, null, null };
+ exception = false;
+ try {
+ WaitHandle.WaitAny(handles);
+ }
+ catch (ArgumentNullException) {
+ exception = true;
+ }
+ if (!exception) {
+ Expect.Fail("expecting exception");
+ return;
+ }
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Test WaitAny() on an array of unsignaled handles and timeout
+ ///
+ private static void TestThreadTimeout()
+ {
+ Console.Write(" test thread timeout ");
+
+ //
+ // timeout on unsignaled auto reset events
+ //
+ Cleanup();
+ Console.Write('.');
+ evtGate = new ManualResetEvent(false);
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new AutoResetEvent(false);
+ }
+ TestThreadTimeoutWorker();
+
+ //
+ // timeout on unsignaled manual reset events
+ //
+ Cleanup();
+ Console.Write('.');
+ evtGate = new ManualResetEvent(false);
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new ManualResetEvent(false);
+ }
+ TestThreadTimeoutWorker();
+
+ //
+ // timeout on owned mutexes
+ //
+ Cleanup();
+ Console.Write('.');
+ evtGate.Reset();
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new Mutex();
+ ((!)handles[i]).WaitOne();
+ }
+ TestThreadTimeoutWorker();
+
+ //
+ // timeout on owned
+ //
+ Cleanup();
+ Console.Write('.');
+ evtGate.Reset();
+ handles = new WaitHandle[numHandles];
+ for (int i = 0; i < handles.Length; i++) {
+ handles[i] = new Mutex(true);
+ }
+ TestThreadTimeoutWorker();
+
+ Cleanup();
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// create threads WaitAny on an array of unsignaled handles,
+ /// they should all timeout
+ ///
+ private static void TestThreadTimeoutWorker()
+ {
+ Thread[] threads = new Thread[numHandles];
+ for (int i = 0; i < threads.Length; i++) {
+ threads[i] = new Thread(new ThreadStart(TimeoutWaitMain));
+ ((!)threads[i]).Start();
+ }
+ evtGate.Set();
+
+ for (int i = 0; i < threads.Length; i++) {
+ ((!)threads[i]).Join();
+ }
+ // all wait should timeout, therefore counter == numHandles
+ if (Thread.VolatileRead(ref counter) != numHandles) {
+ Expect.Fail("unexpected number of timeouts");
+ }
+ }
+
+ ///
+ /// Thread entry point for waiter.
+ /// Increment readyCount before waiting on the gate, then performs
+ /// WaitAny, and increment the counter if wait timeout
+ ///
+ private static void TimeoutWaitMain()
+ {
+ Interlocked.Increment(ref readyCount);
+ evtGate.WaitOne();
+ int ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret == -1) {
+ // increment counter only if wait timeout
+ Interlocked.Increment(ref counter);
+ }
+ }
+
+ ///
+ /// Test WaitAny on an array of unsignaled handles and the wait should timeout
+ ///
+ private static void TestTrivialTimeout()
+ {
+ Console.Write(" test trivial timeout ");
+
+ //
+ // wait on unsignaled manual reset event
+ //
+ Console.Write('.');
+ handles = new WaitHandle[3] {
+ new ManualResetEvent(false),
+ new ManualResetEvent(false),
+ new ManualResetEvent(false)
+ };
+ int ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+ //
+ // wait on unsignaled auto reset event
+ //
+ Console.Write('.');
+ handles = new WaitHandle[3] {
+ new AutoResetEvent(false),
+ new AutoResetEvent(false),
+ new AutoResetEvent(false)
+ };
+ ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+ //
+ // wait on mixture of unsignaled events
+ //
+ Console.Write('.');
+ handles = new WaitHandle[4] {
+ new AutoResetEvent(false),
+ new ManualResetEvent(false),
+ new AutoResetEvent(false),
+ new ManualResetEvent(false)
+ };
+ ret = WaitHandle.WaitAny(handles, waitTimeout);
+ if (ret != -1) {
+ Expect.Fail("wait should timeout");
+ return;
+ }
+ Cleanup();
+
+ Console.WriteLine("OK");
+ }
+
+ ///
+ /// Release all wait handles, reset counters
+ ///
+ private static void Cleanup()
+ {
+ if (handles != null) {
+ for (int i = 0; i < handles.Length; i++) {
+ if (handles[i] != null) {
+ ((!)handles[i]).Close();
+ }
+ }
+ handles = null;
+ }
+ readyCount = 0;
+ counter = 0;
+ }
+ }
+}
diff --git a/base/Applications/Tests/Scheduler/Threading/Threading.csproj b/base/Applications/Tests/Scheduler/Threading/Threading.csproj
new file mode 100644
index 0000000..0e62284
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/Threading/Threading.csproj
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ Threading
+ Exe
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/Scheduler/Threading/ThreadingTest.cs b/base/Applications/Tests/Scheduler/Threading/ThreadingTest.cs
new file mode 100644
index 0000000..1f2990a
--- /dev/null
+++ b/base/Applications/Tests/Scheduler/Threading/ThreadingTest.cs
@@ -0,0 +1,56 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+
+using System;
+using System.Threading;
+using Microsoft.Singularity.UnitTest;
+
+namespace Microsoft.Singularity.Applications
+{
+ ///
+ /// Test synchronization objects.
+ ///
+ [TestClass]
+ public class ThreadingTest : TestClass
+ {
+ [TestMethod]
+ public void ManualResetEventTest()
+ {
+ TestManualResetEvent.Expect = Expect;
+ TestManualResetEvent.Run();
+ }
+
+ [TestMethod]
+ public void AutoResetEventTest()
+ {
+ TestAutoResetEvent.Expect = Expect;
+ TestAutoResetEvent.Run();
+ }
+
+ [TestMethod]
+ public void MutexTest()
+ {
+ TestMutex.Expect = Expect;
+ TestMutex.Run();
+ }
+
+ [TestMethod]
+ public void WaitAnyTest()
+ {
+ TestWaitAny.Expect = Expect;
+ TestWaitAny.Run();
+ }
+
+ [TestMethod]
+ public void SyncTest()
+ {
+ Console.WriteLine(" synchronization between 2 threads...");
+ TestSynchronize.Run();
+ Console.WriteLine(" ...OK");
+ }
+ }
+}
diff --git a/base/Applications/Tests/SdsTiming/SdsTiming.sg b/base/Applications/Tests/SdsTiming/SdsTiming.sg
index a4784af..bf008eb 100644
--- a/base/Applications/Tests/SdsTiming/SdsTiming.sg
+++ b/base/Applications/Tests/SdsTiming/SdsTiming.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: SDSTest.sg
-//
// Note:
//
@@ -130,7 +128,7 @@ namespace Microsoft.Singularity.Applications
bool ok = SdsUtils.GetLinkValue(path, ds, out linkValue, out errorOut);
CheckError("GetLinkValue", path, expected, errorOut, ok);
if (ok) {
- if (expectedValue != linkValue){
+ if (expectedValue != linkValue) {
Console.WriteLine(" expected({0}) got({1})", expectedValue, linkValue);
}
}
@@ -193,10 +191,12 @@ namespace Microsoft.Singularity.Applications
NodeType expectedNodeType)
{
ErrorCode errorOut;
- long length;
NodeType nodeType;
+ FileAttributesRecord attributes;
+
+ bool ok = SdsUtils.GetAttributes(path, ds, out attributes, out errorOut);
+ nodeType = attributes.Type;
- bool ok = SdsUtils.GetAttributes(path, ds, out length, out nodeType, out errorOut);
CheckError("GetAttributes", path, expectedNodeType, nodeType, ok);
CheckError("GetAttributes", path, expected, errorOut, ok);
}
@@ -229,7 +229,7 @@ namespace Microsoft.Singularity.Applications
DebugStub.WriteLine("\nstart get DirectoryService endpoint");
start = ProcessService.GetUpTime();
- for ( int i = 0; i < ITERATIONS; i++) {
+ for (int i = 0; i < ITERATIONS; i++) {
DirectoryServiceContract.Imp! d = DirectoryService.NewClientEndpoint();
delete d;
}
@@ -240,23 +240,23 @@ namespace Microsoft.Singularity.Applications
///
- DebugStub.WriteLine("\nstart bind to /init/testpe/testpe.x86");
+ DebugStub.WriteLine("\nstart bind to /init/testpe/testpe");
start = ProcessService.GetUpTime();
- for ( int i = 0; i < ITERATIONS; i++) {
+ for (int i = 0; i < ITERATIONS; i++) {
FileContract.NewChannel(out fc, out fs);
- DoBind(ds,"/init/testpe/testpe.x86",fs,ErrorCode.NoError);
+ DoBind(ds,"/init/testpe/testpe",fs,ErrorCode.NoError);
delete fc;
}
end = ProcessService.GetUpTime();
elapsed = end - start;
- Console.WriteLine("\nBind /init/testpe/testpe.x86 count={0} time={1}",
+ Console.WriteLine("\nBind /init/testpe/testpe count={0} time={1}",
ITERATIONS, elapsed);
///
if (dspLoaded) {
DebugStub.WriteLine("\nstart bind to /dsp");
start = ProcessService.GetUpTime();
- for ( int i = 0; i < ITERATIONS; i++) {
+ for (int i = 0; i < ITERATIONS; i++) {
DirectoryServiceContract.NewChannel(out dspImp, out dspExp);
DoBind(ds,"/dsp",dspExp,ErrorCode.NoError);
delete dspImp;
@@ -274,7 +274,7 @@ namespace Microsoft.Singularity.Applications
if (haveDir && haveDsp) {
DebugStub.WriteLine("\nstart bind to /dsp/bindtime");
start = ProcessService.GetUpTime();
- for ( int i = 0; i < ITERATIONS; i++) {
+ for (int i = 0; i < ITERATIONS; i++) {
DirectoryServiceContract.NewChannel(out dspDirImp, out dspDirExp);
DoBind(ds,"/dsp/bindtime",dspDirExp,ErrorCode.NoError);
delete dspDirImp;
@@ -289,7 +289,7 @@ namespace Microsoft.Singularity.Applications
DebugStub.WriteLine("\nstart bind to /dsp/bindtime via mountpoint");
dspImp.RecvSuccess();
start = ProcessService.GetUpTime();
- for ( int i = 0; i < ITERATIONS; i++) {
+ for (int i = 0; i < ITERATIONS; i++) {
DirectoryServiceContract.NewChannel(out dspDirImp, out dspDirExp);
DoBind(dspImp,"/bindtime",dspDirExp,ErrorCode.NoError);
delete dspDirImp;
@@ -303,21 +303,21 @@ namespace Microsoft.Singularity.Applications
delete dspImp;
}
- DebugStub.WriteLine("start bind to /init/testpe/testpe.x86 with NoAllocateAttribute ds");
+ DebugStub.WriteLine("start bind to /init/testpe/testpe with NoAllocateAttribute ds");
TimeSpan s2 = ProcessService.GetUpTime();
- for ( int i = 0; i < ITERATIONS; i++) {
+ for (int i = 0; i < ITERATIONS; i++) {
FileContract.NewChannel(out fc, out fs);
- DoBind("/init/testpe/testpe.x86",fs,ErrorCode.NoError);
+ DoBind("/init/testpe/testpe",fs,ErrorCode.NoError);
delete fc;
}
TimeSpan e2 = ProcessService.GetUpTime();
TimeSpan elapsed2 = e2 -s2;
- Console.WriteLine("Bind testpe.x86 count={0} time={1}",
+ Console.WriteLine("Bind testpe count={0} time={1}",
ITERATIONS, elapsed2);
DebugStub.WriteLine("start directory to /init/testpe");
TimeSpan s3 = ProcessService.GetUpTime();
- for ( int i = 0; i < ITERATIONS; i++) {
+ for (int i = 0; i < ITERATIONS; i++) {
DirectoryServiceContract.NewChannel(out imp, out exp);
DoBind("/init/testpe",exp,ErrorCode.NoError);
delete imp;
@@ -357,7 +357,7 @@ namespace Microsoft.Singularity.Applications
Process dsp = null;
ErrorCode errorOut;
- string dspName = "TestDSP.x86";
+ string dspName = "TestDSP";
string dspMountPoint = "/dsp";
DirectoryServiceContract.Imp! ds = DirectoryService.NewClientEndpoint();
diff --git a/base/Applications/Tests/Select/Select.csproj b/base/Applications/Tests/Select/Select.csproj
index 2352fe8..d4fb2d0 100644
--- a/base/Applications/Tests/Select/Select.csproj
+++ b/base/Applications/Tests/Select/Select.csproj
@@ -5,8 +5,6 @@ Microsoft Research Singularity
Copyright (c) Microsoft Corporation. All rights reserved.
-File: Applications\Tests\Select\Select.csproj
-
Note: Tests "select receive".
##############################################################################
diff --git a/base/Applications/Tests/Select/Select.sg b/base/Applications/Tests/Select/Select.sg
index a0a7fdf..7710d01 100644
--- a/base/Applications/Tests/Select/Select.sg
+++ b/base/Applications/Tests/Select/Select.sg
@@ -4,10 +4,9 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Select.cs
-//
// Note: Simple Singularity test program.
//
+
using System;
using System.Threading;
using Microsoft.Singularity.Channels;
@@ -19,7 +18,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -258,203 +258,203 @@ namespace Microsoft.Singularity.Applications {
}
}
- /*
- //[ShellCommand("select", "Run select test")]
- public static int DoSelect()
- {
- SelectTest.Exp[] expEndpoints = new SelectTest.Exp [3];
- impEndpoints = new TRef [3];
-
- for (int i = 0; i < 3; i++) {
- SelectTest.Imp! imp;
- SelectTest.Exp! exp;
- SelectTest.NewChannel(out imp, out exp);
- expEndpoints[i] = exp;
- impEndpoints[i] = new TRef(imp);
- }
-
- Thread t1 = new Thread(new ThreadStart(SelectThread));
- t1.Start();
-
- int[][] patterns = new int[3][];
- patterns[0] = new int [] { 0, 0, SelectTest.Tags.A };
- patterns[1] = new int [] { SelectTest.Tags.B, SelectTest.Tags.C, 0 };
- patterns[2] = new int [] { SelectTest.Tags.A, SelectTest.Tags.C, 0 };
-
- ISelectable[] selects = new ISelectable[3];
- for (int i = 0; i<3; i++) {
- selects[i] = expEndpoints[i];
- }
-
- object setMatch;
- int i1 = Endpoint.Select(patterns, selects, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i1);
-
- expEndpoints[2].RecvA();
- expEndpoints[2].SendAck();
-
- int i2 = Endpoint.Select(patterns, selects, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i2);
-
- expEndpoints[2].RecvA();
- expEndpoints[2].SendAck();
-
- int i3 = Endpoint.Select(patterns, selects, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i3);
-
- expEndpoints[2].RecvA();
- expEndpoints[2].SendAck();
-
- int i4 = Endpoint.Select(patterns, selects, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 1.)", i4);
-
- expEndpoints[0].RecvB();
- expEndpoints[1].RecvC();
- expEndpoints[0].SendAck();
- expEndpoints[1].SendAck();
-
- int i5 = Endpoint.Select(patterns, selects, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 2.)", i5);
-
- expEndpoints[0].RecvA();
- expEndpoints[1].RecvC();
- expEndpoints[0].SendAck();
- expEndpoints[1].SendAck();
-
- int i6 = Endpoint.Select(patterns, selects, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 2.)", i6);
-
- expEndpoints[0].RecvA();
- expEndpoints[1].RecvC();
- expEndpoints[0].SendAck();
- expEndpoints[1].SendAck();
-
- int i7 = Endpoint.Select(patterns, selects, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected -1.)", i7);
-
- Console.WriteLine("[1] Done.");
- return 0;
- }
-
-
- //[ShellCommand("selectset", "Run select set test")]
- public static int DoSelectSet()
- {
- SelectTest.Exp[] expEndpoints = new SelectTest.Exp [3];
- impEndpoints = new TRef [3];
-
- for (int i = 0; i < 3; i++) {
- SelectTest.Imp! imp;
- SelectTest.Exp! exp;
- SelectTest.NewChannel(out imp, out exp);
- expEndpoints[i] = exp;
- impEndpoints[i] = new TRef(imp);
- }
-
- Thread t1 = new Thread(new ThreadStart(SelectThread));
- t1.Start();
-
- int[][] patterns = new int[3][];
- patterns[0] = new int [] { SelectTest.Tags.A };
- patterns[1] = new int [] { SelectTest.Tags.B };
- patterns[2] = new int [] { SelectTest.Tags.C };
-
- ESet eset = new ESet();
- eset.Add(expEndpoints[0]);
- eset.Add(expEndpoints[1]);
- eset.Add(expEndpoints[2]);
-
- ISelectable[] selectEPs = new ISelectable[1]{eset};
-
- object setMatch;
- int i1 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i1);
-
- SetRecvA(setMatch, eset);
-
- int i2 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i2);
-
- SetRecvA(setMatch, eset);
-
- int i3 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i3);
-
- SetRecvA(setMatch, eset);
-
- int i4 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 1.)", i4);
-
- SetRecvB(setMatch, eset);
-
- int i5 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 2.)", i5);
-
- SetRecvC(setMatch, eset);
-
- int i6 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i6);
-
- SetRecvA(setMatch, eset);
-
- int i7 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 2.)", i7);
-
- SetRecvC(setMatch, eset);
-
- int i8 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i8);
-
- SetRecvA(setMatch, eset);
-
- int i9 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 2.)", i9);
-
- SetRecvC(setMatch, eset);
-
- int i10 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 0.)", i10);
-
- SetRecvA(setMatch, eset);
-
- int i11 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 1.)", i11);
-
- SetRecvB(setMatch, eset);
-
- int i12 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected 2.)", i12);
-
- SetRecvC(setMatch, eset);
-
- int i13 = Endpoint.Select(patterns, selectEPs, out setMatch);
- Console.WriteLine("[1] Got {0}! (Expected -1.)", i13);
-
- Console.WriteLine("[1] Done.");
- return 0;
- }
-
- private static void SetRecvA(object match, ESet eset) {
- SelectTest.Exp exp = eset.Extract(match);
- exp.RecvA();
- exp.SendAck();
- eset.Add(exp);
- }
-
- private static void SetRecvB(object match, ESet eset) {
- SelectTest.Exp exp = eset.Extract(match);
- exp.RecvB();
- exp.SendAck();
- eset.Add(exp);
- }
-
- private static void SetRecvC(object match, ESet eset) {
- SelectTest.Exp exp = eset.Extract(match);
- exp.RecvC();
- exp.SendAck();
- eset.Add(exp);
- }
- */
+ //
+ ////[ShellCommand("select", "Run select test")]
+ //public static int DoSelect()
+ //{
+ // SelectTest.Exp[] expEndpoints = new SelectTest.Exp [3];
+ // impEndpoints = new TRef [3];
+//
+ // for (int i = 0; i < 3; i++) {
+ // SelectTest.Imp! imp;
+ // SelectTest.Exp! exp;
+ // SelectTest.NewChannel(out imp, out exp);
+ // expEndpoints[i] = exp;
+ // impEndpoints[i] = new TRef(imp);
+ // }
+//
+ // Thread t1 = new Thread(new ThreadStart(SelectThread));
+ // t1.Start();
+//
+ // int[][] patterns = new int[3][];
+ // patterns[0] = new int [] { 0, 0, SelectTest.Tags.A };
+ // patterns[1] = new int [] { SelectTest.Tags.B, SelectTest.Tags.C, 0 };
+ // patterns[2] = new int [] { SelectTest.Tags.A, SelectTest.Tags.C, 0 };
+//
+ // ISelectable[] selects = new ISelectable[3];
+ // for (int i = 0; i < 3; i++) {
+ // selects[i] = expEndpoints[i];
+ // }
+//
+ // object setMatch;
+ // int i1 = Endpoint.Select(patterns, selects, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i1);
+//
+ // expEndpoints[2].RecvA();
+ // expEndpoints[2].SendAck();
+//
+ // int i2 = Endpoint.Select(patterns, selects, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i2);
+//
+ // expEndpoints[2].RecvA();
+ // expEndpoints[2].SendAck();
+//
+ // int i3 = Endpoint.Select(patterns, selects, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i3);
+//
+ // expEndpoints[2].RecvA();
+ // expEndpoints[2].SendAck();
+//
+ // int i4 = Endpoint.Select(patterns, selects, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 1.)", i4);
+//
+ // expEndpoints[0].RecvB();
+ // expEndpoints[1].RecvC();
+ // expEndpoints[0].SendAck();
+ // expEndpoints[1].SendAck();
+//
+ // int i5 = Endpoint.Select(patterns, selects, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 2.)", i5);
+//
+ // expEndpoints[0].RecvA();
+ // expEndpoints[1].RecvC();
+ // expEndpoints[0].SendAck();
+ // expEndpoints[1].SendAck();
+//
+ // int i6 = Endpoint.Select(patterns, selects, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 2.)", i6);
+//
+ // expEndpoints[0].RecvA();
+ // expEndpoints[1].RecvC();
+ // expEndpoints[0].SendAck();
+ // expEndpoints[1].SendAck();
+//
+ // int i7 = Endpoint.Select(patterns, selects, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected -1.)", i7);
+//
+ // Console.WriteLine("[1] Done.");
+ // return 0;
+ //}
+//
+//
+ ////[ShellCommand("selectset", "Run select set test")]
+ //public static int DoSelectSet()
+ //{
+ // SelectTest.Exp[] expEndpoints = new SelectTest.Exp [3];
+ // impEndpoints = new TRef [3];
+//
+ // for (int i = 0; i < 3; i++) {
+ // SelectTest.Imp! imp;
+ // SelectTest.Exp! exp;
+ // SelectTest.NewChannel(out imp, out exp);
+ // expEndpoints[i] = exp;
+ // impEndpoints[i] = new TRef(imp);
+ // }
+//
+ // Thread t1 = new Thread(new ThreadStart(SelectThread));
+ // t1.Start();
+//
+ // int[][] patterns = new int[3][];
+ // patterns[0] = new int [] { SelectTest.Tags.A };
+ // patterns[1] = new int [] { SelectTest.Tags.B };
+ // patterns[2] = new int [] { SelectTest.Tags.C };
+//
+ // ESet eset = new ESet();
+ // eset.Add(expEndpoints[0]);
+ // eset.Add(expEndpoints[1]);
+ // eset.Add(expEndpoints[2]);
+//
+ // ISelectable[] selectEPs = new ISelectable[1]{eset};
+//
+ // object setMatch;
+ // int i1 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i1);
+//
+ // SetRecvA(setMatch, eset);
+//
+ // int i2 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i2);
+//
+ // SetRecvA(setMatch, eset);
+//
+ // int i3 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i3);
+//
+ // SetRecvA(setMatch, eset);
+//
+ // int i4 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 1.)", i4);
+//
+ // SetRecvB(setMatch, eset);
+//
+ // int i5 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 2.)", i5);
+//
+ // SetRecvC(setMatch, eset);
+//
+ // int i6 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i6);
+//
+ // SetRecvA(setMatch, eset);
+//
+ // int i7 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 2.)", i7);
+//
+ // SetRecvC(setMatch, eset);
+//
+ // int i8 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i8);
+//
+ // SetRecvA(setMatch, eset);
+//
+ // int i9 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 2.)", i9);
+//
+ // SetRecvC(setMatch, eset);
+//
+ // int i10 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 0.)", i10);
+//
+ // SetRecvA(setMatch, eset);
+//
+ // int i11 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 1.)", i11);
+//
+ // SetRecvB(setMatch, eset);
+//
+ // int i12 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected 2.)", i12);
+//
+ // SetRecvC(setMatch, eset);
+//
+ // int i13 = Endpoint.Select(patterns, selectEPs, out setMatch);
+ // Console.WriteLine("[1] Got {0}! (Expected -1.)", i13);
+//
+ // Console.WriteLine("[1] Done.");
+ // return 0;
+ //}
+//
+ //private static void SetRecvA(object match, ESet eset) {
+ // SelectTest.Exp exp = eset.Extract(match);
+ // exp.RecvA();
+ // exp.SendAck();
+ // eset.Add(exp);
+ //}
+//
+ //private static void SetRecvB(object match, ESet eset) {
+ // SelectTest.Exp exp = eset.Extract(match);
+ // exp.RecvB();
+ // exp.SendAck();
+ // eset.Add(exp);
+ //}
+//
+ //private static void SetRecvC(object match, ESet eset) {
+ // SelectTest.Exp exp = eset.Extract(match);
+ // exp.RecvC();
+ // exp.SendAck();
+ // eset.Add(exp);
+ //}
+ //
internal static int AppMain(Parameters! config)
{
diff --git a/base/Applications/Tests/SharedHeapTest/SharedHeapTest.cs b/base/Applications/Tests/SharedHeapTest/SharedHeapTest.cs
index b58b396..e81e26c 100644
--- a/base/Applications/Tests/SharedHeapTest/SharedHeapTest.cs
+++ b/base/Applications/Tests/SharedHeapTest/SharedHeapTest.cs
@@ -4,10 +4,9 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: SharedHeapTest.cs
-//
// Note: User-mode test program for calling shared heap through the ABI.
//
+
using Microsoft.Singularity.V1.Services;
using System;
using System.Runtime.CompilerServices;
@@ -21,7 +20,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -87,7 +87,8 @@ namespace Microsoft.Singularity.Applications {
AllocRandomSizedThingy(loop);
if (CheckForValue(loop, 0) == true) {
Console.WriteLine("Passed zero-fill test.\n");
- } else {
+ }
+ else {
Console.WriteLine("Failed zero-fill test.\n");
}
FillWithValue(loop, (byte)(1 << (int)loop));
@@ -137,7 +138,7 @@ namespace Microsoft.Singularity.Applications {
//
// Play around.
//
- switch(action) {
+ switch (action) {
case 0:
//
// Allocate something new.
@@ -146,7 +147,8 @@ namespace Microsoft.Singularity.Applications {
AllocRandomSizedThingy(which);
if (CheckForValue(which, 0) == true) {
Console.WriteLine("Passed zero-fill test.\n");
- } else {
+ }
+ else {
Console.WriteLine("Failed zero-fill test.\n");
}
diff --git a/base/Applications/Tests/SmpTest/ForkTest.sg b/base/Applications/Tests/SmpTest/ForkTest.sg
index 773bc11..606cebf 100644
--- a/base/Applications/Tests/SmpTest/ForkTest.sg
+++ b/base/Applications/Tests/SmpTest/ForkTest.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: HeapTest.cs
-//
// Note: Allocate strings and encourage GCs
//
@@ -19,7 +17,7 @@ namespace Microsoft.Singularity.Applications
{
public class ForkTest
{
- static readonly string []! ProcessArgs = new string[] { "testpe.x86" };
+ static readonly string []! ProcessArgs = new string[] { "testpe" };
static readonly TimeSpan ProcessTimeout = TimeSpan.FromSeconds(10);
const int IterationsPerThread = 64;
diff --git a/base/Applications/Tests/SmpTest/HeapTest.sg b/base/Applications/Tests/SmpTest/HeapTest.sg
index 0bf3177..ac001c4 100644
--- a/base/Applications/Tests/SmpTest/HeapTest.sg
+++ b/base/Applications/Tests/SmpTest/HeapTest.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: HeapTest.sg
-//
// Note:
//
diff --git a/base/Applications/Tests/SmpTest/Settings.sg b/base/Applications/Tests/SmpTest/Settings.sg
index 183ec15..3f25812 100644
--- a/base/Applications/Tests/SmpTest/Settings.sg
+++ b/base/Applications/Tests/SmpTest/Settings.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Settings.sg
-//
// Note:
//
diff --git a/base/Applications/Tests/SmpTest/SmpTest.csproj b/base/Applications/Tests/SmpTest/SmpTest.csproj
index e505a9a..2a5e53e 100644
--- a/base/Applications/Tests/SmpTest/SmpTest.csproj
+++ b/base/Applications/Tests/SmpTest/SmpTest.csproj
@@ -24,6 +24,7 @@
+
diff --git a/base/Applications/Tests/SmpTest/SmpTest.sg b/base/Applications/Tests/SmpTest/SmpTest.sg
index fd35956..fba62e9 100644
--- a/base/Applications/Tests/SmpTest/SmpTest.sg
+++ b/base/Applications/Tests/SmpTest/SmpTest.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: SmpTest.cs
-//
// Note: Some basic tests of system code on SMP.
//
diff --git a/base/Applications/Tests/SpecTest/SpecTest.csproj b/base/Applications/Tests/SpecTest/SpecTest.csproj
new file mode 100644
index 0000000..231efc6
--- /dev/null
+++ b/base/Applications/Tests/SpecTest/SpecTest.csproj
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ SpecTest
+ Exe
+ "Spec#\ Program\ Verifier\ finished\ with\ [0-9]*\ verified,\ 0\ errors"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/SpecTest/SpecTest.sg b/base/Applications/Tests/SpecTest/SpecTest.sg
new file mode 100644
index 0000000..ac6d097
--- /dev/null
+++ b/base/Applications/Tests/SpecTest/SpecTest.sg
@@ -0,0 +1,144 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Microsoft Research Singularity
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Note: Test of various Spec# and Boogie features.
+//
+using System;
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Io;
+using Microsoft.SingSharp;
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Contracts;
+using Microsoft.Singularity.Applications;
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+
+namespace Microsoft.Singularity.Applications
+{
+ [ConsoleCategory(HelpMessage="SpecTest [options] Test of Spec# and Boogie",
+ DefaultAction=true)]
+ [Verify(false)]
+ internal sealed class Parameters
+ {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ reflective internal Parameters();
+
+ internal int AppMain()
+ {
+ return new SpecTest().Run();
+ }
+ }
+
+ [Verify(false)]
+ internal contract Con1
+ {
+ out message M1();
+ in message M2();
+ state S1 : one
+ {
+ M1! -> M2? -> S1;
+ }
+ }
+
+ public class SpecTest
+ {
+ public int Run()
+ {
+ Console.WriteLine();
+ PrintHello();
+ int[]! arr = new int[] {3, 4, 5};
+ bool b1 = bsearch(4, arr);
+ assert arr[1] == 4;
+ assert b1;
+ bool b2 = bsearch(6, arr);
+ assert !b2;
+ Console.WriteLine(b1);
+ Console.WriteLine(b2);
+ MakeCon();
+ G();
+ return 0;
+ }
+
+ void T1(Con1.Imp:S1! imp, Con1.Exp:S1! exp)
+ {
+ }
+
+ void F(int i)
+ requires i == 0;
+ {
+ }
+
+ void G()
+ {
+ F(0);
+ }
+
+ bool bsearch(int x, int[]! arr)
+ requires forall { int i in ( 0 : arr.Length - 1); arr[i] <= arr[i+1] };
+ ensures forall { int i in ( 0 : arr.Length - 1); arr[i] <= arr[i+1] };
+ ensures forall { int i in ( 0 : arr.Length); old(arr)[i] == arr[i]};
+ ensures result == exists { int i in (0 : arr.Length); arr[i] == x};
+ {
+ return bsearchr(x, arr, 0, arr.Length);
+ }
+
+ bool bsearchr(int x, int[]! arr, int left, int right)
+ requires 0 <= left;
+ requires left <= right;
+ requires right <= arr.Length;
+ requires forall { int i in ( 0 : arr.Length - 1); arr[i] <= arr[i+1] };
+ ensures forall { int i in ( 0 : arr.Length - 1); arr[i] <= arr[i+1]};
+ ensures forall { int i in ( 0 : arr.Length); old(arr)[i] == arr[i]};
+ ensures result == exists { int i in (left : right); arr[i] == x};
+ {
+ if (right == left) return false;
+ else if (right == left + 1) return arr[left] == x;
+ else {
+ int mid = left / 2 + (right + 1) / 2;
+ return bsearchr(x, arr, left, mid) || bsearchr(x, arr, mid, right);
+ }
+ }
+
+
+ [Verify(false)]
+ void PrintHello()
+ {
+ Console.WriteLine("This is SpecTest");
+ }
+
+ [Verify(false)]
+ void T2(Con1.Imp:S1! imp, Con1.Exp:S1! exp)
+ {
+ exp.SendM1();
+ imp.RecvM1();
+ imp.SendM2();
+ exp.RecvM2();
+ }
+
+ [Verify(false)]
+ void MakeCon()
+ {
+ Con1.Imp !imp;
+ Con1.Exp !exp;
+ Con1.NewChannel(out imp, out exp);
+ T1(imp, exp);
+ T2(imp, exp);
+ exp.SendM1();
+ imp.RecvM1();
+ imp.SendM2();
+ exp.RecvM2();
+ delete imp;
+ delete exp;
+ }
+ }
+}
diff --git a/base/Applications/Tests/Sync/Sync.cs b/base/Applications/Tests/Sync/Sync.cs
index e08b986..3fc1dc8 100644
--- a/base/Applications/Tests/Sync/Sync.cs
+++ b/base/Applications/Tests/Sync/Sync.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Sync.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/TesterTest/SampleTest.sg b/base/Applications/Tests/TesterTest/SampleTest.sg
new file mode 100644
index 0000000..fdf89d0
--- /dev/null
+++ b/base/Applications/Tests/TesterTest/SampleTest.sg
@@ -0,0 +1,221 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+
+// needed for DebugStub
+using Microsoft.Singularity;
+// needed for stdin and stdout
+using Microsoft.Singularity.Io;
+
+// needed for the transform
+using Microsoft.SingSharp.Reflection;
+
+// needed for the Thread.sleep()
+using System.Threading;
+
+// needed for tests
+using Microsoft.Singularity.UnitTest;
+
+// needed for the generated infrastructure
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.Test.Contracts;
+
+[assembly: Transform(typeof(ApplicationResourceTransform))]
+//[assembly: Transform(typeof(TestTransform))]
+namespace Microsoft.Singularity
+{
+
+ /// Classes with the [TestClass] attribute are classes containing test
+ /// methods.
+ /// Methods with the [TestMethod] attribute are unit test methods.
+
+ [TestClass]
+ public class SampleTest : TestClass
+ {
+ int data = 0;
+
+ [ClassInitialize]
+ public void Init()
+ {
+ data = 2;
+ Expect.Info("Initializing Sample");
+ }
+
+ [TestMethod]
+ public void HelloTest()
+ {
+ //TODO add something
+ Expect.Info("Hello test");
+ Expect.True(true, "Got here");
+ }
+
+ [TestMethod]
+ public void ClassInitTest()
+ {
+ Expect.Equal(2, data, "data was setup correctly in ClassInitialize phase");
+ }
+
+ [TestMethod]
+ public void EqualTest()
+ {
+ Expect.Equal("","", "Empty strings are equal");
+ Expect.NotEqual("","a", "Empty is not equal to a nonempty string");
+ }
+ }
+
+ [TestClass]
+ public class FailTest : TestClass
+ {
+ [ClassInitialize]
+ public void Init()
+ {
+ }
+
+ [TestMethod]
+ public void SkipTest()
+ {
+ Expect.Continue(false, "This test should be skipped");
+ Expect.Fail("This test should have been skipped");
+ }
+
+ [TestMethod]
+ public void TimeoutTest()
+ {
+ for (int i = 0; i < 1000; i++) {
+ Thread.Sleep(50);
+ }
+ Expect.Fail("This test should be aborted before now via timeout");
+ }
+ }
+
+ // EXAMPLE OF CODE THAT WOULD BE GENERATED /////////////////////
+ internal class SampleTest_Jig : SuiteJig
+ {
+ private SampleTest! m_test;
+
+ public SampleTest_Jig(TestLog! log) {
+ SampleTest t = new SampleTest();
+ t.SetLog(log);
+ m_test = t;
+ }
+
+ override public void Initialize()
+ {
+ m_test.Init();
+ }
+
+ override public void DoTest(string! test)
+ {
+ switch (test) {
+ case "HelloTest":
+ m_test.HelloTest();
+ break;
+ case "EqualTest":
+ m_test.EqualTest();
+ break;
+ case "ClassInitTest":
+ m_test.ClassInitTest();
+ break;
+ default:
+ base.DoTest(test);
+ break;
+ }
+ }
+ }
+
+ internal class FailTest_Jig : SuiteJig
+ {
+ private FailTest! m_test;
+
+ public FailTest_Jig(TestLog! log) {
+ FailTest t = new FailTest();
+ t.SetLog(log);
+ m_test = t;
+ }
+
+ override public void Initialize()
+ {
+ m_test.Init();
+ }
+
+ override public void DoTest(string! test)
+ {
+ switch (test) {
+ case "SkipTest":
+ m_test.SkipTest();
+ break;
+ case "TimeoutTest":
+ m_test.TimeoutTest();
+ break;
+ default:
+ base.DoTest(test);
+ break;
+ }
+ }
+ }
+
+ public class Sample_ModuleJig : ModuleJig
+ {
+ override public SuiteJig GetSuite(string! name, TestLog! log)
+ {
+ switch (name) {
+ case "SampleTest":
+ return new SampleTest_Jig(log);
+ case "FailTest":
+ return new FailTest_Jig(log);
+ case "Shell":
+ return new ShellTest_Jig(log);
+ default:
+ return base.GetSuite(name, log);
+ }
+ }
+ }
+
+ // Currently required to get process launch code generated.
+ [ConsoleCategory(HelpMessage="Run using the test framework", DefaultAction=true)]
+ internal class ModuleConsole {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ reflective internal ModuleConsole();
+
+ internal int AppMain() {
+ Console.WriteLine("This is a test application and can only be run from the tester.");
+ return -1;
+ }
+ }
+
+ [ConsoleCategory(HelpMessage="ModuleTester", Action="test")]
+ internal class ModuleTest {
+ [InputEndpoint("data")]
+ public readonly TRef Stdin;
+ [OutputEndpoint("data")]
+ public readonly TRef Stdout;
+
+ [CustomEndpoint]
+ public readonly TRef testerRef;
+
+ reflective internal ModuleTest();
+
+ internal int AppMain() {
+ ModuleTesterContract.Exp tester = ((!) testerRef).Acquire();
+ if (tester == null) {
+ DebugStub.WriteLine("TEST unable to acquite handle to test driver");
+ throw new Exception("Unable to acquire handle to the test driver");
+ }
+
+ ModuleJig jig = new Sample_ModuleJig();
+ ModuleTester.RunTests(tester, jig);
+ return 0;
+ }
+ }
+}
diff --git a/base/Applications/Tests/TesterTest/ShellTest.sg b/base/Applications/Tests/TesterTest/ShellTest.sg
new file mode 100644
index 0000000..d24cecd
--- /dev/null
+++ b/base/Applications/Tests/TesterTest/ShellTest.sg
@@ -0,0 +1,98 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+using Microsoft.Bartok.Options;
+using Microsoft.Bartok.Runtime;
+
+using Microsoft.Singularity.Directory;
+
+using Microsoft.Singularity;
+using Microsoft.Singularity.Io;
+
+using Microsoft.Singularity.V1.Services;
+
+using Microsoft.SingSharp.Reflection;
+using Microsoft.Singularity.Test;
+using Microsoft.Singularity.UnitTest;
+
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Applications;
+using Microsoft.Contracts;
+using Microsoft.Singularity.Test.Contracts;
+
+//[assembly: Transform(typeof(TestTransform))]
+namespace Microsoft.Singularity
+{
+
+ internal class ShellTest_Jig : SuiteJig
+ {
+ TContainer m_outputMux;
+ private TestLog! Expect;
+
+ public ShellTest_Jig(TestLog! log) {
+ Expect = log;
+ }
+
+ override public void Initialize()
+ {
+ m_outputMux = new TContainer(MuxOut());
+ Expect.NotNull(m_outputMux, "Got output multiplexer");
+ }
+
+ override public void Cleanup()
+ {
+ PipeMultiplexer outputMux = ((!) m_outputMux).Acquire();
+ outputMux.Dispose();
+ m_outputMux = null;
+ }
+
+ // Special test implementation:
+ // take any test requested an dispatch a shell to execute it
+ // as a command
+ override public void DoTest(string! test)
+ {
+ string[] args = new string[] {"shell", "@single", test};
+ PipeMultiplexer outputMux = ((!) m_outputMux).Acquire();
+ DirectoryServiceContract.Imp ds = DirectoryService.NewClientEndpoint();
+ try {
+ Manifest manifest;
+ Process child = Binder.CreateProcess(ds, args, outputMux, out manifest);
+ Expect.NotNull(child, "Spawned shell for requested test");
+ Process! proc = (!) child;
+ proc.Start();
+ proc.Join();
+ Expect.Equal(proc.ExitCode, 0, "Spawned shell exited without errors");
+ }
+ finally {
+ delete ds;
+ m_outputMux.Release(outputMux);
+ }
+ }
+
+ // Redirect our standard output into a multiplexer so we can interleave
+ // output from child processes
+ private PipeMultiplexer! MuxOut()
+ {
+ // Swap our real stdOut with a newly created one
+ UnicodePipeContract.Exp! newOutputExp;
+ UnicodePipeContract.Imp! newOutputImp;
+ UnicodePipeContract.NewChannel(out newOutputImp, out newOutputExp);
+ UnicodePipeContract.Imp stdOut = ConsoleOutput.Swap(newOutputImp);
+ Expect.True(stdOut != null, "Got stdout pipe");
+ // Use a mux to splice our own output together with the child
+ // processes we will run.
+ return PipeMultiplexer.Start((!)stdOut, newOutputExp);
+ }
+ }
+
+}
diff --git a/base/Applications/Tests/TesterTest/shellbvt.tst b/base/Applications/Tests/TesterTest/shellbvt.tst
new file mode 100644
index 0000000..c4db52a
--- /dev/null
+++ b/base/Applications/Tests/TesterTest/shellbvt.tst
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/TesterTest/shellfail.tst b/base/Applications/Tests/TesterTest/shellfail.tst
new file mode 100644
index 0000000..0ad7294
--- /dev/null
+++ b/base/Applications/Tests/TesterTest/shellfail.tst
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/TesterTest/testdriver.csproj b/base/Applications/Tests/TesterTest/testdriver.csproj
new file mode 100644
index 0000000..6007e20
--- /dev/null
+++ b/base/Applications/Tests/TesterTest/testdriver.csproj
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+ TestDriver
+ Exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/TesterTest/tester.tst b/base/Applications/Tests/TesterTest/tester.tst
new file mode 100644
index 0000000..d20d0c2
--- /dev/null
+++ b/base/Applications/Tests/TesterTest/tester.tst
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/Tests/ThreadTest/ThreadTest.cs b/base/Applications/Tests/ThreadTest/ThreadTest.cs
index 6bc837a..055419b 100644
--- a/base/Applications/Tests/ThreadTest/ThreadTest.cs
+++ b/base/Applications/Tests/ThreadTest/ThreadTest.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ThreadTest.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -20,7 +18,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -57,8 +56,7 @@ namespace Microsoft.Singularity.Applications {
Console.WriteLine("Second thread!");
DebugStub.Print("Second thread!\n");
- for (int i = 0; i < 10; i++)
- {
+ for (int i = 0; i < 10; i++) {
Console.WriteLine(" ... [1]");
Thread.Yield();
}
@@ -80,8 +78,7 @@ namespace Microsoft.Singularity.Applications {
t2.Start();
Console.WriteLine("Started second thread.");
- for (int i = 0; i < 30; i++)
- {
+ for (int i = 0; i < 30; i++) {
Thread.Yield();
}
return 0;
diff --git a/base/Applications/Tests/ThreadTest/ThreadTest.csproj b/base/Applications/Tests/ThreadTest/ThreadTest.csproj
index 72547ff..545d57a 100644
--- a/base/Applications/Tests/ThreadTest/ThreadTest.csproj
+++ b/base/Applications/Tests/ThreadTest/ThreadTest.csproj
@@ -5,8 +5,6 @@ Microsoft Research Singularity
Copyright (c) Microsoft Corporation. All rights reserved.
-File: Applications\Tests\ThreadTest\ThreadTest.csproj
-
Note:
##############################################################################
diff --git a/base/Applications/Tests/Throw/Throw.cs b/base/Applications/Tests/Throw/Throw.cs
index 8b12881..1b79df1 100644
--- a/base/Applications/Tests/Throw/Throw.cs
+++ b/base/Applications/Tests/Throw/Throw.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Throw.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -42,17 +41,14 @@ namespace Microsoft.Singularity.Applications {
{
string args = "something";
- try
- {
+ try {
DebugStub.Print("About to throw exception\n");
- if (args == null)
- {
+ if (args == null) {
throw new ArgumentNullException("ArgNullException");
}
throw new ApplicationException("AppException");
}
- catch (Exception e)
- {
+ catch (Exception e) {
Console.WriteLine("Caught exception {0}", e);
}
return 0;
diff --git a/base/Applications/Tests/Throw/Throw.csproj b/base/Applications/Tests/Throw/Throw.csproj
index 35a18eb..e1fe451 100644
--- a/base/Applications/Tests/Throw/Throw.csproj
+++ b/base/Applications/Tests/Throw/Throw.csproj
@@ -5,8 +5,6 @@ Microsoft Research Singularity
Copyright (c) Microsoft Corporation. All rights reserved.
-File: Applications\Tests\Throw\Throw.csproj
-
Note:
##############################################################################
diff --git a/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.cs b/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.cs
index 65d7281..797dedf 100644
--- a/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.cs
+++ b/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: ThrowWithLinkStack.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -20,7 +18,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -41,13 +40,11 @@ namespace Microsoft.Singularity.Applications {
//[ShellCommand("throwWithLinkStack", "Throw an exception with link stack")]
internal static int AppMain(Parameters! config)
{
- try
- {
+ try {
DebugStub.Print("About to throw exception\n");
Throw();
}
- catch (Exception e)
- {
+ catch (Exception e) {
Console.WriteLine("Throw with Link Stack Caught exception {0}", e);
}
return 0;
diff --git a/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.csproj b/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.csproj
index 636987f..5f12af6 100644
--- a/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.csproj
+++ b/base/Applications/Tests/ThrowWithLinkStack/ThrowWithLinkStack.csproj
@@ -5,8 +5,6 @@ Microsoft Research Singularity
Copyright (c) Microsoft Corporation. All rights reserved.
-File: Applications\Tests\ThrowWithLinkStack\ThrowWithLinkStack.csproj
-
Note:
##############################################################################
diff --git a/base/Applications/Tests/UnitTestTest/UnitTestTest.cs b/base/Applications/Tests/UnitTestTest/UnitTestTest.cs
index 70a0651..d72a949 100644
--- a/base/Applications/Tests/UnitTestTest/UnitTestTest.cs
+++ b/base/Applications/Tests/UnitTestTest/UnitTestTest.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: UnitTestTest.cs
-//
// Note: A test of the Unit testing code.
//
@@ -22,7 +20,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/UnitTestTest/UnitTestTest.csproj b/base/Applications/Tests/UnitTestTest/UnitTestTest.csproj
deleted file mode 100644
index 70b8670..0000000
--- a/base/Applications/Tests/UnitTestTest/UnitTestTest.csproj
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
- UnitTestTest
- Exe
- true
- true
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/base/Applications/Tests/VQTest/VQTest.sg b/base/Applications/Tests/VQTest/VQTest.sg
index cb529ab..44efafd 100644
--- a/base/Applications/Tests/VQTest/VQTest.sg
+++ b/base/Applications/Tests/VQTest/VQTest.sg
@@ -1,11 +1,11 @@
-///////////////////////////////////////////////////////////////////////////////
+// ----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
+// ----------------------------------------------------------------------------
using System;
using Microsoft.Singularity.Channels;
-using Microsoft.Singularity.Channels;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
@@ -13,7 +13,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -30,7 +31,8 @@ namespace Microsoft.Singularity.Applications {
}
}
- class Test {
+ class Test
+ {
const int NUM = 21;
@@ -39,7 +41,7 @@ namespace Microsoft.Singularity.Applications {
VectorQueue vq1 = new VectorQueue();
VectorQueue vq2 = new VectorQueue();
- for (int i=0; i<=Test.NUM; i++) {
+ for (int i = 0; i <= Test.NUM; i++) {
int[] in ExHeap v = new[ExHeap] int[i];
vq1.AddTail(v);
}
diff --git a/base/Applications/Tests/Varargs/Varargs.sg b/base/Applications/Tests/Varargs/Varargs.sg
index d7f566a..a3a0880 100644
--- a/base/Applications/Tests/Varargs/Varargs.sg
+++ b/base/Applications/Tests/Varargs/Varargs.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Varargs.sg
-//
// Note: Test __arglist parameters
//
using System;
@@ -17,7 +15,7 @@ namespace Microsoft.Singularity.Applications
{
public static int Main(String[]! args)
{
- string name = "VarArgs.x86";
+ string name = "VarArgs";
int len = 1;
int code = Printf("Invoked command with name '%s' and %d arguments", __arglist(name, len));
Console.WriteLine("Varargs exiting.");
diff --git a/base/Applications/Tests/Verify/Verify.cs b/base/Applications/Tests/Verify/Verify.cs
index d676e45..e6a4882 100644
--- a/base/Applications/Tests/Verify/Verify.cs
+++ b/base/Applications/Tests/Verify/Verify.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Verify.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -18,7 +16,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/Wait/Wait.cs b/base/Applications/Tests/Wait/Wait.cs
index c7ecb18..0da2400 100644
--- a/base/Applications/Tests/Wait/Wait.cs
+++ b/base/Applications/Tests/Wait/Wait.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: Wait.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -19,7 +17,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
diff --git a/base/Applications/Tests/WaitTest/WaitTest.cs b/base/Applications/Tests/WaitTest/WaitTest.cs
index 4045917..f3d8b29 100644
--- a/base/Applications/Tests/WaitTest/WaitTest.cs
+++ b/base/Applications/Tests/WaitTest/WaitTest.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: WaitTest.cs
-//
// Note: Simple Singularity test program.
//
using System;
@@ -20,7 +18,8 @@ using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
-namespace Microsoft.Singularity.Applications {
+namespace Microsoft.Singularity.Applications
+{
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
@@ -103,7 +102,7 @@ namespace Microsoft.Singularity.Applications {
Console.WriteLine("Queue: {0}\n", q);
#endif
- for(int i=0; i < 5; i++) {
+ for (int i = 0; i < 5; i++) {
Console.WriteLine("Thread One About To Sleep " + ProcessService.GetUpTime().Ticks);
Thread.Sleep(TimeSpan.FromMilliseconds(1000));
Console.WriteLine("Thread One Waking Up " + ProcessService.GetUpTime().Ticks);
@@ -113,7 +112,7 @@ namespace Microsoft.Singularity.Applications {
}
public static void WaitThreadTwo() {
Console.WriteLine("Starting Wait Thread Two");
- for(int i=0; i < 10; i++) {
+ for (int i = 0; i < 10; i++) {
Console.WriteLine("Thread Two About To Sleep " + ProcessService.GetUpTime().Ticks);
Thread.Sleep(TimeSpan.FromMilliseconds(30));
Console.WriteLine("Thread Two Waking Up " + ProcessService.GetUpTime().Ticks);
diff --git a/base/Applications/TftpClient/tftp.cs b/base/Applications/TftpClient/tftp.cs
index 80d7210..0b433a6 100644
--- a/base/Applications/TftpClient/tftp.cs
+++ b/base/Applications/TftpClient/tftp.cs
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: TftpClient.cs
-//
// Note:
//
@@ -99,13 +97,12 @@ namespace Microsoft.Singularity.Applications
int len;
int rc;
- if (null != localName)
- {
+ if (null != localName) {
Console.WriteLine ("Creating file "+localName);
success = FileUtils.CreateFile(localName);
if (0 == success) {
persistHandle = FileUtils.OpenFile(localName);
- if (null == persistHandle){
+ if (null == persistHandle) {
Console.WriteLine("unable to open file " + localName);
return "";
}
@@ -128,43 +125,34 @@ namespace Microsoft.Singularity.Applications
//string str = null;
int count = 0;
int lastBlock = -1;
- while (!done)
- {
+ while (!done) {
//Socket.Select(listenList, null, null, 1000);
- if (s.Poll(1000000, SelectMode.SelectRead))
- {
+ if (s.Poll(1000000, SelectMode.SelectRead)) {
rc = s.Receive(reply);
if (verboseMode) Console.WriteLine("Receive rc={0}", rc);
- if (rc >= 4)
- {
+ if (rc >= 4) {
TftpHdr rh = new TftpHdr(reply, 0);
//Console.WriteLine("Opcode {0} Arg {1} rc={2} curPos={3}", rh.Opcode, rh.Arg, rc, curPos);
if (rh.Arg == lastBlock)
Console.WriteLine(" duplicate block? block ="+rh.Arg);
lastBlock = rh.Arg;
- if (rh.Opcode == TftpOpcode.DATA)
- {
- if (!verboseMode)
- {
+ if (rh.Opcode == TftpOpcode.DATA) {
+ if (!verboseMode) {
Console.Write(".");
- if (count++ > 50)
- {
+ if (count++ > 50) {
count = 0;
Console.Write("\n");
}
}
- else
- {
+ else {
//str = Encoding.ASCII.GetString(reply, 4, rc-4);
//Console.WriteLine("pos="+curPos+" str="+str);
//str = null;
}
- if (persistHandle != null)
- {
+ if (persistHandle != null) {
Bitter.FromByteArray(buf,0,rc-4,reply,4);
persistHandle.SendWrite(buf,0,curPos,rc-4);
- switch receive
- {
+ switch receive {
case persistHandle.AckWrite( _buf, bytesWritten, error) :
buf = _buf;
curPos = rh.Arg * 512;
@@ -188,10 +176,9 @@ namespace Microsoft.Singularity.Applications
hdr.Marshal(request, 0);
len = 4;
}
- if (rc < 512+4) done = true;
+ if (rc < 512 + 4) done = true;
}
- else
- {
+ else {
//Console.WriteLine("poll for data failed!");
//return null;
}
@@ -199,8 +186,7 @@ namespace Microsoft.Singularity.Applications
if (verboseMode)Console.WriteLine("Sent {0} {1} rc {2}", hdr.Opcode, hdr.Arg, rc);
//Thread.Sleep(1000);
}
- if (persistHandle != null)
- {
+ if (persistHandle != null) {
Console.WriteLine("Closing EP handle via delete");
delete persistHandle;
}
@@ -218,27 +204,26 @@ namespace Microsoft.Singularity.Applications
int len;
int rc;
- long fileLength =0;
- NodeType nodeType;
+ long fileLength = 0;
ErrorCode errorOut;
- if (null != localName)
- {
+ if (null != localName) {
DirectoryServiceContract.Imp! rootNS = DirectoryService.NewClientEndpoint();
- bool ok = FileUtils.GetAttributes(localName, rootNS, out fileLength, out nodeType, out errorOut);
+ FileAttributesRecord record;
+ bool ok = FileUtils.GetAttributes(localName, rootNS, out record, out errorOut);
delete rootNS;
- if (!ok)
- {
+ if (!ok) {
Console.WriteLine("Unable to open file ({0}) for send. reason:{1}",
localName, SdsUtils.ErrorCodeToString(errorOut)
);
return null;
}
+ fileLength = record.FileSize;
+
fileHandle = FileUtils.OpenFile(localName);
- if (null == fileHandle)
- {
+ if (null == fileHandle) {
Console.WriteLine("Unable to open file "+localName+" for send");
return null;
}
@@ -256,32 +241,26 @@ namespace Microsoft.Singularity.Applications
int threshold = 20;
int waitCount = 0;
Console.WriteLine(" file size =" + fileLength);
- while (!done)
- {
+ while (!done) {
//Socket.Select(listenList, null, null, 1000);
- if (s.Poll(100000, SelectMode.SelectRead))
- {
+ if (s.Poll(100000, SelectMode.SelectRead)) {
rc = s.Receive(reply);
Console.WriteLine("Receive rc={0}", rc);
- if (rc >= 4)
- {
+ if (rc >= 4) {
TftpHdr rh = new TftpHdr(reply, 0);
Console.WriteLine("PUT: Opcode {0} Arg {1}", rh.Opcode, rh.Arg);
- if (rh.Opcode == TftpOpcode.ACK)
- {
+ if (rh.Opcode == TftpOpcode.ACK) {
int datalen;
int error;
long bytesRead;
Console.WriteLine("ACK for block {0}, pos={1}", rh.Arg,pos);
waitCount = 0;
- if (pos >= fileLength)
- {
+ if (pos >= fileLength) {
Console.WriteLine(" here");
bytesRead = 0;
}
- else
- {
+ else {
if (fileHandle == null)
throw new Exception("fileHandle is null when I want to SendRead");
fileHandle.SendRead(buf, 0, pos, 512);
@@ -302,8 +281,7 @@ namespace Microsoft.Singularity.Applications
Bitter.ToByteArray(buf,0,datalen,request,4);
len = 4 + datalen;
}
- else
- {
+ else {
Console.WriteLine("NOT AN ACK!\n");
DebugStub.Break();
}
@@ -311,12 +289,10 @@ namespace Microsoft.Singularity.Applications
rc = s.Send(request, len, SocketFlags.None);
Console.WriteLine("Sent {0} {1} rc {2}", hdr.Opcode, hdr.Arg, rc);
}
- else
- {
+ else {
Console.WriteLine("Waiting.");
waitCount++;
- if (waitCount > threshold)
- {
+ if (waitCount > threshold) {
Console.WriteLine (" exceeded timeout threshold");
done = true;
break;
@@ -333,19 +309,18 @@ namespace Microsoft.Singularity.Applications
private static IPAddress GetServerAddress(string server)
{
- try
- {
+ try {
return IPAddress.Parse(server);
}
- catch
- {}
+ catch {
+ }
try {
IPHostEntry he = Dns.GetHostByName(server);
return he.AddressList[0];
}
- catch
- {}
+ catch {
+ }
return null;
}
@@ -361,29 +336,25 @@ namespace Microsoft.Singularity.Applications
{
bool verboseMode = false;
String localName, remoteName;
- if (args.Length < 4 || args.Length > 6)
- {
+ if (args.Length < 4 || args.Length > 6) {
Usage();
return 1;
}
IPAddress server = GetServerAddress(args[1]);
- if (server == null)
- {
+ if (server == null) {
Console.WriteLine("Could not find server : {0}", args[1]);
return 2;
}
int pos =2;
- if (args[pos] == "-v")
- {
+ if (args[pos] == "-v") {
verboseMode = true;
pos++;
}
bool doGet;
- switch (args[pos])
- {
+ switch (args[pos]) {
case "get":
doGet = true;
break;
@@ -398,23 +369,19 @@ namespace Microsoft.Singularity.Applications
remoteName = (!)args[pos];
pos++;
localName = null;
- if (pos >= args.Length)
- {
+ if (pos >= args.Length) {
Console.WriteLine("no destination given");
}
- else
- {
+ else {
localName = args[pos];
}
Console.WriteLine("doGet="+doGet+" src="+remoteName+" dest="+localName);
TftpClient tftpClient = new TftpClient(server);
- if (doGet)
- {
+ if (doGet) {
string contents = tftpClient.Get(remoteName,localName,verboseMode);
if (verboseMode) Console.WriteLine("Contents:\n{0}", contents);
}
- else
- {
+ else {
//put
tftpClient.Put(remoteName,localName);
}
diff --git a/base/Applications/Transforms/AppTransforms.csproj b/base/Applications/Transforms/AppTransforms.csproj
index be09bfa..486fad6 100644
--- a/base/Applications/Transforms/AppTransforms.csproj
+++ b/base/Applications/Transforms/AppTransforms.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ MapDemoWebApp
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Microsoft.Singularity.WebApps
+ MainMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ SeattleAllMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ SeattleStarMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ SeattleSBCMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ SeattleTullysMapPage
+ HTMLData
+
+
+
+
+ Microsoft.Singularity.WebApps
+ RedmondAllMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ RedmondStarMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ RedmondSBCMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ RedmondTullysMapPage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ BlueIcon
+ ImageData
+
+
+
+ Microsoft.Singularity.WebApps
+ RedIcon
+ ImageData
+
+
+
+ Microsoft.Singularity.WebApps
+ GreenIcon
+ ImageData
+
+
+
+ Microsoft.Singularity.WebApps
+ TowerIcon
+ ImageData
+
+
+
+ Microsoft.Singularity.WebApps
+ VePage1
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ VePage2
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ VePage3
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ VePage
+ HTMLData
+
+
+
+ Microsoft.Singularity.WebApps
+ MapControl
+ HTMLData
+
+
+
+
+
+
+
diff --git a/base/Applications/WebApps/MapDemo/blue.bmp b/base/Applications/WebApps/MapDemo/blue.bmp
new file mode 100644
index 0000000..6d256e5
Binary files /dev/null and b/base/Applications/WebApps/MapDemo/blue.bmp differ
diff --git a/base/Applications/WebApps/MapDemo/green.bmp b/base/Applications/WebApps/MapDemo/green.bmp
new file mode 100644
index 0000000..ce07fe3
Binary files /dev/null and b/base/Applications/WebApps/MapDemo/green.bmp differ
diff --git a/base/Applications/WebApps/MapDemo/mainpage.htm b/base/Applications/WebApps/MapDemo/mainpage.htm
new file mode 100644
index 0000000..39a413b
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/mainpage.htm
@@ -0,0 +1,16 @@
+
+
+Caffeinate me!
+
+
+
+In Search of Caffeine
+
+
+Caffeinate me, I'm:
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/red.bmp b/base/Applications/WebApps/MapDemo/red.bmp
new file mode 100644
index 0000000..57ffeeb
Binary files /dev/null and b/base/Applications/WebApps/MapDemo/red.bmp differ
diff --git a/base/Applications/WebApps/MapDemo/redmond_all.htm b/base/Applications/WebApps/MapDemo/redmond_all.htm
new file mode 100644
index 0000000..b92621e
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/redmond_all.htm
@@ -0,0 +1,42 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+Looks like a drive to Redmond is in your future...
+
+
|
+
+ |
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/redmond_sbc.htm b/base/Applications/WebApps/MapDemo/redmond_sbc.htm
new file mode 100644
index 0000000..39cc958
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/redmond_sbc.htm
@@ -0,0 +1,41 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+Looks like a drive to Redmond is in your future...
+
+
|
+
+ |
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/redmond_star.htm b/base/Applications/WebApps/MapDemo/redmond_star.htm
new file mode 100644
index 0000000..0243720
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/redmond_star.htm
@@ -0,0 +1,41 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+Looks like a drive to Redmond is in your future...
+
+
|
+
+ |
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/redmond_tullys.htm b/base/Applications/WebApps/MapDemo/redmond_tullys.htm
new file mode 100644
index 0000000..493c531
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/redmond_tullys.htm
@@ -0,0 +1,41 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+Looks like a drive to Redmond is in your future...
+
+
|
+
+ |
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/seattle_all.htm b/base/Applications/WebApps/MapDemo/seattle_all.htm
new file mode 100644
index 0000000..dc3d961
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/seattle_all.htm
@@ -0,0 +1,43 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+Looks like you have quite a few choices...
+
+
+ |
+
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/seattle_sbc.htm b/base/Applications/WebApps/MapDemo/seattle_sbc.htm
new file mode 100644
index 0000000..780e7eb
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/seattle_sbc.htm
@@ -0,0 +1,41 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+Is Seattle's Best Coffee either from Seattle, or its best? Discuss.
+
+
+ |
+
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/seattle_star.htm b/base/Applications/WebApps/MapDemo/seattle_star.htm
new file mode 100644
index 0000000..486cafe
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/seattle_star.htm
@@ -0,0 +1,41 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+The original Starbucks location is in Pike Place Market
+
+
+ |
+
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/seattle_tullys.htm b/base/Applications/WebApps/MapDemo/seattle_tullys.htm
new file mode 100644
index 0000000..0ea6a9a
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/seattle_tullys.htm
@@ -0,0 +1,42 @@
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+Looks like you have quite a few choices...
+
+
+ |
+
+ |
+
+
+
+
+
+
\ No newline at end of file
diff --git a/base/Applications/WebApps/MapDemo/tower.bmp b/base/Applications/WebApps/MapDemo/tower.bmp
new file mode 100644
index 0000000..70ce45f
Binary files /dev/null and b/base/Applications/WebApps/MapDemo/tower.bmp differ
diff --git a/base/Applications/WebApps/MapDemo/ve.aspx b/base/Applications/WebApps/MapDemo/ve.aspx
new file mode 100644
index 0000000..4ac9650
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/ve.aspx
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+Caffeinate me!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+In Search of Caffeine
+
+
+
diff --git a/base/Applications/WebApps/MapDemo/ve1.aspx b/base/Applications/WebApps/MapDemo/ve1.aspx
new file mode 100644
index 0000000..7084647
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/ve1.aspx
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+VE Demo 1
+
+
+
+
+
+
+
+
+
+
+
+VE Demo 1 - Virtual Earth Hosting
+
+
+
diff --git a/base/Applications/WebApps/MapDemo/ve2.aspx b/base/Applications/WebApps/MapDemo/ve2.aspx
new file mode 100644
index 0000000..e9af801
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/ve2.aspx
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+VE Demo 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+VE Demo 2 - Local Search on Virtual Earth
+
+
+
diff --git a/base/Applications/WebApps/MapDemo/ve3.aspx b/base/Applications/WebApps/MapDemo/ve3.aspx
new file mode 100644
index 0000000..4b07705
--- /dev/null
+++ b/base/Applications/WebApps/MapDemo/ve3.aspx
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+VE Demo 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+VE Demo 3 - Traffic and Search on Virtual Earth
+
+
+
diff --git a/base/Applications/WebApps/SPECweb99/CachedFile.sg b/base/Applications/WebApps/SPECweb99/CachedFile.sg
index d25ab1c..c9db26e 100644
--- a/base/Applications/WebApps/SPECweb99/CachedFile.sg
+++ b/base/Applications/WebApps/SPECweb99/CachedFile.sg
@@ -4,8 +4,6 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
-// File: CachedFile.sg
-//
// Note: CachedFile is intended to hold copies of Custom.Ads
// and User.Profiles in memory.
//
diff --git a/base/Applications/WebApps/SPECweb99/README.txt b/base/Applications/WebApps/SPECweb99/README.txt
index be4295e..78836fa 100644
--- a/base/Applications/WebApps/SPECweb99/README.txt
+++ b/base/Applications/WebApps/SPECweb99/README.txt
@@ -1,8 +1,3 @@
-From: Mark Aiken
-Sent: Sunday, October 16, 2005 4:19 PM
-To: Chris Hawblitzel
-Subject: Running SPECweb
-
Here is how to run SPECweb:
Build:
@@ -13,7 +8,7 @@ Build:
- Distro
On Windows:
-Run \\maiken\pub\SPECweb99.exe. Install as "prime client"
+Run SPECweb99.exe. Install as "prime client"
Copy the rc.sing file into "c:\SPECweb99"
Edit the attached file to point to your Singularity machine
(you will need to get a DHCP lease as described below, first.
diff --git a/base/Applications/WebApps/SPECweb99/SPECWeb99.csproj b/base/Applications/WebApps/SPECweb99/SPECWeb99.csproj
index 0198007..972e9c0 100644
--- a/base/Applications/WebApps/SPECweb99/SPECWeb99.csproj
+++ b/base/Applications/WebApps/SPECweb99/SPECWeb99.csproj
@@ -1,8 +1,6 @@

+
+
+
+
+
+ Exe
+ SPECWeb99WebAppIN
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/WebApps/SPECweb99in/SPECWeb99in_app.csproj b/base/Applications/WebApps/SPECweb99in/SPECWeb99in_app.csproj
new file mode 100644
index 0000000..808568f
--- /dev/null
+++ b/base/Applications/WebApps/SPECweb99in/SPECWeb99in_app.csproj
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ Exe
+ SPECWeb99WebAppIN
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/WebApps/ServiceManager/ServiceManagerWebApp.csproj b/base/Applications/WebApps/ServiceManager/ServiceManagerWebApp.csproj
new file mode 100644
index 0000000..daf6bb5
--- /dev/null
+++ b/base/Applications/WebApps/ServiceManager/ServiceManagerWebApp.csproj
@@ -0,0 +1,35 @@
+
+
+
+
+
+ Exe
+ ServiceManagerWebApp
+ true
+ {6FF50C76-A677-44BD-A178-B9F556686BBD}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/base/Applications/WebApps/ServiceManager/ServiceManagerWebApp.sg b/base/Applications/WebApps/ServiceManager/ServiceManagerWebApp.sg
new file mode 100644
index 0000000..d338fb8
--- /dev/null
+++ b/base/Applications/WebApps/ServiceManager/ServiceManagerWebApp.sg
@@ -0,0 +1,790 @@
+// ----------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// ----------------------------------------------------------------------------
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+using System.Web;
+
+using Microsoft.SingSharp;
+using Microsoft.SingSharp.Runtime;
+using Microsoft.Singularity.Diagnostics.Contracts;
+using Microsoft.Singularity.Channels;
+using Microsoft.Singularity.Directory;
+using Microsoft.Singularity.WebApps;
+using Microsoft.Singularity.WebApps.Contracts;
+using Microsoft.Singularity.PingPong.Contracts;
+using Microsoft.Singularity.Io;
+using Microsoft.Singularity.Configuration;
+using Microsoft.Singularity.Applications;
+using Microsoft.Singularity.ServiceManager;
+
+[assembly: Microsoft.SingSharp.Reflection.Transform(typeof(WebAppResourceTransform))]
+
+namespace Microsoft.Singularity.WebApps
+{
+ [Category("WebApp")]
+ internal sealed class Parameters
+ {
+ [Endpoint]
+ public readonly TRef webAppRef;
+
+
+ reflective private Parameters();
+ }
+
+ class ServiceManagerWebApp : IWebApp, IDisposable
+ {
+ const string dbgprefix = "ServiceManagerWebApp: ";
+
+ readonly TRef! rootdsRef;
+ readonly TRef! svmanagerRef;
+ readonly Hashtable/**/! urlHandlers = new Hashtable();
+ readonly Hashtable/**/! fileHandlers = new Hashtable();
+
+
+ readonly Encoding! encoding;
+ readonly byte[]! newlineBytes;
+
+ [Microsoft.Contracts.NotDelayed]
+ ServiceManagerWebApp()
+ {
+ DirectoryServiceContract.Imp! rootds = DirectoryService.NewClientEndpoint();
+
+ // First, connect to SCM.
+
+ ServiceManagerContract.Imp! svmanager = ConnectServiceManager(rootds);
+
+ this.rootdsRef = new TRef(rootds);
+ this.svmanagerRef = new TRef(svmanager);
+
+ Encoding encoding = Encoding.UTF8;
+ this.encoding = encoding;
+ this.newlineBytes = encoding.GetBytes("\r\n");
+
+ base();
+
+ this.urlHandlers["/"] = new UrlHandler(this.RootPageHandler);
+ this.fileHandlers["/style.css"] = new FileEntry("/init/sv_style.css", "text/css");
+ }
+
+
+ void Run(Parameters! config)
+ {
+ Dbg("Calling Driver.ServiceChannel");
+ WebAppContract.Exp! webappChannel = config.webAppRef.Acquire();
+ webappChannel.SendWebAppReady();
+ Driver.ServiceChannel(this, webappChannel);
+ }
+
+ internal static int AppMain(Parameters! config)
+ {
+ Dbg("Starting");
+
+ using (ServiceManagerWebApp app = new ServiceManagerWebApp()) {
+ app.Run(config);
+ }
+
+ return 0;
+ }
+
+ public void Dispose()
+ {
+
+ }
+
+ static ServiceManagerContract.Imp! ConnectServiceManager(DirectoryServiceContract.Imp! rootds)
+ {
+ ServiceManagerContract.Imp! svmanager_imp;
+ ServiceManagerContract.Exp! svmanager_exp;
+ ServiceManagerContract.NewChannel(out svmanager_imp, out svmanager_exp);
+
+ ErrorCode error;
+ if (!SdsUtils.Bind("/service/services", rootds, svmanager_exp, out error)) {
+ delete svmanager_imp;
+ throw new Exception("Failed to connect to Service Manager.");
+ }
+
+ svmanager_imp.RecvSuccess();
+
+ return svmanager_imp;
+ }
+
+ public void ProcessRequest(IHttpRequest! request)
+ {
+ try {
+ string! path = request.GetUriPath();
+ string verb = request.GetVerb();
+
+ if (verb == null)
+ throw new InvalidRequestException("Invalid verb");
+
+ UrlHandler handler = (UrlHandler)urlHandlers[path];
+ if (handler != null) {
+ Dbg("Received ProcessRequest - " + path);
+ handler(request);
+ return;
+ }
+
+ FileEntry file_entry = (FileEntry)fileHandlers[path];
+ if (file_entry != null) {
+ Dbg("Received ProcessRequest - " + path + " --> file " + file_entry.LocalPath);
+
+ if (verb != "GET") {
+ throw new InvalidRequestException("Invalid verb");
+ }
+ SendFile(request, file_entry.LocalPath, file_entry.ContentType);
+ return;
+ }
+
+ Dbg("No handler for path '{0}'.", path);
+ request.SendStatus(404, "Not Found");
+
+ }
+ catch (InvalidRequestException ex) {
+ Dbg("Invalid request: " + ex.Message);
+ request.SendStatus(500, ex.Message);
+ }
+ catch (Exception ex) {
+ Dbg("Exception: " + ex.GetType().FullName + ": " + ex.Message);
+ DebugStub.Break();
+ }
+ finally {
+ request.Done();
+ }
+ }
+
+ ServiceManagerContract.Imp! AcquireServiceManager()
+ {
+ return this.svmanagerRef.Acquire();
+ }
+
+ void ReleaseServiceManager([Claims]ServiceManagerContract.Imp! svmanager)
+ {
+ this.svmanagerRef.Release(svmanager);
+ }
+
+ class RequestFormData
+ {
+ public readonly StringDictionary Values = new StringDictionary();
+
+ public string! this[string! name]
+ {
+ get {
+ string value = this.Values[name];
+ if (value == null)
+ return "";
+ else
+ return value;
+ }
+ }
+
+ public bool IsSet(string! name)
+ {
+ string value = this.Values[name];
+ return value != null && value.Length != 0;
+ }
+ }
+
+ const string ContentTypeHeaderName = "Content-Type";
+ const string UrlEncodedContentType = "application/x-www-form-urlencoded";
+
+ RequestFormData! GetFormData(IHttpRequest! request)
+ {
+ Dbg("Parsing form data...");
+
+ RequestFormData data = new RequestFormData();
+
+ string contentType = request.GetHeader(ContentTypeHeaderName);
+ if (contentType == null) {
+ Dbg("No content type. Assuming form data is not present.");
+ return data;
+ }
+
+ if (String.Compare(contentType, UrlEncodedContentType, true) != 0) {
+ Dbg("Content type is not '{0}'; it's '{1}', which is not recognized.", UrlEncodedContentType, contentType);
+ return data;
+ }
+
+ Dbg("Content type is correct.");
+
+ byte[]! body_data = request.GetBodyData();
+
+ string! urlEncodedText = Encoding.UTF8.GetString(body_data);
+ Dbg("Decoding: " + urlEncodedText);
+
+ string[]! fields = urlEncodedText.Split('&');
+ foreach (string field in fields) {
+ if (field == null)
+ continue;
+ int equals_index = field.IndexOf('=');
+ if (equals_index == -1) {
+ Dbg("field is invalid: " + field);
+ continue;
+ }
+
+ string! name_encoded = field.Substring(0, equals_index);
+ string! value_encoded = field.Substring(equals_index + 1);
+ string! name_decoded = (!)HttpUtility.UrlDecode(name_encoded);
+ string! value_decoded = (!)HttpUtility.UrlDecode(value_encoded);
+ data.Values[name_decoded] = value_decoded;
+ Dbg("found field '{0}' value '{1}'", name_decoded, value_decoded);
+ }
+
+ return data;
+ }
+
+ bool SelectService(ServiceManagerContract.Imp! svmanager, string! serviceName)
+ {
+ svmanager.SendSelectService(Bitter.FromString2(serviceName));
+
+ switch receive {
+ case svmanager.Ok():
+ return true;
+
+ case svmanager.RequestFailed(error):
+ Dbg("Failed to select service '{0}': {1}", serviceName, ServiceEnums.ToString(error));
+ return false;
+
+ case svmanager.ChannelClosed():
+ Dbg("Service Manager closed channel!");
+ return false;
+ }
+ }
+
+ void StartService(string! serviceName)
+ {
+ Dbg("Starting service '{0}'...", serviceName);
+
+ ServiceManagerContract.Imp! svmanager = AcquireServiceManager();
+
+ if (!SelectService(svmanager, serviceName))
+ return;
+
+ svmanager.SendStartServiceNoWait();
+ switch receive {
+ case svmanager.ServiceStarting():
+ break;
+
+ case svmanager.RequestFailed(error):
+ break;
+ }
+
+ svmanager.SendUnselectService();
+
+ ReleaseServiceManager(svmanager);
+ }
+
+ void StopService(string! serviceName)
+ {
+ Dbg("Stopping service '{0}'...", serviceName);
+
+ ServiceManagerContract.Imp! svmanager = AcquireServiceManager();
+
+ if (!SelectService(svmanager, serviceName))
+ return;
+
+ svmanager.SendStopServiceNoWait();
+ switch receive {
+ case svmanager.ServiceStopping():
+ break;
+
+ case svmanager.RequestFailed(error):
+ break;
+ }
+
+ svmanager.SendUnselectService();
+
+ ReleaseServiceManager(svmanager);
+ }
+
+ void EnableService(string! serviceName, bool enabled)
+ {
+ Dbg("Setting service enabled to {0} for service '{1}'...", enabled, serviceName);
+
+ ServiceManagerContract.Imp! svmanager = AcquireServiceManager();
+
+ if (!SelectService(svmanager, serviceName))
+ return;
+
+ svmanager.SendEnableService(enabled);
+ switch receive {
+ case svmanager.Ok():
+ Dbg("Service Manager accepted request to enable/disable service.");
+ break;
+
+ case svmanager.RequestFailed(error):
+ Dbg("Service Manager FAILED request to enable/disable service: " + ServiceEnums.ToString(error));
+ break;
+ }
+
+ svmanager.SendUnselectService();
+
+ ReleaseServiceManager(svmanager);
+ }
+
+ void RootPageHandler(IHttpRequest! request)
+ {
+ Dbg("RootPageHandler running");
+
+ //
+ // If the user clicked one of the state-control buttons, then check to see which one.
+ // Perform the requested action, then redirect to this page. This prevents the
+ // browser from interpreting "refresh" as "post the data again".
+ //
+ string! verb = request.GetVerb();
+ if (verb == "POST") {
+ // User clicked one of our buttons.
+ Dbg("Verb is POST, user probably clicked a control button");
+ RequestFormData! data = GetFormData(request);
+
+ string! serviceName = data["ServiceName"];
+ Dbg("Service name from form: " + serviceName);
+
+ if (serviceName == "") {
+ Dbg("Service name is empty!");
+ }
+
+ if (data.IsSet("StartService")) {
+ StartService(serviceName);
+ }
+ else if (data.IsSet("StopService")) {
+ StopService(serviceName);
+ }
+ else if (data.IsSet("DisableService")) {
+ EnableService(serviceName, false);
+ }
+ else if (data.IsSet("EnableService")) {
+ EnableService(serviceName, false);
+ }
+ else {
+ Dbg("Request did not contain a recognized control action.");
+ }
+
+ Dbg("Redirecting client");
+ request.SendStatus(303, "See Other");
+ request.SendHeader(HttpHeader.RedirectLocation, "/");
+ return;
+ }
+
+ request.SendStatus(200, "OK");
+ request.SendHeader(HttpHeader.Refresh, "5"); // refresh every N seconds
+
+
+ ResponseWrite(request,
+@"
+
+Singularity Service Manager
+
+
+
+");
+
+ ResponseWrite(request, "Services
\r\n");
+
+ ServiceManagerContract.Imp! svmanager = AcquireServiceManager();
+
+ try {
+
+ ServiceInfo[]! in ExHeap first_infos = new[ExHeap] ServiceInfo[40];
+
+ svmanager.SendEnumerateServices(first_infos);
+
+ string![]! columns = {
+ "Service Name", // 0
+ // "Display Name", //
+ // "Executable", //
+ "Activation Mode", // 1
+ "State", // 2
+ "Process ID", // 3
+ "Actions" // 4
+ };
+
+ string[] cells = new string[columns.Length];
+
+ ResponseWriteLine(request, "\r\n");
+ for (int i = 0; i < columns.Length; i++) {
+ string! column = columns[i];
+ ResponseWrite(request, column);
+ if (i + 1 < columns.Length)
+ ResponseWrite(request, " | ");
+ }
+ ResponseWriteLine(request, " |
");
+
+ for (;;) {
+
+ ServiceInfo[]! in ExHeap infos;
+ bool more;
+ int count;
+
+ switch receive {
+ case svmanager.NextServiceInfo(returned_infos, c):
+ infos = returned_infos;
+ count = c;
+ more = true;
+ break;
+
+ case svmanager.EnumerationTerminated(returned_infos, c):
+ infos = returned_infos;
+ more = false;
+ count = c;
+ break;
+
+ case timeout(TimeSpan.FromSeconds(30)):
+ ResponseWriteLine(request, "Error: Timeout occurred while waiting to receive data from Service Manager.
");
+ goto done;
+ }
+
+ if (count > 0) {
+
+ for (int i = 0; i < count; i++) {
+ expose(infos[i]) {
+ string! serviceName = Bitter.ToString2(infos[i].Config.ServiceName);
+ //string! displayName = Bitter.ToString2(infos[i].Config.DisplayName);
+ //string! executableName = Bitter.ToString2(infos[i].Config.ExecutableName);
+ string! activationMode = ServiceEnums.ToString(infos[i].Config.ActivationMode);
+
+ int c = 0;
+ cells[c++] = serviceName;
+ // cells[c++] = displayName;
+ // cells[c++] = executableName;
+ cells[c++] = activationMode;
+ cells[c++] = ServiceEnums.ToString(infos[i].Status.State);
+ cells[c++] = infos[i].Status.ProcessId.ToString();
+
+ StringBuilder! actions = new StringBuilder();
+
+ bool start_stop_applies =
+ infos[i].Config.ActivationMode == ServiceActivationMode.Manual
+ || infos[i].Config.ActivationMode == ServiceActivationMode.Demand;
+ ServiceState svstate = infos[i].Status.State;
+
+ bool disabled = infos[i].Config.IsAdministrativelyDisabled;
+ bool can_start = start_stop_applies && svstate == ServiceState.Stopped && !disabled;
+ bool can_stop = start_stop_applies && (svstate == ServiceState.Running || svstate == ServiceState.Starting) && !disabled;
+
+ actions.Append("\r\n");
+
+ cells[c++] = actions.ToString();
+ }
+
+ ResponseWrite(request, "");
+ for (int j = 0; j < cells.Length; j++) {
+ string cell = cells[j];
+ if (cell == null)
+ cell = "";
+ ResponseWrite(request, cell);
+
+ if (j + 1 < cells.Length)
+ ResponseWrite(request, " | ");
+ }
+
+ ResponseWriteLine(request, " |
");
+ }
+ }
+
+ if (more) {
+ svmanager.SendEnumerateServices(infos);
+ }
+ else {
+ delete infos;
+ break;
+ }
+ }
+
+ done:
+ ResponseWriteLine(request, "
");
+
+ }
+ finally {
+ ReleaseServiceManager(svmanager);
+ }
+ }
+
+ static string! MakeServiceControlButton(string! action, string! label, bool enabled)
+ {
+ return String.Format("\r\n", action, label,
+ enabled ? "" : " disabled");
+
+ }
+
+ DirectoryServiceContract.Imp! AcquireDirectory()
+ {
+ return rootdsRef.Acquire();
+ }
+
+ void ReleaseDirectory([Claims]DirectoryServiceContract.Imp! rootds)
+ {
+ rootdsRef.Release(rootds);
+ }
+
+ void SendFile(IHttpRequest! request, string! path, string! contentType)
+ {
+ FileContract.Imp! file;
+ FileContract.Exp! file_exp;
+ FileContract.NewChannel(out file, out file_exp);
+
+ DirectoryServiceContract.Imp! rootds = AcquireDirectory();
+ ErrorCode error;
+ if (!SdsUtils.Bind(path, rootds, file_exp, out error)) {
+ delete file;
+
+ ReleaseDirectory(rootds);
+
+ string! errorText = SdsUtils.ErrorCodeToString(error);
+ request.SendStatus(400, errorText);
+ request.SendHeader(HttpHeader.ContentType, ContentType.TextHtmlUtf8);
+
+ StringBuilder! html = new StringBuilder();
+ html.Append("Error - ");
+ html.Append(errorText);
+ html.Append("Error
");
+ html.AppendFormat("The file '{0}' could not be opened.
", path);
+ html.Append("Error: ");
+ html.Append(errorText);
+ html.Append("
");
+ html.Append("