Subversion Repositories shark

Rev

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

Rev Author Line No. Line
241 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
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/*
22
 * Copyright (C) 2002 Paolo Gai
23
 *
24
 * This program is free software; you can redistribute it and/or modify
25
 * it under the terms of the GNU General Public License as published by
26
 * the Free Software Foundation; either version 2 of the License, or
27
 * (at your option) any later version.
28
 *
29
 * This program is distributed in the hope that it will be useful,
30
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
 * GNU General Public License for more details.
33
 *
34
 * You should have received a copy of the GNU General Public License
35
 * along with this program; if not, write to the Free Software
36
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
37
 *
38
 */
39
 
253 giacomo 40
#include "grubstar.h"
241 giacomo 41
 
266 trimarchi 42
//#define GRUBSTAR_DEBUG
241 giacomo 43
 
44
/* this structure contains the status for a single budget */
45
struct budget_struct {
46
  TIME Q;                 /* budget */
47
  TIME T;                 /* period */
48
 
49
  struct timespec dline;  /* deadline */
50
  int dline_timer;        /* oslib event for budget reactivation*/
51
  int vtimer;
52
  int avail;              /* current budget */
53
 
253 giacomo 54
  LEVEL l;                /* Current GRUBSTAR level */
241 giacomo 55
  int loc_sched_id;       /* Local scheduler id */
56
  LEVEL loc_sched_level;  /* Local scheduler level */
57
 
58
  PID current;            /* the task currently put in execution */
59
  int flags;
60
 
61
  IQUEUE tasks;           /* a FIFO queue for the tasks handled
62
                             using the budget */
63
 
64
};
65
 
253 giacomo 66
#define GRUBSTAR_NOACTIVE   0
67
#define GRUBSTAR_ACTIVE     1
68
#define GRUBSTAR_RECLAIMING 2
241 giacomo 69
 
70
typedef struct {
71
  level_des l;               /* the standard level descriptor */
72
 
73
  struct budget_struct *b;   /* the budgets! */
74
  int n;                     /* the maximum index for the budgets */
75
  int freebudgets;           /* number of free budgets; starts from n */
76
 
77
  int tb[MAX_PROC];          /* link task->budget (used in guest_end) */
78
 
79
  bandwidth_t U;   /*+ the used bandwidth by the server       +*/
80
  bandwidth_t Uf;   /*+ the actual used bandwidth by the server       +*/
81
 
82
  int cap_lev;
83
 
84
  LEVEL scheduling_level;
85
 
253 giacomo 86
} GRUBSTAR_level_des;
241 giacomo 87
 
88
 
253 giacomo 89
static void GRUBSTAR_deadline_timer_hardreservation(void *a)
241 giacomo 90
{
91
  struct budget_struct *b = a;
92
  PID p;
253 giacomo 93
  GRUBSTAR_level_des *lev;
94
 
95
  lev = (GRUBSTAR_level_des *)(level_table[b->l]);
96
 
97
  #ifdef GRUBSTAR_DEBUG
98
    kern_printf("(GS:HrdRes:");  
241 giacomo 99
  #endif
100
 
101
  b->dline_timer = NIL;
102
 
103
  b->avail += b->Q;
104
  if (b->avail > b->Q) b->avail = b->Q;
105
 
253 giacomo 106
  if (b->flags==GRUBSTAR_RECLAIMING && b->avail>0) {
107
         bandwidth_t bw;
108
         bw = (MAX_BANDWIDTH / b->T) * b->Q;
241 giacomo 109
 
253 giacomo 110
         lev->Uf += bw;
111
 
112
         #ifdef GRUBSTAR_DEBUG
113
              kern_printf("BW=%ld, U=%u, Uf=%u",(long)bw, lev->U, lev->Uf);
114
         #endif
115
  }
116
 
117
  if (b->avail > 0) b->flags = GRUBSTAR_ACTIVE;
118
 
241 giacomo 119
  if (b->current == NIL && b->flags) {
120
      if (iq_query_first(&(b->tasks)) != NIL) {
121
        JOB_TASK_MODEL job;
122
 
123
        p = iq_getfirst(&b->tasks);
124
 
253 giacomo 125
        #ifdef GRUBSTAR_DEBUG
126
          kern_printf("%d",p);
241 giacomo 127
        #endif
128
 
129
        kern_gettime(&b->dline);
130
        ADDUSEC2TIMESPEC(b->T, &b->dline);
131
 
132
        b->current = p;
133
 
134
 
135
        job_task_default_model(job, b->dline);
136
        job_task_def_noexc(job);
137
        level_table[ lev->scheduling_level ]->
138
          private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
139
 
140
        event_need_reschedule();
141
 
142
    }
143
  }
144
 
253 giacomo 145
  if (b->flags == GRUBSTAR_NOACTIVE) {
241 giacomo 146
    kern_gettime(&b->dline);
147
    ADDUSEC2TIMESPEC(b->T, &b->dline);
148
 
253 giacomo 149
    b->dline_timer=kern_event_post(&b->dline, GRUBSTAR_deadline_timer_hardreservation, b);
241 giacomo 150
  }
151
 
253 giacomo 152
  #ifdef GRUBSTAR_DEBUG
153
    kern_printf(")");
241 giacomo 154
  #endif
155
 
156
}
157
 
