Subversion Repositories shark

Rev

Rev 737 | Rev 744 | Go to most recent revision | 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
 *
737 anton 8
 * Authors:
671 giacomo 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
 
741 giacomo 42
#include <ll/i386/64bit.h>
43
 
671 giacomo 44
#include <stdlib.h>
45
 
46
#include <modules/elastic.h>
47
 
48
#include <tracer.h>
49
 
707 anton 50
/* Task flags */
51
 
673 giacomo 52
#define ELASTIC_PRESENT       1
707 anton 53
#define ELASTIC_JOB_PRESENT   2  
671 giacomo 54
 
707 anton 55
/* Task statuses */
56
 
683 giacomo 57
#define ELASTIC_IDLE          APER_STATUS_BASE
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
 
741 giacomo 114
  int c_scaling_factor;   /*+ the computation time scaling factor +*/
671 giacomo 115
 
741 giacomo 116
  ELASTIC_task_descr *elist;
117
 
671 giacomo 118
  LEVEL scheduling_level;
119
 
120
  LEVEL current_level;
121
 
122
  int flags;
123
 
124
} ELASTIC_level_des;
125
 
673 giacomo 126
 
707 anton 127
static void ELASTIC_activation(ELASTIC_level_des *lev, PID p,
128
                               struct timespec *acttime)
129
{
130
  JOB_TASK_MODEL job;
131
  ELASTIC_task_descr *et = &lev->elist[p];
697 anton 132
 
707 anton 133
  /* Assign release time */
134
  et->release = *acttime;
135
 
136
  /* Assign absolute deadline */
137
  et->dline = *acttime;
138
  ADDUSEC2TIMESPEC(et->T, &et->dline);
139
 
140
#ifdef ELASTIC_DEBUG
141
  cprintf("At %s: activating %s; rel=%s; dl=%s\n", pnow(), proc_table[p].name,
142
          ptime1(&et->release), ptime2(&et->dline));
143
#endif  
144
 
741 giacomo 145
  mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,proc_table[p].avail_time);
146
  mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,proc_table[p].wcet);
707 anton 147
 
148
  /* Job insertion */
149
  job_task_default_model(job, et->dline);
150
  level_table[lev->scheduling_level]->
151
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
737 anton 152
  et->flags |= ELASTIC_JOB_PRESENT;
707 anton 153
}
154
 
155
 
156
static void ELASTIC_timer_act(void *arg) {
157
 
158
  PID p = (PID)(arg);
159
  ELASTIC_level_des *lev;
160
 
161
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
162
  ELASTIC_task_descr *et = &lev->elist[p];
163
 
164
  /* Use the current deadline as the new activation time */
165
  ELASTIC_activation(lev, p, &et->dline);
166
 
167
  event_need_reschedule();
168
 
169
  /* Next activation */
170
  et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act, (void *)(p));
171
}
172
 
173
 
174
/* Check feasability and compute new utilizations for the task set */
175
 
