Source('module.cc')
     Source('object.cc')
     Source('process.cc')
+    Source('process_types.cc')
+    Source('scheduler.cc')
 
     Source('sc_attr.cc')
     Source('sc_event.cc')
 
  */
 
 #include "systemc/core/kernel.hh"
+#include "systemc/core/scheduler.hh"
 
 namespace SystemC
 {
 
-Kernel::Kernel(Params *params) : SimObject(params)
+Kernel::Kernel(Params *params) : SimObject(params), t0Event(this) {}
+
+void
+Kernel::startup()
+{
+    schedule(t0Event, curTick());
+}
+
+void
+Kernel::t0Handler()
 {
+    ::sc_gem5::scheduler.initialize();
 }
 
 } // namespace SystemC
 
   public:
     typedef SystemC_KernelParams Params;
     Kernel(Params *params);
+
+    void startup() override;
+
+    void t0Handler();
+
+  private:
+    EventWrapper<Kernel, &Kernel::t0Handler> t0Event;
 };
 
 } // namespace SystemC
 
--- /dev/null
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __SYSTEMC_CORE_LIST_HH__
+#define __SYSTEMC_CORE_LIST_HH__
+
+#include <functional>
+
+#include "base/fiber.hh"
+#include "systemc/core/object.hh"
+#include "systemc/ext/core/sc_event.hh"
+#include "systemc/ext/core/sc_module.hh"
+#include "systemc/ext/core/sc_process_handle.hh"
+
+namespace sc_gem5
+{
+
+struct ListNode
+{
+    ListNode() : nextListNode(nullptr), prevListNode(nullptr) {}
+    virtual ~ListNode() {}
+
+    ListNode *nextListNode;
+    ListNode *prevListNode;
+
+    void
+    popListNode()
+    {
+        if (nextListNode)
+            nextListNode->prevListNode = prevListNode;
+        if (prevListNode)
+            prevListNode->nextListNode = nextListNode;
+        nextListNode = nullptr;
+        prevListNode = nullptr;
+    }
+};
+
+template <typename T>
+struct NodeList : public ListNode
+{
+    NodeList()
+    {
+        nextListNode = this;
+        prevListNode = this;
+    }
+
+    void
+    pushFirst(T *t)
+    {
+        // Make sure this node isn't currently in a different list.
+        t->popListNode();
+
+        // The node behind t is whoever used to be first.
+        t->nextListNode = nextListNode;
+        // The node that used to be first is behind t.
+        nextListNode->prevListNode = t;
+
+        // Nobody is in front of t.
+        t->prevListNode = this;
+        // The first node is t.
+        nextListNode = t;
+    }
+
+    void
+    pushLast(T *t)
+    {
+        // Make sure this node isn't currently in a different list.
+        t->popListNode();
+
+        // The node in front of t is whoever used to be last.
+        t->prevListNode = prevListNode;
+        // The node that used to be last is in front of t.
+        prevListNode->nextListNode = t;
+
+        // Nobody is behind t.
+        t->nextListNode = this;
+        // The last node is t.
+        prevListNode = t;
+    }
+
+    T *getNext() { return dynamic_cast<T *>(nextListNode); }
+    bool empty() { return getNext() == nullptr; }
+};
+
+} // namespace sc_gem5
+
+#endif  //__SYSTEMC_CORE_LIST_HH__
 
 
 #include "base/logging.hh"
 #include "systemc/core/module.hh"
+#include "systemc/core/scheduler.hh"
 
 namespace sc_gem5
 {
         // constructor is running.
         parent = p->obj()->sc_obj;
         addObject(&parent->_gem5_object->children, sc_obj);
-    } else if (false /* TODO Check if a process is running */) {
-        // The process is our parent.
+    } else if (scheduler.current()) {
+        // Our parent is the currently running process.
+        parent = scheduler.current();
     } else {
         // We're a top level object.
         addObject(&topLevelObjects, sc_obj);
 
  */
 
 #include "systemc/core/process.hh"
+#include "systemc/core/scheduler.hh"
 
 namespace sc_gem5
 {
         //TODO Suspend this process.
     }
 
-    if (procKind() != ::sc_core::SC_METHOD_PROC_ /* && we're running */) {
-        // We suspended this thread or cthread. Stop running.
+    if (procKind() != ::sc_core::SC_METHOD_PROC_ &&
+            scheduler.current() == this) {
+        scheduler.yield();
     }
 }
 
 }
 
 void
-Thread::throw_it(ExceptionWrapperBase &exc, bool inc_kids)
-{
-    Process::throw_it(exc, inc_kids);
-
-    if (_terminated)
-        return;
+Process::run()
+{
+    _running = true;
+    bool reset;
+    do {
+        reset = false;
+        try {
+            func->call();
+        } catch(::sc_core::sc_unwind_exception exc) {
+            reset = exc.is_reset();
+        }
+    } while (reset);
+    _running = false;
+}
 
-    injectException(exc);
+Process::Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) :
+    ::sc_core::sc_object(name), excWrapper(nullptr), func(func),
+    _running(false), _dynamic(_dynamic), _isUnwinding(false),
+    _terminated(false), _suspended(false), _disabled(false),
+    _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize)
+{
+    _newest = this;
+    if (!_dynamic)
+        scheduler.init(this);
 }
 
