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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc2/] [or1ksim/] [support/] [sched.c] - Blame information for rev 1748

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

powered by: WebSVN 2.1.0

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