Subversion Repositories shark

Rev

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

Rev Author Line No. Line
853 trimarchi 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 "nonestar.h"
867 trimarchi 46
#include "fsf_configuration_parameters.h"
47
#include "fsf_core.h"
853 trimarchi 48
#include "fsf_server.h"
49
#include "tracer.h"
867 trimarchi 50
#include <modules/comm_message.h>
853 trimarchi 51
 
867 trimarchi 52
//#define NONESTAR_DEBUG
853 trimarchi 53
 
867 trimarchi 54
#define NONESTAR_CHANGE_LEVEL 1
55
 
853 trimarchi 56
/*+ Status used in the level +*/
57
#define NONESTAR_READY   MODULE_STATUS_BASE
58
 
59
#define NONESTAR_IDLE 0
60
 
61
typedef struct {
62
  level_des l;          /*+ the standard level descriptor          +*/
63
 
64
  int server_Q;
65
  int server_T;
66
 
67
  int budget;
68
  int current;
69
  int status;
867 trimarchi 70
  int flag;
853 trimarchi 71
 
72
  int scheduling_level;
867 trimarchi 73
  int new_level[MAX_PROC];
853 trimarchi 74
 
75
} NONESTAR_level_des;
76
 
77
static int NONESTAR_public_eligible(LEVEL l, PID p)
78
{
79
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
80
  return level_table[ lev->scheduling_level ]->
81
      private_eligible(lev->scheduling_level,p);
82
 
83
  return 0;
84
}
85
 
86
static int NONESTAR_public_create(LEVEL l, PID p, TASK_MODEL *m)
87
{
88
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
867 trimarchi 89
 
853 trimarchi 90
  #ifdef NONESTAR_DEBUG
91
    kern_printf("(NN:Crt:%d)",p);
92
  #endif
93
 
857 blundell 94
  if (m->pclass != DUMMY_PCLASS) return -1;
853 trimarchi 95
 
867 trimarchi 96
  if (m->level != 0 && m->level != l) return -1;
97
  if (lev->current != NIL) return -1;
98
 
853 trimarchi 99
  lev->current = p;
867 trimarchi 100
  lev->flag = 0;
853 trimarchi 101
  lev->status = NONESTAR_IDLE;
102
 
103
  proc_table[p].avail_time = lev->server_Q;
104
  proc_table[p].wcet       = lev->server_Q;                                                                                    
105
  proc_table[p].control = (proc_table[p].control & ~CONTROL_CAP);                  
106
 
107
  return 0; /* OK */
108
 
109
}
110
 
111
static void NONESTAR_public_dispatch(LEVEL l, PID p, int nostop)
112
{
113
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
114
 
115
  #ifdef NONESTAR_DEBUG
116
     kern_printf("(NN:Dsp:%d)",p);
117
  #endif
118
 
119
  if (!nostop) {
120
    level_table[ lev->scheduling_level ] ->
121
      private_dispatch(lev->scheduling_level, p, nostop);
122
  }
123
 
124
}
125
 
867 trimarchi 126
static int NONESTAR_change_level(LEVEL l, PID p)
127
{
128
 
129
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
130
 
131
  /* Change task level */
132
  if (lev->flag & NONESTAR_CHANGE_LEVEL) {
133
    STD_command_message msg;
134
    proc_table[p].status = SLEEP;
135
    lev->current=NIL;
136
 
137
    lev->budget = -1;
138
    proc_table[p].task_level = lev->new_level[p];
139
 
140
    /* Send change level command to local scheduler */
141
 
142
    msg.command = STD_ACTIVATE_TASK;
143
    msg.param = NULL;
144
 
145
    level_table[ lev->new_level[p] ]->public_message(lev->new_level[p],p,&msg);
146
 
147
    return 1;
148
 
149
  }
150
 
151
  return 0;
152
 
153
}
154
 
155
 
156
 
