Subversion Repositories shark

Rev

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

Rev Author Line No. Line
221 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
 
40
#include "cbsstar.h"
830 trimarchi 41
#include "ll/i386/64bit.h"
42
#include <tracer.h>
221 giacomo 43
 
44
/*
45
 * DEBUG stuffs begin
46
 */
263 giacomo 47
//#define CBSSTAR_DEBUG
221 giacomo 48
#ifdef CBSSTAR_DEBUG
49
 
50
static __inline__ void fake_printf(char *fmt, ...) {}
51
 
52
#define cbsstar_printf kern_printf
53
#define cbsstar_printf2 kern_printf
54
#define cbsstar_printf3 kern_printf
55
 
56
//#define cbsstar_printf fake_printf
57
//#define cbsstar_printf2 fake_printf
58
//#define cbsstar_printf3 fake_printf
59
 
60
#endif
61
/*
62
 * DEBUG stuffs end
63
 */
64
 
65
/* this structure contains the status for a single budget */
66
struct budget_struct {
67
  TIME Q;                 /* budget */
68
  TIME T;                 /* period */
830 trimarchi 69
  TIME D;                 /* deadline */
221 giacomo 70
 
71
  struct timespec dline;  /* deadline */
830 trimarchi 72
  struct timespec replenish; /* server period */
73
 
74
  int replenish_timer;        /* oslib event for budget reactivation*/
221 giacomo 75
  int avail;              /* current budget */
76
 
77
  LEVEL l;                /* Current CBSSTAR level */
78
  int loc_sched_id;       /* Local scheduler id */
79
  LEVEL loc_sched_level;  /* Local scheduler level */
80
 
81
  PID current;            /* the task currently put in execution */
82
  int flags;
83
 
84
  IQUEUE tasks;           /* a FIFO queue for the tasks handled
85
                             using the budget */
86
 
87
};
88
 
241 giacomo 89
#define CBSSTAR_NOACTIVE   0
90
#define CBSSTAR_ACTIVE     1
221 giacomo 91
 
92
typedef struct {
93
  level_des l;               /* the standard level descriptor */
94
 
95
  struct budget_struct *b;   /* the budgets! */
96
  int n;                     /* the maximum index for the budgets */
97
  int freebudgets;           /* number of free budgets; starts from n */
98
 
99
  int tb[MAX_PROC];          /* link task->budget (used in guest_end) */
100
 
263 giacomo 101
  bandwidth_t U;             /*+ the used bandwidth by the server       +*/
221 giacomo 102
 
103
  int cap_lev;
279 giacomo 104
  struct timespec cap_lasttime;
221 giacomo 105
 
106
  LEVEL scheduling_level;
107
 
108
} CBSSTAR_level_des;
109
 
110
 
830 trimarchi 111
static void CBSSTAR_replenish_timer_hardreservation(void *a)
221 giacomo 112
{
113
  struct budget_struct *b = a;
114
  PID p;
263 giacomo 115
 
221 giacomo 116
  #ifdef CBSSTAR_DEBUG
117
    cbsstar_printf("(CS:HrdRes:");  
118
  #endif
119
 
830 trimarchi 120
  b->replenish_timer = NIL;
221 giacomo 121
 
122
  /* we modify the deadline according to rule 4 ... */
123
  /* there is a while because if the wcet is << than the system tick
124
     we need to postpone the deadline many times */
125
 
126
  b->avail += b->Q;
127
  if (b->avail > b->Q) b->avail = b->Q;
128
 
129
  if (b->avail > 0) b->flags = CBSSTAR_ACTIVE;
130
 
830 trimarchi 131
 /* Tracer */
132
  TRACER_LOGEVENT(FTrace_EVT_server_replenish,0,(unsigned int)(b));
133
 
221 giacomo 134
  /* avail may be <0 because a task executed via a shadow fo many time
135
     b->current == NIL only if the prec task was finished and there
136
     was not any other task to be put in the ready queue
137
     ... we are now activating the next task */
138
  if (b->current == NIL && b->flags) {
139
      if (iq_query_first(&(b->tasks)) != NIL) {
263 giacomo 140
        CBSSTAR_level_des *lev;
221 giacomo 141
        JOB_TASK_MODEL job;
142
 
143
        p = iq_getfirst(&b->tasks);
144
 
145
        #ifdef CBSSTAR_DEBUG
146
          cbsstar_printf("%d",p);
147
        #endif
148
 
840 trimarchi 149
        kern_gettime(&b->replenish);
150
        TIMESPEC_ASSIGN(&b->dline, &b->replenish);
151
        ADDUSEC2TIMESPEC(b->D, &b->dline);
152
        ADDUSEC2TIMESPEC(b->T, &b->replenish);
221 giacomo 153
 
154
        b->current = p;
155
 
263 giacomo 156
        lev = (CBSSTAR_level_des *)(level_table[b->l]);
221 giacomo 157
 
158
        job_task_default_model(job, b->dline);
159
        job_task_def_noexc(job);
160
        level_table[ lev->scheduling_level ]->
161
          private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
162
 
163
        event_need_reschedule();
164
 
165
    }
234 giacomo 166
  }
241 giacomo 167
 
168
  if (b->flags == CBSSTAR_NOACTIVE) {
830 trimarchi 169
 
170
    kern_gettime(&b->replenish);
171
    ADDUSEC2TIMESPEC(b->T, &b->replenish);;
241 giacomo 172
 
830 trimarchi 173
    b->replenish_timer=kern_event_post(&b->replenish, CBSSTAR_replenish_timer_hardreservation, b);
241 giacomo 174
  }
221 giacomo 175
 
241 giacomo 176
  #ifdef CBSSTAR_DEBUG
177
    cbsstar_printf(")");
178
  #endif
237 giacomo 179
 
241 giacomo 180
}
181
 