253 giacomo 158
void GRUBSTAR_ANC(void *arg)
241 giacomo 159
{
160
  struct budget_struct *b = arg;
253 giacomo 161
  GRUBSTAR_level_des *lev=(GRUBSTAR_level_des *)level_table[b->l];
241 giacomo 162
 
253 giacomo 163
  #ifdef GRUBSTAR_DEBUG
164
    kern_printf("(GS:Rec:");
241 giacomo 165
  #endif
166
 
167
  b->vtimer = NIL;
266 trimarchi 168
  if (b->current == NIL && iq_query_first(&(b->tasks)) == NIL) {
241 giacomo 169
     bandwidth_t bw;
170
 
253 giacomo 171
     b->flags=GRUBSTAR_RECLAIMING;
241 giacomo 172
 
173
     bw = (MAX_BANDWIDTH / b->T) * b->Q;
174
 
175
     lev->Uf -= bw;
176
 
253 giacomo 177
     #ifdef GRUBSTAR_DEBUG
178
       kern_printf("bw=%ld, U=%u, Uf=%u",(long)bw, lev->U, lev->Uf);
241 giacomo 179
     #endif
180
 
181
 
182
  }
183
 
253 giacomo 184
  #ifdef GRUBSTAR_DEBUG
185
    kern_printf(")");
241 giacomo 186
  #endif
187
 
188
 
189
}
190
 
253 giacomo 191
static void GRUBSTAR_activation(GRUBSTAR_level_des *lev,
241 giacomo 192
                           PID p,
193
                           struct timespec *acttime)
