Subversion Repositories shark

Rev

Rev 867 | Rev 877 | 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
 
871 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;
871 trimarchi 135
 
136
    if (lev->current!=NIL && lev->status!=NONESTAR_IDLE)
137
       level_table[ lev->scheduling_level ]->
138
          private_extract(lev->scheduling_level, p);
139
 
140
    lev->current = NIL;
867 trimarchi 141
    lev->budget = -1;
142
    proc_table[p].task_level = lev->new_level[p];
143
 
144
    /* Send change level command to local scheduler */
145
 
146
    msg.command = STD_ACTIVATE_TASK;
147
    msg.param = NULL;
148
 
149
    level_table[ lev->new_level[p] ]->public_message(lev->new_level[p],p,&msg);
150
 
151
    return 1;
152
 
153
  }
154
 
155
  return 0;
156
 
157
}
158
 
159
 
160
 
853 trimarchi 161
static void NONESTAR_public_epilogue(LEVEL l, PID p)
162
{
163
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
867 trimarchi 164
  //int r;
853 trimarchi 165
 
166
  #ifdef NONESTAR_DEBUG
167
     kern_printf("(NN:Epi:%d)",p);
168
  #endif
169
 
871 trimarchi 170
  if (NONESTAR_change_level(l, p)) return;
867 trimarchi 171
 
853 trimarchi 172
  level_table[ lev->scheduling_level ] ->
173
    private_epilogue(lev->scheduling_level,p);
174
/*
175
  r = SERVER_get_remain_capacity(lev->scheduling_level,lev->budget);
176
  if (r < 0) {
177
 
178
    #ifdef NONESTAR_DEBUG
179
      kern_printf("(NN:NONE END %d)",p);
180
    #endif
181
 
182
    lev->status = NONESTAR_IDLE;
183
 
184
    level_table[ lev->scheduling_level ]->
185
        private_extract(lev->scheduling_level, p);
186
 
187
  }  
188
*/
189
}
190
 
191
static void NONESTAR_public_activate(LEVEL l, PID p, struct timespec *o)
192
{
193
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
194
  BUDGET_TASK_MODEL b;
195
 
196
  budget_task_default_model(b, lev->budget);
197
 
198
  #ifdef NONESTAR_DEBUG
199
    kern_printf("(NN:Act:%d:%d)",p,lev->budget);
200
  #endif
201
 
202
  lev->status = NONESTAR_READY;
203
 
204
  level_table[ lev->scheduling_level ]->
205
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&b);
206
 
207
}
208
 
209
static void NONESTAR_public_unblock(LEVEL l, PID p)
210
{
211
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
867 trimarchi 212
  BUDGET_TASK_MODEL b;
853 trimarchi 213
 
867 trimarchi 214
#ifdef NONESTAR_DEBUG
215
  kern_printf("(NS:pu)");
216
#endif
217
  lev->current=p;
218
 
219
  budget_task_default_model(b, lev->budget);
220
 
221
  level_table[ lev->scheduling_level ]->
222
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&b);
223
 
853 trimarchi 224
}
225
 
226
static void NONESTAR_public_block(LEVEL l, PID p)
227
{  
228
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
229
 
867 trimarchi 230
#ifdef NONESTAR_DEBUG
231
  kern_printf("(NN:pb)");
232
#endif
233
 
234
  /* the task is blocked on a synchronization primitive. we have to
235
     remove it from the master module -and- from the local queue! */
236
  lev->current=NIL;
237
  level_table[ lev->scheduling_level ]->
238
     private_extract(lev->scheduling_level, p);
239
 
853 trimarchi 240
}
241
 
