using Aitex.Core.Common; using Aitex.Core.RT.Log; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Jobs; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.SubstrateTrackings; using PunkHPX8_RT.Modules; using PunkHPX8_RT.Schedulers; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Markup; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.ToolLayout; using PunkHPX8_RT.Devices.EFEM; using Aitex.Core.RT.Device; using MECF.Framework.RT.Core.Equipments; namespace PunkHPX8_RT.Dispatch { public class WaferTaskManager : Singleton { #region 常量 private const string SIDE_A = "SideA"; private const string SIDE_B = "SideB"; #endregion #region 内部变量 /// /// FA回复 /// private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback(); /// /// 任务锁 /// private object _taskLocker = new object(); /// /// 任务集合 /// private List _waferTaskList = new List(); /// /// Wafer task字典 /// private ConcurrentDictionary _waferTasksDic = new ConcurrentDictionary(); /// /// Wafer配对字典(key-自身WaferId,value-配对WaferId) /// private ConcurrentDictionary _waferTaskMatchDic = new ConcurrentDictionary(); #endregion /// /// 初始化Task /// /// public void InitializeTask(WaferTask task) { _waferTasksDic[task.WaferId] = task; lock(_taskLocker) { _waferTaskList.Add(task); } } /// /// 获取WaferTask /// /// /// public WaferTask GetWaferTask(string waferId) { return _waferTasksDic.ContainsKey(waferId) ? _waferTasksDic[waferId] : null; } /// /// 是否包含 /// /// /// public bool Contains(string waferId) { return _waferTasksDic.ContainsKey(waferId); } /// /// 移除任务 /// /// public void RemoveWaferTask(string waferId) { if(_waferTasksDic.ContainsKey(waferId)) { _waferTasksDic.TryRemove(waferId, out var task); task.Dispose(); task.OnTaskComplete -= WaferTask_OnTaskComplete; LOG.WriteBackgroundLog(eEvent.EV_SCHEDULER, "Scheduler", $"remove wafer {waferId} task"); } if(_waferTaskMatchDic.ContainsKey(waferId)) { _waferTaskMatchDic.TryRemove(waferId,out var taskMath); } lock(_taskLocker) { int index = _waferTaskList.FindIndex(O => O.WaferId == waferId); if (index >= 0) { _waferTaskList.RemoveAt(index); } } } /// /// 加载Wafer Task集合 /// /// public List LoadWaferTaskList() { return _waferTaskList.ToList(); } /// /// 检验是否可以创建Wafer Task /// /// public bool CheckEnableCreateWaferTask() { lock (_taskLocker) { if (_waferTaskList.Count == 0) { return true; } if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0)) { return false; } foreach (WaferTask item in _waferTaskList) { //Wafer还未离开Aligner if (item.CurrentSequenceIndex <= 1) { return false; } } return true; } } /// /// 获取下一个执行的ProcessJob /// /// /// private ProcessJobInfo GetNextProcessJob(List jobs, List executedPPids) { try { bool isRunInParallelMode = SC.GetValue("Scheduler.IsRunInParallelMode"); if (!isRunInParallelMode) { return jobs[0]; } else { if (_waferTaskList.Count == 0) { return jobs[0]; } WaferTask lastWaferTask = _waferTaskList[_waferTaskList.Count - 1]; string lastSequence = lastWaferTask.ProcessJobInfo.SequenceRecipe?.Ppid; List lastSamePjs = new List(); List otherPjs = new List(); int lastIndex = jobs.FindIndex(O => O.SequenceRecipe?.Ppid == lastSequence); int nextIndex = (lastIndex == -1 || lastIndex >= jobs.Count - 1) ? 0 : lastIndex + 1; for (int i = nextIndex; i < jobs.Count; i++) { ProcessJobInfo processJobInfo = jobs[i]; if (processJobInfo.SequenceRecipe?.Ppid == lastSequence) { lastSamePjs.Add(processJobInfo); continue; } if (executedPPids.Contains(processJobInfo.SequenceRecipe?.Ppid)) { continue; } return processJobInfo; } for (int i = 0; i < lastIndex; i++) { ProcessJobInfo processJobInfo = jobs[i]; if (processJobInfo.SequenceRecipe?.Ppid == lastSequence) { lastSamePjs.Add(processJobInfo); continue; } if (executedPPids.Contains(processJobInfo.SequenceRecipe?.Ppid)) { continue; } return processJobInfo; } if (lastSamePjs.Count != 0) { return lastSamePjs[0]; } return jobs[0]; } } catch { return jobs[0]; } } /// /// 创建Wafer任务 /// public void CreateWaferTask(List processJobInfos) { int count = 0; string mateWaferTask = ""; List wafers = new List(); if (processJobInfos.Count == 0) { return; } List excludes = new List(); ProcessJobInfo processJob = GetNextProcessJob(processJobInfos, excludes); if (processJob == null) { return; } for(int i=0; i= 2) { CreateWaferTaskSchedulerSequence(wafers[0], sequenceRecipe, ""); mateWaferTask = wafers[0].WaferID; CreateWaferTaskSchedulerSequence(wafers[1], sequenceRecipe,mateWaferTask); _waferTaskMatchDic[wafers[0].WaferID] = wafers[1].WaferID; _waferTaskMatchDic[wafers[1].WaferID] = wafers[0].WaferID; } } /// /// 获取Dummy Wafer /// /// /// private WaferInfo GetDummyWafer(int waferSize) { List dummmys= DummyCasseteItemManager.Instance.InstalledModules; foreach(string item in dummmys) { if (Enum.TryParse(item, out ModuleName dummyModule)) { DummyDevice dummyDevice= Singleton.Instance.EFEM.GetDummyDevice(dummyModule - ModuleName.Dummy1); if ((int)dummyDevice.WaferSize != waferSize) { continue; } int maxSlot = dummyDevice.MaxSlotNumber; for (int i = 0; i < maxSlot; i++) { if (WaferManager.Instance.CheckHasWafer(item, i)) { return WaferManager.Instance.GetWafer(dummyModule, i); } } } } return null; } /// /// 创建WaferTask SchedulerSequence /// /// /// /// /// private void CreateWaferTaskSchedulerSequence(WaferInfo waferInfo, SequenceRecipe sequenceRecipe, string mateWafeTask) { List sequences = SchedulerSequenceManager.Instance.AnalyWaferAllSchedulerSequence(waferInfo,sequenceRecipe); WaferTask waferTask = new WaferTask(waferInfo, sequences); if (!string.IsNullOrEmpty(mateWafeTask)) { waferTask.MateWaferTask = mateWafeTask; } waferTask.OnTaskComplete += WaferTask_OnTaskComplete; LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create wafer {waferInfo.WaferID} task"); InitializeTask(waferTask); } /// /// 创建Dummy Wafer Task 调度工序 /// /// /// /// private void CreateDummyWaferTaskSchedulerSequence(SequenceRecipe sequenceRecipe,WaferInfo waferInfo,string mateWaferTask) { List sequences = SchedulerSequenceManager.Instance.AnalyDummyWaferAllSchedulerSequence(sequenceRecipe,waferInfo); WaferTask waferTask = new WaferTask(waferInfo,sequences); if (!string.IsNullOrEmpty(mateWaferTask)) { waferTask.MateWaferTask = mateWaferTask; } LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create Dummy wafer {waferInfo.WaferID} task"); waferTask.OnTaskStart += WaferTask_OnTaskStart; waferTask.OnTaskComplete += WaferTask_OnTaskComplete; InitializeTask(waferTask); } /// /// 任务开始 /// /// /// private void WaferTask_OnTaskStart(string id) { WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(id); if (waferInfo != null && waferInfo.WaferType == WaferType.Production) { ModuleName moduleName = (ModuleName)waferInfo.OriginStation; if (ModuleHelper.IsLoadPort(moduleName)) { CycleManager.Instance.UpdateCycleWaferCount(moduleName.ToString()); } _schedulerFACallback.JobWaferStart(JobProcesser.Instance.GetControlJobInfoByProcessJob(waferInfo.ProcessJob), waferInfo.SequenceName, waferInfo.OriginSlot); } } /// /// Wafer task完成事件 /// /// private void WaferTask_OnTaskComplete(string id) { WaferInfo waferInfo=WaferManager.Instance.GetWaferByWaferId(id); if (waferInfo != null&&waferInfo.WaferType==WaferType.Production) { ModuleName moduleName = (ModuleName)waferInfo.OriginStation; if (ModuleHelper.IsLoadPort(moduleName)) { CycleManager.Instance.UpdateCycleWaferCount(moduleName.ToString()); } _schedulerFACallback.JobWaferEnd(JobProcesser.Instance.GetControlJobInfoByProcessJob(waferInfo.ProcessJob), waferInfo.SequenceName, waferInfo.OriginSlot); } RemoveWaferTask(id); } /// /// 检验所有task是否完成 /// /// public bool CheckAllTaskComplete() { return _waferTaskList.Count == 0; } /// /// 暂停 /// public void PauseAllTask() { List waferTasks = _waferTaskList.ToList(); foreach(WaferTask item in waferTasks) { item.Pause(); } } /// /// 恢复所有任务 /// public void ResumeAllTask() { List waferTasks = _waferTaskList.ToList(); foreach (WaferTask item in waferTasks) { item.Resume(); } } /// /// 恢复所有任务 /// public void RemoveAllTask() { List waferTasks = _waferTaskList.ToList(); foreach (WaferTask item in waferTasks) { RemoveWaferTask(item.WaferId); } } /// /// 根据WaferId获取配对另一个WaferId /// /// /// public string GetMatchWaferIdByWaferId(string waferId) { return _waferTaskMatchDic.ContainsKey(waferId) ? _waferTaskMatchDic[waferId] : ""; } /// /// 检验Wafer存在匹配的wafer任务(wafer是单片任务还是双片任务) /// /// /// public string CheckWaferHasMatch(string waferId) { if (_waferTaskMatchDic.ContainsKey(waferId)) { return _waferTaskMatchDic[waferId]; } else { return ""; } } } }