194
{
195
  JOB_TASK_MODEL job;
196
  struct budget_struct *b = &lev->b[lev->tb[p]];
253 giacomo 197
  TIME t;
198
  struct timespec t2,t3;
241 giacomo 199
 
253 giacomo 200
  t = (b->T * b->avail) / b->Q;
201
  t3.tv_sec = t / 1000000;
202
  t3.tv_nsec = (t % 1000000) * 1000;
241 giacomo 203
 
253 giacomo 204
  SUBTIMESPEC(&b->dline, acttime, &t2);
205
  if (/* 1 */ TIMESPEC_A_LT_B(&b->dline, acttime) ||
241 giacomo 206
       /* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
207
       TIMESPEC_ASSIGN(&b->dline, acttime);
208
       ADDUSEC2TIMESPEC(b->T, &b->dline);
209
       b->avail=b->Q;
253 giacomo 210
       if (b->flags==GRUBSTAR_RECLAIMING) {
241 giacomo 211
         bandwidth_t bw;
212
 
213
         bw = (MAX_BANDWIDTH / b->T) * b->Q;
214
 
215
         lev->Uf += bw;
216
 
253 giacomo 217
         #ifdef grubSTAR_DEBUG
218
            kern_printf("BW=%ld, U=%u, Uf=%u",(long)bw, lev->U, lev->Uf);
241 giacomo 219
         #endif
220
       }
221
 
222
 
253 giacomo 223
       b->flags=GRUBSTAR_ACTIVE;
241 giacomo 224
 
225
  }
226
 
253 giacomo 227
  SUBTIMESPEC(&b->dline, &t3, &t2);
228
  if (b->vtimer!=NIL) kern_event_delete(b->vtimer);
229
  b->vtimer=NIL;
230
  b->vtimer = kern_event_post(&t2, GRUBSTAR_ANC, b);
241 giacomo 231
 
253 giacomo 232
 
241 giacomo 233
  /* record the current task inserted in the master module */
234
  b->current = p;
235
 
236
  job_task_default_model(job, b->dline);
237
  job_task_def_noexc(job);
238
  level_table[ lev->scheduling_level ]->
239
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
240
 
241
}
242
 
253 giacomo 243
static void GRUBSTAR_account_capacity(GRUBSTAR_level_des *lev, PID p)
241 giacomo 244
{
245
  struct timespec ty;
246
  TIME tx;
247
  struct budget_struct *b = &lev->b[lev->tb[p]];
248
 
249
  if (lev->cap_lev != NIL && b->current == p) {
250
    kern_event_delete(lev->cap_lev);
251
    lev->cap_lev = NIL;
252
  }
253
 
254
  SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty);
255
  tx = TIMESPEC2USEC(&ty);
266 trimarchi 256
  #ifdef GRUBSTAR_DEBUG
257
      kern_printf("(GS:Cap p%d av=%d)", p, b->avail);
258
  #endif
241 giacomo 259
 
266 trimarchi 260
  b->avail -= (tx-(unsigned int)((long long)tx * (long long)(lev->U - lev->Uf)/MAX_BANDWIDTH));
261
 
253 giacomo 262
  #ifdef GRUBSTAR_DEBUG
266 trimarchi 263
    kern_printf("(GS:Cap p%d av=%d Uf=%u U=%u, tx=%d)", p, b->avail,lev->Uf, lev->U,tx);
241 giacomo 264
  #endif
265
 
253 giacomo 266
  if (b->avail <= 0) b->flags = GRUBSTAR_NOACTIVE;
241 giacomo 267
 
268
  if (TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
269
    /* we modify the deadline ... */
270
    TIMESPEC_ASSIGN(&b->dline, &schedule_time);
271
    ADDUSEC2TIMESPEC(b->T, &b->dline);
272
  }
273
 
253 giacomo 274
  if (b->flags == GRUBSTAR_NOACTIVE && b->dline_timer == NIL)  {
275
    b->dline_timer=kern_event_post(&b->dline, GRUBSTAR_deadline_timer_hardreservation, b);
241 giacomo 276
  }
277
 
278
}
279
 
280
 
281
/* The on-line guarantee is enabled only if the appropriate flag is set... */
253 giacomo 282
static int GRUBSTAR_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
241 giacomo 283
{
253 giacomo 284
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 285
 
253 giacomo 286
  #ifdef GRUBSTAR_DEBUG
287
    kern_printf("(GS:Gua)");
241 giacomo 288
  #endif
289
 
290
  if (*freebandwidth >= lev->U) {
291
    *freebandwidth -= lev->U;
292
    return 1;
293
  }
294
  else
295
    return 0;
296
}
297
 
298
static void capacity_handler(void *l)
299
{
300
 
253 giacomo 301
  GRUBSTAR_level_des *lev = l;
241 giacomo 302
  lev->cap_lev = NIL;
303
  event_need_reschedule();
304
 
305
}
306
 
253 giacomo 307
static int GRUBSTAR_private_eligible(LEVEL l, PID p)
241 giacomo 308
{
253 giacomo 309
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 310
  struct budget_struct *b = &lev->b[lev->tb[p]];
311
  JOB_TASK_MODEL job;
312
 
313
  if (b->current == p) {
314
    if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
315
      if (lev->cap_lev!=NIL) {
316
        kern_event_delete(lev->cap_lev);
317
        lev->cap_lev=NIL;
318
      }
319
 
320
      /* we kill the current activation */
321
      level_table[ lev->scheduling_level ]->
322
        private_extract(lev->scheduling_level, p);
323
      /* we modify the deadline ... */
324
      TIMESPEC_ASSIGN(&b->dline, &schedule_time);
325
      ADDUSEC2TIMESPEC(b->T, &b->dline);
326
 
327
      /* and the capacity */
328
      b->avail = b->Q;
253 giacomo 329
      b->flags = GRUBSTAR_ACTIVE;
241 giacomo 330
 
331
      if (b->dline_timer!=NIL)  {
332
        kern_event_delete(b->dline_timer);
333
        b->dline_timer=NIL;
334
      }
335
 
336
      /* and, finally, we reinsert the task in the master level */
337
      job_task_default_model(job, b->dline);
338
      job_task_def_noexc(job);
339
      level_table[ lev->scheduling_level ]->
340
        private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
341
 
342
      return -1;
343
 
344
    }  
345
  }
