Subversion Repositories shark

Rev

Rev 747 | 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
 
744 anton 59
//#define ELASTIC_DEBUG
707 anton 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
 
747 giacomo 116
  ELASTIC_task_descr elist[MAX_PROC];
741 giacomo 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
748 anton 141
  /*  cprintf("At %s: activating %s; rel=%s; dl=%s\n", pnow(), proc_table[p].name,
142
      ptime1(&et->release), ptime2(&et->dline)); */
707 anton 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
745 giacomo 184
  unsigned int temp;
676 giacomo 185
 
697 anton 186
  ext_bandwidth_t Uf;    // amount of non-compressable utilization
187
  int Ev;                // sum of elasticity among compressable tasks
188
 
707 anton 189
  JOB_TASK_MODEL job;
190
 
697 anton 191
  Umin = 0;
192
  Umax = 0;
193
 
676 giacomo 194
  for (i=0; i<MAX_PROC; i++) {
707 anton 195
    et = &lev->elist[i];
196
    if (et->flags & ELASTIC_PRESENT) {
197
      if (et->E == 0) {
198
        Umin += et->U;
199
        Umax += et->U;
697 anton 200
      } else {
707 anton 201
        Umin += et->Umin;
202
        Umax += et->Umax;
203
        et->U = et->Umax;   // reset previous saturations (if any)
697 anton 204
      }
691 anton 205
    }
676 giacomo 206
  }
207
 
744 anton 208
  if (Umin > lev->U) {
209
#ifdef ELASTIC_DEBUG
210
    cprintf("ELASTIC_compress: Task set not feasible\n");
211
#endif
212
    return -1;  // NOT FEASIBLE
213
  }
700 anton 214
 
744 anton 215
  if (Umax <= lev->U) {
216
#ifdef ELASTIC_DEBUG
217
    cprintf("ELASTIC_compress: Task set feasible with maximum utilizations\n");
218
#endif
219
    return 0;  // FEASIBLE WITH MAXIMUM UTILIZATIONS
220
  }
221
 
697 anton 222
  do {
223
    Uf = 0;
224
    Ev = 0;
225
    Umax = 0;
673 giacomo 226
 
697 anton 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
          Uf += et->U;
697 anton 232
        } else {
707 anton 233
          Ev += et->E;
234
          Umax += et->Umax;
697 anton 235
        }
236
      }
237
    }
238
 
239
    ok = 1;
240
 
241
    for (i=0; i<MAX_PROC; i++) {
707 anton 242
      et = &lev->elist[i];
243
      if (et->flags & ELASTIC_PRESENT) {
244
        if (et->E > 0 && et->U > et->Umin) {
245
          et->U = et->Umax - (Umax - lev->U + Uf) * et->E / Ev;
246
          if (et->U < et->Umin) {
247
            et->U = et->Umin;
697 anton 248
            ok = 0;
249
          }
250
        }
251
      }
252
    }
673 giacomo 253
 
697 anton 254
  } while (ok == 0);
673 giacomo 255
 
707 anton 256
  // Increase periods of compressed tasks IMMEDIATELY.
257
  // The other ones will be changed at their next activation
258
 
259
  for (i=0; i<MAX_PROC; i++) {
260
    et = &lev->elist[i];
261
    if (et->flags & ELASTIC_PRESENT) {
262
      if (et->U != et->oldU) {
263
        /* Utilization has been changed. Compute new period */
745 giacomo 264
        temp = (long long)et->C * (long long)MAX_BANDWIDTH / et->U;
265
        mul32div32to32(temp,lev->c_scaling_factor,SCALING_UNIT,et->T);
707 anton 266
      }
267
      if (et->U < et->oldU) {
268
        /* Task has been compressed. Change its deadline NOW! */
269
        if (et->flags & ELASTIC_JOB_PRESENT) {
737 anton 270
          /* Remove job from level */
707 anton 271
          level_table[lev->scheduling_level]->
272
            private_extract(lev->scheduling_level, i);
273
        }
274
        /* Compute new deadline */
275
        et->dline = et->release;
276
        ADDUSEC2TIMESPEC(et->T, &et->dline);
277
        if (et->dltimer != -1) {
278
          /* Delete old deadline timer, post new one */
279
          kern_event_delete(et->dltimer);
280
          et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act,(void *)(i));
281
        }
282
        if (et->flags & ELASTIC_JOB_PRESENT) {
283
          /* Reinsert job */
284
          job_task_default_model(job, et->dline);
285
          level_table[lev->scheduling_level]->
286
            private_insert(lev->scheduling_level, i, (TASK_MODEL *)&job);
287
        }
288
      }
289
      et->oldU = et->U;  /* Update oldU */
290
    }
