/// <summary> /// Keeps trying to do a task, blocking until a worker is /// available. /// </summary> public void DoTaskASAP(IKernelTask task) { while (DoTask(task) == false) { BlockUntilFreeWorker(500); } }
/// <summary> /// Adds a schedulable task to the work queue, optionally with /// the maximum time we can wait for the task to be processed. /// If not set, the default latency for the type of task is used. /// </summary> public void Add(IKernelTask task, int maxMsec = -1) { if (maxMsec < 0) { maxMsec = task.ExpectedLatencyMsec; } _workQueue.Enqueue(task, maxMsec); }
/// <summary> /// Gives the task to a worker that isn't doing anything, /// returnning null if all workers are busy. /// </summary> public bool DoTask(IKernelTask task) { lock (_workLock) { for (var i = 0; i < _threads.Length; i++) { if (_work[i] == null) { lock (_newWorkSignal) { _work[i] = task; Monitor.PulseAll(_newWorkSignal); } return(true); } } } return(false); }
/// <summary> /// Creates the workers and work slots to match the number /// of available processors. /// </summary> public WorkerThreads() { #if FORCE_SINGLETHREADED var count = 1; #warning KERNEL FORCED TO SINGLE THREADED MODE! #else var count = Environment.ProcessorCount * 2; // TESTING WITH 4 THREADS PER CORE... TODO: fix the deadlocks instead #endif // create the real time thread _realTimeWork = new RealTimeQueue <IKernelTask>(); _realTimeThread = new Thread(RealTimeThreadMain); // create empty standard work load _work = new IKernelTask[count]; for (var i = 0; i < count; i++) { _work[i] = null; } //start up the threads _threads = new Thread[count]; Start(); }
/// <summary> /// Adds a task to the real-time queue instead of the standard /// work queue to be executed at an exact time. This should be /// used sparingly as only one real-time task runs at a time, /// and should only be used when something needs to go out at /// an EXACT time, such as MIDI clock signals. /// </summary> public void Add(IKernelTask task, DateTime executeAtUTC) { _workers.AddRealTimeTask(task, executeAtUTC); }
/// <summary> /// Adds a task for the real time worker. /// </summary> public void AddRealTimeTask(IKernelTask task, DateTime executeUTC) { _realTimeWork.Enqueue(task, executeUTC); }