Subversion Repositories shark

Rev

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