697 anton 176
static int ELASTIC_compress(ELASTIC_level_des *lev) {
177
 
676 giacomo 178
  PID i;
707 anton 179
  ELASTIC_task_descr *et;
697 anton 180
  int ok;
181
 
182
  ext_bandwidth_t Umin;  // minimum utilization
183
  ext_bandwidth_t Umax;  // nominal (maximum) utilization of compressable tasks
676 giacomo 184
 
697 anton 185
  ext_bandwidth_t Uf;    // amount of non-compressable utilization
186
  int Ev;                // sum of elasticity among compressable tasks
187
 
707 anton 188
  JOB_TASK_MODEL job;
189
 
697 anton 190
  Umin = 0;
191
  Umax = 0;
192
 
676 giacomo 193
  for (i=0; i<MAX_PROC; i++) {
707 anton 194
    et = &lev->elist[i];
195
    if (et->flags & ELASTIC_PRESENT) {
196
      if (et->E == 0) {
197
        Umin += et->U;
198
        Umax += et->U;
697 anton 199
      } else {
707 anton 200
        Umin += et->Umin;
201
        Umax += et->Umax;
202
        et->U = et->Umax;   // reset previous saturations (if any)
697 anton 203
      }
691 anton 204
    }
676 giacomo 205
  }
697 anton 206
 
700 anton 207
  if (Umin > lev->U) return -1;  // NOT FEASIBLE
676 giacomo 208
 
700 anton 209
  if (Umax <= lev->U) return 0;  // FEASIBLE WITH MAXIMUM UTILIZATIONS
210
 
697 anton 211
  do {
212
    Uf = 0;
213
    Ev = 0;
214
    Umax = 0;
673 giacomo 215
 
697 anton 216
    for (i=0; i<MAX_PROC; i++) {
707 anton 217
      et = &lev->elist[i];
218
      if (et->flags & ELASTIC_PRESENT) {
219
        if (et->E == 0 || et->U == et->Umin) {
220
          Uf += et->U;
697 anton 221
        } else {
707 anton 222
          Ev += et->E;
223
          Umax += et->Umax;
697 anton 224
        }
225
      }
226
    }
227
 
228
    ok = 1;
229
 
230
    for (i=0; i<MAX_PROC; i++) {
707 anton 231
      et = &lev->elist[i];
232
      if (et->flags & ELASTIC_PRESENT) {
233
        if (et->E > 0 && et->U > et->Umin) {
234
          et->U = et->Umax - (Umax - lev->U + Uf) * et->E / Ev;
235
          if (et->U < et->Umin) {
236
            et->U = et->Umin;
697 anton 237
            ok = 0;
238
          }
239
        }
240
      }
241
    }
673 giacomo 242
 
697 anton 243
  } while (ok == 0);
673 giacomo 244
 
707 anton 245
  // Increase periods of compressed tasks IMMEDIATELY.
246
  // The other ones will be changed at their next activation
247
 
248
  for (i=0; i<MAX_PROC; i++) {
249
    et = &lev->elist[i];
250
    if (et->flags & ELASTIC_PRESENT) {
251
      if (et->U != et->oldU) {
252
        /* Utilization has been changed. Compute new period */
741 giacomo 253
        et->T = ((long long)et->C * (long long)lev->c_scaling_factor * (long long)MAX_BANDWIDTH) / (et->U * (long long)SCALING_UNIT);
707 anton 254
      }
255
      if (et->U < et->oldU) {
256
        /* Task has been compressed. Change its deadline NOW! */
257
        if (et->flags & ELASTIC_JOB_PRESENT) {
737 anton 258
          /* Remove job from level */
707 anton 259
          level_table[lev->scheduling_level]->
260
            private_extract(lev->scheduling_level, i);
261
        }
262
        /* Compute new deadline */
263
        et->dline = et->release;
264
        ADDUSEC2TIMESPEC(et->T, &et->dline);
265
        if (et->dltimer != -1) {
266
          /* Delete old deadline timer, post new one */
267
          kern_event_delete(et->dltimer);
268
          et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act,(void *)(i));
269
        }
270
        if (et->flags & ELASTIC_JOB_PRESENT) {
271
          /* Reinsert job */
272
          job_task_default_model(job, et->dline);
273
          level_table[lev->scheduling_level]->
274
            private_insert(lev->scheduling_level, i, (TASK_MODEL *)&job);
275
        }
276
      }
277
      et->oldU = et->U;  /* Update oldU */
278
    }
279
  }
280
 
281
#ifdef ELASTIC_DEBUG
697 anton 282
  cprintf("New periods: ");
691 anton 283
  for (i=0; i<MAX_PROC; i++) {
707 anton 284
    et = &lev->elist[i];
285
    if (et->flags & ELASTIC_PRESENT) {
286
      cprintf("%s:%d ", proc_table[i].name, (int)et->T);
691 anton 287
    }
288
  }
697 anton 289
  cprintf("\n");
707 anton 290
#endif
691 anton 291
 
697 anton 292
  return 0; // FEASIBLE
691 anton 293
 
673 giacomo 294
}
295
 
697 anton 296
 
671 giacomo 297
/* The on-line guarantee is enabled only if the appropriate flag is set... */
298
static int ELASTIC_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
299
{
300
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
301
 
691 anton 302
  if (*freebandwidth >= lev->U) {
700 anton 303
    *freebandwidth -= (unsigned int)lev->U;
691 anton 304
    return 1;
305
  } else {
306
    return 0;
307
  }
737 anton 308
 
671 giacomo 309
}
310
 
