/// <summary> /// Get the lock. If taken the current thread will enter a queue for the lock. /// </summary> public virtual void TakeRead() { _lock.Take(); ReadLocked = true; ++_readCount; _lock.Release(); }
/// <summary> /// Return a task if there is one. /// </summary> public override bool Next(out ActionAct task) { // is the current task still running, has the needle been // paused or is the lock already taken? if (_paused || !_current.Ready || !_lock.TryTake) { // yes, return no task task = null; return(false); } // get the next task while (--_taskCount >= 0 && _tasks.Dequeue()) { if (!_tasks.Current.Remove) { _tasks.Enqueue(_tasks.Current); } // should the task be run? if (_tasks.Current.ToRun && _tasks.Current.Ready) { // set the current item task = _current = _tasks.Current; _current.Ready = false; _lock.Release(); return(true); } } // get the number of ticks since the last update _deltaTicks = Time.Timestamp - _lastDeltaTicks; _lastDeltaTicks += _deltaTicks; // no task _lock.Release(); // get the number of tasks to execute next iteration _taskCount = _tasks.Count; task = null; return(false); }
/// <summary> /// Return a task if there is one. /// </summary> public override bool Next(out ActionAct task) { // has the needle been paused or is the lock already taken? if (_paused) { // yes, return no task task = null; return(false); } // if currently running if (_running) { // try get the A side lock if (_lockA.TryTake) { var tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } if (_flip) { _flip = false; _lockB.Take(); _tasks.Flip(); _lockB.Release(); tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } } // return to wait for delta time _running = false; // release the a lock _lockA.Release(); } else { task = null; return(false); } } if (!_lockA.TryTake) { task = null; return(false); } // if delta is greater than target it's time for another loop of tasks if (Time.Timestamp >= _nextTimestamp) { // add the target number of ticks _nextTimestamp = _nextTimestamp + _targetTicks; // this is running _running = true; _flip = true; // log of target ticks vs actual // if(Delta == 1000) { // Log.D(System.Threading.Thread.CurrentThread.Name + " Offset " + (_nextTimestamp - _targetTicks - Time.Timestamp)); // } var tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } if (_flip) { _flip = false; _lockB.Take(); _tasks.Flip(); _lockB.Release(); tasks = _tasks.A; // get the next task while (tasks.Next() && !tasks.Loop) { if (tasks.Current.Remove) { tasks.RemoveCurrent(); tasks.Current.Remove = false; } task = tasks.Current; // should the task be run? if (task.ToRun && task.Ready) { _current = task; // set the current item task.Ready = false; _lockA.Release(); return(true); } } } _running = false; } // release the a lock _lockA.Release(); // no task return task = null; return(false); }
/// <summary> /// Ensures the current value is accessible to all threads. /// </summary> public void Release() { Locker.Release(); }
/// <summary> /// Return a task if there is one. /// </summary> public override bool Next(out ActionAct task) { // has the needle been paused? if (_paused) { // yes, return no task task = null; return(false); } // update the delta time if (_lock.TryTake) { Delta = (Time.Timestamp - _lastUpdate) / Time.Frequency; _lastUpdate = Time.Timestamp; _updateCount = 0; // get the next task while (_tasks.Dequeue(out task)) { // updating tasks is much less likely with dynamic needles if (!task.Remove) { // re-enqueue the task _tasks.Enqueue(task); // should the task be run? if (task.ToRun && task.Ready) { // set the current item _lock.Release(); _current = task; task.Ready = false; return(true); } // does the number of update tasks equal the number of remaining // tasks? if (++_updateCount == _tasks.Count) { // yes, return _lock.Release(); return(false); } } // should the task be run? if (task.ToRun && task.Ready) { // set the current item _lock.Release(); _current = task; task.Ready = false; return(true); } } _lock.Release(); } task = null; return(false); }