Subversion Repositories shark

Rev

Go to most recent revision | Details | 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
 
123
 
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;
172
       kern_printf("((1)ds sec %ld, us %ld)", b->dline.tv_sec, b->dline.tv_nsec/1000);
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
 
206
  //  #ifdef CBSNHSTAR_DEBUG
207
    kern_printf("(CS:Cap p%d av=%d tx=%d)", p, b->avail,tx);
208
  //#endif
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
 
238
    TIMESPEC_ASSIGN(&b->replenish, &schedule_time);
239
    ADDUSEC2TIMESPEC(b->T, &b->replenish);
240
    TIMESPEC_ASSIGN(&b->dline, &schedule_time);
241
    ADDUSEC2TIMESPEC(b->D, &b->dline);
242
    b->avail=b->Q;
243
    b->flags=CBSNHSTAR_ACTIVE;
244
    kern_printf("((2)ds sec %ld, us %ld)", b->dline.tv_sec, b->dline.tv_nsec/1000);
245
  }
246
 
247
}
248
 
249
 
250
/* The on-line guarantee is enabled only if the appropriate flag is set... */
251
static int CBSNHSTAR_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
252
{
253
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
254
 
255
  #ifdef CBSNHSTAR_DEBUG
256
    cbsnhstar_printf("(CS:Gua)");
257
  #endif
258
 
259
  if (*freebandwidth >= lev->U) {
260
    *freebandwidth -= lev->U;
261
    return 1;
262
  }
263
  else
264
    return 0;
265
}
266
 
267
static void capacity_handler(void *l)
268
{
269
 
270
  CBSNHSTAR_level_des *lev = l;
271
  lev->cap_lev = NIL;
272
  event_need_reschedule();
273
 
274
}
275
 
276
static int CBSNHSTAR_private_eligible(LEVEL l, PID p)
277
{
278
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
279
  struct budget_struct *b = &lev->b[lev->tb[p]];
280
  JOB_TASK_MODEL job;
281
 
282
  /* we have to check if the deadline and the wcet are correct...
283
     if the CBSNHSTAR level schedules in background with respect to others
284
     levels, there can be the case in witch a task is scheduled by
285
     schedule_time > CBSNHSTAR_deadline; in this case (not covered in the
286
     article because if there is only the standard scheduling policy
287
     this never apply) we reassign the deadline */
288
 
289
    if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
290
      if (lev->cap_lev!=NIL) {
291
        kern_event_delete(lev->cap_lev);
292
        lev->cap_lev=NIL;
293
      }
294
 
295
      if (b->negotiation) {
296
        lev->negotiation_in_progress--;
297
        b->negotiation=0;
298
        b->Q=b->N_Q;
299
        b->T=b->N_T;
300
        b->D=b->N_D;
301
 
302
        b->N_Q=0;
303
        b->N_T=0;
304
        b->N_D=0;
305
      }
306
 
307
      /* we kill the current activation */
308
      level_table[ lev->scheduling_level ]->
309
        private_extract(lev->scheduling_level, p);
310
      /* we modify the deadline ... */
311
      kern_gettime(&b->replenish);
312
      TIMESPEC_ASSIGN(&b->dline, &b->replenish);
313
      ADDUSEC2TIMESPEC(b->D, &b->dline);
314
      ADDUSEC2TIMESPEC(b->T, &b->replenish);  
315
      kern_printf("((3)ds sec %ld, us %ld)", b->dline.tv_sec, b->dline.tv_nsec/1000);
316
 
317
      /* and the capacity */
318
      b->avail = b->Q;
319
 
320
      b->flags = CBSNHSTAR_ACTIVE;
321
 
322
      /* Tracer */
323
      TRACER_LOGEVENT(FTrace_EVT_server_replenish,0,(unsigned int)(b));
324
 
325
      /* and, finally, we reinsert the task in the master level */
326
      job_task_default_model(job, b->dline);
327
      job_task_def_noexc(job);
328
      level_table[ lev->scheduling_level ]->
329
        private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
330
 
331
      return -1;
332
 
333
    }  
334
 
335
 
336
  return 0;
337
 
338
}
339
 
