Subversion Repositories shark

Rev

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

Rev Author Line No. Line
671 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
 *      Giacomo Guidi    <giacomo@gandalf.sssup.it>
10
 *      Mauro Marinoni
11
 *      Anton Cervin
12
 *
13
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
14
 *
15
 * http://www.sssup.it
16
 * http://retis.sssup.it
17
 * http://shark.sssup.it
18
 */
19
 
20
/*
21
 * This program is free software; you can redistribute it and/or modify
22
 * it under the terms of the GNU General Public License as published by
23
 * the Free Software Foundation; either version 2 of the License, or
24
 * (at your option) any later version.
25
 *
26
 * This program is distributed in the hope that it will be useful,
27
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
 * GNU General Public License for more details.
30
 *
31
 * You should have received a copy of the GNU General Public License
32
 * along with this program; if not, write to the Free Software
33
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34
 *
35
 */
36
 
37
#include <kernel/model.h>
38
#include <kernel/descr.h>
39
#include <kernel/var.h>
40
#include <kernel/func.h>
41
 
42
#include <stdlib.h>
43
 
44
#include <modules/elastic.h>
45
 
46
#include <tracer.h>
47
 
707 anton 48
 
49
/* Task flags */
50
 
673 giacomo 51
#define ELASTIC_PRESENT       1
707 anton 52
#define ELASTIC_JOB_PRESENT   2  
671 giacomo 53
 
707 anton 54
/* Task statuses */
55
 
683 giacomo 56
#define ELASTIC_IDLE          APER_STATUS_BASE
57
 
676 giacomo 58
 
707 anton 59
#define ELASTIC_DEBUG
60
 
61
#ifdef ELASTIC_DEBUG
62
char *pnow() {
63
  static char buf[40];
64
  struct timespec t;
65
  kern_gettime(&t);
66
  sprintf(buf, "%ld.%06ld", t.tv_sec, t.tv_nsec/1000);
67
  return buf;
68
}
69
char *ptime1(struct timespec *t) {
70
  static char buf[40];
71
  sprintf(buf, "%ld.%06ld", t->tv_sec, t->tv_nsec/1000);
72
  return buf;
73
}
74
char *ptime2(struct timespec *t) {
75
  static char buf[40];
76
  sprintf(buf, "%ld.%06ld", t->tv_sec, t->tv_nsec/1000);
77
  return buf;
78
}
79
#endif
80
 
81
 
671 giacomo 82
typedef struct {
83
 
697 anton 84
  /* Task parameters (set/changed by the user) */
85
 
86
  TIME Tmin;   /* The nominal (minimum) period */
87
  TIME Tmax;   /* The maximum tolerable period */
88
  TIME C;      /* The declared worst-case execution time */
89
  int  E;      /* The elasticity coefficient */
90
  int  beta;   /* PERIOD_SCALING or WCET_SCALING */
91
 
92
  /* Task variables (changed by the module) */
93
 
707 anton 94
  struct timespec release;    /* The current activation time */
95
  struct timespec dline;      /* The current absolute deadline */
96
  int dltimer;                /* Deadline timer handle */
671 giacomo 97
 
700 anton 98
  ext_bandwidth_t Umax;       /* The maximum utilization, Umax = C/Tmin  */
99
  ext_bandwidth_t Umin;       /* The minimum utilization, Umin = C/Tmax  */
671 giacomo 100
 
707 anton 101
  ext_bandwidth_t U;          /* New assigned utilization             */
102
  ext_bandwidth_t oldU;       /* Old utilization                      */
103
  TIME T;                     /* The current period, T = C/U          */
673 giacomo 104
 
671 giacomo 105
  int  flags;
106
 
107
} ELASTIC_task_descr;
108
 
109
typedef struct {
110
  level_des l;     /*+ the standard level descriptor          +*/
111
 
700 anton 112
  ext_bandwidth_t U;   /*+ the bandwidth reserved for elastic tasks  +*/
671 giacomo 113
 
697 anton 114
  ELASTIC_task_descr elist[MAX_PROC];
671 giacomo 115
 
116
  LEVEL scheduling_level;
117
 
118
  LEVEL current_level;
119
 
120
  int flags;
121
 
122
} ELASTIC_level_des;
123
 
