Line 36... |
Line 36... |
#include "port.h"
|
#include "port.h"
|
#include "arch.h"
|
#include "arch.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "config.h"
|
#include "config.h"
|
#include "sched.h"
|
#include "sched.h"
|
|
#include "debug.h"
|
|
|
|
DEFAULT_DEBUG_CHANNEL(sched);
|
|
DECLARE_DEBUG_CHANNEL(sched_jobs);
|
|
|
|
#define SCHED_HEAP_SIZE 128
|
|
#define SCHED_TIME_MAX INT32_MAX
|
|
|
/* FIXME: Scheduler should continue from previous cycles not current ones */
|
/* FIXME: Scheduler should continue from previous cycles not current ones */
|
|
|
struct scheduler_struct scheduler;
|
struct scheduler_struct scheduler;
|
|
|
Line 88... |
Line 95... |
}
|
}
|
scheduler.job_queue = NULL;
|
scheduler.job_queue = NULL;
|
sched_guard(NULL);
|
sched_guard(NULL);
|
}
|
}
|
|
|
|
static void sched_print_jobs(void)
|
|
{
|
|
struct sched_entry *cur;
|
|
int i;
|
|
|
|
for (cur = scheduler.job_queue, i = 0; cur; cur = cur->next, i++)
|
|
TRACE("\t%i: %p $%p @ %"PRIi32"\n", i, cur->func, cur->param, cur->time);
|
|
}
|
|
|
|
/* Adds new job to the queue */
|
|
void sched_add(void (*job_func)(void *), void *job_param, int32_t job_time,
|
|
const char *func)
|
|
{
|
|
struct sched_entry *cur, *prev, *new_job;
|
|
int32_t alltime;
|
|
|
|
TRACE("%s@%lli:SCHED_ADD(time %"PRIi32")\n", func, runtime.sim.cycles,
|
|
job_time);
|
|
if(TRACE_ON(sched_jobs)) {
|
|
sched_print_jobs();
|
|
TRACE("--------\n");
|
|
}
|
|
|
|
cur = scheduler.job_queue;
|
|
prev = NULL;
|
|
alltime = cur->time;
|
|
while(cur && (alltime < job_time)) {
|
|
prev = cur;
|
|
cur = cur->next;
|
|
if(cur)
|
|
alltime += cur->time;
|
|
}
|
|
|
|
new_job = scheduler.free_job_queue;
|
|
scheduler.free_job_queue = new_job->next;
|
|
new_job->next = cur;
|
|
|
|
new_job->func = job_func;
|
|
new_job->param = job_param;
|
|
|
|
if(prev) {
|
|
new_job->time = job_time - (alltime - (cur ? cur->time : 0));
|
|
prev->next = new_job;
|
|
TRACE("Scheduled job not going to head of queue, relative time: %"
|
|
PRIi32"\n", new_job->time);
|
|
} else {
|
|
scheduler.job_queue = new_job;
|
|
new_job->time = job_time >= 0 ? job_time : cur->time;
|
|
TRACE("Setting to-go cycles to %"PRIi32" at %lli\n", job_time,
|
|
runtime.sim.cycles);
|
|
}
|
|
|
|
if(cur)
|
|
cur->time -= new_job->time;
|
|
|
|
if(TRACE_ON(sched_jobs))
|
|
sched_print_jobs();
|
|
}
|
|
|
|
/* Returns a job with specified function and param, NULL if not found */
|
|
void sched_find_remove(void (*job_func)(void *), void *dat, const char *func)
|
|
{
|
|
struct sched_entry *cur;
|
|
struct sched_entry *prev = NULL;
|
|
|
|
TRACE("%s@%lli:SCHED_REMOVE()\n", func, runtime.sim.cycles);
|
|
|
|
for (cur = scheduler.job_queue; cur; prev = cur, cur = cur->next) {
|
|
if ((cur->func == job_func) && (cur->param == dat)) {
|
|
if(cur->next)
|
|
cur->next->time += cur->time;
|
|
|
|
if(prev)
|
|
prev->next = cur->next;
|
|
else
|
|
scheduler.job_queue = cur->next;
|
|
cur->next = scheduler.free_job_queue;
|
|
scheduler.free_job_queue = cur;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
/* Schedules the next job so that it will run after the next instruction */
|
/* Schedules the next job so that it will run after the next instruction */
|
void sched_next_insn(void (*func)(void *), void *dat)
|
void sched_next_insn(void (*func)(void *), void *dat)
|
{
|
{
|
int32_t cycles = 1;
|
int32_t cycles = 1;
|
struct sched_entry *cur = scheduler.job_queue;
|
struct sched_entry *cur = scheduler.job_queue;
|