691 anton 311
 
671 giacomo 312
static int ELASTIC_public_create(LEVEL l, PID p, TASK_MODEL *m)
313
{
314
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
691 anton 315
  ELASTIC_TASK_MODEL *elastic = (ELASTIC_TASK_MODEL *)m;
707 anton 316
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 317
 
318
  if (m->pclass != ELASTIC_PCLASS) return -1;
319
  if (m->level != 0 && m->level != l) return -1;
320
 
691 anton 321
  if (elastic->C == 0) return -1;
673 giacomo 322
  if (elastic->Tmin > elastic->Tmax) return -1;
323
  if (elastic->Tmax == 0) return -1;
707 anton 324
  if (elastic->Tmin == 0) return -1;
673 giacomo 325
 
707 anton 326
  NULL_TIMESPEC(&(et->dline));
327
  et->Tmin = elastic->Tmin;
328
  et->Tmax = elastic->Tmax;
329
  et->C = elastic->C;
330
  et->E = elastic->E;
331
  et->beta = elastic->beta;
673 giacomo 332
 
741 giacomo 333
  et->Umax = ((long long)MAX_BANDWIDTH * (long long)elastic->C * (long long)lev->c_scaling_factor) / ((long long)elastic->Tmin * (long long)SCALING_UNIT);
334
  et->Umin = ((long long)MAX_BANDWIDTH * (long long)elastic->C * (long long)lev->c_scaling_factor) / ((long long)elastic->Tmax * (long long)SCALING_UNIT);
673 giacomo 335
 
707 anton 336
  et->U = et->Umax;
337
  et->oldU = 0;
338
  et->T = et->Tmin;
339
  et->dltimer = -1;
673 giacomo 340
 
741 giacomo 341
  mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,proc_table[p].avail_time);
342
  mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,proc_table[p].wcet);
674 giacomo 343
  proc_table[p].control    |= CONTROL_CAP;
673 giacomo 344
 
697 anton 345
  return 0;
671 giacomo 346
}
347
 
697 anton 348
 
671 giacomo 349
static void ELASTIC_public_detach(LEVEL l, PID p)
350
{
707 anton 351
  //ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
671 giacomo 352
 
353
}
354
 
355
static int ELASTIC_public_eligible(LEVEL l, PID p)
356
{
707 anton 357
  //ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
671 giacomo 358
 
359
  return 0;
360
 
361
}
362
 
363
static void ELASTIC_public_dispatch(LEVEL l, PID p, int nostop)
364
{
365
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
674 giacomo 366
 
671 giacomo 367
  level_table[ lev->scheduling_level ]->
368
    private_dispatch(lev->scheduling_level,p,nostop);
674 giacomo 369
 
671 giacomo 370
}
371
 
372
static void ELASTIC_public_epilogue(LEVEL l, PID p)
373
{
374
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
375
 
674 giacomo 376
  /* check if the wcet is finished... */
377
  if (proc_table[p].avail_time <= 0) {
378
 
707 anton 379
    TRACER_LOGEVENT(FTrace_EVT_task_wcet_violation,
380
                    (unsigned short int)proc_table[p].context,0);
674 giacomo 381
    kern_raise(XWCET_VIOLATION,p);
382
 
383
  }
691 anton 384
 
707 anton 385
  level_table[lev->scheduling_level]->
674 giacomo 386
      private_epilogue(lev->scheduling_level,p);
387
 
671 giacomo 388
}
389
 
390
static void ELASTIC_public_activate(LEVEL l, PID p, struct timespec *t)
391
{
707 anton 392
 
671 giacomo 393
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
707 anton 394
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 395
 
674 giacomo 396
  /* check if we are not in the SLEEP state */
397
  if (proc_table[p].status != SLEEP) {
398
    return;
399
  }
400
 
707 anton 401
  et->flags |= ELASTIC_PRESENT;
402
  if (ELASTIC_compress(lev) == -1) {
403
    et->flags &= ~ELASTIC_PRESENT;
404
#ifdef ELASTIC_DEBUG
405
    cprintf("ELASTIC_public_activate: compression failed!\n");
406
#endif
407
    return;
408
  }
409
 
674 giacomo 410
  ELASTIC_activation(lev,p,t);
411
 
412
  /* Next activation */
707 anton 413
  et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act, (void *)(p));
