Exemple #1
0
 /// <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();
 }
Exemple #2
0
        /// <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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
 /// <summary>
 /// Ensures the current value is accessible to all threads.
 /// </summary>
 public void Release()
 {
     Locker.Release();
 }
Exemple #5
0
        /// <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);
        }