340
static void CBSNHSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
341
{
342
  /* A task has been activated for some reason. Basically, the task is
343
  inserted in the queue if the queue is empty, otherwise the task is
344
  inserted into the master module, and an oslib event is posted. */
345
 
346
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
347
  BUDGET_TASK_MODEL *budget;
348
 
349
  if (m->pclass != BUDGET_PCLASS ||
350
      (m->level != 0 && m->level != l)) {
351
    kern_raise(XINVALID_TASK, p);
352
    return;
353
  }
354
  budget = (BUDGET_TASK_MODEL *)m;
355
 
356
  #ifdef CBSNHSTAR_DEBUG
357
    cbsnhstar_printf("(CS:PriIns:%d:%d", p, budget->b);
358
  #endif
359
 
360
  if (budget->b == -1)
361
    return;
362
 
363
  lev->tb[p] = budget->b;
364
 
365
  if (lev->b[budget->b].current == NIL && lev->b[budget->b].flags ) {
366
    /* This is the first task in the budget,
367
       the task have to be inserted into the master module */
368
    struct timespec t;
369
    kern_gettime(&t);
370
    CBSNHSTAR_activation(lev,p,&t);
371
  } else {
372
    /* The budget is not empty, another task is already into the
373
       master module, so the task is inserted at the end of the budget
374
       queue */
375
    iq_insertlast(p,&lev->b[budget->b].tasks);
376
  }
377
 
378
  #ifdef CBSNHSTAR_DEBUG
379
    cbsnhstar_printf(")");
380
  #endif
381
 
382
}
383
 
384
static void CBSNHSTAR_private_extract(LEVEL l, PID p)
385
{
386
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
387
 
388
 
389
  #ifdef CBSNHSTAR_DEBUG
390
    kern_printf("(CS:Ext:%d)", p);
391
  #endif
392
 
393
  /* a task is removed from execution for some reasons. It must be
394
     that it is the first in its budget queue (only the first task in
395
     a budget queue is put into execution!) */
396
 
397
  /* remove the task from execution (or from the ready queue) */
398
  if (lev->b[lev->tb[p]].current == p) {
399
    //struct timespec t;
400
 
401
   CBSNHSTAR_account_capacity(lev,p);
402
 
403
    /* remove the task from the master module */
404
    level_table[ lev->scheduling_level ]->
405
      private_extract(lev->scheduling_level, p);
406
 
407
    /* check if the buffer has someone else to schedule */
408
    if (iq_query_first(&lev->b[lev->tb[p]].tasks) == NIL) {
409
      /* the buffer has no tasks! */
410
      lev->b[lev->tb[p]].current = NIL;
411
    }
412
    else if (lev->b[lev->tb[p]].flags) {
413
      /* if so, insert the new task into the master module */
414
      PID n;
415
      struct timespec t;
416
 
417
      kern_gettime(&t);
418
      n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
419
      CBSNHSTAR_activation(lev,n,&t);  // it modifies b[lev->tb[p]].current
420
    }
421
    else
422
      lev->b[lev->tb[p]].current=NIL;
423
 
424
  }
425
  else  {
426
    iq_extract(p, &lev->b[lev->tb[p]].tasks);
427
  }
428
}
429
 
430
static void CBSNHSTAR_private_dispatch(LEVEL l, PID p, int nostop)
431
{
432
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
433
  struct timespec ty;
434
 
435
  #ifdef CBSNHSTAR_DEBUG
436
    kern_printf("(CS:Dsp:%d)", p);
437
  #endif
438
 
439
  /* the current task (that is the only one inserted in the master module
440
     for the corresponding budget) is dispatched. Note that the current
441
     task is not inserted in any FIFO queue, so the task does not have to
442
     be extracted! */
443
 
444
  /* ... then, we dispatch it to the master level */
445
  if (!nostop)
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
  TIMESPEC_ASSIGN(&ty, &schedule_time);
451
  TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time);
452
  ADDUSEC2TIMESPEC(lev->b[lev->tb[exec]].avail,&ty);
453
  lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
454
 
455
 
456
 
457
}
458
 
459
static void CBSNHSTAR_private_epilogue(LEVEL l, PID p)
460
{
461
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
462
  struct budget_struct *b;
463
  int skip_epilog;
464
  skip_epilog = 0;
465
 
466
  #ifdef CBSNHSTAR_DEBUG
467
    kern_printf("(CS:Epi:%d)",p);
468
  #endif
469
 
470
  if (p==exec) b = &lev->b[lev->tb[p]];
471
    else if (lev->tb[exec]!=NIL)  {
472
          b = &lev->b[lev->tb[exec]];
473
          p=exec;
474
          skip_epilog=1;
475
       }
476
       else return;    
477
 
478
  CBSNHSTAR_account_capacity(lev,p);
479
 
480
  // L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch
481
  /* we have to check if the capacity is still available */
482
  //  if (b->flags)  {
483
    /* there is capacity available, maybe it is simply a preemption;
484
       the task have to return to the ready queue */
485
    if (!skip_epilog)
486
      level_table[ lev->scheduling_level ]->
487
        private_epilogue(lev->scheduling_level,p);
488
 
489
    //} else {
490
    /* we kill the current activation */
491
    //level_table[ lev->scheduling_level ]->
492
    //  private_extract(lev->scheduling_level, p);    
493
 
494
    //iq_insertfirst(p, &b->tasks);
495
    //b->current = NIL;
496
 
497
    //}
498
 
499
}
500
 
