Subversion Repositories shark

Rev

Rev 355 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
324 giacomo 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Trimarchi Michael   <trimarchi@gandalf.sssup.it>
10
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/*
20
 * Copyright (C) 2000 Paolo Gai
21
 *
22
 * This program is free software; you can redistribute it and/or modify
23
 * it under the terms of the GNU General Public License as published by
24
 * the Free Software Foundation; either version 2 of the License, or
25
 * (at your option) any later version.
26
 *
27
 * This program is distributed in the hope that it will be useful,
28
 * but WITHOUT ANY WARR2ANTY; without even the implied waRR2anty of
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30
 * GNU General Public License for more details.
31
 *
32
 * You should have received a copy of the GNU General Public License
33
 * along with this program; if not, write to the Free Software
34
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
35
 *
36
 */
37
 
38
 
39
#include <ll/stdio.h>
40
#include <ll/string.h>
41
#include <kernel/model.h>
42
#include <kernel/descr.h>
43
#include <kernel/var.h>
44
#include <kernel/func.h>
45
#include "mpegstar.h"
46
#include "fsf_server.h"
47
 
338 giacomo 48
//#define MPEGSTAR_DEBUG
324 giacomo 49
 
50
/*+ Status used in the level +*/
51
#define MPEGSTAR_READY   MODULE_STATUS_BASE
52
 
343 giacomo 53
#define FRAME_IDLE 0
54
#define FRAME_DECODING 1
55
#define FRAME_SKIPPED 2
56
 
324 giacomo 57
typedef struct {
58
  level_des l;          /*+ the standard level descriptor          +*/
334 giacomo 59
 
60
  int server_Q;
61
  int server_T;
62
 
338 giacomo 63
  int budget;
64
  int current;
343 giacomo 65
  int status;
334 giacomo 66
 
324 giacomo 67
  int scheduling_level;
68
 
69
} MPEGSTAR_level_des;
70
 
71
static int MPEGSTAR_public_eligible(LEVEL l, PID p)
72
{
73
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
74
  return level_table[ lev->scheduling_level ]->
75
      private_eligible(lev->scheduling_level,p);
76
 
77
  return 0;
78
}
79
 
80
static int MPEGSTAR_public_create(LEVEL l, PID p, TASK_MODEL *m)
81
{
82
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
83
 
334 giacomo 84
  #ifdef MPEGSTAR_DEBUG
85
    kern_printf("(MP:Crt:%d)",p);
86
  #endif
338 giacomo 87
 
88
  if (m->pclass != HARD_PCLASS) return -1;
334 giacomo 89
  if (m->level != 0 && m->level != l) return -1;
341 giacomo 90
  if (lev->current != NIL) return -1;
338 giacomo 91
 
92
  lev->current = p;
343 giacomo 93
  lev->status = FRAME_IDLE;
334 giacomo 94
 
95
  proc_table[p].avail_time = lev->server_Q;
338 giacomo 96
  proc_table[p].wcet       = lev->server_Q;                                                                                    
97
  proc_table[p].control = (proc_table[p].control & ~CONTROL_CAP);                  
98
 
324 giacomo 99
  return 0; /* OK */
338 giacomo 100
 
324 giacomo 101
}
102
 
103
static void MPEGSTAR_public_dispatch(LEVEL l, PID p, int nostop)
104
{
105
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
106
 
338 giacomo 107
  #ifdef MPEGSTAR_DEBUG
108
     kern_printf("(MS:Dsp:%d)",p);
109
  #endif
110
 
111
  if (!nostop) {
339 giacomo 112
    level_table[ lev->scheduling_level ] ->
113
      private_dispatch(lev->scheduling_level, p, nostop);
338 giacomo 114
  }
334 giacomo 115
 
324 giacomo 116
}
117
 
118
static void MPEGSTAR_public_epilogue(LEVEL l, PID p)
119
{
120
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
343 giacomo 121
  int r;
334 giacomo 122
 
338 giacomo 123
  #ifdef MPEGSTAR_DEBUG
124
     kern_printf("(MS:Epi:%d)",p);
125
  #endif
126
 
334 giacomo 127
  level_table[ lev->scheduling_level ] ->
128
    private_epilogue(lev->scheduling_level,p);
343 giacomo 129
 
130
  r = SERVER_get_remain_capacity(lev->scheduling_level,lev->budget);
131
  if (r < 0) {
132
 
133
    #ifdef MPEGSTAR_DEBUG
134
      kern_printf("(MS:FRAME SKIP %d)",p);
135
    #endif
136
 
137
    lev->status = FRAME_SKIPPED;
138
 
139
    level_table[ lev->scheduling_level ]->
140
        private_extract(lev->scheduling_level, p);
141
 
142
  }  
143
 
324 giacomo 144
}
145
 
146
static void MPEGSTAR_public_activate(LEVEL l, PID p)
147
{
148
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
334 giacomo 149
  BUDGET_TASK_MODEL b;
338 giacomo 150
 
151
  budget_task_default_model(b, lev->budget);
334 giacomo 152
 
153
  #ifdef MPEGSTAR_DEBUG
338 giacomo 154
    kern_printf("(MP:Act:%d:%d)",p,lev->budget);
334 giacomo 155
  #endif
324 giacomo 156
 
343 giacomo 157
  lev->status = FRAME_DECODING;
158
 
334 giacomo 159
  level_table[ lev->scheduling_level ]->
160
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&b);
161
 
324 giacomo 162
}
163
 
164
static void MPEGSTAR_public_unblock(LEVEL l, PID p)
165
{
166
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
167
 
168
}
169
 
170
static void MPEGSTAR_public_block(LEVEL l, PID p)
171
{  
172
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
173
 
174
}
175
 