291
  }
292
 
293
#ifdef ELASTIC_DEBUG
744 anton 294
  cprintf("ELASTIC_compress: New periods: ");
691 anton 295
  for (i=0; i<MAX_PROC; i++) {
707 anton 296
    et = &lev->elist[i];
297
    if (et->flags & ELASTIC_PRESENT) {
298
      cprintf("%s:%d ", proc_table[i].name, (int)et->T);
691 anton 299
    }
300
  }
697 anton 301
  cprintf("\n");
707 anton 302
#endif
691 anton 303
 
697 anton 304
  return 0; // FEASIBLE
691 anton 305
 
673 giacomo 306
}
307
 
697 anton 308
 
671 giacomo 309
/* The on-line guarantee is enabled only if the appropriate flag is set... */
310
static int ELASTIC_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
311
{
312
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
313
 
691 anton 314
  if (*freebandwidth >= lev->U) {
700 anton 315
    *freebandwidth -= (unsigned int)lev->U;
691 anton 316
    return 1;
317
  } else {
318
    return 0;
319
  }
737 anton 320
 
671 giacomo 321
}
322
 
691 anton 323
 
671 giacomo 324
static int ELASTIC_public_create(LEVEL l, PID p, TASK_MODEL *m)
325
{
326
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
691 anton 327
  ELASTIC_TASK_MODEL *elastic = (ELASTIC_TASK_MODEL *)m;
707 anton 328
  ELASTIC_task_descr *et = &lev->elist[p];
745 giacomo 329
  unsigned int temp;
671 giacomo 330
 
331
  if (m->pclass != ELASTIC_PCLASS) return -1;
332
  if (m->level != 0 && m->level != l) return -1;
333
 
691 anton 334
  if (elastic->C == 0) return -1;
673 giacomo 335
  if (elastic->Tmin > elastic->Tmax) return -1;
336
  if (elastic->Tmax == 0) return -1;
707 anton 337
  if (elastic->Tmin == 0) return -1;
673 giacomo 338
 
707 anton 339
  NULL_TIMESPEC(&(et->dline));
340
  et->Tmin = elastic->Tmin;
341
  et->Tmax = elastic->Tmax;
342
  et->C = elastic->C;
343
  et->E = elastic->E;
344
  et->beta = elastic->beta;
673 giacomo 345
 
745 giacomo 346
  mul32div32to32(elastic->C,lev->c_scaling_factor,SCALING_UNIT,temp);
347
  et->Umax = ((long long)MAX_BANDWIDTH * (long long)temp) / (long long)elastic->Tmin;
348
  et->Umin = ((long long)MAX_BANDWIDTH * (long long)temp) / (long long)elastic->Tmax;
673 giacomo 349
 
707 anton 350
  et->U = et->Umax;
351
  et->oldU = 0;
352
  et->T = et->Tmin;
353
  et->dltimer = -1;
673 giacomo 354
 
744 anton 355
  et->flags |= ELASTIC_PRESENT;
356
  if (ELASTIC_compress(lev) == -1) {
357
    et->flags &= ~ELASTIC_PRESENT;
358
#ifdef ELASTIC_DEBUG
359
    cprintf("ELASTIC_public_create: compression failed!\n");
360
#endif
361
    return -1;
362
  }
363
 
741 giacomo 364
  mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,proc_table[p].avail_time);
365
  mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,proc_table[p].wcet);
744 anton 366
 
674 giacomo 367
  proc_table[p].control    |= CONTROL_CAP;
673 giacomo 368
 
697 anton 369
  return 0;
671 giacomo 370
}
371
 
697 anton 372
 
671 giacomo 373
static void ELASTIC_public_detach(LEVEL l, PID p)
374
{
707 anton 375
  //ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
671 giacomo 376
 
377
}
378
 
