Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / tests / bug-10127.cs
1 using System;
2 using System.Threading;
3 using System.Collections.Generic;
4 using System.Runtime.InteropServices;
5
6 namespace WeakReferenceTest
7 {
8         public static class Cache {
9                 static GCHandle[] table = new GCHandle[1024 * 1024];
10
11                 public static T Probe<T>(int hc) where T : class
12                 {
13                         int index = hc & (table.Length - 1);
14                         lock (table)
15                         {
16                                 var wr = table[index];
17                                 if (!wr.IsAllocated)
18                                         return null;
19                                 return wr.Target as T;
20                         }
21                 }
22
23                 public static T Add<T>(T obj, int hc) where T : class 
24                 {
25                         int index = hc & (table.Length - 1);
26                         lock (table)
27                         {
28                                 table[index] = GCHandle.Alloc (obj, GCHandleType.Weak);
29                         }
30                         return obj;
31                 }
32
33         }
34
35         public class Tester {
36                 public static readonly int seed = unchecked(DateTime.Now.Ticks.GetHashCode());
37
38                 Random rand = new Random(seed);
39
40                 bool alive;
41                 Thread thread;
42
43                 public void Start()
44                 {
45                         alive = true;
46                         thread = new Thread(new ThreadStart(Work));
47                         thread.Start();
48                 }
49
50                 void Work()
51                 {
52                         do {
53
54                                 var item = rand.Next ();
55                                 var probed = Cache.Probe<object>(item.GetHashCode());
56
57                                 if (probed == null) {
58                                         Cache.Add<object>(item, item.GetHashCode());
59                                 }
60
61                                 if (rand.NextDouble() <= 0.1) {
62                                         GC.Collect();
63                                 }
64
65                         } while (alive);
66                 }
67
68                 public void Stop ()
69                 {
70                         alive = false;
71                 }
72
73         }
74
75         static class RandHelper {
76                 public static string RandString(this Random rand, int len)
77                 {
78                         char[] table = new char[len];
79                         for (int idx = 0; idx < len; idx++) {
80                                 table[idx] = (char) ('a' + idx);
81                         }
82                         return new string(table, 0, len);
83                 }
84         }
85
86         class MainClass
87         {
88                 public static void Main (string[] args)
89                 {
90                         Console.WriteLine("Starting cache testers");
91                         Console.WriteLine("Thread seed: " + Tester.seed);
92                         List<Tester> testers = new List<Tester>();
93                         for (int count = 0; count < 10; count++) {
94                                 testers.Add(new Tester());
95                         }
96
97                         foreach (var tester in testers) {
98                                 tester.Start();
99                         }
100
101                         for (int i = 0; i < 4; ++i)
102                         {
103                                 Thread.Sleep(TimeSpan.FromSeconds(1));
104                         }
105
106                         foreach (var tester in testers)
107                         {
108                                 tester.Stop ();
109                         }
110                 }
111         }
112 }