673 giacomo 124
 
707 anton 125
static void ELASTIC_activation(ELASTIC_level_des *lev, PID p,
126
                               struct timespec *acttime)
127
{
128
  JOB_TASK_MODEL job;
129
  ELASTIC_task_descr *et = &lev->elist[p];
697 anton 130
 
707 anton 131
  /* Assign release time */
132
  et->release = *acttime;
133
 
134
  /* Assign absolute deadline */
135
  et->dline = *acttime;
136
  ADDUSEC2TIMESPEC(et->T, &et->dline);
137
 
138
#ifdef ELASTIC_DEBUG
139
  cprintf("At %s: activating %s; rel=%s; dl=%s\n", pnow(), proc_table[p].name,
140
          ptime1(&et->release), ptime2(&et->dline));
141
#endif  
142
 
143
  proc_table[p].avail_time = et->C;
144
  proc_table[p].wcet = et->C;
145
 
146
  /* Job insertion */
147
  job_task_default_model(job, et->dline);
148
  level_table[lev->scheduling_level]->
149
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
150
}
151
 
152
 
153
static void ELASTIC_timer_act(void *arg) {
154
 
155
  PID p = (PID)(arg);
156
  ELASTIC_level_des *lev;
157
 
158
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
159
  ELASTIC_task_descr *et = &lev->elist[p];
160
 
161
  /* Use the current deadline as the new activation time */
162
  ELASTIC_activation(lev, p, &et->dline);
163
 
164
  event_need_reschedule();
165
 
166
  /* Next activation */
167
  et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act, (void *)(p));
168
}
169
 
170
 
171
/* Check feasability and compute new utilizations for the task set */
172
 
697 anton 173
static int ELASTIC_compress(ELASTIC_level_des *lev) {
174
 
676 giacomo 175
  PID i;
707 anton 176
  ELASTIC_task_descr *et;
697 anton 177
  int ok;
178
 
179
  ext_bandwidth_t Umin;  // minimum utilization
180
  ext_bandwidth_t Umax;  // nominal (maximum) utilization of compressable tasks
676 giacomo 181
 
697 anton 182
  ext_bandwidth_t Uf;    // amount of non-compressable utilization
183
  int Ev;                // sum of elasticity among compressable tasks
184
 
707 anton 185
  JOB_TASK_MODEL job;
186
 
697 anton 187
  Umin = 0;
188
  Umax = 0;
189
 
676 giacomo 190
  for (i=0; i<MAX_PROC; i++) {
707 anton 191
    et = &lev->elist[i];
192
    if (et->flags & ELASTIC_PRESENT) {
193
      if (et->E == 0) {
194
        Umin += et->U;
195
        Umax += et->U;
697 anton 196
      } else {
707 anton 197
        Umin += et->Umin;
198
        Umax += et->Umax;
199
        et->U = et->Umax;   // reset previous saturations (if any)
697 anton 200
      }
691 anton 201
    }
676 giacomo 202
  }
697 anton 203
 
700 anton 204
  if (Umin > lev->U) return -1;  // NOT FEASIBLE
676 giacomo 205
 
700 anton 206
  if (Umax <= lev->U) return 0;  // FEASIBLE WITH MAXIMUM UTILIZATIONS
207
 
697 anton 208
  do {
209
    Uf = 0;
210
    Ev = 0;
211
    Umax = 0;
673 giacomo 212
 
697 anton 213
    for (i=0; i<MAX_PROC; i++) {
707 anton 214
      et = &lev->elist[i];
215
      if (et->flags & ELASTIC_PRESENT) {
216
        if (et->E == 0 || et->U == et->Umin) {
217
          Uf += et->U;
697 anton 218
        } else {
707 anton 219
          Ev += et->E;
220
          Umax += et->Umax;
697 anton 221
        }
222
      }
223
    }
224
 
225
    ok = 1;
226
 
227
    for (i=0; i<MAX_PROC; i++) {
707 anton 228
      et = &lev->elist[i];
229
      if (et->flags & ELASTIC_PRESENT) {
230
        if (et->E > 0 && et->U > et->Umin) {
231
          et->U = et->Umax - (Umax - lev->U + Uf) * et->E / Ev;
232
          if (et->U < et->Umin) {
233
            et->U = et->Umin;
697 anton 234
            ok = 0;
235
          }
236
        }
237
      }
238
    }
673 giacomo 239
 
697 anton 240
  } while (ok == 0);
673 giacomo 241
 
707 anton 242
  // Increase periods of compressed tasks IMMEDIATELY.
243
  // The other ones will be changed at their next activation
244
 
245
  for (i=0; i<MAX_PROC; i++) {
246
    et = &lev->elist[i];
247
    if (et->flags & ELASTIC_PRESENT) {
248
      if (et->U != et->oldU) {
249
        /* Utilization has been changed. Compute new period */
250
        et->T = ((long long)et->C * (long long)MAX_BANDWIDTH) / et->U;
251
      }
252
      if (et->U < et->oldU) {
253
        /* Task has been compressed. Change its deadline NOW! */
254
        if (et->flags & ELASTIC_JOB_PRESENT) {
255
          /* Remove job from level and change its deadline */
256
          level_table[lev->scheduling_level]->
257
            private_extract(lev->scheduling_level, i);
258
        }
259
        /* Compute new deadline */
260
        et->dline = et->release;
261
        ADDUSEC2TIMESPEC(et->T, &et->dline);
262
        if (et->dltimer != -1) {
263
          /* Delete old deadline timer, post new one */
264
          kern_event_delete(et->dltimer);
265
          et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act,(void *)(i));
266
        }
267
        if (et->flags & ELASTIC_JOB_PRESENT) {
268
          /* Reinsert job */
269
          job_task_default_model(job, et->dline);
270
          level_table[lev->scheduling_level]->
271
            private_insert(lev->scheduling_level, i, (TASK_MODEL *)&job);
272
        }
273
      }
274
      et->oldU = et->U;  /* Update oldU */
275
    }
276
  }