+Process *Process::_newest;
+
 void
 throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids)
 {
 
 #include <functional>
 
 #include "base/fiber.hh"
+#include "systemc/core/list.hh"
 #include "systemc/core/object.hh"
 #include "systemc/ext/core/sc_event.hh"
 #include "systemc/ext/core/sc_module.hh"
 namespace sc_gem5
 {
 
-class Process : public ::sc_core::sc_object
+class Process : public ::sc_core::sc_object, public ListNode
 {
   public:
     virtual ::sc_core::sc_curr_proc_kind procKind() const = 0;
+    bool running() const { return _running; }
     bool dynamic() const { return _dynamic; }
     bool isUnwinding() const { return _isUnwinding; }
     bool terminated() const { return _terminated; }
     const ::sc_core::sc_event &resetEvent() { return _resetEvent; }
     const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; }
 
+    // This should only be called before initialization.
+    void dontInitialize() { popListNode(); }
+
+    void setStackSize(size_t size) { stackSize = size; }
+
+    void run();
+
+    virtual Fiber *fiber() { return Fiber::primaryFiber(); }
+
+    static Process *newest() { return _newest; }
+
   protected:
-    Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) :
-        ::sc_core::sc_object(name), func(func), _dynamic(_dynamic),
-        _isUnwinding(false), _terminated(false), _suspended(false),
-        _disabled(false), _syncReset(false), refCount(0)
-    {}
+    Process(const char *name, ProcessFuncWrapper *func, bool _dynamic);
+
+    static Process *_newest;
 
     virtual ~Process() { delete func; }
 
 
     ProcessFuncWrapper *func;
     sc_core::sc_curr_proc_kind _procKind;
+    bool _running;
     bool _dynamic;
     bool _isUnwinding;
     bool _terminated;
     bool _syncReset;
 
     int refCount;
-};
-
-class Method : public Process
-{
-  public:
-    Method(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
-        Process(name, func, _dynamic)
-    {}
-
-    const char *kind() const override { return "sc_method_process"; }
-
-    sc_core::sc_curr_proc_kind
-    procKind() const override
-    {
-        return sc_core::SC_METHOD_PROC_;
-    }
-};
-
-class Thread : public Process
-{
-  public:
-    Thread(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
-        Process(name, func, _dynamic)
-    {}
-
-    const char *kind() const override { return "sc_thread_process"; }
-
-    void throw_it(ExceptionWrapperBase &exc, bool inc_kids) override;
-
-    sc_core::sc_curr_proc_kind
-    procKind() const override
-    {
-        return sc_core::SC_THREAD_PROC_;
-    }
-};
-
-class CThread : public Thread
-{
-  public:
-    CThread(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
-        Thread(name, func, _dynamic)
-    {}
-
-    const char *kind() const override { return "sc_cthread_process"; }
 
-    sc_core::sc_curr_proc_kind
-    procKind() const override
-    {
-        return sc_core::SC_CTHREAD_PROC_;
-    }
+    size_t stackSize;
 };
 
 } // namespace sc_gem5
 
--- /dev/null
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "systemc/core/process_types.hh"
+
+namespace sc_gem5
+{
+
+void
+Thread::throw_it(ExceptionWrapperBase &exc, bool inc_kids)
+{
+    Process::throw_it(exc, inc_kids);
+
+    if (_terminated)
+        return;
+
+    injectException(exc);
+}
+
+} // namespace sc_gem5
 
--- /dev/null
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __SYSTEMC_CORE_PROCESS_TYPES_HH__
+#define __SYSTEMC_CORE_PROCESS_TYPES_HH__
+
+#include "systemc/core/process.hh"
+#include "systemc/core/scheduler.hh"
+
+namespace sc_gem5
+{
+
+class Method : public Process
+{
+  public:
+    Method(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
+        Process(name, func, _dynamic)
+    {}
+
+    const char *kind() const override { return "sc_method_process"; }
+
+    sc_core::sc_curr_proc_kind
+    procKind() const override
+    {
+        return sc_core::SC_METHOD_PROC_;
+    }
+};
+
+class Thread : public Process
+{
+  public:
+    Thread(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
+        Process(name, func, _dynamic), ctx(nullptr)
+    {}
+
+    ~Thread() { delete ctx; }
+
+    const char *kind() const override { return "sc_thread_process"; }
+
+    void throw_it(ExceptionWrapperBase &exc, bool inc_kids) override;
+
+    sc_core::sc_curr_proc_kind
+    procKind() const override
+    {
+        return sc_core::SC_THREAD_PROC_;
+    }
+
+    Fiber *
+    fiber() override
+    {
+        if (!ctx)
+            ctx = new Context(this, stackSize);
+        return ctx;
+    }
+
+  private:
+    class Context : public Fiber
+    {
+      public:
+        Context(Thread *thread, size_t size) : Fiber(size), thread(thread) {}
+
+      private:
+        Thread *thread;
+
+        void main() override { thread->run(); }
+    };
+
+    Context *ctx;
+};
+
+class CThread : public Thread
+{
+  public:
+    CThread(const char *name, ProcessFuncWrapper *func, bool _dynamic=false) :
+        Thread(name, func, _dynamic)
+    {
+        // We'll be in the initialization list now, but we shouldn't be.
+        popListNode();
+    }
+
+    const char *kind() const override { return "sc_cthread_process"; }
+
+    sc_core::sc_curr_proc_kind
+    procKind() const override
+    {
+        return sc_core::SC_CTHREAD_PROC_;
+    }
+};
+
+} // namespace sc_gem5
+
+#endif  //__SYSTEMC_CORE_PROCESS_TYPES_HH__
 
 
 #include "base/logging.hh"
 #include "systemc/core/module.hh"
-#include "systemc/core/process.hh"
+#include "systemc/core/process_types.hh"
 #include "systemc/ext/core/sc_module.hh"
 #include "systemc/ext/core/sc_module_name.hh"
 
 void
 sc_module::dont_initialize()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    ::sc_gem5::Process::newest()->dontInitialize();
 }
 
 void
-sc_module::set_stack_size(size_t)
+sc_module::set_stack_size(size_t size)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    ::sc_gem5::Process::newest()->setStackSize(size);
 }
 
 
 
 
 #include "base/logging.hh"
 #include "systemc/core/process.hh"
+#include "systemc/core/scheduler.hh"
 #include "systemc/ext/core/sc_process_handle.hh"
 
 namespace sc_core
 sc_process_handle
 sc_get_current_process_handle()
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-    return sc_process_handle(nullptr /* Current process pointer */);
+    return sc_process_handle(::sc_gem5::scheduler.current());
 }
 
 bool
 
--- /dev/null
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#include "systemc/core/scheduler.hh"
+
+#include "base/fiber.hh"
+
+namespace sc_gem5
+{
+
+Scheduler::Scheduler() : _numCycles(0), _current(nullptr) {}
+
+void
+Scheduler::initialize()
+{
+    update();
+
+    while (!initList.empty())
+        ready(initList.getNext());
+
+    delta();
+}
+
+void
+Scheduler::runCycles()
+{
+    while (!readyList.empty()) {
+        evaluate();
+        update();
+        delta();
+    }
+}
+
+void
+Scheduler::yield()
+{
+    _current = readyList.getNext();
+    if (!_current) {
+        // There are no more processes, so return control to evaluate.
+        Fiber::primaryFiber()->run();
+    } else {
+        _current->popListNode();
+        // Switch to whatever Fiber is supposed to run this process. All
+        // Fibers which aren't running should be parked at this line.
+        _current->fiber()->run();
+        // If the current process hasn't been started yet, start it. This
+        // should always be true for methods, but may not be true for threads.
+        if (_current && !_current->running())
+            _current->run();
+    }
+}
+
+void
+Scheduler::evaluate()
+{
+    if (!readyList.empty())
+        _numCycles++;
+
+    do {
+        yield();
+    } while (!readyList.empty());
+}
+
+void
+Scheduler::update()
+{
+}
+
+void
+Scheduler::delta()
+{
+}
+
+Scheduler scheduler;
+
+} // namespace sc_gem5
 
--- /dev/null
+/*
+ * Copyright 2018 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __SYSTEMC_CORE_SCHEDULER_HH__
+#define __SYSTEMC_CORE_SCHEDULER_HH__
+
+#include "systemc/core/list.hh"
+#include "systemc/core/process.hh"
+
+namespace sc_gem5
+{
+
+typedef NodeList<Process> ProcessList;
+
+class Scheduler
+{
+  public:
+    Scheduler();
+
+    uint64_t numCycles() { return _numCycles; }
+    Process *current() { return _current; }
+
+    // Run the initialization phase.
+    void initialize();
+
+    // Run delta cycles until time needs to advance.
+    void runCycles();
+
+    // Put a process on the list of processes to be initialized.
+    void init(Process *p) { initList.pushLast(p); }
+
+    // Run the next process, if there is one.
+    void yield();
+
+    // Put a process on the ready list.
+    void
+    ready(Process *p)
+    {
+        // Clump methods together to minimize context switching.
+        if (p->procKind() == ::sc_core::SC_METHOD_PROC_)
+            readyList.pushFirst(p);
+        else
+            readyList.pushLast(p);
+    }
+
+    // Run the given process immediately, preempting whatever may be running.
+    void
+    runNow(Process *p)
+    {
+        // If a process is running, schedule it/us to run again.
+        if (_current)
+            readyList.pushFirst(_current);
+        // Schedule p to run first.
+        readyList.pushFirst(p);
+        yield();
+    }
+
+  private:
+    uint64_t _numCycles;
+
+    Process *_current;
+
+    ProcessList initList;
+    ProcessList readyList;
+
+    void evaluate();
+    void update();
+    void delta();
+};
+
+extern Scheduler scheduler;
+
+} // namespace sc_gem5
+
+#endif // __SYSTEMC_CORE_SCHEDULER_H__