346
 
347
  return 0;
348
 
349
}
350
 
253 giacomo 351
static void GRUBSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
241 giacomo 352
{
253 giacomo 353
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 354
  BUDGET_TASK_MODEL *budget;
355
 
356
  if (m->pclass != BUDGET_PCLASS ||
357
      (m->level != 0 && m->level != l)) {
358
    kern_raise(XINVALID_TASK, p);
359
    return;
360
  }
361
  budget = (BUDGET_TASK_MODEL *)m;
362
 
253 giacomo 363
  #ifdef GRUBSTAR_DEBUG
364
    kern_printf("(GS:PriIns:%d:%d", p, budget->b);
241 giacomo 365
  #endif
366
 
367
  if (budget->b == -1)
368
    return;
369
 
370
  lev->tb[p] = budget->b;
371
 
372
  if (lev->b[budget->b].current == NIL && lev->b[budget->b].flags ) {
373
    /* This is the first task in the budget,
374
       the task have to be inserted into the master module */
375
    struct timespec t;
376
    kern_gettime(&t);
253 giacomo 377
    GRUBSTAR_activation(lev,p,&t);
241 giacomo 378
  } else {
379
    /* The budget is not empty, another task is already into the
380
       master module, so the task is inserted at the end of the budget
381
       queue */
382
    iq_insertlast(p,&lev->b[budget->b].tasks);
383
  }
384
 
253 giacomo 385
  #ifdef GRUBSTAR_DEBUG
386
    kern_printf(")");
241 giacomo 387
  #endif
388
 
389
}
390
 
253 giacomo 391
static void GRUBSTAR_private_extract(LEVEL l, PID p)
241 giacomo 392
{
253 giacomo 393
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 394
 
253 giacomo 395
  #ifdef GRUBSTAR_DEBUG
396
    kern_printf("(GS:Ext:%d)", p);
241 giacomo 397
  #endif
398
 
399
  /* a task is removed from execution for some reasons. It must be
400
     that it is the first in its budget queue (only the first task in
401
     a budget queue is put into execution!) */
402
 
403
  /* remove the task from execution (or from the ready queue) */
404
  if (lev->b[lev->tb[p]].current == p) {
405
 
253 giacomo 406
   GRUBSTAR_account_capacity(lev,p);
241 giacomo 407
    /* remove the task from the master module */
408
    level_table[ lev->scheduling_level ]->
409
      private_extract(lev->scheduling_level, p);
410
 
411
    /* check if the buffer has someone else to schedule */
412
    if (iq_query_first(&lev->b[lev->tb[p]].tasks) == NIL) {
413
      /* the buffer has no tasks! */
414
      lev->b[lev->tb[p]].current = NIL;
415
    }
416
    else if (lev->b[lev->tb[p]].flags) {
417
      /* if so, insert the new task into the master module */
418
      PID n;
419
      struct timespec t;
420
 
421
      kern_gettime(&t);
422
      n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
253 giacomo 423
      GRUBSTAR_activation(lev,n,&t);  // it modifies b[lev->tb[p]].current
241 giacomo 424
    }
425
    else
426
      lev->b[lev->tb[p]].current=NIL;
427
 
428
  }
429
  else  {
430
    iq_extract(p, &lev->b[lev->tb[p]].tasks);
431
  }
432
}
433
 