277
 
278
#ifdef ELASTIC_DEBUG
697 anton 279
  cprintf("New periods: ");
691 anton 280
  for (i=0; i<MAX_PROC; i++) {
707 anton 281
    et = &lev->elist[i];
282
    if (et->flags & ELASTIC_PRESENT) {
283
      cprintf("%s:%d ", proc_table[i].name, (int)et->T);
691 anton 284
    }
285
  }
697 anton 286
  cprintf("\n");
707 anton 287
#endif
691 anton 288
 
697 anton 289
  return 0; // FEASIBLE
691 anton 290
 
673 giacomo 291
}
292
 
697 anton 293
 
671 giacomo 294
/* The on-line guarantee is enabled only if the appropriate flag is set... */
295
static int ELASTIC_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
296
{
297
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
298
 
700 anton 299
  return 1;
300
 
691 anton 301
  if (*freebandwidth >= lev->U) {
700 anton 302
    *freebandwidth -= (unsigned int)lev->U;
691 anton 303
    return 1;
304
  } else {
305
    return 0;
306
  }
671 giacomo 307
}
308
 
691 anton 309
 
671 giacomo 310
static int ELASTIC_public_create(LEVEL l, PID p, TASK_MODEL *m)
311
{
312
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
691 anton 313
  ELASTIC_TASK_MODEL *elastic = (ELASTIC_TASK_MODEL *)m;
707 anton 314
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 315
 
316
  if (m->pclass != ELASTIC_PCLASS) return -1;
317
  if (m->level != 0 && m->level != l) return -1;
318
 
691 anton 319
  if (elastic->C == 0) return -1;
673 giacomo 320
  if (elastic->Tmin > elastic->Tmax) return -1;
321
  if (elastic->Tmax == 0) return -1;
707 anton 322
  if (elastic->Tmin == 0) return -1;
673 giacomo 323
 
707 anton 324
  NULL_TIMESPEC(&(et->dline));
325
  et->Tmin = elastic->Tmin;
326
  et->Tmax = elastic->Tmax;
327
  et->C = elastic->C;
328
  et->E = elastic->E;
329
  et->beta = elastic->beta;
673 giacomo 330
 
707 anton 331
  et->Umax = ((long long)MAX_BANDWIDTH * (long long)elastic->C) / elastic->Tmin;
332
  et->Umin = ((long long)MAX_BANDWIDTH * (long long)elastic->C) / elastic->Tmax;
673 giacomo 333
 
707 anton 334
  et->U = et->Umax;
335
  et->oldU = 0;
336
  et->T = et->Tmin;
337
  et->dltimer = -1;
673 giacomo 338
 
691 anton 339
  proc_table[p].avail_time = elastic->C;
340
  proc_table[p].wcet       = elastic->C;
674 giacomo 341
  proc_table[p].control    |= CONTROL_CAP;
673 giacomo 342
 
697 anton 343
  return 0;
671 giacomo 344
}
345
 