242
static int NONESTAR_public_message(LEVEL l, PID p, void *m)
243
{
867 trimarchi 244
  NONESTAR_level_des  *lev = (NONESTAR_level_des *)(level_table[l]);
245
  STD_command_message *msg;
246
  DUMMY_TASK_MODEL    *h;
853 trimarchi 247
 
248
  switch ((long)(m)) {
249
 
250
    /* Task EndCycle */
251
    case (long)(NULL):
252
 
253
      #ifdef NONESTAR_DEBUG
254
        kern_printf("(NN:EndCycle:%d)",p);
255
      #endif
256
 
871 trimarchi 257
      if (NONESTAR_change_level(l, p)) return 0;
258
 
853 trimarchi 259
      lev->status = NONESTAR_IDLE;
260
 
261
      level_table[ lev->scheduling_level ]->
262
        private_extract(lev->scheduling_level, p);
263
 
264
      level_table[ lev->scheduling_level ]->
265
        public_message(lev->scheduling_level, p, NULL);
266
 
267
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,proc_table[p].context,proc_table[p].task_level);
268
      jet_update_endcycle(); /* Update the Jet data... */
269
      break;
270
 
271
    /* Task Disable */
272
    case (long)(1):
273
 
274
      break;
275
 
276
    default:
867 trimarchi 277
      msg = (STD_command_message *)m;
278
 
279
      switch(msg->command) {
280
      case STD_SET_NEW_MODEL:
281
        /* if the NONESTAR_task_create is called, then the pclass must be a
282
           valid pclass. */
283
        h=(DUMMY_TASK_MODEL *)(msg->param);
284
 
285
        /* now we know that m is a valid model */
286
        lev->flag = 0;      
287
        lev->current = p;
288
        lev->status = NONESTAR_IDLE;
289
 
853 trimarchi 290
 
867 trimarchi 291
 
292
        break;
293
 
294
      case STD_SET_NEW_LEVEL:
295
 
296
        lev->flag |= NONESTAR_CHANGE_LEVEL;
297
        lev->new_level[p] = (int)(msg->param);
298
 
299
        break;
300
 
301
      case STD_ACTIVATE_TASK:
302
 
303
      /* Enable wcet check */
304
        proc_table[p].avail_time = lev->server_Q;
305
        proc_table[p].wcet       = lev->server_Q;                                                                                    
306
        proc_table[p].control = (proc_table[p].control & ~CONTROL_CAP);                  
307
 
308
        NONESTAR_public_activate(l, p, NULL);
309
 
310
        break;
311
      }
312
 
853 trimarchi 313
      break;
867 trimarchi 314
 
853 trimarchi 315
  }
316
 
317
 
318
 
319
  return 0;
320
 
321
}
322
 
323
static void NONESTAR_public_end(LEVEL l, PID p)
324
{
325
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
326
 
327
  #ifdef NONESTAR_DEBUG
328
    kern_printf("(NN:End:%d)", p);
329
  #endif
330
 
331
  lev->current = NIL;
332
  lev->status = NONESTAR_IDLE;
333
  proc_table[p].status = FREE;
334
 
335
}
336
 
337
/* Registration functions */
338
 
339
/*+ Registration function:
340
    TIME slice                the slice for the Round Robin queue +*/
341
LEVEL NONESTAR_register_level(int master)
342
{
343
  LEVEL l;            /* the level that we register */
344
  NONESTAR_level_des *lev;  /* for readableness only */
345
 
346
  l = level_alloc_descriptor(sizeof(NONESTAR_level_des));
347
 
348
  lev = (NONESTAR_level_des *)level_table[l];
349
 
350
  lev->l.public_guarantee = NULL;
351
  lev->l.public_create    = NONESTAR_public_create;
352
  lev->l.public_end       = NONESTAR_public_end;
353
  lev->l.public_dispatch  = NONESTAR_public_dispatch;
354
  lev->l.public_epilogue  = NONESTAR_public_epilogue;
355
  lev->l.public_activate  = NONESTAR_public_activate;
356
  lev->l.public_unblock   = NONESTAR_public_unblock;
357
  lev->l.public_block     = NONESTAR_public_block;
358
  lev->l.public_message   = NONESTAR_public_message;
359
  lev->l.public_eligible  = NONESTAR_public_eligible;
360
 
361
  lev->budget = NIL;
362
  lev->current = NIL;
867 trimarchi 363
  lev->flag = 0;
853 trimarchi 364
  lev->status = NONESTAR_IDLE;
365
  lev->server_Q = 0;
366
  lev->server_T = 0;
367
 
368
  lev->scheduling_level = master;
369
 
370
  return l;
371
 
372
}
373
 
374
int NONESTAR_setbudget(LEVEL l, PID p, int budget)
375
{
376
 
377
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
378
 
379
  lev->budget = budget;
380
 
381
  return 0;
382
 
383
}
384
 
385
int NONESTAR_getbudget(LEVEL l, PID p)
386
{
387
 
388
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
389
 
390
  return lev->budget;
391
 
392
}
393
 
394
int NONESTAR_budget_has_thread(LEVEL l, int budget)
395
{                                                                                                                            
396
  NONESTAR_level_des *lev = (NONESTAR_level_des *)(level_table[l]);
397
 
398
  if (lev->budget == budget) return 1;                                                                                                            
399
  return 0;
400
 
401
}
402
 
403
int NONESTAR_get_remain_capacity(int budget)
404
{
405
  return SERVER_get_remain_capacity(fsf_get_server_level(),budget);
406
}
407
 
408
int NONESTAR_get_last_reclaiming(int budget)
409
{
410
  return SERVER_get_last_reclaiming(fsf_get_server_level(),exec_shadow);
411
}
412
 
413