enum {
Nproc = 8,
Nres = 8,
Ntask = 8,
Maxtasks = 20,
Maxresources = 20,
Maxsteps = Maxtasks * 2 * 100, /* 100 periods of maximum # of tasks */
/* Edf.flags field */
Verbose = 0x1,
Useblocking = 0x2,
Infinity = 0xffffffffffffffffULL,
};
enum Edfstate {
EdfUnused, /* task structure not in use */
EdfExpelled, /* in initialization, not yet admitted */
EdfAdmitted, /* admitted, but not started */
EdfIdle, /* admitted, but no member processes */
EdfAwaitrelease, /* released, but too early (on qwaitrelease) */
EdfReleased, /* released, but not yet scheduled (on qreleased) */
EdfRunning, /* one of this task's procs is running (on stack) */
EdfExtra, /* one of this task's procs is running in extra time (off stack) */
EdfPreempted, /* the running proc was preempted */
EdfBlocked, /* none of the procs are runnable as a result of sleeping */
EdfDeadline, /* none of the procs are runnable as a result of scheduling */
};
typedef enum Edfstate Edfstate;
typedef struct Edf Edf;
typedef struct Head Head;
typedef struct List List;
typedef struct Resource Resource;
typedef struct Task Task;
typedef struct Taskq Taskq;
typedef struct CSN CSN;
typedef struct TaskLink TaskLink;
struct List {
List * next; /* next in list */
void * i; /* item in list */
};
struct Head {
List *next; /* First item in list */
int n; /* number of items in list */
};
struct Edf {
/* time intervals */
Ticks D; /* Deadline */
Ticks Delta; /* Inherited deadline */
Ticks T; /* period */
Ticks C; /* Cost */
Ticks S; /* Slice: time remaining in this period */
/* times */
Ticks r; /* (this) release time */
Ticks d; /* (this) deadline */
Ticks t; /* Start of next period, t += T at release */
/* for schedulability testing */
Ticks testDelta;
int testtype; /* Release or Deadline */
Ticks testtime;
Task * testnext;
/* statistics gathering */
ulong periods; /* number of periods */
ulong missed; /* number of deadlines missed */
ulong preemptions;
Ticks total; /* total time used */
Ticks aged; /* aged time used */
/* other */
Edfstate state;
};
struct Task {
QLock;
Ref; /* ref count for farbage collection */
int taskno; /* task number in Qid */
Edf;
Ticks scheduled;
Schedq runq; /* Queue of runnable member procs */
Head procs; /* List of member procs */
Head csns; /* List of resources */
CSN *curcsn; /* Position in CSN tree or nil */
char *user; /* mallocated */
Dirtab dir;
int flags; /* e.g., Verbose */
Task *rnext;
};
struct Taskq
{
Lock;
Task* head;
int (*before)(Task*, Task*); /* ordering function for queue (nil: fifo) */
};
struct Resource
{
Ref;
char * name;
Head tasks;
Ticks Delta;
/* for schedulability testing */
Ticks testDelta;
};
struct CSN {
List; /* links and identifies the resource (must be first) */
Task *t; /* task the CSN belongs to */
Ticks C; /* cost */
int R; /* read-only access (as opposed to exclusive access) */
Ticks Delta; /* of the Tasks critical section */
Ticks testDelta;
Ticks S; /* Remaining slice */
CSN* p; /* parent resource items */
};
struct TaskLink {
List; /* links and identifies the task (must be first) */
Ticks C; /* cost */
int R; /* read-only access (as opposed to exclusive access) */
};
extern QLock edfschedlock;
extern Head tasks;
extern Head resources;
extern int nresources;
extern Lock edflock;
extern Taskq qwaitrelease;
extern Taskq qreleased;
extern Taskq qextratime;
extern Taskq edfstack[];
extern int edfstateupdate;
extern void (*devrt)(Task *, Ticks, int);
extern char * edfstatename[];
#pragma varargck type "T" Time
#pragma varargck type "U" Ticks
Time ticks2time(Ticks);
Ticks time2ticks(Time);
int putlist(Head*, List*);
int enlist(Head*, void*);
int delist(Head*, void*);
char * parsetime(Time*, char*);
void * findlist(Head*, void*);
Task * findtask(int);
List * onlist(Head*, void*);
int timeconv(Fmt*);
void resourcefree(Resource*);
Resource* resource(char*, int);
void removetask(Task*);
void taskfree(Task*);
char * parseresource(Head*, CSN*, char*);
char * seprintresources(char*, char*);
char * seprintcsn(char*, char*, Head*);
void resourcetimes(Task*, Head*);
char* dumpq(char*, char*, Taskq*, Ticks);
char* seprinttask(char*, char*, Task*, Ticks);
char* dumpq(char*, char*, Taskq*, Ticks);
#define DEBUG if(1){}else iprint