697 anton 346
 
671 giacomo 347
static void ELASTIC_public_detach(LEVEL l, PID p)
348
{
707 anton 349
  //ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
671 giacomo 350
 
351
}
352
 
353
static int ELASTIC_public_eligible(LEVEL l, PID p)
354
{
707 anton 355
  //ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
671 giacomo 356
 
357
  return 0;
358
 
359
}
360
 
361
static void ELASTIC_public_dispatch(LEVEL l, PID p, int nostop)
362
{
363
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
674 giacomo 364
 
671 giacomo 365
  level_table[ lev->scheduling_level ]->
366
    private_dispatch(lev->scheduling_level,p,nostop);
674 giacomo 367
 
671 giacomo 368
}
369
 
370
static void ELASTIC_public_epilogue(LEVEL l, PID p)
371
{
372
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
373
 
674 giacomo 374
  /* check if the wcet is finished... */
375
  if (proc_table[p].avail_time <= 0) {
376
 
707 anton 377
    TRACER_LOGEVENT(FTrace_EVT_task_wcet_violation,
378
                    (unsigned short int)proc_table[p].context,0);
674 giacomo 379
    kern_raise(XWCET_VIOLATION,p);
380
 
381
  }
691 anton 382
 
707 anton 383
  level_table[lev->scheduling_level]->
674 giacomo 384
      private_epilogue(lev->scheduling_level,p);
385
 
671 giacomo 386
}
387
 
388
static void ELASTIC_public_activate(LEVEL l, PID p, struct timespec *t)
389
{
707 anton 390
 
671 giacomo 391
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
707 anton 392
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 393
 
674 giacomo 394
  /* check if we are not in the SLEEP state */
395
  if (proc_table[p].status != SLEEP) {
396
    return;
397
  }
398
 
707 anton 399
  et->flags |= ELASTIC_PRESENT;
400
  if (ELASTIC_compress(lev) == -1) {
401
    et->flags &= ~ELASTIC_PRESENT;
402
#ifdef ELASTIC_DEBUG
403
    cprintf("ELASTIC_public_activate: compression failed!\n");
404
#endif
405
    return;
406
  }
407
 
674 giacomo 408
  ELASTIC_activation(lev,p,t);
409
 
410
  /* Next activation */
707 anton 411
  et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act, (void *)(p));
674 giacomo 412
 
671 giacomo 413
}
414
 
415
static void ELASTIC_public_unblock(LEVEL l, PID p)
416
{
417
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
418
  struct timespec acttime;
419
 
420
  kern_gettime(&acttime);
421
 
422
  ELASTIC_activation(lev,p,&acttime);
423
 
424
}
425
 
426
static void ELASTIC_public_block(LEVEL l, PID p)
427
{
428
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
707 anton 429
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 430
 
707 anton 431
  level_table[lev->scheduling_level]->
671 giacomo 432
    private_extract(lev->scheduling_level,p);
707 anton 433
  et->flags &= ~ELASTIC_JOB_PRESENT;
671 giacomo 434
 
435
}
436
 
437
static int ELASTIC_public_message(LEVEL l, PID p, void *m)
438
{
439
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
440
 
441
  switch((long)(m)) {
442
 
443
    case (long)(NULL):
444
 
707 anton 445
      level_table[lev->scheduling_level]->
676 giacomo 446
        private_extract(lev->scheduling_level,p);
447
 
683 giacomo 448
      proc_table[p].status = ELASTIC_IDLE;
676 giacomo 449
 
671 giacomo 450
      jet_update_endcycle(); /* Update the Jet data... */
451
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,(unsigned short int)proc_table[p].context,(unsigned int)l);
452
 
453
      break;
454
 
455
    case 1:
456
 
676 giacomo 457
      level_table[ lev->scheduling_level ]->
458
        private_extract(lev->scheduling_level,p);
459
 
460
      proc_table[p].status = SLEEP;
461
 
671 giacomo 462
      TRACER_LOGEVENT(FTrace_EVT_task_disable,(unsigned short int)proc_table[p].context,(unsigned int)l);
463
 
464
      break;
465
 
466
  }