221 giacomo 182
static void CBSSTAR_activation(CBSSTAR_level_des *lev,
241 giacomo 183
                           PID p,
184
                           struct timespec *acttime)
221 giacomo 185
{
186
  JOB_TASK_MODEL job;
187
  struct budget_struct *b = &lev->b[lev->tb[p]];
188
  /* we have to check if the deadline and the wcet are correct before
189
     activating a new task or an old task... */
190
 
241 giacomo 191
  /* we have to check if the deadline and the wcet are correct before
192
   *      activating a new task or an old task... */
193
 
194
   /* check 1: if the deadline is before than the actual scheduling time */
195
 
196
   /* check 2: if ( avail_time >= (cbs_dline - acttime)* (wcet/period) )
197
    *      (rule 7 in the CBS article!) */
198
   TIME t;
199
   struct timespec t2,t3;
200
 
830 trimarchi 201
   mul32div32to32(b->D,b->avail,b->Q,t);
202
 
241 giacomo 203
   t3.tv_sec = t / 1000000;
204
   t3.tv_nsec = (t % 1000000) * 1000;
830 trimarchi 205
   SUBTIMESPEC(&b->dline, acttime, &t2);
241 giacomo 206
 
830 trimarchi 207
   TRACER_LOGEVENT(FTrace_EVT_server_active,0,(unsigned int)b);
208
 
241 giacomo 209
   if (/* 1 */ TIMESPEC_A_LT_B(&b->dline, acttime) ||
210
       /* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
830 trimarchi 211
       TIMESPEC_ASSIGN(&b->replenish, acttime);
212
       ADDUSEC2TIMESPEC(b->T, &b->replenish);
241 giacomo 213
       TIMESPEC_ASSIGN(&b->dline, acttime);
830 trimarchi 214
       ADDUSEC2TIMESPEC(b->D, &b->dline);
241 giacomo 215
       b->avail=b->Q;
216
       b->flags=CBSSTAR_ACTIVE;
237 giacomo 217
  }
221 giacomo 218
 
219
  /* record the current task inserted in the master module */
220
  b->current = p;
221
 
222
  job_task_default_model(job, b->dline);
223
  job_task_def_noexc(job);
224
  level_table[ lev->scheduling_level ]->
225
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
226
 
227
}
228
 
229
static void CBSSTAR_account_capacity(CBSSTAR_level_des *lev, PID p)
230
{
231
  struct timespec ty;
232
  TIME tx;
233
  struct budget_struct *b = &lev->b[lev->tb[p]];
234
 
235
  if (lev->cap_lev != NIL && b->current == p) {
236
    kern_event_delete(lev->cap_lev);
237
    lev->cap_lev = NIL;
238
  }
239
 
279 giacomo 240
  SUBTIMESPEC(&schedule_time, &lev->cap_lasttime, &ty);
221 giacomo 241
  tx = TIMESPEC2USEC(&ty);
263 giacomo 242
  b->avail -= tx;
221 giacomo 243
 
244
  #ifdef CBSSTAR_DEBUG
263 giacomo 245
    kern_printf("(CS:Cap p%d av=%d)", p, b->avail);
221 giacomo 246
  #endif
247
 
830 trimarchi 248
  if (b->avail <= 0) {
249
    b->flags = CBSSTAR_NOACTIVE;
250
    TRACER_LOGEVENT(FTrace_EVT_server_exhaust,0,(unsigned int)(b));
251
  }
221 giacomo 252
 
241 giacomo 253
  if (TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
254
    /* we modify the deadline ... */
255
    TIMESPEC_ASSIGN(&b->dline, &schedule_time);
830 trimarchi 256
    ADDUSEC2TIMESPEC(b->D, &b->dline);
257
    TIMESPEC_ASSIGN(&b->replenish, &schedule_time);
258
    ADDUSEC2TIMESPEC(b->T, &b->replenish);
241 giacomo 259
  }
221 giacomo 260
 
830 trimarchi 261
  if (b->flags == CBSSTAR_NOACTIVE && b->replenish_timer == NIL)  {
262
    b->replenish_timer=kern_event_post(&b->replenish, CBSSTAR_replenish_timer_hardreservation, b);
241 giacomo 263
  }
264
 
221 giacomo 265
}
266
 
267
 
268
/* The on-line guarantee is enabled only if the appropriate flag is set... */
269
static int CBSSTAR_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
270
{
271
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
272
 
273
  #ifdef CBSSTAR_DEBUG
274
    cbsstar_printf("(CS:Gua)");
275
  #endif
276
 
277
  if (*freebandwidth >= lev->U) {
278
    *freebandwidth -= lev->U;
279
    return 1;
280
  }
281
  else
282
    return 0;
283
}
284
 
285
static void capacity_handler(void *l)
286
{
287
 
288
  CBSSTAR_level_des *lev = l;
289
  lev->cap_lev = NIL;
290
  event_need_reschedule();
291
 
292
}
293
 
294
static int CBSSTAR_private_eligible(LEVEL l, PID p)
295
{
296
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
297
  struct budget_struct *b = &lev->b[lev->tb[p]];
298
  JOB_TASK_MODEL job;
299
 
300
  /* we have to check if the deadline and the wcet are correct...
301
     if the CBSSTAR level schedules in background with respect to others
302
     levels, there can be the case in witch a task is scheduled by
303
     schedule_time > CBSSTAR_deadline; in this case (not covered in the
304
     article because if there is only the standard scheduling policy
305
     this never apply) we reassign the deadline */
830 trimarchi 306
 
221 giacomo 307
    if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
308
      if (lev->cap_lev!=NIL) {
309
        kern_event_delete(lev->cap_lev);
310
        lev->cap_lev=NIL;
311
      }
312
 
313
      /* we kill the current activation */
314
      level_table[ lev->scheduling_level ]->
315
        private_extract(lev->scheduling_level, p);
316
      /* we modify the deadline ... */
830 trimarchi 317
      kern_gettime(&b->replenish);
318
      TIMESPEC_ASSIGN(&b->dline, &b->replenish);
319
      ADDUSEC2TIMESPEC(b->D, &b->dline);
320
      ADDUSEC2TIMESPEC(b->T, &b->replenish);      
221 giacomo 321
 
322
      /* and the capacity */
323
      b->avail = b->Q;
324
      b->flags = CBSSTAR_ACTIVE;
325
 
830 trimarchi 326
      /* Tracer */
327
      TRACER_LOGEVENT(FTrace_EVT_server_replenish,0,(unsigned int)(b));
328
 
329
      if (b->replenish_timer!=NIL)  {
330
        kern_event_delete(b->replenish_timer);
331
        b->replenish_timer=NIL;
221 giacomo 332
      }
333
 
334
      /* and, finally, we reinsert the task in the master level */
335
      job_task_default_model(job, b->dline);
336
      job_task_def_noexc(job);
337
      level_table[ lev->scheduling_level ]->
338
        private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
339
 
340
      return -1;
341
 
342
    }  
830 trimarchi 343
 
221 giacomo 344
 
345
  return 0;
346
 
347
}
348
 