853 trimarchi 157
static void NONESTAR_public_epilogue(LEVEL l, PID p)
158
{
159
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
867 trimarchi 160
  //int r;
853 trimarchi 161
 
162
  #ifdef NONESTAR_DEBUG
163
     kern_printf("(NN:Epi:%d)",p);
164
  #endif
165
 
867 trimarchi 166
     if (NONESTAR_change_level(l, p)) return;
167
 
853 trimarchi 168
  level_table[ lev->scheduling_level ] ->
169
    private_epilogue(lev->scheduling_level,p);
170
/*
171
  r = SERVER_get_remain_capacity(lev->scheduling_level,lev->budget);
172
  if (r < 0) {
173
 
174
    #ifdef NONESTAR_DEBUG
175
      kern_printf("(NN:NONE END %d)",p);
176
    #endif
177
 
178
    lev->status = NONESTAR_IDLE;
179
 
180
    level_table[ lev->scheduling_level ]->
181
        private_extract(lev->scheduling_level, p);
182
 
183
  }  
184
*/
185
}
186
 
187
static void NONESTAR_public_activate(LEVEL l, PID p, struct timespec *o)
188
{
189
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
190
  BUDGET_TASK_MODEL b;
191
 
192
  budget_task_default_model(b, lev->budget);
193
 
194
  #ifdef NONESTAR_DEBUG
195
    kern_printf("(NN:Act:%d:%d)",p,lev->budget);
196
  #endif
197
 
198
  lev->status = NONESTAR_READY;
199
 
200
  level_table[ lev->scheduling_level ]->
201
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&b);
202
 
203
}
204
 
205
static void NONESTAR_public_unblock(LEVEL l, PID p)
206
{
207
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
867 trimarchi 208
  BUDGET_TASK_MODEL b;
853 trimarchi 209
 
867 trimarchi 210
#ifdef NONESTAR_DEBUG
211
  kern_printf("(NS:pu)");
212
#endif
213
  lev->current=p;
214
 
215
  budget_task_default_model(b, lev->budget);
216
 
217
  level_table[ lev->scheduling_level ]->
218
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&b);
219
 
853 trimarchi 220
}
221
 
222
static void NONESTAR_public_block(LEVEL l, PID p)
223
{  
224
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
225
 
867 trimarchi 226
#ifdef NONESTAR_DEBUG
227
  kern_printf("(NN:pb)");
228
#endif
229
 
230
  /* the task is blocked on a synchronization primitive. we have to
231
     remove it from the master module -and- from the local queue! */
232
  lev->current=NIL;
233
  level_table[ lev->scheduling_level ]->
234
     private_extract(lev->scheduling_level, p);
235
 
853 trimarchi 236
}
237
 
238
static int NONESTAR_public_message(LEVEL l, PID p, void *m)
239
{
867 trimarchi 240
  NONESTAR_level_des  *lev = (NONESTAR_level_des *)(level_table[l]);
241
  STD_command_message *msg;
242
  DUMMY_TASK_MODEL    *h;
853 trimarchi 243
 
244
  switch ((long)(m)) {
245
 
246
    /* Task EndCycle */
247
    case (long)(NULL):
248
 
249
      #ifdef NONESTAR_DEBUG
250
        kern_printf("(NN:EndCycle:%d)",p);
251
      #endif
252
 
253
      lev->status = NONESTAR_IDLE;
254
 
255
      level_table[ lev->scheduling_level ]->
256
        private_extract(lev->scheduling_level, p);
257
 
258
      level_table[ lev->scheduling_level ]->
259
        public_message(lev->scheduling_level, p, NULL);
260
 
261
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,proc_table[p].context,proc_table[p].task_level);
262
      jet_update_endcycle(); /* Update the Jet data... */
263
      break;
264
 
265
    /* Task Disable */
266
    case (long)(1):
267
 
268
      break;
269
 
270
    default:
867 trimarchi 271
      msg = (STD_command_message *)m;
272
 
273
      switch(msg->command) {
274
      case STD_SET_NEW_MODEL:
275
        /* if the NONESTAR_task_create is called, then the pclass must be a
276
           valid pclass. */
277
        h=(DUMMY_TASK_MODEL *)(msg->param);
278
 
279
        /* now we know that m is a valid model */
280
        lev->flag = 0;      
281
        lev->current = p;
282
        lev->status = NONESTAR_IDLE;
283
 
853 trimarchi 284
 
867 trimarchi 285
 
286
        break;
287
 
288
      case STD_SET_NEW_LEVEL:
289
 
290
        lev->flag |= NONESTAR_CHANGE_LEVEL;
291
        lev->new_level[p] = (int)(msg->param);
292
 
293
        break;
294
 
295
      case STD_ACTIVATE_TASK:
296
 
297
      /* Enable wcet check */
298
        proc_table[p].avail_time = lev->server_Q;
299
        proc_table[p].wcet       = lev->server_Q;                                                                                    
300
        proc_table[p].control = (proc_table[p].control & ~CONTROL_CAP);                  
301
 
302
        NONESTAR_public_activate(l, p, NULL);
303
 
304
        break;
305
      }
306
 
853 trimarchi 307
      break;
867 trimarchi 308
 
853 trimarchi 309
  }