379
static int ELASTIC_public_eligible(LEVEL l, PID p)
380
{
707 anton 381
  //ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
671 giacomo 382
 
383
  return 0;
384
 
385
}
386
 
387
static void ELASTIC_public_dispatch(LEVEL l, PID p, int nostop)
388
{
389
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
674 giacomo 390
 
671 giacomo 391
  level_table[ lev->scheduling_level ]->
392
    private_dispatch(lev->scheduling_level,p,nostop);
674 giacomo 393
 
671 giacomo 394
}
395
 
396
static void ELASTIC_public_epilogue(LEVEL l, PID p)
397
{
398
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
399
 
674 giacomo 400
  /* check if the wcet is finished... */
401
  if (proc_table[p].avail_time <= 0) {
402
 
707 anton 403
    TRACER_LOGEVENT(FTrace_EVT_task_wcet_violation,
404
                    (unsigned short int)proc_table[p].context,0);
674 giacomo 405
    kern_raise(XWCET_VIOLATION,p);
406
 
407
  }
691 anton 408
 
707 anton 409
  level_table[lev->scheduling_level]->
674 giacomo 410
      private_epilogue(lev->scheduling_level,p);
411
 
671 giacomo 412
}
413
 
414
static void ELASTIC_public_activate(LEVEL l, PID p, struct timespec *t)
415
{
416
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
707 anton 417
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 418
 
674 giacomo 419
  /* check if we are not in the SLEEP state */
420
  if (proc_table[p].status != SLEEP) {
421
    return;
422
  }
423
 
424
  ELASTIC_activation(lev,p,t);
425
 
426
  /* Next activation */
707 anton 427
  et->dltimer = kern_event_post(&et->dline, ELASTIC_timer_act, (void *)(p));
674 giacomo 428
 
671 giacomo 429
}
430
 
431
static void ELASTIC_public_unblock(LEVEL l, PID p)
432
{
433
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
434
  struct timespec acttime;
435
 
436
  kern_gettime(&acttime);
437
 
438
  ELASTIC_activation(lev,p,&acttime);
439
 
440
}
441
 
442
static void ELASTIC_public_block(LEVEL l, PID p)
443
{
444
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
707 anton 445
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 446
 
707 anton 447
  level_table[lev->scheduling_level]->
671 giacomo 448
    private_extract(lev->scheduling_level,p);
707 anton 449
  et->flags &= ~ELASTIC_JOB_PRESENT;
671 giacomo 450
 
451
}
452
 
453
static int ELASTIC_public_message(LEVEL l, PID p, void *m)
454
{
455
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
737 anton 456
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 457
 
458
  switch((long)(m)) {
459
 
460
    case (long)(NULL):
461
 
707 anton 462
      level_table[lev->scheduling_level]->
676 giacomo 463
        private_extract(lev->scheduling_level,p);
737 anton 464
      et->flags &= ~ELASTIC_JOB_PRESENT;
676 giacomo 465
 
683 giacomo 466
      proc_table[p].status = ELASTIC_IDLE;
676 giacomo 467
 
671 giacomo 468
      jet_update_endcycle(); /* Update the Jet data... */
469
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,(unsigned short int)proc_table[p].context,(unsigned int)l);
470
 
471
      break;
472
 
473
    case 1:
474
 
747 giacomo 475
      if (et->dltimer != -1)
476
        kern_event_delete(et->dltimer);
676 giacomo 477
 
747 giacomo 478
      if (et->flags & ELASTIC_JOB_PRESENT) {
479
        level_table[ lev->scheduling_level ]->
480
          private_extract(lev->scheduling_level,p);
481
        et->flags &= ~ELASTIC_JOB_PRESENT;
482
      }
483
 
676 giacomo 484
      proc_table[p].status = SLEEP;
485
 
671 giacomo 486
      TRACER_LOGEVENT(FTrace_EVT_task_disable,(unsigned short int)proc_table[p].context,(unsigned int)l);
487
 
488
      break;
489
 
490
  }
491
 
492
  return 0;
493
 
494
}
495
 