349
static void CBSSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
350
{
351
  /* A task has been activated for some reason. Basically, the task is
352
  inserted in the queue if the queue is empty, otherwise the task is
353
  inserted into the master module, and an oslib event is posted. */
354
 
355
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
356
  BUDGET_TASK_MODEL *budget;
357
 
358
  if (m->pclass != BUDGET_PCLASS ||
359
      (m->level != 0 && m->level != l)) {
360
    kern_raise(XINVALID_TASK, p);
361
    return;
362
  }
363
  budget = (BUDGET_TASK_MODEL *)m;
364
 
365
  #ifdef CBSSTAR_DEBUG
366
    cbsstar_printf("(CS:PriIns:%d:%d", p, budget->b);
367
  #endif
368
 
369
  if (budget->b == -1)
370
    return;
371
 
372
  lev->tb[p] = budget->b;
373
 
374
  if (lev->b[budget->b].current == NIL && lev->b[budget->b].flags ) {
375
    /* This is the first task in the budget,
376
       the task have to be inserted into the master module */
241 giacomo 377
    struct timespec t;
378
    kern_gettime(&t);
379
    CBSSTAR_activation(lev,p,&t);
221 giacomo 380
  } else {
381
    /* The budget is not empty, another task is already into the
382
       master module, so the task is inserted at the end of the budget
383
       queue */
384
    iq_insertlast(p,&lev->b[budget->b].tasks);
385
  }
386
 
387
  #ifdef CBSSTAR_DEBUG
388
    cbsstar_printf(")");
389
  #endif
390
 
391
}
392
 