501
/* Registration functions }*/
502
 
503
/*+ Registration function:
504
    int flags                 the init flags ... see CBSNHSTAR.h +*/
505
LEVEL CBSNHSTAR_register_level(int n, LEVEL master)
506
{
507
  LEVEL l;            /* the level that we register */
508
  CBSNHSTAR_level_des *lev;  /* for readableness only */
509
  PID i;              /* a counter */
510
 
511
  printk("CBSNHSTAR_register_level\n");
512
 
513
  /* request an entry in the level_table */
514
  l = level_alloc_descriptor(sizeof(CBSNHSTAR_level_des));
515
 
516
  lev = (CBSNHSTAR_level_des *)level_table[l];
517
 
518
  /* fill the standard descriptor */
519
  lev->l.private_insert   = CBSNHSTAR_private_insert;
520
  lev->l.private_extract  = CBSNHSTAR_private_extract;
521
  lev->l.private_eligible = CBSNHSTAR_private_eligible;
522
  lev->l.private_dispatch = CBSNHSTAR_private_dispatch;
523
  lev->l.private_epilogue = CBSNHSTAR_private_epilogue;
524
 
525
  lev->l.public_guarantee = CBSNHSTAR_public_guarantee;
526
 
527
  /* fill the CBSNHSTAR descriptor part */
528
  lev->b = (struct budget_struct *)kern_alloc(sizeof(struct budget_struct)*n);
529
 
530
  for (i=0; i<n; i++) {
531
    lev->b[i].Q = 0;
532
    lev->b[i].T = 0;
533
    lev->b[i].D = 0;
534
 
535
    lev->b[i].N_Q = 0;
536
    lev->b[i].N_T = 0;
537
    lev->b[i].N_D = 0;
538
 
539
    NULL_TIMESPEC(&lev->b[i].dline);
540
    NULL_TIMESPEC(&lev->b[i].replenish);
541
    lev->b[i].avail = 0;
542
    lev->b[i].current = -1;
543
    lev->b[i].flags = CBSNHSTAR_ACTIVE;
544
    lev->b[i].l=l;
545
    lev->b[i].negotiation = 0;
546
    lev->b[i].recharge_count=0;
547
    iq_init(&lev->b[i].tasks, /* &freedesc */NULL, 0);
548
  }
549
 
550
  lev->n = n;
551
  lev->freebudgets = 0;
552
 
553
  for (i=0; i<MAX_PROC; i++)
554
    lev->tb[i] = NIL;
555
 
556
  lev->U = 0;
557
  lev->cap_lev = NIL;
558
  NULL_TIMESPEC(&lev->cap_lasttime);
559
  lev->scheduling_level = master;
560
 
561
  return l;
562
 
563
}
564
 
565
int CBSNHSTAR_setbudget(LEVEL l, TIME Q, TIME T, TIME D, LEVEL local_scheduler_level, int scheduler_id)
566
{
567
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
568
  int r;
569
 
570
  // #ifdef CBSNHSTAR_DEBUG
571
    kern_printf("(CS:SetBud)");
572
    //#endif
573
 
574
  for (r = 0; r < lev->n; r++)
575
    if (lev->b[r].Q == 0) break;
576
 
577
  if (r != lev->n) {
578
    bandwidth_t b;
579
    mul32div32to32(MAX_BANDWIDTH, Q, T, b);
580
    /* b = (MAX_BANDWIDTH / T) * Q; */
581
 
582
    /* really update lev->U, checking an overflow... */
583
    if (Q< T /* && MAX_BANDWIDTH - lev->U > b */) {
584
 
585
      lev->U += b;
586
      lev->freebudgets++;
587
 
588
      lev->b[r].Q = Q;
589
      lev->b[r].T = T;
590
      lev->b[r].D = D;
591
 
592
      lev->b[r].N_Q = 0;
593
      lev->b[r].N_T = 0;
594
      lev->b[r].N_D = 0;
595
 
596
      lev->b[r].avail = Q;
597
      lev->b[r].flags = CBSNHSTAR_ACTIVE;
598
      lev->b[r].negotiation=0;
599
      lev->b[r].loc_sched_id = scheduler_id;
600
      lev->b[r].loc_sched_level = local_scheduler_level;
601
      lev->b[r].recharge_count=0;
602
      return r;
603
    }
604
    else
605
      return -2;
606
  }
607
  else
608
    return -1;
609
}
610
 
611
int CBSNHSTAR_get_remain_capacity(LEVEL l, int budget)
612
{
613
  struct timespec actual,ty;
614
  int    tx;
615
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
616
  kern_gettime(&actual);
617
  SUBTIMESPEC(&actual, &schedule_time, &ty);
618
  tx = TIMESPEC2USEC(&ty);
619
  // the remain capacity is from the first dispatch so is less then
620
  // actual capacity
621
  return (lev->b[budget].avail-tx);
622
 
623
}
624
 
