Subversion Repositories shark

Rev

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