#include "types.h"
#include "globals.h"
+struct L4_sched_param_wfq : public L4_sched_param
+{
+ enum : Smword { Class = -2 };
+ Mword quantum;
+ Mword weight;
+};
+
template< typename E >
class Ready_queue_wfq
{
void set_idle(E *sc)
{
idle = sc;
- E::wfq_elem(sc)->_ready_link = &idle;
- E::wfq_elem(sc)->_idle = 1;
+ _e(sc)->_ready_link = &idle;
+ _e(sc)->_idle = 1;
}
- void enqueue(E *);
+ void enqueue(E *, bool is_current);
void dequeue(E *);
E *next_to_run() const;
E *_current_sched;
unsigned _cnt;
E *_heap[1024];
+
+ static typename E::Wfq_sc *_e(E *e) { return E::wfq_elem(e); }
+};
+
+template< typename IMPL >
+class Sched_context_wfq
+{
+public:
+ bool operator <= (Sched_context_wfq const &o) const
+ { return _impl()._dl <= o._impl()._dl; }
+
+ bool operator < (Sched_context_wfq const &o) const
+ { return _impl()._dl < o._impl()._dl; }
+
+private:
+ IMPL const &_impl() const { return static_cast<IMPL const &>(*this); }
+ IMPL &_impl() { return static_cast<IMPL &>(*this); }
};
return _heap[0];
if (_current_sched)
- E::wfq_elem(idle)->_dl = E::wfq_elem(_current_sched)->_dl;
+ _e(idle)->_dl = _e(_current_sched)->_dl;
return idle;
}
void
Ready_queue_wfq<E>::swap(unsigned a, unsigned b)
{
- E::wfq_elem(_heap[a])->_ready_link = &_heap[b];
- E::wfq_elem(_heap[b])->_ready_link = &_heap[a];
+ _e(_heap[a])->_ready_link = &_heap[b];
+ _e(_heap[b])->_ready_link = &_heap[a];
E *s = _heap[a];
_heap[a] = _heap[b];
_heap[b] = s;
for (;a > 0;)
{
unsigned p = (a-1)/2;
- if (*E::wfq_elem(_heap[p]) < *E::wfq_elem(_heap[a]))
+ if (*_e(_heap[p]) < *_e(_heap[a]))
return;
swap(p, a);
a = p;
if (_cnt <= c1)
return;
- if (_cnt > c2 && *E::wfq_elem(_heap[c2]) <= *E::wfq_elem(_heap[c1]))
+ if (_cnt > c2 && *_e(_heap[c2]) <= *_e(_heap[c1]))
c1 = c2;
- if (*E::wfq_elem(_heap[a]) <= *E::wfq_elem(_heap[c1]))
+ if (*_e(_heap[a]) <= *_e(_heap[c1]))
return;
swap(c1, a);
IMPLEMENT
template<typename E>
void
-Ready_queue_wfq<E>::enqueue(E *i)
+Ready_queue_wfq<E>::enqueue(E *i, bool /*is_current_sched**/)
{
assert_kdb(cpu_lock.test());
E *&h = _heap[n];
h = i;
- E::wfq_elem(i)->_ready_link = &h;
+ _e(i)->_ready_link = &h;
heap_up(n);
}
if (EXPECT_FALSE (!i->in_ready_list() || i == idle))
return;
- unsigned x = E::wfq_elem(i)->_ready_link - _heap;
+ unsigned x = _e(i)->_ready_link - _heap;
if (x == --_cnt)
{
- E::wfq_elem(i)->_ready_link = 0;
+ _e(i)->_ready_link = 0;
return;
}
swap(x, _cnt);
heap_down(x);
- E::wfq_elem(i)->_ready_link = 0;
+ _e(i)->_ready_link = 0;
}
/**
Ready_queue_wfq<E>::requeue(E *i)
{
if (!i->in_ready_list())
- enqueue(i);
+ enqueue(i, false);
+
+ heap_down(_e(i)->_ready_link - _heap);
+}
+
+
+PUBLIC template< typename E > inline
+void
+Ready_queue_wfq<E>::deblock_refill(E *sc)
+{
+ Unsigned64 da = 0;
+ if (EXPECT_TRUE(_current_sched != 0))
+ da = _e(_current_sched)->_dl;
+
+ if (_e(sc)->_dl >= da)
+ return;
- heap_down(E::wfq_elem(i)->_ready_link - _heap);
+ _e(sc)->_left += (da - _e(sc)->_dl) * _e(sc)->_w;
+ if (_e(sc)->_left > _e(sc)->_q)
+ _e(sc)->_left = _e(sc)->_q;
+ _e(sc)->_dl = da;
}