// EPOS-- Scheduler Abstraction Declarations

#ifndef __scheduler_h
#define __scheduler_h

#include <utility/list.h>
#include <cpu.h>
#include <machine.h>

__BEGIN_SYS

// All scheduling criteria, or disciplins, must define operator int() with 
// semantics of returning the desired order of a given object in the 
// scheduling list

namespace Scheduling_Criteria
{
 ...

///////
    // Least Laxity First
    class LLF: public Priority
    {
    public:
	enum {
	    MAIN      = 0,
	    PERIODIC  = 1,
	    APERIODIC = (unsigned(1) << (sizeof(int) * 8 - 1)) -2,
	    NORMAL    = APERIODIC,
	    IDLE      = (unsigned(1) << (sizeof(int) * 8 - 1)) -1
	};

	static const bool timed = true;
	static const bool preemptive = true;
	static const bool energy_aware = false;

    public:
	LLF(int p): Priority(p), _deadline(0), _wcet(0), _computed_time(0) {} // Aperiodic
	LLF(const RTC::Microsecond & d, const RTC::Microsecond & c);

	void update(Timer::Tick _computation_start);

	void reset() { _computed_time = 0;}

    private:
	Timer::Tick _deadline;
	Timer::Tick _wcet;
	Timer::Tick _computed_time;
    };
////

...

	//Multicore EDF
	    class SMP_EDF: public EDF
	    {
	    public:
		static const unsigned int QUEUES = Traits<Machine>::MAX_CPUS;
	  
	    public:
		SMP_EDF(int p = NORMAL): EDF(p),
		     _affinity(((p == IDLE) || (p == MAIN)) ? Machine::cpu_id()
			       : ++_next_cpu %= Machine::n_cpus()) {}

		SMP_EDF(int p = NORMAL, int a): EDF(p), _affinity(a) {}

		const volatile int & queue() const volatile { return _affinity; }

		static int current() { return Machine::cpu_id(); }

	    private:
		volatile int _affinity;

		static int _next_cpu;
	    };

	//Multicore Rate Monotonic
	    class SMP_RM: public RM
	    {
	    public:
		static const unsigned int QUEUES = Traits<Machine>::MAX_CPUS;
	  
	    public:
		SMP_RM(int p = NORMAL): RM(p),
		     _affinity(((p == IDLE) || (p == MAIN)) ? Machine::cpu_id()
			       : ++_next_cpu %= Machine::n_cpus()) {}

		SMP_RM(int p = NORMAL, int a): RM(p), _affinity(a) {}

		const volatile int & queue() const volatile { return _affinity; }

		static int current() { return Machine::cpu_id(); }

	    private:
		volatile int _affinity;

		static int _next_cpu;
	    };

	//Multicore LLF
	    class SMP_LLF: public LLF
	    {
	    public:
		static const unsigned int QUEUES = Traits<Machine>::MAX_CPUS;

	    public:
		SMP_LLF(int p): LLF(p), _affinity(((p == IDLE) || (p == MAIN)) ? Machine::cpu_id(): ++_next_cpu %= Machine::n_cpus()) {} // Aperiodic
		SMP_LLF(int p = NORMAL, int a): LLF(p), _affinity(a) {}

		SMP_LLF(const RTC::Microsecond & d, const RTC::Microsecond & c): LLF(d,c), _affinity(++_next_cpu %= Machine::n_cpus()) {}
		SMP_LLF(const RTC::Microsecond & d, const RTC::Microsecond & c, int a): LLF(d,c), _affinity(a) {}

		const volatile int & queue() const volatile { return _affinity; }

		static int current() { return Machine::cpu_id(); }

	    private:
		volatile int _affinity;

		static int _next_cpu;
	    };
};

...