496
static void ELASTIC_public_end(LEVEL l, PID p)
497
{
498
  ELASTIC_level_des *lev = (ELASTIC_level_des *)(level_table[l]);
737 anton 499
  ELASTIC_task_descr *et = &lev->elist[p];
671 giacomo 500
 
748 anton 501
  if (et->dltimer != -1) {
747 giacomo 502
        kern_event_delete(et->dltimer);
748 anton 503
  }
747 giacomo 504
 
746 anton 505
  if (et->flags & ELASTIC_JOB_PRESENT) {
506
    level_table[ lev->scheduling_level ]->
507
      private_extract(lev->scheduling_level,p);
508
    et->flags &= ~ELASTIC_JOB_PRESENT;
509
  }
671 giacomo 510
 
511
}
512
 
513
/*+ Registration function +*/
700 anton 514
LEVEL ELASTIC_register_level(int flags, LEVEL master, ext_bandwidth_t U)
671 giacomo 515
{
516
  LEVEL l;            /* the level that we register */
517
  ELASTIC_level_des *lev;  /* for readableness only */
518
  PID i;
519
 
520
  printk("ELASTIC_register_level\n");
521
 
522
  /* request an entry in the level_table */
523
  l = level_alloc_descriptor(sizeof(ELASTIC_level_des));
524
 
525
  lev = (ELASTIC_level_des *)level_table[l];
526
 
527
  /* fill the standard descriptor */
528
  if (flags & ELASTIC_ENABLE_GUARANTEE)
529
    lev->l.public_guarantee = ELASTIC_public_guarantee;
530
  else
531
    lev->l.public_guarantee = NULL;
532
  lev->l.public_create    = ELASTIC_public_create;
533
  lev->l.public_detach    = ELASTIC_public_detach;
534
  lev->l.public_end       = ELASTIC_public_end;
535
  lev->l.public_eligible  = ELASTIC_public_eligible;
536
  lev->l.public_dispatch  = ELASTIC_public_dispatch;
537
  lev->l.public_epilogue  = ELASTIC_public_epilogue;
538
  lev->l.public_activate  = ELASTIC_public_activate;
539
  lev->l.public_unblock   = ELASTIC_public_unblock;
540
  lev->l.public_block     = ELASTIC_public_block;
541
  lev->l.public_message   = ELASTIC_public_message;
542
 
676 giacomo 543
  /* fill the ELASTIC task descriptor part */
671 giacomo 544
  for (i=0; i<MAX_PROC; i++) {
545
     NULL_TIMESPEC(&(lev->elist[i].dline));
546
     lev->elist[i].Tmin = 0;
547
     lev->elist[i].Tmax = 0;
691 anton 548
     lev->elist[i].T = 0;
697 anton 549
     lev->elist[i].U = 0;
691 anton 550
     lev->elist[i].C = 0;
551
     lev->elist[i].E = 0;
671 giacomo 552
     lev->elist[i].beta = 0;
707 anton 553
     lev->elist[i].flags = 0;
671 giacomo 554
  }
555
 
741 giacomo 556
  lev->c_scaling_factor = SCALING_UNIT;
557
 
691 anton 558
  lev->U = U;
671 giacomo 559
 
560
  lev->scheduling_level = master;
561
 
562
  lev->current_level = l;
563
 
707 anton 564
  lev->flags = 0;
671 giacomo 565
 
566
  return l;
567
}
568
 
707 anton 569
 
570
 
748 anton 571
/* Force the period of task p to a given value (between Tmin and Tmax) */
572
 
707 anton 573
int ELASTIC_set_period(PID p, TIME period) {
574
 
575
  SYS_FLAGS f;
745 giacomo 576
  int saveE;          
577
  unsigned int temp;
707 anton 578
  ext_bandwidth_t saveU;
748 anton 579
  TIME saveT;
707 anton 580
 
581
  f = kern_fsave();
582
 
583
  ELASTIC_level_des *lev;
584
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
585
  ELASTIC_task_descr *et = &lev->elist[p];
586
 
748 anton 587
  if (period < et->Tmin || period > et->Tmax) {
588
    kern_frestore(f);
589
    return -1;
590
  }
591
 
707 anton 592
  saveE = et->E;
593
  saveU = et->U;
748 anton 594
  saveT = et->T;
707 anton 595
 
737 anton 596
  et->E = 0;  /* set elasticity to zero to force period */
745 giacomo 597
  mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,temp);
598
  et->U = ((long long)MAX_BANDWIDTH * (long long)(temp))/((long long)period);
748 anton 599
  et->T = period;
707 anton 600
 
