From db11b9a38323d994d42303c6149c9e06ff29b7d2 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Sat, 3 Mar 2007 10:55:25 -0600 Subject: [PATCH] Untangle header file interdependencies. --- kernel/arch/x86/misc.cc | 1 + kernel/arch/x86/thread.cc | 1 + kernel/include/kern/lock.h | 8 +- kernel/include/kern/mem.h | 9 -- kernel/include/kern/process.h | 17 +++ kernel/include/kern/radix.h | 4 + kernel/include/kern/sched.h | 189 ++++++++++++++++++++++++++++++++++ kernel/include/kern/thread.h | 188 ++------------------------------- kernel/mem/addrspace.cc | 2 + kernel/mem/rmap.cc | 2 + kernel/orb/invoke.cc | 3 + kernel/tests/aspace.cc | 1 + 12 files changed, 234 insertions(+), 191 deletions(-) create mode 100644 kernel/include/kern/process.h create mode 100644 kernel/include/kern/sched.h diff --git a/kernel/arch/x86/misc.cc b/kernel/arch/x86/misc.cc index ffc774e..48bf24c 100644 --- a/kernel/arch/x86/misc.cc +++ b/kernel/arch/x86/misc.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/kernel/arch/x86/thread.cc b/kernel/arch/x86/thread.cc index f3923f5..d7e445c 100644 --- a/kernel/arch/x86/thread.cc +++ b/kernel/arch/x86/thread.cc @@ -15,6 +15,7 @@ #include #include #include +#include namespace Arch { void set_aspace(Mem::ProcAddrSpace *aspace) diff --git a/kernel/include/kern/lock.h b/kernel/include/kern/lock.h index 99a139e..46e009c 100644 --- a/kernel/include/kern/lock.h +++ b/kernel/include/kern/lock.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include namespace Lock { @@ -22,10 +22,8 @@ namespace Lock { void lock(); void unlock(); - bool held_by_curthread() - { - return lockval == reinterpret_cast(curthread); - } + // Include kern/thread.h for inline definition + bool held_by_curthread(); }; } diff --git a/kernel/include/kern/mem.h b/kernel/include/kern/mem.h index 06f4084..6020a90 100644 --- a/kernel/include/kern/mem.h +++ b/kernel/include/kern/mem.h @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -325,14 +324,6 @@ namespace Mem { friend class ASpaceMappable; }; - class ProcAddrSpace : public AddrSpace { - public: - ProcAddrSpace(); - ProcAddrSpace(void *page_table); - - ORB::IDSpace idspace; - }; - extern Factory addr_space_factory, proc_addr_space_factory; using ::System::RunTime::orbmm; diff --git a/kernel/include/kern/process.h b/kernel/include/kern/process.h new file mode 100644 index 0000000..afccbf6 --- /dev/null +++ b/kernel/include/kern/process.h @@ -0,0 +1,17 @@ +#ifndef _KERN_PROCESS_H +#define _KERN_PROCESS_H + +#include +#include + +namespace Mem { + class ProcAddrSpace : public AddrSpace { + public: + ProcAddrSpace(); + ProcAddrSpace(void *page_table); + + ORB::IDSpace idspace; + }; +} + +#endif diff --git a/kernel/include/kern/radix.h b/kernel/include/kern/radix.h index 256fdc4..1399356 100644 --- a/kernel/include/kern/radix.h +++ b/kernel/include/kern/radix.h @@ -10,6 +10,10 @@ #include #include +#include + +#include + namespace Util { // Key must be an integer. template diff --git a/kernel/include/kern/sched.h b/kernel/include/kern/sched.h new file mode 100644 index 0000000..5592063 --- /dev/null +++ b/kernel/include/kern/sched.h @@ -0,0 +1,189 @@ +#ifndef _KERN_SCHED_H +#define _KERN_SCHED_H + +#include +#include +#include + +#include + +#include + +extern "C" void schedule(); +extern "C" void sched_new_thread(); + +// FIXME: per-CPU +extern int need_resched; + +namespace Threads { + class Thread; + class WaitQueue; + + // This is a reasonably simple O(1) scheduler that provides both + // real-time and timeshared scheduling, with (non-rt) priority boosts + // for interactive tasks. + // + // At some point, it'd be nice to extend/replace this with something + // that gives more options to how to schedule tasks. Priority + // inheritance would be nice, as would the ability to schedule groups + // of threads as one prior to scheduling within the group. The latter + // would help avoid giving more CPU time to certain apps simply + // because they divided their work among more threads (or to certain + // users simply because they're running more programs). + // + // At some sooner point, SMP support will need to be added. + + class Sched { + public: + enum { + // The default timeslice of 10 ms applies to priority 8 + // timeshared tasks. + + default_timeslice = 10000000, + rt_prios = 256, + ts_static_prios = 16, + + // This must not exceed 32 without increasing the size + // of ts_bitmap. + + ts_prios = 32 + }; + + private: + ulong bitmap[rt_prios / sizeof(ulong)]; + Util::List rt_runqueue[rt_prios]; + + u32 ts_bitmap, ts_depleted_bitmap; + int last_replenish; + + Util::List ts_runqueue[ts_prios]; + Util::List ts_depleted[ts_prios]; + + Lock::SpinLock runqueue_lock; + + void schedule_nolock(); + Thread *best_rt(int prio); + Thread *best_ts(); + + void replenish_prio(int prio); + void replenish_all(); + + static u32 prio_to_slice(int prio); + static int slice_to_prio(u32 slice); + + Time::KTimerEntry resched_timer; + + public: + Util::List threadlist; + + // FIXME: use sleeping lock once implemented + Lock::SpinLock threadlist_lock; + + typedef void (*thread_func)(void *arg); + + Thread *new_thread(thread_func func, void *arg, char *name = NULL); + void schedule(); + void sched_new_thread(); + + void init(); + + friend class Thread; + friend class WaitQueue; + }; + + extern Sched sched; + + struct Blocker { + Util::List list_node; + bool blocked; + + // Besides the obvious use by ThreadBlocker, this is used in + // CascadeBlocker by WaitQueue both for prioritization of wakeups + // and for calling wake_nolock(). + + Thread *thread; + + Blocker() + { + blocked = true; + } + + virtual ~Blocker() + { + } + + virtual void wake() = 0; + + // Like wake, but doesn't wake the thread -- used by WaitQueue + // which calls thread->wake_nolock itself. + + virtual void unblock() = 0; + }; + + // This is a basic one-thread blocker; all blocked threads must + // use one of these. + + struct ThreadBlocker : public Blocker { + ThreadBlocker() + { + } + + ThreadBlocker(Thread *THREAD) + { + thread = THREAD; + } + + void wake(); + void unblock(); + }; + + // A thread that needs to block on more than one blocker can create + // multiple CascadeBlockers all pointing to the same ThreadBlocker. + // The thread wakes when any of the cascades has been woken. + + struct CascadeBlocker : public Blocker { + CascadeBlocker() + { + } + + CascadeBlocker(Blocker *BLOCKER) + { + blocker = BLOCKER; + thread = blocker->thread; + } + + Blocker *blocker; + void wake(); + void unblock(); + }; + + // Waitqueues are queues of Blockers that can be woken up either one + // at a time in priority order or all at once, at the waker's option. + // Unlike Blockers, waitqueues do not have a blocked field; blocking + // threads must check for completion after adding themselves to the + // wait queue. When a blocker is woken, it is removed from the waitqueue. + + class WaitQueue { + Util::List blockers; + Lock::SpinLock lock; + + Blocker *unblock_one_nolock(); + + public: + void block(Blocker *blocker); + void unblock(Blocker *blocker); + + bool empty(); + + // Returns true if a task was successfully woken + bool wake_one(); + + // Returns the number of tasks successfully woken + int wake_all(); + + // Like wake_one, but return the thread instead of waking it. + Blocker *unblock_one(); + }; +} + +#endif diff --git a/kernel/include/kern/thread.h b/kernel/include/kern/thread.h index d679a81..f4e585b 100644 --- a/kernel/include/kern/thread.h +++ b/kernel/include/kern/thread.h @@ -3,192 +3,19 @@ #include #include -#include -#include -#include -#include #include +#include +#include -extern "C" void schedule(); -extern "C" void sched_new_thread(); +#include -// FIXME: per-CPU -extern int need_resched; +#include namespace Mem { class ProcAddrSpace; } namespace Threads { - class Thread; - class WaitQueue; - - // This is a reasonably simple O(1) scheduler that provides both - // real-time and timeshared scheduling, with (non-rt) priority boosts - // for interactive tasks. - // - // At some point, it'd be nice to extend/replace this with something - // that gives more options to how to schedule tasks. Priority - // inheritance would be nice, as would the ability to schedule groups - // of threads as one prior to scheduling within the group. The latter - // would help avoid giving more CPU time to certain apps simply - // because they divided their work among more threads (or to certain - // users simply because they're running more programs). - // - // At some sooner point, SMP support will need to be added. - - class Sched { - public: - enum { - // The default timeslice of 10 ms applies to priority 8 - // timeshared tasks. - - default_timeslice = 10000000, - rt_prios = 256, - ts_static_prios = 16, - - // This must not exceed 32 without increasing the size - // of ts_bitmap. - - ts_prios = 32 - }; - - private: - ulong bitmap[rt_prios / sizeof(ulong)]; - Util::List rt_runqueue[rt_prios]; - - u32 ts_bitmap, ts_depleted_bitmap; - int last_replenish; - - Util::List ts_runqueue[ts_prios]; - Util::List ts_depleted[ts_prios]; - - Lock::SpinLock runqueue_lock; - - void schedule_nolock(); - Thread *best_rt(int prio); - Thread *best_ts(); - - void replenish_prio(int prio); - void replenish_all(); - - static u32 prio_to_slice(int prio); - static int slice_to_prio(u32 slice); - - Time::KTimerEntry resched_timer; - - public: - Util::List threadlist; - - // FIXME: use sleeping lock once implemented - Lock::SpinLock threadlist_lock; - - typedef void (*thread_func)(void *arg); - - Thread *new_thread(thread_func func, void *arg, char *name = NULL); - void schedule(); - void sched_new_thread(); - - void init(); - - friend class Thread; - friend class WaitQueue; - }; - - extern Sched sched; - - struct Blocker { - Util::List list_node; - bool blocked; - - // Besides the obvious use by ThreadBlocker, this is used in - // CascadeBlocker by WaitQueue both for prioritization of wakeups - // and for calling wake_nolock(). - - Thread *thread; - - Blocker() - { - blocked = true; - } - - virtual ~Blocker() - { - } - - virtual void wake() = 0; - - // Like wake, but doesn't wake the thread -- used by WaitQueue - // which calls thread->wake_nolock itself. - - virtual void unblock() = 0; - }; - - // This is a basic one-thread blocker; all blocked threads must - // use one of these. - - struct ThreadBlocker : public Blocker { - ThreadBlocker() - { - } - - ThreadBlocker(Thread *THREAD) - { - thread = THREAD; - } - - void wake(); - void unblock(); - }; - - // A thread that needs to block on more than one blocker can create - // multiple CascadeBlockers all pointing to the same ThreadBlocker. - // The thread wakes when any of the cascades has been woken. - - struct CascadeBlocker : public Blocker { - CascadeBlocker() - { - } - - CascadeBlocker(Blocker *BLOCKER) - { - blocker = BLOCKER; - thread = blocker->thread; - } - - Blocker *blocker; - void wake(); - void unblock(); - }; - - // Waitqueues are queues of Blockers that can be woken up either one - // at a time in priority order or all at once, at the waker's option. - // Unlike Blockers, waitqueues do not have a blocked field; blocking - // threads must check for completion after adding themselves to the - // wait queue. When a blocker is woken, it is removed from the waitqueue. - - class WaitQueue { - Util::List blockers; - Lock::SpinLock lock; - - Blocker *unblock_one_nolock(); - - public: - void block(Blocker *blocker); - void unblock(Blocker *blocker); - - bool empty(); - - // Returns true if a task was successfully woken - bool wake_one(); - - // Returns the number of tasks successfully woken - int wake_all(); - - // Like wake_one, but return the thread instead of waking it. - Blocker *unblock_one(); - }; - class Thread { // This must be first. Arch::ArchThread arch; @@ -291,4 +118,11 @@ namespace Threads { #include #define curthread (::Arch::get_current_thread()) +namespace Lock { + inline bool Lock::held_by_curthread() + { + return lockval == reinterpret_cast(curthread); + } +} + #endif diff --git a/kernel/mem/addrspace.cc b/kernel/mem/addrspace.cc index 20a46fb..eb92a6a 100644 --- a/kernel/mem/addrspace.cc +++ b/kernel/mem/addrspace.cc @@ -26,6 +26,8 @@ #include #include #include +#include +#include extern int roshared_start, roshared_page_end; extern int rwshared_start, rwshared_page_end; diff --git a/kernel/mem/rmap.cc b/kernel/mem/rmap.cc index 14ca7f7..2ef4a03 100644 --- a/kernel/mem/rmap.cc +++ b/kernel/mem/rmap.cc @@ -17,6 +17,8 @@ #include #include #include +#include +#include namespace Mem { static const ulong rmap_node_len = diff --git a/kernel/orb/invoke.cc b/kernel/orb/invoke.cc index 57097c5..2e1440f 100644 --- a/kernel/orb/invoke.cc +++ b/kernel/orb/invoke.cc @@ -16,7 +16,10 @@ #include #include #include +#include + #include + #include using System::RunTime::ParamInfoBlock; diff --git a/kernel/tests/aspace.cc b/kernel/tests/aspace.cc index 22ca29f..694021e 100644 --- a/kernel/tests/aspace.cc +++ b/kernel/tests/aspace.cc @@ -17,6 +17,7 @@ #include #include #include +#include using namespace Mem; namespace Mem { -- 2.39.2