176
static int MPEGSTAR_public_message(LEVEL l, PID p, void *m)
177
{
178
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
179
 
180
  switch ((long)(m)) {
181
 
182
    /* Task EndCycle */
183
    case (long)(NULL):
184
 
339 giacomo 185
      #ifdef MPEGSTAR_DEBUG
186
        kern_printf("(MS:EndCycle:%d)",p);
187
      #endif
338 giacomo 188
 
343 giacomo 189
      lev->status = FRAME_IDLE;
190
 
334 giacomo 191
      level_table[ lev->scheduling_level ]->
338 giacomo 192
        private_extract(lev->scheduling_level, p);
193
 
194
      level_table[ lev->scheduling_level ]->
334 giacomo 195
        public_message(lev->scheduling_level, p, NULL);
196
 
324 giacomo 197
      break;
198
 
199
    /* Task Disable */
200
    case (long)(1):
201
 
202
      break;
203
 
204
    default:
205
 
206
      break;
207
 
208
  }
209
 
210
  return 0;
211
 
212
}
213
 
214
static void MPEGSTAR_public_end(LEVEL l, PID p)
215
{
216
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
341 giacomo 217
 
218
  #ifdef MPEGSTAR_DEBUG
219
    kern_printf("(MS:End:%d)", p);
220
  #endif
324 giacomo 221
 
343 giacomo 222
  lev->current = NIL;
223
  lev->status = FRAME_IDLE;
224
  proc_table[p].status = FREE;
341 giacomo 225
 
324 giacomo 226
}
227
 
228
/* Registration functions */
229
 
230
/*+ Registration function:
231
    TIME slice                the slice for the Round Robin queue +*/
334 giacomo 232
LEVEL MPEGSTAR_register_level(int master)
324 giacomo 233
{
234
  LEVEL l;            /* the level that we register */
235
  MPEGSTAR_level_des *lev;  /* for readableness only */
236
 
237
  l = level_alloc_descriptor(sizeof(MPEGSTAR_level_des));
238
 
239
  lev = (MPEGSTAR_level_des *)level_table[l];
240
 
241
  lev->l.public_guarantee = NULL;
242
  lev->l.public_create    = MPEGSTAR_public_create;
243
  lev->l.public_end       = MPEGSTAR_public_end;
244
  lev->l.public_dispatch  = MPEGSTAR_public_dispatch;
245
  lev->l.public_epilogue  = MPEGSTAR_public_epilogue;
246
  lev->l.public_activate  = MPEGSTAR_public_activate;
247
  lev->l.public_unblock   = MPEGSTAR_public_unblock;
248
  lev->l.public_block     = MPEGSTAR_public_block;
249
  lev->l.public_message   = MPEGSTAR_public_message;
250
  lev->l.public_eligible  = MPEGSTAR_public_eligible;
251
 
338 giacomo 252
  lev->budget = NIL;
253
  lev->current = NIL;
343 giacomo 254
  lev->status = FRAME_IDLE;
339 giacomo 255
  lev->server_Q = 0;
256
  lev->server_T = 0;
334 giacomo 257
 
258
  lev->scheduling_level = master;
259
 
324 giacomo 260
  return l;
261
 
262
}
334 giacomo 263
 
264
int MPEGSTAR_setbudget(LEVEL l, PID p, int budget)
265
{
266
 
267
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
268
 
338 giacomo 269
  lev->budget = budget;
334 giacomo 270
 
271
  return 0;
272
 
273
}
274
 
275
int MPEGSTAR_getbudget(LEVEL l, PID p)
276
{
277
 
278
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
279
 
338 giacomo 280
  return lev->budget;
334 giacomo 281
 
282
}
283
 
284
int MPEGSTAR_budget_has_thread(LEVEL l, int budget)
338 giacomo 285
{                                                                                                                            
286
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
287
 
288
  if (lev->budget == budget) return 1;                                                                                                            
289
  return 0;
290
 
291
}
292
 
339 giacomo 293
int MPEGSTAR_rescale(int budget, TIME Q, TIME T)
334 giacomo 294
{
339 giacomo 295
  LEVEL l = SERVER_get_local_scheduler_level_from_budget(fsf_get_server_level(),budget);
334 giacomo 296
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
338 giacomo 297
 
661 giacomo 298
  SERVER_adjust_budget(lev->scheduling_level,Q,T,T,lev->budget);
338 giacomo 299
  lev->server_Q = Q;
300
  lev->server_T = T;
301
  if (lev->current != NIL) {
302
    proc_table[lev->current].avail_time = Q;
303
    proc_table[lev->current].wcet = Q;
304
  }
305
 
334 giacomo 306
  return 0;
307
}
340 giacomo 308
 
309
int MPEGSTAR_get_remain_capacity(int budget)
310
{
341 giacomo 311
  return SERVER_get_remain_capacity(fsf_get_server_level(),budget);
340 giacomo 312
}
341 giacomo 313
 
343 giacomo 314
int MPEGSTAR_get_last_reclaiming(int budget)
341 giacomo 315
{
316
  return SERVER_get_last_reclaiming(fsf_get_server_level(),exec_shadow);
317
}
343 giacomo 318
 
319
int MPEGSTAR_is_frame_skipped(int budget)
320
{
321
  LEVEL l = SERVER_get_local_scheduler_level_from_budget(fsf_get_server_level(),budget);
322
  MPEGSTAR_level_des *lev = (MPEGSTAR_level_des *)(level_table[l]);
323
 
324
  if (lev->status == FRAME_SKIPPED)
325
    return 1;
326
  else
327
    return 0;
328
 
329
}