253 giacomo 434
static void GRUBSTAR_private_dispatch(LEVEL l, PID p, int nostop)
241 giacomo 435
{
253 giacomo 436
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 437
  struct timespec ty;
438
 
253 giacomo 439
  #ifdef GRUBSTAR_DEBUG
440
    kern_printf("(GS:Dsp:%d)", p);
241 giacomo 441
  #endif
442
 
443
  /* the current task (that is the only one inserted in the master module
444
     for the corresponding budget) is dispatched. Note that the current
445
     task is not inserted in any FIFO queue, so the task does not have to
446
     be extracted! */
447
 
448
  /* ... then, we dispatch it to the master level */
449
  level_table[ lev->scheduling_level ]->
450
    private_dispatch(lev->scheduling_level,p,nostop);
451
 
452
  /* ...and finally, we have to post a capacity event */
453
  if (!nostop) {
454
    TIMESPEC_ASSIGN(&ty, &schedule_time);
455
    ADDUSEC2TIMESPEC(lev->b[lev->tb[p]].avail,&ty);
456
    lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
457
  }
458
 
459
}
460
 
253 giacomo 461
static void GRUBSTAR_private_epilogue(LEVEL l, PID p)
241 giacomo 462
{
253 giacomo 463
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 464
  struct budget_struct *b = &lev->b[lev->tb[p]];
465
 
253 giacomo 466
  #ifdef GRUBSTAR_DEBUG
254 giacomo 467
    kern_printf("(GS:Epi:%d)",p);
241 giacomo 468
  #endif
469
 
470
  if (p==b->current)  {
471
 
253 giacomo 472
    GRUBSTAR_account_capacity(lev,p);
241 giacomo 473
 
474
    // L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch
475
    /* we have to check if the capacity is still available */
476
    if (b->flags)  {
477
      /* there is capacity available, maybe it is simply a preemption;
478
         the task have to return to the ready queue */
479
      level_table[ lev->scheduling_level ]->
480
        private_epilogue(lev->scheduling_level,p);
481
 
482
    } else {
483
      /* we kill the current activation */
484
      level_table[ lev->scheduling_level ]->
485
        private_extract(lev->scheduling_level, p);    
486
 
487
      iq_insertfirst(p, &b->tasks);
488
      b->current = NIL;
489
 
490
    }
491
 
492
  }
493
 
494
}
495
 
496
/* Registration functions }*/
497
 
253 giacomo 498
LEVEL GRUBSTAR_register_level(int n, LEVEL master)
241 giacomo 499
{
500
  LEVEL l;            /* the level that we register */
253 giacomo 501
  GRUBSTAR_level_des *lev;  /* for readableness only */
241 giacomo 502
  PID i;              /* a counter */
503
 
253 giacomo 504
  printk("GRUBSTAR_register_level\n");
241 giacomo 505
 
506
  /* request an entry in the level_table */
253 giacomo 507
  l = level_alloc_descriptor(sizeof(GRUBSTAR_level_des));
241 giacomo 508
 
253 giacomo 509
  lev = (GRUBSTAR_level_des *)level_table[l];
241 giacomo 510
 
511
  /* fill the standard descriptor */
253 giacomo 512
  lev->l.private_insert   = GRUBSTAR_private_insert;
513
  lev->l.private_extract  = GRUBSTAR_private_extract;
514
  lev->l.private_eligible = GRUBSTAR_private_eligible;
515
  lev->l.private_dispatch = GRUBSTAR_private_dispatch;
516
  lev->l.private_epilogue = GRUBSTAR_private_epilogue;
241 giacomo 517
 
253 giacomo 518
  lev->l.public_guarantee = GRUBSTAR_public_guarantee;
241 giacomo 519
 
520
  lev->b = (struct budget_struct *)kern_alloc(sizeof(struct budget_struct)*n);
521
 
522
  for (i=0; i<n; i++) {
523
    lev->b[i].Q = 0;
524
    lev->b[i].T = 0;
525
    NULL_TIMESPEC(&lev->b[i].dline);
526
    lev->b[i].dline_timer = NIL;
253 giacomo 527
    lev->b[i].vtimer=NIL;
241 giacomo 528
    lev->b[i].avail = 0;
529
    lev->b[i].current = -1;
253 giacomo 530
    lev->b[i].flags = GRUBSTAR_ACTIVE;
241 giacomo 531
    lev->b[i].l=l;
253 giacomo 532
    iq_init(&lev->b[i].tasks, NULL, 0);
241 giacomo 533
  }
534
 
535
  lev->n = n;
536
  lev->freebudgets = 0;
537
 
538
  for (i=0; i<MAX_PROC; i++)
539
    lev->tb[i] = NIL;
540
 
541
  lev->U = 0;
542
  lev->Uf = 0;
543
  lev->cap_lev = NIL;
544
  lev->scheduling_level = master;
545
 
546
  return l;
547
 
548
}
549
 
