#ifndef SDI2_PAGER_TASKLIST_H
#define SDI2_PAGER_TASKLIST_H
#include <assert.h>
#include "SlabAllocator.h"
#include "PageMappingList.h"
enum taskstatus_t { TS_NEWBORN = 0, TS_RUNNING, TS_ZOMBIE };
struct TaskEntry
{
struct TaskEntry *prev, *next;
L4_ThreadId_t thread;
taskstatus_t status;
L4_Word_t heaplimit;
PageMappingList mapping;
L4_Word_t retcode;
L4_ThreadId_t waitfor;
};
class TaskList
{
private:
typedef SlabAllocator<TaskEntry> slaballoc_t;
slaballoc_t::Pool* slaballoc;
struct TaskEntry *head;
public:
explicit inline TaskList(slaballoc_t::Pool *usedallocator = NULL)
: slaballoc(usedallocator), head(NULL)
{
}
inline void test() const
{
if (!head) return;
class TaskEntry* iter = head;
assert(iter->prev == iter);
while(iter->next != iter)
{
assert(iter->next->prev == iter);
assert(iter->thread.raw <= iter->next->thread.raw);
iter = iter->next;
}
}
inline const struct TaskEntry* begin() const
{ return head; }
inline struct TaskEntry* begin()
{ return head; }
inline struct TaskEntry *allocate()
{
TaskEntry *newnode = slaballoc->allocate();
if (!newnode) {
assert(0);
return NULL;
}
return newnode;
}
inline bool insert(struct TaskEntry *te)
{
test();
if (!head)
{
te->next = te;
te->prev = te;
head = te;
}
else
{
TaskEntry *iter = head;
while(te->thread.raw >= iter->thread.raw)
{
if (iter->next == iter)
{
iter->next = te;
te->next = te;
te->prev = iter;
test();
return true;
}
iter = iter->next;
}
if (iter->prev == iter)
{
assert(head == iter);
te->prev = te;
te->next = iter;
iter->prev = te;
head = te;
}
else
{
iter->prev->next = te;
te->next = iter;
te->prev = iter->prev;
iter->prev = te;
}
}
test();
return true;
}
inline void remove(struct TaskEntry *e)
{
if (e->prev == e)
{
assert(head == e);
if (e->next == head) {
head = NULL;
}
else {
head = e->next;
head->prev = head;
}
}
else if (e->next == e)
{
e->prev->next = e->prev;
}
else
{
e->prev->next = e->next;
e->next->prev = e->prev;
}
slaballoc->freeobj(e);
}
inline struct TaskEntry *find(L4_ThreadId_t ti)
{
if (!head) return NULL;
TaskEntry *iter = head;
while(ti.raw > iter->thread.raw)
{
if (iter->next == iter)
break;
iter = iter->next;
}
if (ti.raw != iter->thread.raw) return NULL;
return iter;
}
inline void dump() const
{
if (!head) {
printf("TaskList is empty\n");
return;
}
TaskEntry *iter = head;
printf("TaskList dump:\n");
while(1)
{
printTaskEntry(iter);
if (iter->next == iter) break;
iter = iter->next;
}
}
static inline void printTaskEntry(TaskEntry *pme)
{
if (!pme) {
printf("te: (null)\n");
}
else {
printf("te: thrid 0x%x\n",
static_cast<unsigned int>(pme->thread.raw));
}
}
};
#endif