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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [support/] [sched.c] - Blame information for rev 1689

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 807 markom
/* sched.c -- Abstract entities, handling job scheduling
2
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* Abstract memory and routines that go with this. I need to
21
add all sorts of other abstract entities. Currently we have
22
only memory. */
23
 
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <ctype.h>
27
#include <string.h>
28
#include <limits.h>
29
 
30
#include "config.h"
31 1365 nogj
 
32
#ifdef HAVE_INTTYPES_H
33
#include <inttypes.h>
34
#endif
35
 
36
#include "port.h"
37
#include "arch.h"
38
#include "sim-config.h"
39
#include "config.h"
40 807 markom
#include "sched.h"
41 1688 nogj
#include "debug.h"
42 807 markom
 
43 1688 nogj
DEFAULT_DEBUG_CHANNEL(sched);
44
DECLARE_DEBUG_CHANNEL(sched_jobs);
45
 
46
#define SCHED_HEAP_SIZE 128
47
#define SCHED_TIME_MAX  INT32_MAX
48
 
49 1557 nogj
/* FIXME: Scheduler should continue from previous cycles not current ones */
50
 
51 807 markom
struct scheduler_struct scheduler;
52
 
53
/* Dummy function, representing a guard, which protects heap from
54
   emptying */
55 1365 nogj
void sched_guard (void *dat)
56 807 markom
{
57 1390 nogj
  if(scheduler.job_queue)
58
    SCHED_ADD(sched_guard, dat, SCHED_TIME_MAX);
59
  else {
60
    scheduler.job_queue = scheduler.free_job_queue;
61
    scheduler.free_job_queue = scheduler.free_job_queue->next;
62
    scheduler.job_queue->next = NULL;
63
    scheduler.job_queue->func = sched_guard;
64
    scheduler.job_queue->time = SCHED_TIME_MAX;
65
  }
66 807 markom
}
67 1390 nogj
 
68
void sched_reset(void)
69
{
70
  struct sched_entry *cur, *next;
71
 
72
  for(cur = scheduler.job_queue; cur; cur = next) {
73
    next = cur->next;
74
    cur->next = scheduler.free_job_queue;
75
    scheduler.free_job_queue = cur;
76
  }
77
  scheduler.job_queue = NULL;
78
  sched_guard(NULL);
79
}
80
 
81
void sched_init(void)
82
{
83
  int i;
84
  struct sched_entry *new;
85
 
86
  scheduler.free_job_queue = NULL;
87
 
88
  for(i = 0; i < SCHED_HEAP_SIZE; i++) {
89
    if(!(new = malloc(sizeof(struct sched_entry)))) {
90
      fprintf(stderr, "Out-of-memory while allocateing scheduler queue\n");
91
      exit(1);
92
    }
93
    new->next = scheduler.free_job_queue;
94
    scheduler.free_job_queue = new;
95
  }
96
  scheduler.job_queue = NULL;
97
  sched_guard(NULL);
98
}
99 1545 nogj
 
100 1689 nogj
/* Executes jobs in time queue */
101
void do_scheduler(void)
102
{
103
  struct sched_entry *tmp;
104
 
105
  /* Execute all jobs till now */
106
  do {
107
    tmp = scheduler.job_queue;
108
    scheduler.job_queue = tmp->next;
109
    tmp->next = scheduler.free_job_queue;
110
    scheduler.free_job_queue = tmp;
111
 
112
    scheduler.job_queue->time += tmp->time;
113
 
114
    tmp->func (tmp->param);
115
  } while(scheduler.job_queue->time <= 0);
116
}
117
 
118 1688 nogj
static void sched_print_jobs(void)
119
{
120
  struct sched_entry *cur;
121
  int i;
122
 
123
  for (cur = scheduler.job_queue, i = 0; cur; cur = cur->next, i++)
124
    TRACE("\t%i: %p $%p @ %"PRIi32"\n", i, cur->func, cur->param, cur->time);
125
}
126
 
127
/* Adds new job to the queue */
128
void sched_add(void (*job_func)(void *), void *job_param, int32_t job_time,
129
               const char *func)
130
{
131
  struct sched_entry *cur, *prev, *new_job;
132
  int32_t alltime;
133
 
134
  TRACE("%s@%lli:SCHED_ADD(time %"PRIi32")\n", func, runtime.sim.cycles,
135
        job_time);
136
  if(TRACE_ON(sched_jobs)) {
137
    sched_print_jobs();
138
    TRACE("--------\n");
139
  }
140
 
141
  cur = scheduler.job_queue;
142
  prev = NULL;
143
  alltime = cur->time;
144
  while(cur && (alltime < job_time)) {
145
    prev = cur;
146
    cur = cur->next;
147
    if(cur)
148
      alltime += cur->time;
149
  }
150
 
151
  new_job = scheduler.free_job_queue;
152
  scheduler.free_job_queue = new_job->next;
153
  new_job->next = cur;
154
 
155
  new_job->func = job_func;
156
  new_job->param = job_param;
157
 
158
  if(prev) {
159
    new_job->time = job_time - (alltime - (cur ? cur->time : 0));
160
    prev->next = new_job;
161
    TRACE("Scheduled job not going to head of queue, relative time: %"
162
          PRIi32"\n", new_job->time);
163
  } else {
164
    scheduler.job_queue = new_job;
165
    new_job->time = job_time >= 0 ? job_time : cur->time;
166
    TRACE("Setting to-go cycles to %"PRIi32" at %lli\n", job_time,
167
          runtime.sim.cycles);
168
  }
169
 
170
  if(cur)
171
    cur->time -= new_job->time;
172
 
173
  if(TRACE_ON(sched_jobs))
174
    sched_print_jobs();
175
}
176
 
177
/* Returns a job with specified function and param, NULL if not found */
178
void sched_find_remove(void (*job_func)(void *), void *dat, const char *func)
179
{
180
  struct sched_entry *cur;
181
  struct sched_entry *prev = NULL;
182
 
183
  TRACE("%s@%lli:SCHED_REMOVE()\n", func, runtime.sim.cycles);
184
 
185
  for (cur = scheduler.job_queue; cur; prev = cur, cur = cur->next) {
186
    if ((cur->func == job_func) && (cur->param == dat)) {
187
      if(cur->next)
188
        cur->next->time += cur->time;
189
 
190
      if(prev)
191
        prev->next = cur->next;
192
      else
193
        scheduler.job_queue = cur->next;
194
      cur->next = scheduler.free_job_queue;
195
      scheduler.free_job_queue = cur;
196
      break;
197
    }
198
  }
199
}
200
 
201 1545 nogj
/* Schedules the next job so that it will run after the next instruction */
202
void sched_next_insn(void (*func)(void *), void *dat)
203
{
204
  int32_t cycles = 1;
205
  struct sched_entry *cur = scheduler.job_queue;
206
 
207
  /* The cycles count of the jobs may go into negatives.  If this happens, func
208
   * will get called before the next instruction has executed. */
209
  while(cur && (cur->time < 0)) {
210
    cycles -= cur->time;
211
    cur = cur->next;
212
  }
213
 
214
  SCHED_ADD(func, dat, cycles);
215
}
216
 
217
 

powered by: WebSVN 2.1.0

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