internal void ExitCPUContext(ICPUContext CPUContext) { System.Diagnostics.Debug.Assert(CPUContext.IsCurrent()); ((CPUContext)CPUContext).Release(); // UnlockCPUでは、deleteしたCPUContextに対してEndDelaySuspendを // 呼んでしまうので、その手前の処理のみ実行。 int TlsLockCount = (int)m_TlsIndex.Value; TlsLockCount--; // ロック解除 if (TlsLockCount == 0) { m_SysSem.Release(); Interlocked.Decrement(ref m_Locked); } m_TlsIndex.Value = TlsLockCount; m_IntEvent.Set(); CPUContext.Exit(); }
public Task(ID TaskID, ref T_CTSK pk_ctsk, Nucleus pNucleus) { StaCD = null; m_TaskID = TaskID; m_ctsk = pk_ctsk; m_rtsk.exinf = m_ctsk.exinf; m_rtsk.tskpri = m_ctsk.itskpri; m_rtsk.tskstat = TSKSTAT.TTS_DMT; m_Nucleus = pNucleus; m_CPUContext = m_Nucleus.NewCPUContext(); m_ReleaseWait = false; }
public Task GetTask(ID tskid) { Task Result = null; Task Task; // 実行中のタスクの場合 if (tskid == ID.TSK_SELF) { #if false // カーネルでもタスクでもないスレッドから呼ばれた場合、この処理では実行中のタスクを返してしまう // 今実行しているスレッドと、実行中と設定されているタスクが同じ場合 if ((m_CurrentTask == null) || m_CurrentTask.GetCPUContext().IsCurrent()) { // 実行中と設定されているタスクを返す return(m_CurrentTask); } // 今実行しているスレッドと、実行中と設定されているタスクが違う場合 LockTaskTable(); try { // 今実行しているスレッドが、管理しているタスクの一つだった場合 for (int i = 0; i < m_TaskTable.Count; i++) { Task = m_TaskTable[i]; if (Task.GetCPUContext().IsCurrent()) { // m_CurrentTaskの設定ミスあり //System.Diagnostics.Debug.Assert(false); Result = Task; break; } } } finally { UnlockTaskTable(); } // m_CurrentTaskの設定にミスがなければカーネルモード扱い return(Result); #else ICPUContext context = m_Kernel.GetCurrent(); if (context == null) { return(null); } return(context.GetTask()); #endif } LockTaskTable(); try { // タスクID指定の場合 for (int i = 0; i < m_TaskTable.Count; i++) { Task = m_TaskTable[i]; if (tskid == Task.TaskID) { Result = Task; break; } } } finally { UnlockTaskTable(); } return(Result); }
void MainLoop() { int intNo; ID tskid; Task task; bool noIntr; Start(); m_Nucleus.Start(); do { ProcInterrupt(); do { noIntr = true; for (intNo = 0; intNo < m_InProcIntr.Length; intNo++) { if (IsTerminated()) return; if (InterruptEnabled(intNo)) { noIntr = false; ClearInterrupt(intNo); if (intNo == Nucleus.SysTmrIntNo) { m_Nucleus.OnSysTime(); } tskid = CallIntHandler(intNo); if (tskid != ID.TSK_NULL) { Task wTask; wTask = Nucleus.GetTask(tskid); if (wTask != null) { wTask.Wakeup(); } } } } } while (!noIntr); m_Nucleus.Scheduling(); task = m_Nucleus.GetScheduledTask(); if (task == null) { Idle(); } else { m_Current = (CPUContext)task.GetCPUContext(); task.Run(); m_Current.PopContext(); UnlockCPU(); m_TaskMode = true; if (!m_IntEvent.WaitOne()) { Terminate(); } m_TaskMode = false; LockCPU(); CPUContext CPUContext = (CPUContext)m_Current; m_Current = null; if (CPUContext.IsReleased()) { CPUContext.Wait(); CPUContext.ClearTask(); } else CPUContext.PushContext(); } task = m_Nucleus.GetCurrentTask(); if (task != null) { task.Ready(); } } while (!IsTerminated()); }
void MainLoop() { int intNo; ID tskid; Task task; bool noIntr; Start(); m_Nucleus.Start(); do { ProcInterrupt(); do { noIntr = true; for (intNo = 0; intNo < m_InProcIntr.Length; intNo++) { if (IsTerminated()) { return; } if (InterruptEnabled(intNo)) { noIntr = false; ClearInterrupt(intNo); if (intNo == Nucleus.SysTmrIntNo) { m_Nucleus.OnSysTime(); } tskid = CallIntHandler(intNo); if (tskid != ID.TSK_NULL) { Task wTask; wTask = Nucleus.GetTask(tskid); if (wTask != null) { wTask.Wakeup(); } } } } }while (!noIntr); m_Nucleus.Scheduling(); task = m_Nucleus.GetScheduledTask(); if (task == null) { Idle(); } else { m_Current = (CPUContext)task.GetCPUContext(); task.Run(); m_Current.PopContext(); UnlockCPU(); m_TaskMode = true; if (!m_IntEvent.WaitOne()) { Terminate(); } m_TaskMode = false; LockCPU(); CPUContext CPUContext = (CPUContext)m_Current; m_Current = null; if (CPUContext.IsReleased()) { CPUContext.Wait(); CPUContext.ClearTask(); } else { CPUContext.PushContext(); } } task = m_Nucleus.GetCurrentTask(); if (task != null) { task.Ready(); } } while (!IsTerminated()); }