Bringing C5 1.0 into the main branch.
[mono.git] / mcs / class / Mono.C5 / current / UserGuideExamples / Locking.cs
1 // C5 example: locking 2005-11-07\r
2 \r
3 // Compile with \r
4 //   csc /r:C5.dll Locking.cs \r
5 \r
6 using System;\r
7 using System.Threading;\r
8 using C5;\r
9 using SCG = System.Collections.Generic;\r
10 \r
11 namespace Locking {\r
12   class Locking {\r
13     static ArrayList<int> coll = new ArrayList<int>();\r
14     // static SCG.List<int> coll = new SCG.List<int>();\r
15     static readonly int count = 1000;\r
16 \r
17     public static void Main(String[] args) {\r
18       Console.WriteLine("Adding and removing without locking:");\r
19       RunTwoThreads(delegate { AddAndRemove(15000); });\r
20       Console.WriteLine("coll has {0} items, should be 0", coll.Count);\r
21 \r
22       coll = new ArrayList<int>();\r
23       Console.WriteLine("Adding and removing with locking:");\r
24       RunTwoThreads(delegate { SafeAddAndRemove(15000); });\r
25       Console.WriteLine("coll has {0} items, should be 0", coll.Count);\r
26 \r
27       Console.WriteLine("Moving items without locking:");\r
28       ArrayList<int> from, to;\r
29       from = new ArrayList<int>();\r
30       to = new ArrayList<int>();\r
31       for (int i=0; i<count; i++) \r
32         from.Add(i);\r
33       RunTwoThreads(delegate { while (!from.IsEmpty) Move(from, to); });\r
34       Console.WriteLine("coll has {0} items, should be {1}", to.Count, count);\r
35 \r
36       Console.WriteLine("Moving items with locking:");\r
37       from = new ArrayList<int>();\r
38       to = new ArrayList<int>();\r
39       for (int i=0; i<count; i++) \r
40         from.Add(i);\r
41       RunTwoThreads(delegate { while (!from.IsEmpty) SafeMove(from, to); });\r
42       Console.WriteLine("coll has {0} items, should be {1}", to.Count, count);\r
43     }\r
44 \r
45     public static void RunTwoThreads(Act run) {\r
46       Thread t1 = new Thread(new ThreadStart(run)),\r
47              t2 = new Thread(new ThreadStart(run));\r
48       t1.Start(); t2.Start();\r
49       t1.Join(); t2.Join();\r
50     }\r
51 \r
52     // Concurrently adding to and removing from an arraylist\r
53 \r
54     public static void AddAndRemove(int count) {\r
55       for (int i=0; i<count; i++) \r
56         coll.Add(i);\r
57       for (int i=0; i<count; i++)\r
58         coll.Remove(i);\r
59     }\r
60 \r
61     private static readonly Object sync = new Object();\r
62 \r
63     public static void SafeAddAndRemove(int count) {\r
64       for (int i=0; i<count; i++) \r
65         lock (sync)\r
66           coll.Add(i);\r
67       for (int i=0; i<count; i++)\r
68         lock (sync)\r
69           coll.Remove(i);\r
70     }\r
71 \r
72     public static void SafeAdd<T>(IExtensible<T> coll, T x) { \r
73       lock (sync) {\r
74         coll.Add(x);\r
75       }\r
76     }\r
77 \r
78     public static void Move<T>(ICollection<T> from, ICollection<T> to) { \r
79       if (!from.IsEmpty) {  \r
80         T x = from.Choose();\r
81         Thread.Sleep(0);        // yield processor to other threads\r
82         from.Remove(x);\r
83         to.Add(x);\r
84       }\r
85     }\r
86     \r
87     public static void SafeMove<T>(ICollection<T> from, ICollection<T> to) { \r
88       lock (sync) \r
89         if (!from.IsEmpty) {  \r
90           T x = from.Choose();\r
91           Thread.Sleep(0);      // yield processor to other threads\r
92           from.Remove(x);\r
93           to.Add(x);\r
94         }\r
95     }\r
96   }\r
97 }\r