New tests.
[mono.git] / mcs / class / corlib / System.Threading.Tasks / Internal / Scheduler.cs
1 #if NET_4_0 || BOOTSTRAP_NET_4_0
2 // Scheduler.cs
3 //
4 // Copyright (c) 2008 Jérémie "Garuma" Laval
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 // THE SOFTWARE.
23 //
24 //
25
26 using System;
27 using System.Collections.Concurrent;
28
29 namespace System.Threading.Tasks
30 {
31         internal class Scheduler: TaskScheduler, IScheduler
32         {
33                 IProducerConsumerCollection<Task> workQueue;
34                 ThreadWorker[]        workers;
35                 bool                  isPulsable = true;
36
37                 public Scheduler ()
38                         : this (Environment.ProcessorCount, 0, ThreadPriority.Normal)
39                 {
40                         
41                 }
42                 
43                 public Scheduler (int maxWorker, int maxStackSize, ThreadPriority priority)
44                 {
45                         workQueue = new ConcurrentQueue<Task> ();
46                         workers = new ThreadWorker [maxWorker];
47                         
48                         for (int i = 0; i < maxWorker; i++) {
49                                 workers [i] = new ThreadWorker (this, workers, workQueue, maxStackSize, priority);
50                         }
51                 }
52                 
53                 public void AddWork (Task t)
54                 {
55                         // Add to the shared work pool
56                         workQueue.TryAdd (t);
57                         // Wake up some worker if they were asleep
58                         PulseAll ();
59                 }
60                 
61                 public void ParticipateUntil (Task task)
62                 {
63                         if (AreTasksFinished (task))
64                                 return;
65                         
66                         ParticipateUntil (delegate {
67                                 return AreTasksFinished (task);
68                         });
69                 }
70                 
71                 public bool ParticipateUntil (Task task, Func<bool> predicate)
72                 {
73                         if (AreTasksFinished (task))
74                                 return false;
75                         
76                         bool isFromPredicate = false;
77                         
78                         ParticipateUntil (delegate {
79                                 if (predicate ()) {
80                                         isFromPredicate = true;
81                                         return true;
82                                 }
83                                 return AreTasksFinished (task); 
84                         });
85                                 
86                         return isFromPredicate;
87                 }
88                 
89                 // Called with Task.WaitAll(someTasks) or Task.WaitAny(someTasks) so that we can remove ourselves
90                 // also when our wait condition is ok
91                 public void ParticipateUntil (Func<bool> predicate)
92                 {       
93                         ThreadWorker.WorkerMethod (predicate, workQueue, workers);
94                 }
95                 
96                 public void PulseAll ()
97                 {
98                         if (isPulsable) {
99                                 foreach (ThreadWorker worker in workers) {
100                                         if (worker != null)
101                                                 worker.Pulse ();        
102                                 }
103                         }
104                 }
105                 
106                 public void InhibitPulse ()
107                 {
108                         isPulsable = false;
109                 }
110                 
111                 public void UnInhibitPulse () 
112                 {
113                         isPulsable = true;
114                 }
115
116                 public void Dispose ()
117                 {
118                         foreach (ThreadWorker w in workers) {
119                                 w.Dispose ();
120                         }
121                 }
122                 
123                 bool AreTasksFinished (Task parent)
124                 {
125                         return parent.IsCompleted;
126                 }
127
128                 #region Scheduler dummy stubs
129                 protected override System.Collections.Generic.IEnumerable<Task> GetScheduledTasks ()
130                 {
131                         throw new System.NotImplementedException();
132                 }
133
134                 protected internal override void QueueTask (Task task)
135                 {
136                         throw new System.NotImplementedException();
137                 }
138
139                 protected internal override bool TryDequeue (Task task)
140                 {
141                         throw new System.NotImplementedException();
142                 }
143
144                 protected override bool TryExecuteTaskInline (Task task, bool taskWasPreviouslyQueued)
145                 {
146                         throw new System.NotImplementedException();
147                 }
148                 
149                 public override int MaximumConcurrencyLevel {
150                         get {
151                                 return base.MaximumConcurrencyLevel;
152                         }
153                 }
154                 #endregion
155         }
156 }
157 #endif