Subversion Repositories shark

Rev

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