601
  if (ELASTIC_compress(lev) == -1) {
602
#ifdef ELASTIC_DEBUG
748 anton 603
    cprintf("ELASTIC_set_period failed!\n");
707 anton 604
#endif
605
    et->E = saveE;
606
    et->U = saveU;
748 anton 607
    et->T = saveT;
707 anton 608
    kern_frestore(f);
609
    return -1;
610
  }
611
 
612
  et->E = saveE;     /* Restore E when compression is done */
613
  kern_frestore(f);
614
  return 0;
615
}
708 giacomo 616
 
617
int ELASTIC_get_period(PID p) {
618
 
619
  SYS_FLAGS f;
620
  ELASTIC_level_des *lev;
621
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
737 anton 622
  TIME retval;
708 giacomo 623
 
624
  f = kern_fsave();
625
 
626
  if (lev->elist[p].flags & ELASTIC_PRESENT) {  
737 anton 627
    retval = lev->elist[p].T;
708 giacomo 628
    kern_frestore(f);
737 anton 629
    return retval;
708 giacomo 630
 
631
  } else {
632
 
633
    kern_frestore(f);
634
    return -1;
635
 
636
  }
637
 
638
}
639
 
744 anton 640
 
746 anton 641
int ELASTIC_set_Tmin(PID p, TIME Tmin)
642
{
643
  SYS_FLAGS f;
644
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
645
  ELASTIC_task_descr *et = &lev->elist[p];
646
  TIME saveTmin;
748 anton 647
  TIME saveT;
648
  ext_bandwidth_t saveU;
649
  unsigned int temp;
746 anton 650
 
651
  f = kern_fsave();
652
 
653
  if (et->flags & ELASTIC_PRESENT) {
654
 
655
    saveTmin = et->Tmin;
748 anton 656
    saveT = et->T;
657
    saveU = et->U;
746 anton 658
 
659
    et->Tmin = Tmin;
748 anton 660
    if (Tmin > et->T) {
661
      et->T = Tmin;
662
      mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,temp);
663
      et->U = ((long long)MAX_BANDWIDTH * (long long)(temp))/((long long)Tmin);
664
    }
665
 
746 anton 666
    if (ELASTIC_compress(lev) == -1) {
667
#ifdef ELASTIC_DEBUG
668
      cprintf("ELASTIC_set_Tmin failed: could not compress\n");
669
#endif
670
      et->Tmin = saveTmin;
748 anton 671
      et->T = saveT;
672
      et->U = saveU;
746 anton 673
      kern_frestore(f);
674
      return -1;
675
    }
676
 
677
    kern_frestore(f);
678
    return 0;
679
 
680
  } else {
681
 
682
    kern_frestore(f);
683
    return -1;
684
  }
685
}
686
 
687
 
744 anton 688
int ELASTIC_get_Tmin(PID p) {
689
 
690
  SYS_FLAGS f;
691
  ELASTIC_level_des *lev;
692
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
693
  TIME retval;
694
 
695
  f = kern_fsave();
696
 
697
  if (lev->elist[p].flags & ELASTIC_PRESENT) {  
698
    retval = lev->elist[p].Tmin;
699
    kern_frestore(f);
700
    return retval;
701
 
702
  } else {
703
 
704
    kern_frestore(f);
705
    return -1;
706
 
707
  }
708
 
709
}
710
 
711
 
748 anton 712
int ELASTIC_set_Tmax(PID p, TIME Tmax)
713
{
714
  SYS_FLAGS f;
715
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
716
  ELASTIC_task_descr *et = &lev->elist[p];
717
  TIME saveTmax;
718
  TIME saveT;
719
  ext_bandwidth_t saveU;
720
  unsigned int temp;
721
 
722
  f = kern_fsave();
723
 
724
  if (et->flags & ELASTIC_PRESENT) {
725
 
726
    saveTmax = et->Tmax;
727
    saveT = et->T;
728
    saveU = et->U;
729
 
730
    et->Tmax = Tmax;
731
    if (Tmax < et->T) {
732
      et->T = Tmax;
733
      mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,temp);
734
      et->U = ((long long)MAX_BANDWIDTH * (long long)(temp))/((long long)Tmax);
735
    }
736
 
737
    if (ELASTIC_compress(lev) == -1) {
738
#ifdef ELASTIC_DEBUG
739
      cprintf("ELASTIC_set_Tmax failed: could not compress\n");
740
#endif
741
      et->Tmax = saveTmax;
742
      et->T = saveT;
743
      et->U = saveU;
744
      kern_frestore(f);
745
      return -1;
746
    }
747
 
748
    kern_frestore(f);
749
    return 0;
750
 
751
  } else {
752
 
753
    kern_frestore(f);
754
    return -1;
755
  }
