Subversion Repositories shark

Rev

Rev 241 | Rev 254 | 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
 
253 giacomo 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;
168
  if (b->current != NIL && iq_query_first(&(b->tasks)) != NIL) {
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);
253 giacomo 256
  b->avail -= (int)((long long)tx * (long long)lev->Uf / (int)lev->U);
241 giacomo 257
 
253 giacomo 258
  #ifdef GRUBSTAR_DEBUG
259
    kern_printf("(GS:Cap p%d av=%d Uf=%u U=%u)", p, b->avail,lev->Uf, lev->U);
241 giacomo 260
  #endif
261
 
253 giacomo 262
  if (b->avail <= 0) b->flags = GRUBSTAR_NOACTIVE;
241 giacomo 263
 
264
  if (TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
265
    /* we modify the deadline ... */
266
    TIMESPEC_ASSIGN(&b->dline, &schedule_time);
267
    ADDUSEC2TIMESPEC(b->T, &b->dline);
268
  }
269
 
253 giacomo 270
  if (b->flags == GRUBSTAR_NOACTIVE && b->dline_timer == NIL)  {
271
    b->dline_timer=kern_event_post(&b->dline, GRUBSTAR_deadline_timer_hardreservation, b);
241 giacomo 272
  }
273
 
274
}
275
 
276
 
277
/* The on-line guarantee is enabled only if the appropriate flag is set... */
253 giacomo 278
static int GRUBSTAR_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
241 giacomo 279
{
253 giacomo 280
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 281
 
253 giacomo 282
  #ifdef GRUBSTAR_DEBUG
283
    kern_printf("(GS:Gua)");
241 giacomo 284
  #endif
285
 
286
  if (*freebandwidth >= lev->U) {
287
    *freebandwidth -= lev->U;
288
    return 1;
289
  }
290
  else
291
    return 0;
292
}
293
 
294
static void capacity_handler(void *l)
295
{
296
 
253 giacomo 297
  GRUBSTAR_level_des *lev = l;
241 giacomo 298
  lev->cap_lev = NIL;
299
  event_need_reschedule();
300
 
301
}
302
 
253 giacomo 303
static int GRUBSTAR_private_eligible(LEVEL l, PID p)
241 giacomo 304
{
253 giacomo 305
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 306
  struct budget_struct *b = &lev->b[lev->tb[p]];
307
  JOB_TASK_MODEL job;
308
 
309
  if (b->current == p) {
310
    if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
311
      if (lev->cap_lev!=NIL) {
312
        kern_event_delete(lev->cap_lev);
313
        lev->cap_lev=NIL;
314
      }
315
 
316
      /* we kill the current activation */
317
      level_table[ lev->scheduling_level ]->
318
        private_extract(lev->scheduling_level, p);
319
      /* we modify the deadline ... */
320
      TIMESPEC_ASSIGN(&b->dline, &schedule_time);
321
      ADDUSEC2TIMESPEC(b->T, &b->dline);
322
 
323
      /* and the capacity */
324
      b->avail = b->Q;
253 giacomo 325
      b->flags = GRUBSTAR_ACTIVE;
241 giacomo 326
 
327
      if (b->dline_timer!=NIL)  {
328
        kern_event_delete(b->dline_timer);
329
        b->dline_timer=NIL;
330
      }
331
 
332
      /* and, finally, we reinsert the task in the master level */
333
      job_task_default_model(job, b->dline);
334
      job_task_def_noexc(job);
335
      level_table[ lev->scheduling_level ]->
336
        private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
337
 
338
      return -1;
339
 
340
    }  
341
  }
342
 
343
  return 0;
344
 
345
}
346
 
