PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Applications/Tests/SharedHeapTest/SharedHeapTest.cs

#
C# | 349 lines | 223 code | 58 blank | 68 comment | 27 complexity | fd251452151c92c34d0f0c778c2e2cc3 MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // Note: User-mode test program for calling shared heap through the ABI.
  8. //
  9. using Microsoft.Singularity.V1.Services;
  10. using System;
  11. using System.Runtime.CompilerServices;
  12. using System.Threading;
  13. using Microsoft.Singularity.Channels;
  14. using Microsoft.Contracts;
  15. using Microsoft.SingSharp.Reflection;
  16. using Microsoft.Singularity.Applications;
  17. using Microsoft.Singularity.Io;
  18. using Microsoft.Singularity.Configuration;
  19. [assembly: Transform(typeof(ApplicationResourceTransform))]
  20. namespace Microsoft.Singularity.Applications
  21. {
  22. [ConsoleCategory(DefaultAction=true)]
  23. internal class Parameters {
  24. [InputEndpoint("data")]
  25. public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
  26. [OutputEndpoint("data")]
  27. public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
  28. reflective internal Parameters();
  29. internal int AppMain() {
  30. SharedHeapTest.AppMain(this);
  31. return 0;
  32. }
  33. }
  34. unsafe public class SharedHeapTest
  35. {
  36. //
  37. // Note: The integrity check relies on there being one bit in each byte
  38. // to represent the owning concurrent allocation slot, so the number of
  39. // concurrent allocations can't exceed 8.
  40. //
  41. private const uint ConcurrentAllocations = 8;
  42. private SharedHeapService.Allocation*[]! mem;
  43. Random! random = new Random();
  44. internal static void AppMain(Parameters! config)
  45. {
  46. SharedHeapTest test = new SharedHeapTest();
  47. uint Iterations = 10;
  48. Console.WriteLine("Starting Shared Heap Test\n");
  49. test.StartUp();
  50. for (uint loop = 0; loop < Iterations; loop++) {
  51. test.Perturb();
  52. if (test.Check() == false) {
  53. break;
  54. }
  55. }
  56. }
  57. private SharedHeapTest() {
  58. //
  59. // Create an array to hold our concurrent allocations.
  60. //
  61. this.mem = new SharedHeapService.Allocation*[ConcurrentAllocations];
  62. }
  63. public static void Usage()
  64. {
  65. Console.WriteLine("Usage: sharedheap [Iterations]\n");
  66. }
  67. public void StartUp()
  68. {
  69. //
  70. // Allocating a bunch of randomly sized things.
  71. //
  72. for (uint loop = 0; loop < ConcurrentAllocations; loop++) {
  73. AllocRandomSizedThingy(loop);
  74. if (CheckForValue(loop, 0) == true) {
  75. Console.WriteLine("Passed zero-fill test.\n");
  76. }
  77. else {
  78. Console.WriteLine("Failed zero-fill test.\n");
  79. }
  80. FillWithValue(loop, (byte)(1 << (int)loop));
  81. }
  82. }
  83. public bool Check()
  84. {
  85. //
  86. // Check all allocations for expected bit settings.
  87. //
  88. Console.WriteLine("--------\n");
  89. Console.WriteLine("Integrity Check\n");
  90. for (uint loop = 0; loop < ConcurrentAllocations; loop++) {
  91. if (CheckBits(loop, (byte)(1 << (int)loop)) == false) {
  92. return false;
  93. }
  94. }
  95. Console.WriteLine("--------\n");
  96. return true;
  97. }
  98. public void Perturb()
  99. {
  100. //
  101. // Pick an element slot to use and an action to take.
  102. //
  103. uint which = (uint)random.Next(ConcurrentAllocations);
  104. uint action = (uint)random.Next(3);
  105. //
  106. // Free up the slot.
  107. //
  108. Console.WriteLine("--------\n");
  109. Console.WriteLine(
  110. "Freeing region: Data = {0}, Size = {1}.\n",
  111. SharedHeapService.GetData(this.mem[which]),
  112. SharedHeapService.GetSize(this.mem[which]));
  113. ClearBits(which, (byte)(1 << (int)which));
  114. SharedHeapService.Free(this.mem[which]);
  115. Console.WriteLine("--------\n");
  116. //
  117. // Play around.
  118. //
  119. switch (action) {
  120. case 0:
  121. //
  122. // Allocate something new.
  123. //
  124. Console.WriteLine("Allocation Test\n");
  125. AllocRandomSizedThingy(which);
  126. if (CheckForValue(which, 0) == true) {
  127. Console.WriteLine("Passed zero-fill test.\n");
  128. }
  129. else {
  130. Console.WriteLine("Failed zero-fill test.\n");
  131. }
  132. //
  133. // Store bit corresponding to slot number in each
  134. // data byte. Used to check integrity later.
  135. //
  136. FillWithValue(which, (byte)(1 << (int)which));
  137. break;
  138. case 1:
  139. //
  140. // Split an element in two. Use the slot we freed
  141. // up above to hold the split-off piece.
  142. //
  143. Console.WriteLine("Split Test\n");
  144. //
  145. // Pick a region to split.
  146. //
  147. uint split;
  148. do {
  149. split = (uint)random.Next(ConcurrentAllocations);
  150. } while (split == which);
  151. Console.Write(
  152. "Splitting region: Data = {0}, Size = {1}",
  153. SharedHeapService.GetData(this.mem[split]),
  154. SharedHeapService.GetSize(this.mem[split]));
  155. UIntPtr offset = (UIntPtr)random.Next(
  156. 1,
  157. (int)SharedHeapService.GetSize(this.mem[split]));
  158. Console.WriteLine(" in two at offset {0}.\n", offset);
  159. this.mem[which] = SharedHeapService.Split(
  160. this.mem[split],
  161. offset);
  162. Console.WriteLine(
  163. "Revised region: Data = {0}, Size = {1}.\n",
  164. SharedHeapService.GetData(this.mem[split]),
  165. SharedHeapService.GetSize(this.mem[split]));
  166. Console.WriteLine(
  167. "New region: Data = {0}, Size = {1}.\n",
  168. SharedHeapService.GetData(this.mem[which]),
  169. SharedHeapService.GetSize(this.mem[which]));
  170. //
  171. // Remove bit corresponding to the slot of the original
  172. // region from the split-off data. Likewise, add the
  173. // bit corresponding to the slot number of the split-off
  174. // region to the split-off data.
  175. //
  176. ClearBits(which, (byte)(1 << (int)split));
  177. SetBits(which, (byte)(1 << (int)which));
  178. break;
  179. case 2:
  180. //
  181. // Share part of a region. Use the slot we freed
  182. // up above to hold the shared piece.
  183. //
  184. Console.WriteLine("Share Test\n");
  185. //
  186. // Pick a region to share.
  187. //
  188. uint share;
  189. do {
  190. share = (uint)random.Next(ConcurrentAllocations);
  191. } while (share == which);
  192. Console.Write(
  193. "Sharing region: Data = {0}, Size = {1}",
  194. SharedHeapService.GetData(this.mem[share]),
  195. SharedHeapService.GetSize(this.mem[share]));
  196. UIntPtr start = (UIntPtr)random.Next(
  197. 1,
  198. (int)SharedHeapService.GetSize(this.mem[share]));
  199. Console.WriteLine(" starting at offset {0}.\n", start);
  200. this.mem[which] = SharedHeapService.Share(
  201. this.mem[share],
  202. start, SharedHeapService.GetSize(this.mem[share]));
  203. Console.WriteLine(
  204. "Original region: Data = {0}, Size = {1}.\n",
  205. SharedHeapService.GetData(this.mem[share]),
  206. SharedHeapService.GetSize(this.mem[share]));
  207. Console.WriteLine(
  208. "New region: Data = {0}, Size = {1}.\n",
  209. SharedHeapService.GetData(this.mem[which]),
  210. SharedHeapService.GetSize(this.mem[which]));
  211. //
  212. // Modify each data byte in the shared region to include
  213. // the bit corresponding to the slot number of the new
  214. // shared allocation handle.
  215. //
  216. SetBits(which, (byte)(1 << (int)which));
  217. break;
  218. }
  219. }
  220. private void AllocRandomSizedThingy(uint index)
  221. {
  222. // REVIEW: We can't ask the system for the PageSize?
  223. // Hardcoded to 2 * Pages.PageSize.
  224. UIntPtr size = (UIntPtr)random.Next(1, 8192);
  225. this.mem[index] = SharedHeapService.Allocate(size, typeof(byte).GetSystemType(), 0);
  226. Console.WriteLine("Allocated region: Data = {0}, Size = {1}.\n",
  227. SharedHeapService.GetData(this.mem[index]),
  228. SharedHeapService.GetSize(this.mem[index]));
  229. }
  230. private void FillWithValue(uint index, byte value)
  231. {
  232. UIntPtr data = SharedHeapService.GetData(this.mem[index]);
  233. UIntPtr size = SharedHeapService.GetSize(this.mem[index]);
  234. for (UIntPtr address = data; address < data + size; address++) {
  235. *(byte *)address = value;
  236. }
  237. return;
  238. }
  239. private bool CheckForValue(uint index, byte value)
  240. {
  241. UIntPtr data = SharedHeapService.GetData(this.mem[index]);
  242. UIntPtr size = SharedHeapService.GetSize(this.mem[index]);
  243. bool status = true;
  244. for (UIntPtr address = data; address < data + size; address++) {
  245. if (*(byte *)address != value) {
  246. status = false;
  247. Console.Write("Wrong value {0} at address {1}.\n",
  248. *(byte *)address, address);
  249. Console.Write("Should be {0}.\n", value);
  250. }
  251. }
  252. return status;
  253. }
  254. private void SetBits(uint index, byte bit)
  255. {
  256. UIntPtr data = SharedHeapService.GetData(this.mem[index]);
  257. UIntPtr size = SharedHeapService.GetSize(this.mem[index]);
  258. for (UIntPtr address = data; address < data + size; address++) {
  259. *(byte *)address |= bit;
  260. }
  261. return;
  262. }
  263. private void ClearBits(uint index, byte bit)
  264. {
  265. UIntPtr data = SharedHeapService.GetData(this.mem[index]);
  266. UIntPtr size = SharedHeapService.GetSize(this.mem[index]);
  267. for (UIntPtr address = data; address < data + size; address++) {
  268. *(byte *)address &= (byte)~bit;
  269. }
  270. return;
  271. }
  272. private bool CheckBits(uint index, byte bit)
  273. {
  274. UIntPtr data = SharedHeapService.GetData(this.mem[index]);
  275. UIntPtr size = SharedHeapService.GetSize(this.mem[index]);
  276. bool status = true;
  277. for (UIntPtr address = data; address < data + size; address++) {
  278. if ((*(byte *)address & bit) != bit) {
  279. status = false;
  280. Console.WriteLine("Bad value {0} at address {1}.\n",
  281. *(byte *)address, address);
  282. //
  283. // Stop at one to prevent huge output.
  284. //
  285. break;
  286. }
  287. }
  288. return status;
  289. }
  290. }
  291. }