Subversion Repositories shark

Rev

Rev 990 | Details | Compare with Previous | Last modification | View Log | RSS feed

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