310
 
311
 
312
 
313
  return 0;
314
 
315
}
316
 
317
static void NONESTAR_public_end(LEVEL l, PID p)
318
{
319
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
320
 
321
  #ifdef NONESTAR_DEBUG
322
    kern_printf("(NN:End:%d)", p);
323
  #endif
324
 
325
  lev->current = NIL;
326
  lev->status = NONESTAR_IDLE;
327
  proc_table[p].status = FREE;
328
 
329
}
330
 
331
/* Registration functions */
332
 
333
/*+ Registration function:
334
    TIME slice                the slice for the Round Robin queue +*/
335
LEVEL NONESTAR_register_level(int master)
336
{
337
  LEVEL l;            /* the level that we register */
338
  NONESTAR_level_des *lev;  /* for readableness only */
339
 
340
  l = level_alloc_descriptor(sizeof(NONESTAR_level_des));
341
 
342
  lev = (NONESTAR_level_des *)level_table[l];
343
 
344
  lev->l.public_guarantee = NULL;
345
  lev->l.public_create    = NONESTAR_public_create;
346
  lev->l.public_end       = NONESTAR_public_end;
347
  lev->l.public_dispatch  = NONESTAR_public_dispatch;
348
  lev->l.public_epilogue  = NONESTAR_public_epilogue;
349
  lev->l.public_activate  = NONESTAR_public_activate;
350
  lev->l.public_unblock   = NONESTAR_public_unblock;
351
  lev->l.public_block     = NONESTAR_public_block;
352
  lev->l.public_message   = NONESTAR_public_message;
353
  lev->l.public_eligible  = NONESTAR_public_eligible;
354
 
355
  lev->budget = NIL;
356
  lev->current = NIL;
867 trimarchi 357
  lev->flag = 0;
853 trimarchi 358
  lev->status = NONESTAR_IDLE;
359
  lev->server_Q = 0;
360
  lev->server_T = 0;
361
 
362
  lev->scheduling_level = master;
363
 
364
  return l;
365
 
366
}
367
 
368
int NONESTAR_setbudget(LEVEL l, PID p, int budget)
369
{
370
 
371
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
372
 
373
  lev->budget = budget;
374
 
375
  return 0;
376
 
377
}
378
 
379
int NONESTAR_getbudget(LEVEL l, PID p)
380
{
381
 
382
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
383
 
384
  return lev->budget;
385
 
386
}
387
 
388
int NONESTAR_budget_has_thread(LEVEL l, int budget)
389
{                                                                                                                            
390
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
391
 
392
  if (lev->budget == budget) return 1;                                                                                                            
393
  return 0;
394
 
395
}
396
 
397
int NONESTAR_get_remain_capacity(int budget)
398
{
399
  return SERVER_get_remain_capacity(fsf_get_server_level(),budget);
400
}
401
 
402
int NONESTAR_get_last_reclaiming(int budget)
403
{
404
  return SERVER_get_last_reclaiming(fsf_get_server_level(),exec_shadow);
405
}
406
 
407