253 giacomo 347
static void GRUBSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
241 giacomo 348
{
253 giacomo 349
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 350
  BUDGET_TASK_MODEL *budget;
351
 
352
  if (m->pclass != BUDGET_PCLASS ||
353
      (m->level != 0 && m->level != l)) {
354
    kern_raise(XINVALID_TASK, p);
355
    return;
356
  }
357
  budget = (BUDGET_TASK_MODEL *)m;
358
 
253 giacomo 359
  #ifdef GRUBSTAR_DEBUG
360
    kern_printf("(GS:PriIns:%d:%d", p, budget->b);
241 giacomo 361
  #endif
362
 
363
  if (budget->b == -1)
364
    return;
365
 
366
  lev->tb[p] = budget->b;
367
 
368
  if (lev->b[budget->b].current == NIL && lev->b[budget->b].flags ) {
369
    /* This is the first task in the budget,
370
       the task have to be inserted into the master module */
371
    struct timespec t;
372
    kern_gettime(&t);
253 giacomo 373
    GRUBSTAR_activation(lev,p,&t);
241 giacomo 374
  } else {
375
    /* The budget is not empty, another task is already into the
376
       master module, so the task is inserted at the end of the budget
377
       queue */
378
    iq_insertlast(p,&lev->b[budget->b].tasks);
379
  }
380
 
253 giacomo 381
  #ifdef GRUBSTAR_DEBUG
382
    kern_printf(")");
241 giacomo 383
  #endif
384
 
385
}
386
 
253 giacomo 387
static void GRUBSTAR_private_extract(LEVEL l, PID p)
241 giacomo 388
{
253 giacomo 389
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 390
 
253 giacomo 391
  #ifdef GRUBSTAR_DEBUG
392
    kern_printf("(GS:Ext:%d)", p);
241 giacomo 393
  #endif
394
 
395
  /* a task is removed from execution for some reasons. It must be
396
     that it is the first in its budget queue (only the first task in
397
     a budget queue is put into execution!) */
398
 
399
  /* remove the task from execution (or from the ready queue) */
400
  if (lev->b[lev->tb[p]].current == p) {
401
 
253 giacomo 402
   GRUBSTAR_account_capacity(lev,p);
241 giacomo 403
    /* remove the task from the master module */
404
    level_table[ lev->scheduling_level ]->
405
      private_extract(lev->scheduling_level, p);
406
 
407
    /* check if the buffer has someone else to schedule */
408
    if (iq_query_first(&lev->b[lev->tb[p]].tasks) == NIL) {
409
      /* the buffer has no tasks! */
410
      lev->b[lev->tb[p]].current = NIL;
411
    }
412
    else if (lev->b[lev->tb[p]].flags) {
413
      /* if so, insert the new task into the master module */
414
      PID n;
415
      struct timespec t;
416
 
417
      kern_gettime(&t);
418
      n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
253 giacomo 419
      GRUBSTAR_activation(lev,n,&t);  // it modifies b[lev->tb[p]].current
241 giacomo 420
    }
421
    else
422
      lev->b[lev->tb[p]].current=NIL;
423
 
424
  }
425
  else  {
426
    iq_extract(p, &lev->b[lev->tb[p]].tasks);
427
  }
428
}
429
 
253 giacomo 430
static void GRUBSTAR_private_dispatch(LEVEL l, PID p, int nostop)
241 giacomo 431
{
253 giacomo 432
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 433
  struct timespec ty;
434
 
253 giacomo 435
  #ifdef GRUBSTAR_DEBUG
436
    kern_printf("(GS:Dsp:%d)", p);
241 giacomo 437
  #endif
438
 
439
  /* the current task (that is the only one inserted in the master module
440
     for the corresponding budget) is dispatched. Note that the current
441
     task is not inserted in any FIFO queue, so the task does not have to
442
     be extracted! */
443
 
444
  /* ... then, we dispatch it to the master level */
445
  level_table[ lev->scheduling_level ]->
446
    private_dispatch(lev->scheduling_level,p,nostop);
447
 
448
  /* ...and finally, we have to post a capacity event */
449
  if (!nostop) {
450
    TIMESPEC_ASSIGN(&ty, &schedule_time);
451
    ADDUSEC2TIMESPEC(lev->b[lev->tb[p]].avail,&ty);
452
    lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
453
  }
454
 
455
}
456
 