756
}
757
 
758
 
744 anton 759
int ELASTIC_get_Tmax(PID p) {
760
 
761
  SYS_FLAGS f;
762
  ELASTIC_level_des *lev;
763
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
764
  TIME retval;
765
 
766
  f = kern_fsave();
767
 
768
  if (lev->elist[p].flags & ELASTIC_PRESENT) {  
769
    retval = lev->elist[p].Tmax;
770
    kern_frestore(f);
771
    return retval;
772
 
773
  } else {
774
 
775
    kern_frestore(f);
776
    return -1;
777
 
778
  }
779
 
780
}
781
 
748 anton 782
int ELASTIC_set_C(PID p, TIME C)
783
{
784
  SYS_FLAGS f;
785
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
786
  ELASTIC_task_descr *et = &lev->elist[p];
787
  TIME saveC;
788
  ext_bandwidth_t saveU;
789
  unsigned int temp;
744 anton 790
 
748 anton 791
  f = kern_fsave();
792
 
793
  if (et->flags & ELASTIC_PRESENT) {
794
 
795
    saveC = et->C;
796
    saveU = et->U;
797
 
798
    et->C = C;
799
 
800
    mul32div32to32(et->C,lev->c_scaling_factor,SCALING_UNIT,temp);
801
    et->U = ((long long)MAX_BANDWIDTH * (long long)(temp))/((long long)et->T);
802
 
803
    if (ELASTIC_compress(lev) == -1) {
804
#ifdef ELASTIC_DEBUG
805
      cprintf("ELASTIC_set_C failed: could not compress\n");
806
#endif
807
      et->C = saveC;
808
      et->U = saveU;
809
      kern_frestore(f);
810
      return -1;
811
    }
812
 
813
    kern_frestore(f);
814
    return 0;
815
 
816
  } else {
817
 
818
    kern_frestore(f);
819
    return -1;
820
  }
821
}
822
 
823
 
744 anton 824
int ELASTIC_get_C(PID p) {
825
 
826
  SYS_FLAGS f;
827
  ELASTIC_level_des *lev;
828
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
829
  TIME retval;
830
 
831
  f = kern_fsave();
832
 
833
  if (lev->elist[p].flags & ELASTIC_PRESENT) {  
834
    retval = lev->elist[p].C;
835
    kern_frestore(f);
836
    return retval;
837
 
838
  } else {
839
 
840
    kern_frestore(f);
841
    return -1;
842
 
843
  }
844
 
845
}
846
 
847
 
737 anton 848
int ELASTIC_set_E(PID p, int E)
849
{
708 giacomo 850
  SYS_FLAGS f;
851
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
852
  ELASTIC_task_descr *et = &lev->elist[p];
853
  int saveE;
854
 
855
  f = kern_fsave();
737 anton 856
 
708 giacomo 857
  if (et->flags & ELASTIC_PRESENT) {
858
 
859
    saveE = et->E;
737 anton 860
 
861
    et->E = E;
708 giacomo 862
    if (ELASTIC_compress(lev) == -1) {
863
#ifdef ELASTIC_DEBUG
864
      cprintf("ELASTIC_set_E failed: could not compress\n");
865
#endif
866
      et->E = saveE;
867
      kern_frestore(f);
868
      return -1;
869
    }
737 anton 870
 
708 giacomo 871
    kern_frestore(f);
872
    return 0;
737 anton 873
 
708 giacomo 874
  } else {
737 anton 875
 
708 giacomo 876
    kern_frestore(f);
877
    return -1;
878
  }
879
}
880
 