393
static void CBSSTAR_private_extract(LEVEL l, PID p)
394
{
395
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
396
 
397
  #ifdef CBSSTAR_DEBUG
398
    kern_printf("(CS:Ext:%d)", p);
399
  #endif
400
 
401
  /* a task is removed from execution for some reasons. It must be
402
     that it is the first in its budget queue (only the first task in
403
     a budget queue is put into execution!) */
404
 
405
  /* remove the task from execution (or from the ready queue) */
406
  if (lev->b[lev->tb[p]].current == p) {
407
 
241 giacomo 408
   CBSSTAR_account_capacity(lev,p);
221 giacomo 409
    /* remove the task from the master module */
410
    level_table[ lev->scheduling_level ]->
411
      private_extract(lev->scheduling_level, p);
412
 
413
    /* check if the buffer has someone else to schedule */
414
    if (iq_query_first(&lev->b[lev->tb[p]].tasks) == NIL) {
415
      /* the buffer has no tasks! */
416
      lev->b[lev->tb[p]].current = NIL;
417
    }
418
    else if (lev->b[lev->tb[p]].flags) {
419
      /* if so, insert the new task into the master module */
420
      PID n;
241 giacomo 421
      struct timespec t;
422
 
423
      kern_gettime(&t);
237 giacomo 424
      n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
241 giacomo 425
      CBSSTAR_activation(lev,n,&t);  // it modifies b[lev->tb[p]].current
221 giacomo 426
    }
427
    else
428
      lev->b[lev->tb[p]].current=NIL;
429
 
430
  }
431
  else  {
432
    iq_extract(p, &lev->b[lev->tb[p]].tasks);
433
  }
434
}
435
 
436
static void CBSSTAR_private_dispatch(LEVEL l, PID p, int nostop)
437
{
438
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
439
  struct timespec ty;
440
 
441
  #ifdef CBSSTAR_DEBUG
442
    kern_printf("(CS:Dsp:%d)", p);
443
  #endif
444
 
445
  /* the current task (that is the only one inserted in the master module
446
     for the corresponding budget) is dispatched. Note that the current
447
     task is not inserted in any FIFO queue, so the task does not have to
448
     be extracted! */
449
 
450
  /* ... then, we dispatch it to the master level */
830 trimarchi 451
  if (!nostop)
452
    level_table[ lev->scheduling_level ]->
453
            private_dispatch(lev->scheduling_level,p,nostop);
221 giacomo 454
 
455
  /* ...and finally, we have to post a capacity event */
830 trimarchi 456
  TIMESPEC_ASSIGN(&ty, &schedule_time);
457
  TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time);
839 trimarchi 458
  ADDUSEC2TIMESPEC(lev->b[lev->tb[exec]].avail,&ty);
830 trimarchi 459
  lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
279 giacomo 460
 
830 trimarchi 461
 
221 giacomo 462
 
463
}
464
 
