#include <kern/time.h>
#include <kern/thread.h>
#include <kern/mem.h>
+#include <kern/process.h>
#include <arch/addrs.h>
#include <arch/multiboot.h>
#include <kern/thread.h>
#include <kern/mem.h>
#include <kern/pagetable.h>
+#include <kern/process.h>
namespace Arch {
void set_aspace(Mem::ProcAddrSpace *aspace)
#include <kern/kernel.h>
#include <kern/spinlock.h>
-#include <kern/thread.h>
+#include <kern/sched.h>
#include <util/spinlock.h>
namespace Lock {
void lock();
void unlock();
- bool held_by_curthread()
- {
- return lockval == reinterpret_cast<ulong>(curthread);
- }
+ // Include kern/thread.h for inline definition
+ bool held_by_curthread();
};
}
#include <System/Mem.h>
#include <kern/kernel.h>
-#include <kern/orb.h>
#include <arch/mem.h>
#include <arch/addrs.h>
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;
--- /dev/null
+#ifndef _KERN_PROCESS_H
+#define _KERN_PROCESS_H
+
+#include <kern/mem.h>
+#include <kern/orb.h>
+
+namespace Mem {
+ class ProcAddrSpace : public AddrSpace {
+ public:
+ ProcAddrSpace();
+ ProcAddrSpace(void *page_table);
+
+ ORB::IDSpace idspace;
+ };
+}
+
+#endif
#include <kern/pagealloc.h>
#include <kern/compiler.h>
+#include <arch/paging.h>
+
+#include <lowlevel/bitops.h>
+
namespace Util {
// Key must be an integer.
template <typename T, typename Key>
--- /dev/null
+#ifndef _KERN_SCHED_H
+#define _KERN_SCHED_H
+
+#include <kern/types.h>
+#include <kern/time.h>
+#include <kern/spinlock.h>
+
+#include <arch/thread.h>
+
+#include <util/list.h>
+
+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
#include <kern/types.h>
#include <kern/time.h>
-#include <arch/thread.h>
-#include <util/list.h>
-#include <kern/irq.h>
-#include <kern/spinlock.h>
#include <kern/orb.h>
+#include <kern/sched.h>
+#include <kern/lock.h>
-extern "C" void schedule();
-extern "C" void sched_new_thread();
+#include <arch/thread.h>
-// FIXME: per-CPU
-extern int need_resched;
+#include <util/list.h>
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;
#include <arch/current.h>
#define curthread (::Arch::get_current_thread())
+namespace Lock {
+ inline bool Lock::held_by_curthread()
+ {
+ return lockval == reinterpret_cast<ulong>(curthread);
+ }
+}
+
#endif
#include <kern/pagealloc.h>
#include <kern/generic-pte.h>
#include <kern/compiler.h>
+#include <kern/process.h>
+#include <kern/thread.h>
extern int roshared_start, roshared_page_end;
extern int rwshared_start, rwshared_page_end;
#include <kern/pagealloc.h>
#include <kern/rmap.h>
#include <kern/pagetable.h>
+#include <kern/sched.h>
+#include <kern/thread.h>
namespace Mem {
static const ulong rmap_node_len =
#include <kern/orb.h>
#include <kern/pagealloc.h>
#include <kern/compiler.h>
+#include <kern/thread.h>
+
#include <arch/usercopy.h>
+
#include <orb.h>
using System::RunTime::ParamInfoBlock;
#include <kern/time.h>
#include <kern/thread.h>
#include <kern/mem.h>
+#include <kern/process.h>
using namespace Mem;
namespace Mem {