674 giacomo 414
 
671 giacomo 415
}
416
 
417
static void ELASTIC_public_unblock(LEVEL l, PID p)
418
{
419
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
420
  struct timespec acttime;
421
 
422
  kern_gettime(&acttime);
423
 
424
  ELASTIC_activation(lev,p,&acttime);
425
 
426
}
427
 
428
static void ELASTIC_public_block(LEVEL l, PID p)
429
{
430
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
707 anton 431
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 432
 
707 anton 433
  level_table[lev->scheduling_level]->
671 giacomo 434
    private_extract(lev->scheduling_level,p);
707 anton 435
  et->flags &= ~ELASTIC_JOB_PRESENT;
671 giacomo 436
 
437
}
438
 
439
static int ELASTIC_public_message(LEVEL l, PID p, void *m)
440
{
441
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
737 anton 442
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 443
 
444
  switch((long)(m)) {
445
 
446
    case (long)(NULL):
447
 
707 anton 448
      level_table[lev->scheduling_level]->
676 giacomo 449
        private_extract(lev->scheduling_level,p);
737 anton 450
      et->flags &= ~ELASTIC_JOB_PRESENT;
676 giacomo 451
 
683 giacomo 452
      proc_table[p].status = ELASTIC_IDLE;
676 giacomo 453
 
671 giacomo 454
      jet_update_endcycle(); /* Update the Jet data... */
455
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,(unsigned short int)proc_table[p].context,(unsigned int)l);
456
 
457
      break;
458
 
459
    case 1:
460
 
676 giacomo 461
      level_table[ lev->scheduling_level ]->
462
        private_extract(lev->scheduling_level,p);
737 anton 463
      et->flags &= ~ELASTIC_JOB_PRESENT;
676 giacomo 464
 
465
      proc_table[p].status = SLEEP;
466
 
671 giacomo 467
      TRACER_LOGEVENT(FTrace_EVT_task_disable,(unsigned short int)proc_table[p].context,(unsigned int)l);
468
 
469
      break;
470
 
471
  }
472
 
473
  return 0;
474
 
475
}
476
 
477
static void ELASTIC_public_end(LEVEL l, PID p)
478
{
479
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
737 anton 480
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 481
 
482
  level_table[ lev->scheduling_level ]->
483
    private_extract(lev->scheduling_level,p);
737 anton 484
  et->flags &= ~ELASTIC_JOB_PRESENT;
671 giacomo 485
 
486
}
487
 
488
/*+ Registration function +*/
700 anton 489
LEVEL ELASTIC_register_level(int flags, LEVEL master, ext_bandwidth_t U)
671 giacomo 490
{
491
  LEVEL l;            /* the level that we register */
492
  ELASTIC_level_des *lev;  /* for readableness only */
493
  PID i;
494
 
495
  printk("ELASTIC_register_level\n");
496
 
497
  /* request an entry in the level_table */
498
  l = level_alloc_descriptor(sizeof(ELASTIC_level_des));
499
 
500
  lev = (ELASTIC_level_des *)level_table[l];
501
 
502
  /* fill the standard descriptor */
503
  if (flags & ELASTIC_ENABLE_GUARANTEE)
504
    lev->l.public_guarantee = ELASTIC_public_guarantee;
505
  else
506
    lev->l.public_guarantee = NULL;
507
  lev->l.public_create    = ELASTIC_public_create;
508
  lev->l.public_detach    = ELASTIC_public_detach;
509
  lev->l.public_end       = ELASTIC_public_end;
510
  lev->l.public_eligible  = ELASTIC_public_eligible;
511
  lev->l.public_dispatch  = ELASTIC_public_dispatch;
512
  lev->l.public_epilogue  = ELASTIC_public_epilogue;
513
  lev->l.public_activate  = ELASTIC_public_activate;
514
  lev->l.public_unblock   = ELASTIC_public_unblock;
515
  lev->l.public_block     = ELASTIC_public_block;
516
  lev->l.public_message   = ELASTIC_public_message;
517
 
741 giacomo 518
  lev->elist = kern_alloc(MAX_PROC * sizeof(ELASTIC_task_descr));
519
 
676 giacomo 520
  /* fill the ELASTIC task descriptor part */
671 giacomo 521
  for (i=0; i<MAX_PROC; i++) {
522
     NULL_TIMESPEC(&(lev->elist[i].dline));
523
     lev->elist[i].Tmin = 0;
524
     lev->elist[i].Tmax = 0;
691 anton 525
     lev->elist[i].T = 0;
697 anton 526
     lev->elist[i].U = 0;
691 anton 527
     lev->elist[i].C = 0;
528
     lev->elist[i].E = 0;
671 giacomo 529
     lev->elist[i].beta = 0;
707 anton 530
     lev->elist[i].flags = 0;
671 giacomo 531
  }
532
 
741 giacomo 533
  lev->c_scaling_factor = SCALING_UNIT;
534
 
691 anton 535
  lev->U = U;
671 giacomo 536
 
537
  lev->scheduling_level = master;
538
 
539
  lev->current_level = l;
540
 
707 anton 541
  lev->flags = 0;
671 giacomo 542
 
543
  return l;
544
}
545
 