465
static void CBSSTAR_private_epilogue(LEVEL l, PID p)
466
{
467
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
830 trimarchi 468
  struct budget_struct *b;
469
  int skip_epilog;
470
  skip_epilog = 0;
221 giacomo 471
 
472
  #ifdef CBSSTAR_DEBUG
473
    kern_printf("(CS:Epi:%d)",p);
474
  #endif
475
 
830 trimarchi 476
  if (p==exec) b = &lev->b[lev->tb[p]];
477
    else if (lev->tb[exec]!=NIL)  {
478
          b = &lev->b[lev->tb[exec]];
479
          p=exec;
480
          skip_epilog=1;
481
       }
482
       else return;    
221 giacomo 483
 
830 trimarchi 484
  CBSSTAR_account_capacity(lev,p);
221 giacomo 485
 
830 trimarchi 486
  // L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch
487
  /* we have to check if the capacity is still available */
488
  if (b->flags)  {
489
    /* there is capacity available, maybe it is simply a preemption;
490
       the task have to return to the ready queue */
491
    if (!skip_epilog)
221 giacomo 492
      level_table[ lev->scheduling_level ]->
493
        private_epilogue(lev->scheduling_level,p);
494
 
830 trimarchi 495
  } else {
496
    /* we kill the current activation */
497
    level_table[ lev->scheduling_level ]->
498
      private_extract(lev->scheduling_level, p);    
499
 
500
    iq_insertfirst(p, &b->tasks);
501
    b->current = NIL;
502
 
503
  }
221 giacomo 504
 
505
}
506
 
507
/* Registration functions }*/
508
 
509
/*+ Registration function:
510
    int flags                 the init flags ... see CBSSTAR.h +*/
511
LEVEL CBSSTAR_register_level(int n, LEVEL master)
512
{
513
  LEVEL l;            /* the level that we register */
514
  CBSSTAR_level_des *lev;  /* for readableness only */
515
  PID i;              /* a counter */
516
 
263 giacomo 517
  printk("CBSSTAR_register_level\n");
221 giacomo 518
 
519
  /* request an entry in the level_table */
520
  l = level_alloc_descriptor(sizeof(CBSSTAR_level_des));
521
 
522
  lev = (CBSSTAR_level_des *)level_table[l];
523
 
524
  /* fill the standard descriptor */
525
  lev->l.private_insert   = CBSSTAR_private_insert;
526
  lev->l.private_extract  = CBSSTAR_private_extract;
527
  lev->l.private_eligible = CBSSTAR_private_eligible;
528
  lev->l.private_dispatch = CBSSTAR_private_dispatch;
529
  lev->l.private_epilogue = CBSSTAR_private_epilogue;
530
 
531
  lev->l.public_guarantee = CBSSTAR_public_guarantee;
532
 
533
  /* fill the CBSSTAR descriptor part */
534
  lev->b = (struct budget_struct *)kern_alloc(sizeof(struct budget_struct)*n);
535
 
536
  for (i=0; i<n; i++) {
537
    lev->b[i].Q = 0;
538
    lev->b[i].T = 0;
539
    NULL_TIMESPEC(&lev->b[i].dline);
830 trimarchi 540
    NULL_TIMESPEC(&lev->b[i].replenish);
541
    lev->b[i].replenish_timer = NIL;
221 giacomo 542
    lev->b[i].avail = 0;
543
    lev->b[i].current = -1;
241 giacomo 544
    lev->b[i].flags = CBSSTAR_ACTIVE;
221 giacomo 545
    lev->b[i].l=l;
241 giacomo 546
    iq_init(&lev->b[i].tasks, /* &freedesc */NULL, 0);
221 giacomo 547
  }
548
 
549
  lev->n = n;
550
  lev->freebudgets = 0;
551
 
552
  for (i=0; i<MAX_PROC; i++)
553
    lev->tb[i] = NIL;
554
 
555
  lev->U = 0;
556
  lev->cap_lev = NIL;
279 giacomo 557
  NULL_TIMESPEC(&lev->cap_lasttime);
221 giacomo 558
  lev->scheduling_level = master;
559
 
560
  return l;
561
 
562
}
563
 
830 trimarchi 564
int CBSSTAR_setbudget(LEVEL l, TIME Q, TIME T, TIME D, LEVEL local_scheduler_level, int scheduler_id)
221 giacomo 565
{
566
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
567
  int r;
568
 
569
  #ifdef CBSSTAR_DEBUG
570
    cbsstar_printf("(CS:SetBud)");
571
  #endif
572
 
573
  for (r = 0; r < lev->n; r++)
574
    if (lev->b[r].Q == 0) break;
575
 
576
  if (r != lev->n) {
577
    bandwidth_t b;
578
    b = (MAX_BANDWIDTH / T) * Q;
579
 
580
    /* really update lev->U, checking an overflow... */
581
    if (Q< T && MAX_BANDWIDTH - lev->U > b) {
582
 
583
      lev->U += b;
584
      lev->freebudgets++;
585
 
586
      lev->b[r].Q = Q;
587
      lev->b[r].T = T;
830 trimarchi 588
      lev->b[r].D = D;
241 giacomo 589
      lev->b[r].avail = Q;
590
      lev->b[r].flags = CBSSTAR_ACTIVE;
221 giacomo 591
      lev->b[r].loc_sched_id = scheduler_id;
592
      lev->b[r].loc_sched_level = local_scheduler_level;
593
 
594
      return r;
595
    }
596
    else
597
      return -2;
598
  }
599
  else
600
    return -1;
601
}
602
 
