public void ContinueWaiters(RCRunner runner, Dictionary <long, RCClosure> all) { if (all != null) { foreach (RCClosure waiter in all.Values) { runner.Continue(null, waiter); } } }
public void Untake(RCRunner runner, RCClosure head) { if (head == null) { throw new Exception("Head closure was missing."); } if (head.Locks == null) { throw new Exception( "There were supposed to be locks on this closure."); } lock (_takeLock) { // Free all of the locks. for (int i = 0; i < head.Locks.Count; ++i) { _takeSymbols.Remove(head.Locks[i]); } // List of all fibers waiting for any of the symbols just released. HashSet <long> candidates = new HashSet <long> (); for (int i = 0; i < head.Locks.Count; ++i) { HashSet <long> waiters; if (_takeFibers.TryGetValue(head.Locks[i], out waiters)) { candidates.UnionWith(waiters); } } // Go through the waiters in the order they came in. // Can any of them go now? for (int i = 0; i < _takeOrder.Count; ++i) { RCClosure candidate = _takeOrder[i]; if (TryGetLocks(candidate)) { // A Little ineffecient but whatevs. // In MapQueue I used a queue instead of a list to avoid the O(n) removals. // This makes the overall algorithm linear instead of quadratic. _takeOrder.RemoveAt(i); runner.Continue(null, candidate); break; } } } }
public void DoTake(RCRunner runner, RCClosure closure, RCSymbol symbols, RCValue section) { RCClosure next = new RCClosure(closure.Bot, closure.Fiber, symbols, closure, section, closure.Left, closure.Parent != null ? closure.Parent.Result : null, 0, closure.UserOp, closure.UserOpContext, noClimb: false, noResolve: false); lock (_takeLock) { if (TryGetLocks(next)) { // Start evaluating the critical section. runner.Continue(null, next); } else { // Record the order in which the waiters arrived. _takeOrder.Add(next); // Remember that we want the lock when the other guy releases it. for (int i = 0; i < symbols.Count; ++i) { HashSet <long> fibers; if (!_takeFibers.TryGetValue(symbols[i], out fibers)) { fibers = new HashSet <long> (); _takeFibers[symbols[i]] = fibers; } fibers.Add(closure.Fiber); } } } }