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

Subversion Repositories or1k

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

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1365 Rev 1390
Line 1... Line 1...
/* 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
 
 
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
Line 18... Line 19...
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"
 
 
/* 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  0x7fffffffffffffffLL
#define SCHED_TIME_MAX  INT32_MAX
 
 
 
DECLARE_DEBUG_CHANNEL(sched);
 
 
/* Structure for holding one job entry */
/* Structure for holding one job entry */
struct sched_entry {
struct sched_entry {
  long long 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;
};
};
 
 
/* Heap of jobs */
/* Heap of jobs */
struct scheduler_struct {
struct scheduler_struct {
  int size;
  struct sched_entry *free_job_queue;
  struct sched_entry heap[SCHED_HEAP_SIZE];
  struct sched_entry *job_queue;
};
};
 
 
extern struct scheduler_struct scheduler;
void sched_init(void);
 
void sched_reset(void);
 
 
/* Dummy function, representing a guard, which protects heap from
extern struct scheduler_struct scheduler;
   emptying */
 
extern void sched_guard (void *);
 
 
 
/* Init scheduler -- clear the heap */
 
#define SCHED_INIT() {\
 
        scheduler.heap[1].func = sched_guard;\
 
        scheduler.heap[1].time = SCHED_TIME_MAX;\
 
        scheduler.size = 2;\
 
}
 
 
 
#if SCHED_DEBUG > 1
#if SCHED_DEBUG > 1
#define SCHED_PRINT_JOBS() {\
#define SCHED_PRINT_JOBS() sched_print_jobs()
        int i;\
static inline void sched_print_jobs(void)
        for (i = 1; i < scheduler.size; i++) \
{
          PRINTF ("\t%i: %x $%i @ %i\n", i, scheduler.heap[i].func, scheduler.heap[i].param, scheduler.heap[i].time);\
  struct sched_entry *cur;
 
  int 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,
 
                  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,
                             long long job_time, const char *func)
                             int32_t job_time, const char *func)
{
{
  int i;
  struct sched_entry *cur, *prev, *new_job;
 
  int32_t alltime;
 
 
  if (SCHED_DEBUG > 0)
  if (SCHED_DEBUG > 1)
    PRINTF ("%s@%lli:SCHED_ADD(func %p, param %p, time %lli)\n", func,
    TRACE_(sched)("%s@%lli:SCHED_ADD(time %"PRIi32")\n", func,
            runtime.sim.cycles, job_func, job_param, job_time);
                  runtime.sim.cycles, job_time);
  SCHED_PRINT_JOBS();
  SCHED_PRINT_JOBS();
 
 
  if (SCHED_DEBUG > 1) PRINTF ("--------\n");\
  if (SCHED_DEBUG > 1) TRACE_(sched) ("--------\n");
 
 
  i = scheduler.size++;
  cur = scheduler.job_queue;
  while (i > 1 && scheduler.heap[i / 2].time > job_time) {
  prev = NULL;
    scheduler.heap[i] = scheduler.heap[i / 2];
  alltime = cur->time;
    i /= 2;
  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_(sched)("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;
 
#if DYNAMIC_EXECUTION
 
    /* If we are replaceing the first job in the queue, then update the
 
     * recompiler's internal cycle counter */
 
    set_sched_cycle(job_time);
 
#endif
 
    TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n", job_time,
 
                  runtime.sim.cycles);
  }
  }
 
 
  scheduler.heap[i].func = job_func;
  if(cur)
  scheduler.heap[i].param = job_param;
    cur->time -= new_job->time;
  scheduler.heap[i].time = 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__)
 
 
/* Removes an item from the heap */
/* Returns a job with specified function and param, NULL if not found */
#define SCHED_REMOVE_ITEM(index) {\
static inline void sched_find_remove(void (*job_func)(void *), void *dat,
        struct sched_entry *tmp;\
                                     const char *func)
        int ___i = (index), ___j;\
{
        if (SCHED_DEBUG > 0) PRINTF ("%s@%i:SCHED_REMOVE%i(time %li)\n", __FUNCTION__, runtime.sim.cycles, (index), scheduler.heap[___i].time); \
  struct sched_entry *cur;
        SCHED_PRINT_JOBS();\
  struct sched_entry *prev = NULL;
        if (SCHED_DEBUG > 1) PRINTF ("--------\n");\
 
        tmp = &scheduler.heap[--scheduler.size];\
 
        while (___i <= scheduler.size / 2) {\
 
          ___j = 2 * ___i;\
 
          if (___j < scheduler.size && scheduler.heap[___j].time > scheduler.heap[___j + 1].time) ___j++;\
 
          if (scheduler.heap[___j].time >= tmp->time) break;\
 
          scheduler.heap[___i] = scheduler.heap[___j];\
 
          ___i = ___j;\
 
        }\
 
        scheduler.heap[___i] = *tmp;\
 
        SCHED_PRINT_JOBS();\
 
}
 
 
 
/* Removes first item from the heap */
 
#define SCHED_REMOVE() SCHED_REMOVE_ITEM(1)
 
 
 
/* Returns item with lowest time in the heap */
  TRACE_(sched)("%s@%lli:SCHED_REMOVE()\n", func, runtime.sim.cycles);
#define SCHED_PEEK() scheduler.heap[1]
 
 
 
/* Returns a job with specified function and param, NULL if not found */
  for (cur = scheduler.job_queue; cur; prev = cur, cur = cur->next) {
#define SCHED_FIND(f, p) ({\
    if ((cur->func == job_func) && (cur->param == dat)) {
        int i;\
      if(cur->next)
        struct sched_entry *t = NULL;\
        cur->next->time += cur->time;
        for (i = 1; i < scheduler.size; i++)\
 
          if (scheduler.heap[i].func == (f) && scheduler.heap[i].param == (p)) {\
      if(prev) {
            t = &scheduler.heap[i]; break;\
        prev->next = cur->next;
          }\
      } else {
        tmp;\
        scheduler.job_queue = cur->next;
})
#if DYNAMIC_EXECUTION
 
        if(cur->next)
/* Returns a index of the job with specified function and param, 0 if not found */
          set_sched_cycle(cur->next->time);
#define SCHED_FIND_INDEX(f, p) ({\
#endif
        int i, found = 0;\
        if(cur->next)
        for (i = 1; i < scheduler.size; i++)\
          TRACE_(sched)("Setting to-go cycles to %"PRIi32" at %lli\n",
          if (scheduler.heap[i].func == (f) && scheduler.heap[i].param == (p)) {\
                        cur->next->time, runtime.sim.cycles);
            found = i; break;\
      }
          }\
      cur->next = scheduler.free_job_queue;
        found;\
      scheduler.free_job_queue = cur;
})
      break;
 
    }
 
  }
 
}
 
 
/* Deletes job with specified function and param */
/* Deletes job with specified function and param */
#define SCHED_FIND_REMOVE(f, p) {\
#define SCHED_FIND_REMOVE(f, p) sched_find_remove(f, p, __FUNCTION__)
        int index;\
 
        index = SCHED_FIND_INDEX(f, p);\
 
        if (index) SCHED_REMOVE_ITEM(index);\
 
}
 
 
 
#endif /* _SCHED_H_ */
#endif /* _SCHED_H_ */
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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