467
 
468
  return 0;
469
 
470
}
471
 
472
static void ELASTIC_public_end(LEVEL l, PID p)
473
{
474
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
475
 
476
  level_table[ lev->scheduling_level ]->
477
    private_extract(lev->scheduling_level,p);
478
 
479
}
480
 
481
/*+ Registration function +*/
700 anton 482
LEVEL ELASTIC_register_level(int flags, LEVEL master, ext_bandwidth_t U)
671 giacomo 483
{
484
  LEVEL l;            /* the level that we register */
485
  ELASTIC_level_des *lev;  /* for readableness only */
486
  PID i;
487
 
488
  printk("ELASTIC_register_level\n");
489
 
490
  /* request an entry in the level_table */
491
  l = level_alloc_descriptor(sizeof(ELASTIC_level_des));
492
 
493
  lev = (ELASTIC_level_des *)level_table[l];
494
 
495
  /* fill the standard descriptor */
496
  if (flags & ELASTIC_ENABLE_GUARANTEE)
497
    lev->l.public_guarantee = ELASTIC_public_guarantee;
498
  else
499
    lev->l.public_guarantee = NULL;
500
  lev->l.public_create    = ELASTIC_public_create;
501
  lev->l.public_detach    = ELASTIC_public_detach;
502
  lev->l.public_end       = ELASTIC_public_end;
503
  lev->l.public_eligible  = ELASTIC_public_eligible;
504
  lev->l.public_dispatch  = ELASTIC_public_dispatch;
505
  lev->l.public_epilogue  = ELASTIC_public_epilogue;
506
  lev->l.public_activate  = ELASTIC_public_activate;
507
  lev->l.public_unblock   = ELASTIC_public_unblock;
508
  lev->l.public_block     = ELASTIC_public_block;
509
  lev->l.public_message   = ELASTIC_public_message;
510
 
676 giacomo 511
  /* fill the ELASTIC task descriptor part */
671 giacomo 512
  for (i=0; i<MAX_PROC; i++) {
513
     NULL_TIMESPEC(&(lev->elist[i].dline));
514
     lev->elist[i].Tmin = 0;
515
     lev->elist[i].Tmax = 0;
691 anton 516
     lev->elist[i].T = 0;
697 anton 517
     lev->elist[i].U = 0;
691 anton 518
     lev->elist[i].C = 0;
519
     lev->elist[i].E = 0;
671 giacomo 520
     lev->elist[i].beta = 0;
707 anton 521
     lev->elist[i].flags = 0;
671 giacomo 522
  }
523
 
691 anton 524
  lev->U = U;
671 giacomo 525
 
526
  lev->scheduling_level = master;
527
 
528
  lev->current_level = l;
529
 
707 anton 530
  lev->flags = 0;
671 giacomo 531
 
532
  return l;
533
}
534
 
707 anton 535
 
536
/* Force the period of task p to a given value */
537
 
538
int ELASTIC_set_period(PID p, TIME period) {
539
 
540
  SYS_FLAGS f;
541
  int saveE;          
542
  ext_bandwidth_t saveU;
543
 
544
  f = kern_fsave();
545
 
546
  ELASTIC_level_des *lev;
547
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
548
  ELASTIC_task_descr *et = &lev->elist[p];
549
 
550
  saveE = et->E;
551
  saveU = et->U;
552
 
553
  et->E = 0;  /* set elasticity to zero to make correct compression */
554
  et->U = ((long long)MAX_BANDWIDTH * (long long)et->C)/period;
555
 
556
  if (ELASTIC_compress(lev) == -1) {
557
#ifdef ELASTIC_DEBUG
558
    cprintf("ELASTIC_set_period failed: could not compress\n");
559
#endif
560
    et->E = saveE;
561
    et->U = saveU;
562
    kern_frestore(f);
563
    return -1;
564
  }
565
 
566
  et->E = saveE;     /* Restore E when compression is done */
567
  kern_frestore(f);
568
  return 0;
569
}
708 giacomo 570
 
