Subversion Repositories shark

Rev

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