625
int CBSNHSTAR_removebudget(LEVEL l, int budget)
626
{
627
 
628
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
629
 
630
  bandwidth_t b;
631
 
632
  b = (MAX_BANDWIDTH / lev->b[budget].T) * lev->b[budget].Q;
633
 
634
  lev->U -= b;
635
 
636
  lev->b[budget].Q = 0;
637
  lev->b[budget].T = 0;
638
  lev->b[budget].D = 0;
639
 
640
  lev->b[budget].N_Q = 0;
641
  lev->b[budget].N_T = 0;
642
  lev->b[budget].N_D = 0;
643
 
644
  lev->b[budget].recharge_count=0;
645
  NULL_TIMESPEC(&lev->b[budget].dline);
646
  NULL_TIMESPEC(&lev->b[budget].replenish);
647
  lev->b[budget].avail = 0;
648
  lev->b[budget].current = -1;
649
  lev->b[budget].negotiation=0;
650
  lev->b[budget].flags = CBSNHSTAR_ACTIVE;
651
 
652
  return 0;
653
 
654
}
655
 
656
int CBSNHSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, TIME D, int budget)
657
{
658
 
659
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
660
 
661
  lev->b[budget].N_Q = Q;
662
  lev->b[budget].N_T = T;
663
  lev->b[budget].N_D = D;
664
 
665
  if (lev->b[budget].current!=NIL && !(lev->b[budget].Q==Q && lev->b[budget].T==T)) {
666
    lev->b[budget].N_Q = Q;
667
    lev->b[budget].N_T = T;
668
    lev->b[budget].N_D = D;
669
    if (!lev->b[budget].negotiation) {
670
      lev->negotiation_in_progress++;
671
      lev->b[budget].negotiation=1;
672
    }                                                  
673
  } else {
674
    lev->b[budget].Q = Q;
675
    lev->b[budget].T = T;
676
    lev->b[budget].D = D;
677
  }
678
 
679
  return 0;
680
 
681
}
682
 
683
int CBSNHSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, TIME *D, int budget)
684
{
685
 
686
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
687
 
688
  *Q = lev->b[budget].Q;
689
  *T = lev->b[budget].T;
690
  *D = lev->b[budget].D;
691
 
692
  return 0;
693
 
694
}
695
 
696
int CBSNHSTAR_get_last_reclaiming(LEVEL l, PID p)
697
{
698
 
699
  return 0;
700
 
701
}
702
 
703
int CBSNHSTAR_is_active(LEVEL l, int budget)
704
{
705
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
706
 
707
  return lev->b[budget].flags;
708
 
709
}
710
 
711
int CBSNHSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget)
712
{
713
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
714
 
715
  return lev->b[budget].loc_sched_level;
716
 
717
}
718
 
719
int CBSNHSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p)
720
{
721
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
722
 
723
  return lev->b[lev->tb[p]].loc_sched_level;
724
 
725
}
726
 
727
int CBSNHSTAR_get_local_scheduler_id_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_id;
732
 
733
}
734
 
735
int CBSNHSTAR_get_local_scheduler_id_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_id;
740
 
741
}
742
 
743
void CBSNHSTAR_disable_server(LEVEL l, int budget)
744
{
745
 CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
746
 int avail_budget;
747
 int spare;
748
 
749
 /* force a hard reservation event */
750
 avail_budget=lev->b[lev->tb[exec]].avail;
751
 lev->b[lev->tb[exec]].flags = CBSNHSTAR_NOACTIVE;
752
 //kern_printf("(CBSNH DS %d)", exec);
753
 /* save the unused capacity */
754
 spare=avail_budget+lev->b[lev->tb[exec]].avail;
755
 if (spare<=0) spare=0;
756
 
757
}
758
 
759
int CBSNHSTAR_getrecharge_number(LEVEL l, int budget) {
760
 
761
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
762
  //kern_printf("CBSNH:rn:budget:%d:rnumber:%d", budget, lev->b[budget].recharge_count);
763
 
764
  return lev->b[budget].recharge_count;
765
 
766
}
767
 
768
int CBSNHSTAR_get_renegotiation_status(LEVEL l, int budget)
769
{
770
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
771
  if (lev->negotiation_in_progress) return 1;
772
  else return 0;
773
}
774
 
775
bandwidth_t  CBSNHSTAR_get_bandwidth(LEVEL l)
776
{
777
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
778
  return lev->U;
779
 
780
}
781
 
782
void  CBSNHSTAR_getdeadline(LEVEL l, int budget, struct timespec *t) {
783
 
784
  CBSNHSTAR_level_des *lev = (CBSNHSTAR_level_des *)(level_table[l]);
785
 
786
   TIMESPEC_ASSIGN(t,&lev->b[budget].dline);
787
}