571
int ELASTIC_get_period(PID p) {
572
 
573
  SYS_FLAGS f;
574
  ELASTIC_level_des *lev;
575
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
576
 
577
  f = kern_fsave();
578
 
579
  if (lev->elist[p].flags & ELASTIC_PRESENT) {  
580
 
581
    kern_frestore(f);
582
    return lev->elist[p].T;
583
 
584
  } else {
585
 
586
    kern_frestore(f);
587
    return -1;
588
 
589
  }
590
 
591
}
592
 
593
int ELASTIC_set_E(PID p, int E) {
594
 
595
  SYS_FLAGS f;
596
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
597
  ELASTIC_task_descr *et = &lev->elist[p];
598
  int saveE;
599
 
600
  f = kern_fsave();
601
 
602
  if (et->flags & ELASTIC_PRESENT) {
603
 
604
    saveE = et->E;
605
 
606
    et->E = E;                                                                                                                            
607
    if (ELASTIC_compress(lev) == -1) {
608
#ifdef ELASTIC_DEBUG
609
      cprintf("ELASTIC_set_E failed: could not compress\n");
610
#endif
611
      et->E = saveE;
612
      kern_frestore(f);
613
      return -1;
614
 
615
    }
616
 
617
    kern_frestore(f);
618
    return 0;
619
 
620
  } else {
621
 
622
    kern_frestore(f);
623
    return -1;
624
 
625
  }
626
 
627
}
628
 
629
int ELASTIC_get_E(PID p) {
630
 
631
  SYS_FLAGS f;
632
  ELASTIC_level_des *lev;
633
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
634
 
635
  f = kern_fsave();
636
 
637
  if (lev->elist[p].flags & ELASTIC_PRESENT) {
638
 
639
    kern_frestore(f);
640
    return lev->elist[p].E;
641
 
642
  } else {
643
 
644
    kern_frestore(f);
645
    return -1;
646
 
647
  }
648
 
649
}
650
 
651
int ELASTIC_set_beta(PID p, int beta) {
652
 
653
  SYS_FLAGS f;
654
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
655
  ELASTIC_task_descr *et = &lev->elist[p];
656
  int saveBeta;
657
 
658
  f = kern_fsave();
659
 
660
  if (et->flags & ELASTIC_PRESENT) {
661
 
662
    saveBeta = et->beta;
663
 
664
    et->beta = beta;                                                                                                                              
665
    if (ELASTIC_compress(lev) == -1) {
666
#ifdef ELASTIC_DEBUG
667
      cprintf("ELASTIC_set_beta failed: could not compress\n");
668
#endif
669
      et->beta = saveBeta;
670
      kern_frestore(f);
671
      return -1;
672
 
673
    }
674
 
675
    kern_frestore(f);
676
    return 0;
677
 
678
  } else {
679
 
680
    kern_frestore(f);
681
    return -1;
682
 
683
  }
684
 
685
}
686
 
687
int ELASTIC_get_beta(PID p) {
688
 
689
  SYS_FLAGS f;
690
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
691
 
692
  f = kern_fsave();
693
 
694
  if (lev->elist[p].flags & ELASTIC_PRESENT) {
695
 
696
    kern_frestore(f);
697
    return lev->elist[p].beta;
698
 
699
  } else {
700
 
701
    kern_frestore(f);
702
    return -1;
703
 
704
  }
705
 
706
}
707
 
708
int ELASTIC_set_bandwidth(LEVEL level, ext_bandwidth_t U) {
709
 
710
  SYS_FLAGS f;
711
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];
712
 
713
  f = kern_fsave();
714
 
715
  lev->U = U;
716
 
717
  if (ELASTIC_compress(lev) == -1) {
718
#ifdef ELASTIC_DEBUG
719
    cprintf("ELASTIC_set_bandwidth failed: could not compress\n");
720
#endif
721
    kern_frestore(f);
722
    return -1;
723
  }
724
 
725
  kern_frestore(f);
726
  return 0;
727
 
728
}
729
 
730
ext_bandwidth_t ELASTIC_get_bandwidth(LEVEL level) {
731
 
732
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];;
733
 
734
  return lev->U;
735
 
736
}