830 trimarchi 603
int CBSSTAR_get_remain_capacity(LEVEL l, int budget)
604
{
605
  struct timespec actual,ty;
606
  int    tx;
607
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
608
  kern_gettime(&actual);
609
  SUBTIMESPEC(&actual, &schedule_time, &ty);
610
  tx = TIMESPEC2USEC(&ty);
611
  // the remain capacity is from the first dispatch so is less then
612
  // actual capacity
613
  return (lev->b[budget].avail-tx);
614
 
615
}
616
 
221 giacomo 617
int CBSSTAR_removebudget(LEVEL l, int budget)
618
{
619
 
620
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
621
 
622
  bandwidth_t b;
623
 
624
  b = (MAX_BANDWIDTH / lev->b[budget].T) * lev->b[budget].Q;
625
 
626
  lev->U -= b;
627
 
628
  lev->b[budget].Q = 0;
629
  lev->b[budget].T = 0;
630
  NULL_TIMESPEC(&lev->b[budget].dline);
830 trimarchi 631
  lev->b[budget].replenish_timer = NIL;
221 giacomo 632
  lev->b[budget].avail = 0;
633
  lev->b[budget].current = -1;
241 giacomo 634
  lev->b[budget].flags = CBSSTAR_ACTIVE;
221 giacomo 635
 
636
  return 0;
637
 
638
}
639
 
830 trimarchi 640
int CBSSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, TIME D, int budget)
221 giacomo 641
{
642
 
643
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
644
 
645
  lev->b[budget].Q = Q;
646
  lev->b[budget].T = T;
830 trimarchi 647
  lev->b[budget].D = D;
221 giacomo 648
 
649
  return 0;
650
 
651
}
652
 
830 trimarchi 653
int CBSSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, TIME *D, int budget)
221 giacomo 654
{
655
 
656
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
657
 
658
  *Q = lev->b[budget].Q;
659
  *T = lev->b[budget].T;
830 trimarchi 660
  *D = lev->b[budget].D;
221 giacomo 661
 
662
  return 0;
663
 
664
}
665
 
288 giacomo 666
int CBSSTAR_get_last_reclaiming(LEVEL l, PID p)
273 giacomo 667
{
668
 
669
  return 0;
670
 
671
}
672
 
221 giacomo 673
int CBSSTAR_is_active(LEVEL l, int budget)
674
{
675
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
676
 
677
  return lev->b[budget].flags;
678
 
679
}
680
 
681
int CBSSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget)
682
{
683
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
684
 
685
  return lev->b[budget].loc_sched_level;
686
 
687
}
688
 
689
int CBSSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p)
690
{
691
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
692
 
693
  return lev->b[lev->tb[p]].loc_sched_level;
694
 
695
}
696
 
697
int CBSSTAR_get_local_scheduler_id_from_budget(LEVEL l, int budget)
698
{
699
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
700
 
701
  return lev->b[budget].loc_sched_id;
702
 
703
}
704
 
705
int CBSSTAR_get_local_scheduler_id_from_pid(LEVEL l, PID p)
706
{
707
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
708
 
709
  return lev->b[lev->tb[p]].loc_sched_id;
710
 
711
}
712
 
830 trimarchi 713
void CBSSTAR_disable_server(LEVEL l, int budget)
714
{
715
 CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
716
 int avail_budget;
717
 int spare;
718
 
719
 /* force a hard reservation event */
720
 avail_budget=lev->b[lev->tb[exec]].avail;
721
 lev->b[lev->tb[exec]].flags = CBSSTAR_NOACTIVE;
722
 //kern_printf("(CBS DS %d)", exec);
723
 /* save the unused capacity */
724
 spare=avail_budget+lev->b[lev->tb[exec]].avail;
725
 if (spare<=0) spare=0;
726
 
727
}