253 giacomo 457
static void GRUBSTAR_private_epilogue(LEVEL l, PID p)
241 giacomo 458
{
253 giacomo 459
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 460
  struct budget_struct *b = &lev->b[lev->tb[p]];
461
 
253 giacomo 462
  #ifdef GRUBSTAR_DEBUG
241 giacomo 463
    kern_printf("(CS:Epi:%d)",p);
464
  #endif
465
 
466
  if (p==b->current)  {
467
 
253 giacomo 468
    GRUBSTAR_account_capacity(lev,p);
241 giacomo 469
 
470
    // L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch
471
    /* we have to check if the capacity is still available */
472
    if (b->flags)  {
473
      /* there is capacity available, maybe it is simply a preemption;
474
         the task have to return to the ready queue */
475
      level_table[ lev->scheduling_level ]->
476
        private_epilogue(lev->scheduling_level,p);
477
 
478
    } else {
479
      /* we kill the current activation */
480
      level_table[ lev->scheduling_level ]->
481
        private_extract(lev->scheduling_level, p);    
482
 
483
      iq_insertfirst(p, &b->tasks);
484
      b->current = NIL;
485
 
486
    }
487
 
488
  }
489
 
490
}
491
 
492
/* Registration functions }*/
493
 
253 giacomo 494
LEVEL GRUBSTAR_register_level(int n, LEVEL master)
241 giacomo 495
{
496
  LEVEL l;            /* the level that we register */
253 giacomo 497
  GRUBSTAR_level_des *lev;  /* for readableness only */
241 giacomo 498
  PID i;              /* a counter */
499
 
253 giacomo 500
  printk("GRUBSTAR_register_level\n");
241 giacomo 501
 
502
  /* request an entry in the level_table */
253 giacomo 503
  l = level_alloc_descriptor(sizeof(GRUBSTAR_level_des));
241 giacomo 504
 
253 giacomo 505
  lev = (GRUBSTAR_level_des *)level_table[l];
241 giacomo 506
 
507
  /* fill the standard descriptor */
253 giacomo 508
  lev->l.private_insert   = GRUBSTAR_private_insert;
509
  lev->l.private_extract  = GRUBSTAR_private_extract;
510
  lev->l.private_eligible = GRUBSTAR_private_eligible;
511
  lev->l.private_dispatch = GRUBSTAR_private_dispatch;
512
  lev->l.private_epilogue = GRUBSTAR_private_epilogue;
241 giacomo 513
 
253 giacomo 514
  lev->l.public_guarantee = GRUBSTAR_public_guarantee;
241 giacomo 515
 
516
  lev->b = (struct budget_struct *)kern_alloc(sizeof(struct budget_struct)*n);
517
 
518
  for (i=0; i<n; i++) {
519
    lev->b[i].Q = 0;
520
    lev->b[i].T = 0;
521
    NULL_TIMESPEC(&lev->b[i].dline);
522
    lev->b[i].dline_timer = NIL;
253 giacomo 523
    lev->b[i].vtimer=NIL;
241 giacomo 524
    lev->b[i].avail = 0;
525
    lev->b[i].current = -1;
253 giacomo 526
    lev->b[i].flags = GRUBSTAR_ACTIVE;
241 giacomo 527
    lev->b[i].l=l;
253 giacomo 528
    iq_init(&lev->b[i].tasks, NULL, 0);
241 giacomo 529
  }
530
 
531
  lev->n = n;
532
  lev->freebudgets = 0;
533
 
534
  for (i=0; i<MAX_PROC; i++)
535
    lev->tb[i] = NIL;
536
 
537
  lev->U = 0;
538
  lev->Uf = 0;
539
  lev->cap_lev = NIL;
540
  lev->scheduling_level = master;
541
 
542
  return l;
543
 
544
}
545
 