253 giacomo 550
int GRUBSTAR_setbudget(LEVEL l, TIME Q, TIME T, LEVEL local_scheduler_level, int scheduler_id)
241 giacomo 551
{
253 giacomo 552
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 553
  int r;
554
 
253 giacomo 555
  #ifdef GRUBSTAR_DEBUG
556
    kern_printf("(GS:SetBud)");
241 giacomo 557
  #endif
558
 
559
  for (r = 0; r < lev->n; r++)
560
    if (lev->b[r].Q == 0) break;
561
 
562
  if (r != lev->n) {
563
    bandwidth_t b;
564
    b = (MAX_BANDWIDTH / T) * Q;
565
 
566
    /* really update lev->U, checking an overflow... */
567
    if (Q< T && MAX_BANDWIDTH - lev->U > b) {
568
 
569
      lev->U += b;
570
      lev->Uf += b;
571
      lev->freebudgets++;
572
 
573
      lev->b[r].Q = Q;
574
      lev->b[r].T = T;
575
      lev->b[r].avail = Q;
253 giacomo 576
      lev->b[r].flags = GRUBSTAR_ACTIVE;
241 giacomo 577
      lev->b[r].loc_sched_id = scheduler_id;
578
      lev->b[r].loc_sched_level = local_scheduler_level;
579
 
580
      return r;
581
    }
582
    else
583
      return -2;
584
  }
585
  else
586
    return -1;
587
}
588
 
253 giacomo 589
int GRUBSTAR_removebudget(LEVEL l, int budget)
241 giacomo 590
{
591
 
253 giacomo 592
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 593
 
594
  bandwidth_t b;
595
 
596
  b = (MAX_BANDWIDTH / lev->b[budget].T) * lev->b[budget].Q;
597
 
598
  lev->U -= b;
599
 
600
  lev->b[budget].Q = 0;
601
  lev->b[budget].T = 0;
602
  NULL_TIMESPEC(&lev->b[budget].dline);
603
  lev->b[budget].dline_timer = NIL;
604
  lev->b[budget].avail = 0;
605
  lev->b[budget].current = -1;
253 giacomo 606
  lev->b[budget].flags = GRUBSTAR_ACTIVE;
241 giacomo 607
 
608
  return 0;
609
 
610
}
611
 
253 giacomo 612
int GRUBSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, int budget)
241 giacomo 613
{
614
 
253 giacomo 615
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 616
 
617
  lev->b[budget].Q = Q;
618
  lev->b[budget].T = T;
619
 
620
  return 0;
621
 
622
}
623
 
253 giacomo 624
int GRUBSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, int budget)
241 giacomo 625
{
626
 
253 giacomo 627
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 628
 
629
  *Q = lev->b[budget].Q;
630
  *T = lev->b[budget].T;
631
 
632
  return 0;
633
 
634
}
635
 
253 giacomo 636
int GRUBSTAR_is_active(LEVEL l, int budget)
241 giacomo 637
{
253 giacomo 638
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 639
 
640
  return lev->b[budget].flags;
641
 
642
}
643
 
253 giacomo 644
int GRUBSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget)
241 giacomo 645
{
253 giacomo 646
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 647
 
648
  return lev->b[budget].loc_sched_level;
649
 
650
}
651
 
253 giacomo 652
int GRUBSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p)
241 giacomo 653
{
253 giacomo 654
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 655
 
656
  return lev->b[lev->tb[p]].loc_sched_level;
657
 
658
}
659
 
253 giacomo 660
int GRUBSTAR_get_local_scheduler_id_from_budget(LEVEL l, int budget)
241 giacomo 661
{
253 giacomo 662
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 663
 
664
  return lev->b[budget].loc_sched_id;
665
 
666
}
667
 
253 giacomo 668
int GRUBSTAR_get_local_scheduler_id_from_pid(LEVEL l, PID p)
241 giacomo 669
{
253 giacomo 670
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 671
 
672
  return lev->b[lev->tb[p]].loc_sched_id;
673
 
674
}
675