707 anton 546
 
547
/* Force the period of task p to a given value */
548
 
549
int ELASTIC_set_period(PID p, TIME period) {
550
 
551
  SYS_FLAGS f;
552
  int saveE;          
553
  ext_bandwidth_t saveU;
554
 
555
  f = kern_fsave();
556
 
557
  ELASTIC_level_des *lev;
558
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
559
  ELASTIC_task_descr *et = &lev->elist[p];
560
 
561
  saveE = et->E;
562
  saveU = et->U;
563
 
737 anton 564
  et->E = 0;  /* set elasticity to zero to force period */
741 giacomo 565
  et->U = ((long long)MAX_BANDWIDTH * (long long)et->C * (long long)lev->c_scaling_factor)/((long long)period * (long long)SCALING_UNIT);
707 anton 566
 
567
  if (ELASTIC_compress(lev) == -1) {
568
#ifdef ELASTIC_DEBUG
569
    cprintf("ELASTIC_set_period failed: could not compress\n");
570
#endif
571
    et->E = saveE;
572
    et->U = saveU;
573
    kern_frestore(f);
574
    return -1;
575
  }
576
 
577
  et->E = saveE;     /* Restore E when compression is done */
578
  kern_frestore(f);
579
  return 0;
580
}
708 giacomo 581
 
582
int ELASTIC_get_period(PID p) {
583
 
584
  SYS_FLAGS f;
585
  ELASTIC_level_des *lev;
586
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
737 anton 587
  TIME retval;
708 giacomo 588
 
589
  f = kern_fsave();
590
 
591
  if (lev->elist[p].flags & ELASTIC_PRESENT) {  
737 anton 592
    retval = lev->elist[p].T;
708 giacomo 593
    kern_frestore(f);
737 anton 594
    return retval;
708 giacomo 595
 
596
  } else {
597
 
598
    kern_frestore(f);
599
    return -1;
600
 
601
  }
602
 
603
}
604
 
737 anton 605
int ELASTIC_set_E(PID p, int E)
606
{
708 giacomo 607
  SYS_FLAGS f;
608
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
609
  ELASTIC_task_descr *et = &lev->elist[p];
610
  int saveE;
611
 
612
  f = kern_fsave();
737 anton 613
 
708 giacomo 614
  if (et->flags & ELASTIC_PRESENT) {
615
 
616
    saveE = et->E;
737 anton 617
 
618
    et->E = E;
708 giacomo 619
    if (ELASTIC_compress(lev) == -1) {
620
#ifdef ELASTIC_DEBUG
621
      cprintf("ELASTIC_set_E failed: could not compress\n");
622
#endif
623
      et->E = saveE;
624
      kern_frestore(f);
625
      return -1;
626
    }
737 anton 627
 
708 giacomo 628
    kern_frestore(f);
629
    return 0;
737 anton 630
 
708 giacomo 631
  } else {
737 anton 632
 
708 giacomo 633
    kern_frestore(f);
634
    return -1;
635
  }
636
}
637
 