881
int ELASTIC_get_E(PID p) {
737 anton 882
 
708 giacomo 883
  SYS_FLAGS f;
884
  ELASTIC_level_des *lev;
885
  lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
737 anton 886
 
708 giacomo 887
  f = kern_fsave();
737 anton 888
 
708 giacomo 889
  if (lev->elist[p].flags & ELASTIC_PRESENT) {
737 anton 890
 
708 giacomo 891
    kern_frestore(f);
892
    return lev->elist[p].E;
737 anton 893
 
708 giacomo 894
  } else {
737 anton 895
 
708 giacomo 896
    kern_frestore(f);
897
    return -1;
898
  }
899
}
900
 
901
int ELASTIC_set_beta(PID p, int beta) {
737 anton 902
 
708 giacomo 903
  SYS_FLAGS f;
904
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
905
  ELASTIC_task_descr *et = &lev->elist[p];
906
  int saveBeta;
907
 
908
  f = kern_fsave();
737 anton 909
 
708 giacomo 910
  if (et->flags & ELASTIC_PRESENT) {
737 anton 911
 
708 giacomo 912
    saveBeta = et->beta;
737 anton 913
 
914
    et->beta = beta;
915
 
708 giacomo 916
    if (ELASTIC_compress(lev) == -1) {
917
#ifdef ELASTIC_DEBUG
918
      cprintf("ELASTIC_set_beta failed: could not compress\n");
919
#endif
920
      et->beta = saveBeta;
921
      kern_frestore(f);
922
      return -1;
923
    }
737 anton 924
 
708 giacomo 925
    kern_frestore(f);
926
    return 0;
737 anton 927
 
708 giacomo 928
  } else {
737 anton 929
 
708 giacomo 930
    kern_frestore(f);
931
    return -1;
737 anton 932
 
708 giacomo 933
  }
737 anton 934
 
708 giacomo 935
}
936
 
937
int ELASTIC_get_beta(PID p) {
737 anton 938
 
708 giacomo 939
  SYS_FLAGS f;
940
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[proc_table[p].task_level];
737 anton 941
  int retval;
942
 
708 giacomo 943
  f = kern_fsave();
737 anton 944
 
708 giacomo 945
  if (lev->elist[p].flags & ELASTIC_PRESENT) {
737 anton 946
    retval = lev->elist[p].beta;
708 giacomo 947
    kern_frestore(f);
737 anton 948
    return retval;
949
 
708 giacomo 950
  } else {
737 anton 951
 
708 giacomo 952
    kern_frestore(f);
953
    return -1;
737 anton 954
 
708 giacomo 955
  }
737 anton 956
 
708 giacomo 957
}
958
 
959
int ELASTIC_set_bandwidth(LEVEL level, ext_bandwidth_t U) {
737 anton 960
 
708 giacomo 961
  SYS_FLAGS f;
962
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];
963
 
964
  f = kern_fsave();
965
 
966
  lev->U = U;
967
 
968
  if (ELASTIC_compress(lev) == -1) {
969
#ifdef ELASTIC_DEBUG
970
    cprintf("ELASTIC_set_bandwidth failed: could not compress\n");
971
#endif
972
    kern_frestore(f);
973
    return -1;
974
  }
737 anton 975
 
708 giacomo 976
  kern_frestore(f);
977
  return 0;
737 anton 978
 
708 giacomo 979
}
980
 
981
ext_bandwidth_t ELASTIC_get_bandwidth(LEVEL level) {
737 anton 982
 
708 giacomo 983
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];;
984
 
985
  return lev->U;
737 anton 986
 
708 giacomo 987
}
741 giacomo 988
 
989
int ELASTIC_set_scaling_factor(LEVEL level, int scaling_factor) {
990
 
991
  SYS_FLAGS f;
992
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];
993
 
994
  f = kern_fsave();
995
 
996
  lev->c_scaling_factor = scaling_factor;
997
 
998
  if (ELASTIC_compress(lev) == -1) {
999
#ifdef ELASTIC_DEBUG
1000
    cprintf("ELASTIC_set_scaling_factor failed: could not compress\n");
1001
#endif
1002
    kern_frestore(f);
1003
    return -1;
1004
  }
1005
 
1006
  kern_frestore(f);
1007
  return 0;
1008
 
1009
}
1010
 
1011
int ELASTIC_get_scaling_factor(LEVEL level) {
1012
 
1013
  ELASTIC_level_des *lev = (ELASTIC_level_des *)level_table[level];;
1014
 
1015
  return lev->c_scaling_factor;
1016
 
1017
}