#ifndef __KERNEL_SCHEDULER_H
#define __KERNEL_SCHEDULER_H

#include <cpp/Uncopyable.h>
#include <sys/types.h>
#include <List.h>

namespace OS {
namespace Kernel {

class Thread;
class Spinlock;
class Timer;

// task scheduler singleton
class Scheduler : private Uncopyable {
  public:
	static status_t Init(); // must be called at bootup once
	static void Start(); // called at the end of kernel initialization to kickstart the threading system
	static bool IsStarted() { return sStarted; }

	static const int kNumPriorities = 32;
	static const int kHighestPriority = 31;
	static const int kDefaultPriority = 16;
	static const int kIdlePriority = 0;

	static bool IsValidPriority(int priority) { return (priority >= kIdlePriority && priority < kNumPriorities); }

	static void Yield(); // yields the current thread, placed at the end of the run queue
	static void Preempt(); // preempt the current thread, placed at the front of the run queue

	// private scheduler calls, usually called from the thread class
	static void Reschedule();
	static void RescheduleAndRelease(Spinlock &lock);
	static void Resume(Thread *t);
	static void RemoveThreadFromRunQueue(Thread *t);

  private:
	// the run queues and modifiers
	static List<Thread> sRunQueue[kNumPriorities];
	static unsigned int sRunQueueBitmap;
	static Spinlock sRunQueueLock;

	static void AddToRunQueueHead(Thread *t, int priority);
	static void AddToRunQueueTail(Thread *t, int priority);
	static Thread *PopRunQueueHead(int priority);

	// the actual reschedule method
	static void _Reschedule();

	// are we active?
	static bool sStarted;

	// quantum timer
	static handler_return QuantumTimerCallback(Timer *, void *, time_t);
	static Timer sQuantumTimer;

	// threads are a friend
	friend class Thread;
};

}} // namespace OS::Kernel

#endif