638
int ELASTIC_get_E(PID p) {
737 anton 639
 
708 giacomo 640
  SYS_FLAGS f;
641
  ELASTIC_level_des *lev;
642
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
737 anton 643
 
708 giacomo 644
  f = kern_fsave();
737 anton 645
 
708 giacomo 646
  if (lev->elist[p].flags & ELASTIC_PRESENT) {
737 anton 647
 
708 giacomo 648
    kern_frestore(f);
649
    return lev->elist[p].E;
737 anton 650
 
708 giacomo 651
  } else {
737 anton 652
 
708 giacomo 653
    kern_frestore(f);
654
    return -1;
655
  }
656
}
657
 
658
int ELASTIC_set_beta(PID p, int beta) {
737 anton 659
 
708 giacomo 660
  SYS_FLAGS f;
661
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
662
  ELASTIC_task_descr *et = &lev->elist[p];
663
  int saveBeta;
664
 
665
  f = kern_fsave();
737 anton 666
 
708 giacomo 667
  if (et->flags & ELASTIC_PRESENT) {
737 anton 668
 
708 giacomo 669
    saveBeta = et->beta;
737 anton 670
 
671
    et->beta = beta;
672
 
708 giacomo 673
    if (ELASTIC_compress(lev) == -1) {
674
#ifdef ELASTIC_DEBUG
675
      cprintf("ELASTIC_set_beta failed: could not compress\n");
676
#endif
677
      et->beta = saveBeta;
678
      kern_frestore(f);
679
      return -1;
680
    }
737 anton 681
 
708 giacomo 682
    kern_frestore(f);
683
    return 0;
737 anton 684
 
708 giacomo 685
  } else {
737 anton 686
 
708 giacomo 687
    kern_frestore(f);
688
    return -1;
737 anton 689
 
708 giacomo 690
  }
737 anton 691
 
708 giacomo 692
}
693
 
694
int ELASTIC_get_beta(PID p) {
737 anton 695
 
708 giacomo 696
  SYS_FLAGS f;
697
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
737 anton 698
  int retval;
699
 
708 giacomo 700
  f = kern_fsave();
737 anton 701
 
708 giacomo 702
  if (lev->elist[p].flags & ELASTIC_PRESENT) {
737 anton 703
    retval = lev->elist[p].beta;
708 giacomo 704
    kern_frestore(f);
737 anton 705
    return retval;
706
 
708 giacomo 707
  } else {
737 anton 708
 
708 giacomo 709
    kern_frestore(f);
710
    return -1;
737 anton 711
 
708 giacomo 712
  }
737 anton 713
 
708 giacomo 714
}
715
 
716
int ELASTIC_set_bandwidth(LEVEL level, ext_bandwidth_t U) {
737 anton 717
 
708 giacomo 718
  SYS_FLAGS f;
719
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];
720
 
721
  f = kern_fsave();
722
 
723
  lev->U = U;
724
 
725
  if (ELASTIC_compress(lev) == -1) {
726
#ifdef ELASTIC_DEBUG
727
    cprintf("ELASTIC_set_bandwidth failed: could not compress\n");
728
#endif
729
    kern_frestore(f);
730
    return -1;
731
  }
737 anton 732
 
708 giacomo 733
  kern_frestore(f);
734
  return 0;
737 anton 735
 
708 giacomo 736
}
737
 
738
ext_bandwidth_t ELASTIC_get_bandwidth(LEVEL level) {
737 anton 739
 
708 giacomo 740
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];;
741
 
742
  return lev->U;
737 anton 743
 
708 giacomo 744
}
741 giacomo 745
 
746
int ELASTIC_set_scaling_factor(LEVEL level, int scaling_factor) {
747
 
748
  SYS_FLAGS f;
749
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];
750
 
751
  f = kern_fsave();
752
 
753
  lev->c_scaling_factor = scaling_factor;
754
 
755
  if (ELASTIC_compress(lev) == -1) {
756
#ifdef ELASTIC_DEBUG
757
    cprintf("ELASTIC_set_scaling_factor failed: could not compress\n");
758
#endif
759
    kern_frestore(f);
760
    return -1;
761
  }
762
 
763
  kern_frestore(f);
764
  return 0;
765
 
766
}
767
 
768
int ELASTIC_get_scaling_factor(LEVEL level) {
769
 
770
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];;
771
 
772
  return lev->c_scaling_factor;
773
 
774
}