Subversion Repositories shark

Rev

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