/* * Copyright (C) 2015 Niek Linnenbank * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "ProcessManager.h" // TODO: replace Vector with an Index.. ProcessManager::ProcessManager(Scheduler *scheduler) : m_procs(MAX_PROCS) { DEBUG("m_procs = " << MAX_PROCS); m_scheduler = scheduler; m_current = ZERO; m_previous = ZERO; m_idle = ZERO; } ProcessManager::~ProcessManager() { } Scheduler * ProcessManager::getScheduler() { return m_scheduler; } Process * ProcessManager::create(Address entry, const MemoryMap &map) { Process *proc = new Arch::Process(m_procs.count(), entry, false, map); // Insert to the process table if (proc && proc->initialize() == Process::Success) { m_procs.insert(proc); return proc; } return ZERO; } Process * ProcessManager::get(ProcessID id) { // TODO: replace with an Index to make this more easy. Process **p = (Process **) m_procs.get(id); return p ? *p : ZERO; } void ProcessManager::remove(Process *proc, uint exitStatus) { if (proc == m_previous) m_previous = ZERO; if (proc == m_idle) m_idle = ZERO; if (proc == m_current) m_current = ZERO; // Wakeup any Processes which are waiting for this Process Size size = m_procs.size(); for (Size i = 0; i < size; i++) { if (m_procs[i] != ZERO && m_procs[i]->getState() == Process::Waiting && m_procs[i]->getWait() == proc->getID()) { m_procs[i]->setState(Process::Ready); m_procs[i]->setWait(exitStatus); } } // Remove process from administration m_procs[proc->getID()] = ZERO; // Free the process memory delete proc; } void ProcessManager::schedule(Process *proc) { /* If needed, let the scheduler select a new process */ if (!proc) { proc = m_scheduler->select(&m_procs, m_idle); /* If no process ready, let us idle. */ if (!proc) proc = m_idle; } if (!proc) { FATAL("no process found to run!"); for(;;); } /* Only execute if its a different process */ if (proc != m_current) { m_previous = m_current; m_current = proc; if (m_previous && m_previous->getState() == Process::Running) m_previous->setState(Process::Ready); proc->setState(Process::Running); proc->execute(m_previous); } } Process * ProcessManager::current() { return m_current; } Process * ProcessManager::previous() { return m_previous; } void ProcessManager::setIdle(Process *proc) { m_idle = proc; } Vector * ProcessManager::getProcessTable() { return &m_procs; }