253 giacomo 546
int GRUBSTAR_setbudget(LEVEL l, TIME Q, TIME T, LEVEL local_scheduler_level, int scheduler_id)
241 giacomo 547
{
253 giacomo 548
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 549
  int r;
550
 
253 giacomo 551
  #ifdef GRUBSTAR_DEBUG
552
    kern_printf("(GS:SetBud)");
241 giacomo 553
  #endif
554
 
555
  for (r = 0; r < lev->n; r++)
556
    if (lev->b[r].Q == 0) break;
557
 
558
  if (r != lev->n) {
559
    bandwidth_t b;
560
    b = (MAX_BANDWIDTH / T) * Q;
561
 
562
    /* really update lev->U, checking an overflow... */
563
    if (Q< T && MAX_BANDWIDTH - lev->U > b) {
564
 
565
      lev->U += b;
566
      lev->Uf += b;
567
      lev->freebudgets++;
568
 
569
      lev->b[r].Q = Q;
570
      lev->b[r].T = T;
571
      lev->b[r].avail = Q;
253 giacomo 572
      lev->b[r].flags = GRUBSTAR_ACTIVE;
241 giacomo 573
      lev->b[r].loc_sched_id = scheduler_id;
574
      lev->b[r].loc_sched_level = local_scheduler_level;
575
 
576
      return r;
577
    }
578
    else
579
      return -2;
580
  }
581
  else
582
    return -1;
583
}
584
 
253 giacomo 585
int GRUBSTAR_removebudget(LEVEL l, int budget)
241 giacomo 586
{
587
 
253 giacomo 588
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 589
 
590
  bandwidth_t b;
591
 
592
  b = (MAX_BANDWIDTH / lev->b[budget].T) * lev->b[budget].Q;
593
 
594
  lev->U -= b;
595
 
596
  lev->b[budget].Q = 0;
597
  lev->b[budget].T = 0;
598
  NULL_TIMESPEC(&lev->b[budget].dline);
599
  lev->b[budget].dline_timer = NIL;
600
  lev->b[budget].avail = 0;
601
  lev->b[budget].current = -1;
253 giacomo 602
  lev->b[budget].flags = GRUBSTAR_ACTIVE;
241 giacomo 603
 
604
  return 0;
605
 
606
}
607
 
253 giacomo 608
int GRUBSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, int budget)
241 giacomo 609
{
610
 
253 giacomo 611
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 612
 
613
  lev->b[budget].Q = Q;
614
  lev->b[budget].T = T;
615
 
616
  return 0;
617
 
618
}
619
 
253 giacomo 620
int GRUBSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, int budget)
241 giacomo 621
{
622
 
253 giacomo 623
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 624
 
625
  *Q = lev->b[budget].Q;
626
  *T = lev->b[budget].T;
627
 
628
  return 0;
629
 
630
}
631
 
253 giacomo 632
int GRUBSTAR_is_active(LEVEL l, int budget)
241 giacomo 633
{
253 giacomo 634
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 635
 
636
  return lev->b[budget].flags;
637
 
638
}
639
 
253 giacomo 640
int GRUBSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget)
241 giacomo 641
{
253 giacomo 642
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 643
 
644
  return lev->b[budget].loc_sched_level;
645
 
646
}
647
 
253 giacomo 648
int GRUBSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p)
241 giacomo 649
{
253 giacomo 650
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 651
 
652
  return lev->b[lev->tb[p]].loc_sched_level;
653
 
654
}
655
 
253 giacomo 656
int GRUBSTAR_get_local_scheduler_id_from_budget(LEVEL l, int budget)
241 giacomo 657
{
253 giacomo 658
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 659
 
660
  return lev->b[budget].loc_sched_id;
661
 
662
}
663
 
253 giacomo 664
int GRUBSTAR_get_local_scheduler_id_from_pid(LEVEL l, PID p)
241 giacomo 665
{
253 giacomo 666
  GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]);
241 giacomo 667
 
668
  return lev->b[lev->tb[p]].loc_sched_id;
669
 
670
}
671