OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_52/] [or1ksim/] [support/] [sched.h] - Diff between revs 1429 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 1429 Rev 1765
/* sched.h -- Abstract entities header file handling job scheduler
/* sched.h -- Abstract entities header file handling job scheduler
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
This file is part of OpenRISC 1000 Architectural Simulator.
 
 
This program is free software; you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
#ifndef _SCHED_H_
#ifndef _SCHED_H_
#define _SCHED_H_
#define _SCHED_H_
 
 
#include "debug.h"
#include "debug.h"
 
 
/* Scheduler debug level */
/* Scheduler debug level */
#define SCHED_DEBUG     0
#define SCHED_DEBUG     0
 
 
#define SCHED_HEAP_SIZE 128
#define SCHED_HEAP_SIZE 128
#define SCHED_TIME_MAX  INT32_MAX
#define SCHED_TIME_MAX  INT32_MAX
 
 
DECLARE_DEBUG_CHANNEL(sched);
DECLARE_DEBUG_CHANNEL(sched);
 
 
/* Structure for holding one job entry */
/* Structure for holding one job entry */
struct sched_entry {
struct sched_entry {
  int32_t time;          /* Clock cycles before job starts */
  int32_t time;          /* Clock cycles before job starts */
  void *param;           /* Parameter to pass to the function */
  void *param;           /* Parameter to pass to the function */
  void (*func)(void *);  /* Function to call when time reaches 0 */
  void (*func)(void *);  /* Function to call when time reaches 0 */
  struct sched_entry *next;
  struct sched_entry *next;
};
};
 
 
/* Heap of jobs */
/* Heap of jobs */
struct scheduler_struct {
struct scheduler_struct {
  struct sched_entry *free_job_queue;
  struct sched_entry *free_job_queue;
  struct sched_entry *job_queue;
  struct sched_entry *job_queue;
};
};
 
 
void sched_init(void);
void sched_init(void);
void sched_reset(void);
void sched_reset(void);
 
 
extern struct scheduler_struct scheduler;
extern struct scheduler_struct scheduler;
 
 
#if SCHED_DEBUG > 1
#if SCHED_DEBUG > 1
#define SCHED_PRINT_JOBS() sched_print_jobs()
#define SCHED_PRINT_JOBS() sched_print_jobs()
static inline void sched_print_jobs(void)
static inline void sched_print_jobs(void)
{
{
  struct sched_entry *cur;
  struct sched_entry *cur;
  int i;
  int i;
 
 
  for (cur = scheduler.job_queue, i = 0; cur; cur = cur->next, i++)
  for (cur = scheduler.job_queue, i = 0; cur; cur = cur->next, i++)
    TRACE_(sched)("\t%i: %p $%p @ %"PRIi32"\n", i, cur->func, cur->param,
    TRACE_(sched)("\t%i: %p $%p @ %"PRIi32"\n", i, cur->func, cur->param,
                  cur->time);
                  cur->time);
}
}
#else
#else
#define SCHED_PRINT_JOBS()
#define SCHED_PRINT_JOBS()
#endif
#endif
 
 
/* Adds new job to the queue */
/* Adds new job to the queue */
static inline void sched_add(void (*job_func)(void *), void *job_param,
static inline void sched_add(void (*job_func)(void *), void *job_param,
                             int32_t job_time, const char *func)
                             int32_t job_time, const char *func)
{
{
  struct sched_entry *cur, *prev, *new_job;
  struct sched_entry *cur, *prev, *new_job;
  int32_t alltime;
  int32_t alltime;
 
 
  if (SCHED_DEBUG > 1)
  if (SCHED_DEBUG > 1)
    TRACE_(sched)("%s@%lli:SCHED_ADD(time %"PRIi32")\n", func,
    TRACE_(sched)("%s@%lli:SCHED_ADD(time %"PRIi32")\n", func,
                  runtime.sim.cycles, job_time);
                  runtime.sim.cycles, job_time);
  SCHED_PRINT_JOBS();
  SCHED_PRINT_JOBS();
 
 
  if (SCHED_DEBUG > 1) TRACE_(sched) ("--------\n");
  if (SCHED_DEBUG > 1) TRACE_(sched) ("--------\n");
 
 
  cur = scheduler.job_queue;
  cur = scheduler.job_queue;
  prev = NULL;
  prev = NULL;
  alltime = cur->time;
  alltime = cur->time;
  while(cur && (alltime < job_time)) {
  while(cur && (alltime < job_time)) {
    prev = cur;
    prev = cur;
    cur = cur->next;
    cur = cur->next;
    if(cur)
    if(cur)
      alltime += cur->time;
      alltime += cur->time;
  }
  }
 
 
  new_job = scheduler.free_job_queue;
  new_job = scheduler.free_job_queue;
  scheduler.free_job_queue = new_job->next;
  scheduler.free_job_queue = new_job->next;
  new_job->next = cur;
  new_job->next = cur;
 
 
  new_job->func = job_func;
  new_job->func = job_func;
  new_job->param = job_param;
  new_job->param = job_param;
 
 
  if(prev) {
  if(prev) {
    new_job->time = job_time - (alltime - (cur ? cur->time : 0));
    new_job->time = job_time - (alltime - (cur ? cur->time : 0));
    prev->next = new_job;
    prev->next = new_job;
    TRACE_(sched)("Scheduled job not going to head of queue, relative time: %"
    TRACE_(sched)("Scheduled job not going to head of queue, relative time: %"
                  PRIi32"\n", new_job->time);
                  PRIi32"\n", new_job->time);
  } else {
  } else {
    scheduler.job_queue = new_job;
    scheduler.job_queue = new_job;
    new_job->time = job_time;
    new_job->time = job_time;
#if DYNAMIC_EXECUTION
#if DYNAMIC_EXECUTION
    /* If we are replaceing the first job in the queue, then update the
    /* If we are replaceing the first job in the queue, then update the
     * recompiler's internal cycle counter */
     * recompiler's internal cycle counter */
    set_sched_cycle(job_time);
    set_sched_cycle(job_time);
#endif
#endif
    TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n", job_time,
    TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n", job_time,
                  runtime.sim.cycles);
                  runtime.sim.cycles);
  }
  }
 
 
  if(cur)
  if(cur)
    cur->time -= new_job->time;
    cur->time -= new_job->time;
 
 
  SCHED_PRINT_JOBS();
  SCHED_PRINT_JOBS();
}
}
 
 
#define SCHED_ADD(job_func, job_param, job_time) sched_add(job_func, job_param, job_time, __FUNCTION__)
#define SCHED_ADD(job_func, job_param, job_time) sched_add(job_func, job_param, job_time, __FUNCTION__)
 
 
/* Returns a job with specified function and param, NULL if not found */
/* Returns a job with specified function and param, NULL if not found */
static inline void sched_find_remove(void (*job_func)(void *), void *dat,
static inline void sched_find_remove(void (*job_func)(void *), void *dat,
                                     const char *func)
                                     const char *func)
{
{
  struct sched_entry *cur;
  struct sched_entry *cur;
  struct sched_entry *prev = NULL;
  struct sched_entry *prev = NULL;
 
 
  TRACE_(sched)("%s@%lli:SCHED_REMOVE()\n", func, runtime.sim.cycles);
  TRACE_(sched)("%s@%lli:SCHED_REMOVE()\n", func, runtime.sim.cycles);
 
 
  for (cur = scheduler.job_queue; cur; prev = cur, cur = cur->next) {
  for (cur = scheduler.job_queue; cur; prev = cur, cur = cur->next) {
    if ((cur->func == job_func) && (cur->param == dat)) {
    if ((cur->func == job_func) && (cur->param == dat)) {
      if(cur->next)
      if(cur->next)
        cur->next->time += cur->time;
        cur->next->time += cur->time;
 
 
      if(prev) {
      if(prev) {
        prev->next = cur->next;
        prev->next = cur->next;
      } else {
      } else {
        scheduler.job_queue = cur->next;
        scheduler.job_queue = cur->next;
#if DYNAMIC_EXECUTION
#if DYNAMIC_EXECUTION
        if(cur->next)
        if(cur->next)
          set_sched_cycle(cur->next->time);
          set_sched_cycle(cur->next->time);
#endif
#endif
        if(cur->next)
        if(cur->next)
          TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n",
          TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n",
                        cur->next->time, runtime.sim.cycles);
                        cur->next->time, runtime.sim.cycles);
      }
      }
      cur->next = scheduler.free_job_queue;
      cur->next = scheduler.free_job_queue;
      scheduler.free_job_queue = cur;
      scheduler.free_job_queue = cur;
      break;
      break;
    }
    }
  }
  }
}
}
 
 
/* Deletes job with specified function and param */
/* Deletes job with specified function and param */
#define SCHED_FIND_REMOVE(f, p) sched_find_remove(f, p, __FUNCTION__)
#define SCHED_FIND_REMOVE(f, p) sched_find_remove(f, p, __FUNCTION__)
 
 
#endif /* _SCHED_H_ */
#endif /* _SCHED_H_ */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.