Subversion Repositories shark

Rev

Rev 1205 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1199 giacomo 1
#include <kernel/kern.h>
2
#include "parser.h"
1200 giacomo 3
#include "dosread.h"
1199 giacomo 4
 
1203 giacomo 5
/* Memory pointers on loaded file */
1200 giacomo 6
extern void *start;
7
extern void *end;
8
 
1203 giacomo 9
/* Calibration Loops */
10
#define CALIBRATION_DELTA 1000000
11
 
1206 giacomo 12
/* Mutex number */
13
#define MAX_MUTEX 10
14
 
1203 giacomo 15
/* Activate task output */
16
#define TASK_OUTPUT
17
 
1202 giacomo 18
struct timespec zero_time;
1203 giacomo 19
int cal_cycles = 0;
20
int cal_rit_start = 0;
21
int cal_rit_calc_const = 0;
22
int cal_rit_calc_mean = 0;
23
int cal_rit_calc_gauss = 0;
1202 giacomo 24
 
1206 giacomo 25
mutex_t mux_table[MAX_MUTEX];
26
 
1203 giacomo 27
/* Not Real-Time Task */
1201 giacomo 28
TASK nrt_test_task(void *arg)
29
{
1203 giacomo 30
  long long i,exec_cycles = 0;
31
  int exec_1,exec_2,exec_3;
32
  int act_1,act_2,act_3,next_act;
1206 giacomo 33
  int crit_1 = 0,crit_2 = 0,crit_3 = 0,crit_4 = 0;
34
  int crit_start,crit_len;
35
  long long crit_start_cycles = 0, crit_len_cycles = 0;
1203 giacomo 36
  struct timespec next_time;
37
  static int act= 0;
38
  struct loader_task *l = (struct loader_task *)(arg);
39
 
40
  act++;
41
 
42
  act_1 = TIMESPEC2USEC(&l->act_par_2);
43
  act_2 = TIMESPEC2USEC(&l->act_par_3);
44
  act_3 = TIMESPEC2USEC(&l->act_par_4);
1202 giacomo 45
 
1203 giacomo 46
  if (l->act_type == PAR_ACT_PERIODIC) {
47
    kern_gettime(&next_time);
48
    ADDUSEC2TIMESPEC(act_1,&next_time);
49
    kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow);
50
  }
1201 giacomo 51
 
1203 giacomo 52
  if (l->act_type == PAR_ACT_MEAN) {
53
    next_act = act_1 + rand() % act_2 - act_2/2;
54
    kern_gettime(&next_time);
55
    ADDUSEC2TIMESPEC(next_act,&next_time);
56
    kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow);
57
  }
1202 giacomo 58
 
1203 giacomo 59
  if (l->act_type == PAR_ACT_GAUSS) {
1201 giacomo 60
  }
1203 giacomo 61
 
62
  if (l->act_type == PAR_ACT_GAUSS_MAX) {
63
  }
64
 
65
  exec_1 = TIMESPEC2USEC(&l->exec_par_1);
66
  exec_2 = TIMESPEC2USEC(&l->exec_par_2);
67
  exec_3 = TIMESPEC2USEC(&l->exec_par_3);
1205 giacomo 68
 
1206 giacomo 69
  if (l->crit_type == PAR_CRIT) {
70
    crit_1 = TIMESPEC2USEC(&l->crit_par_1);
71
    crit_2 = TIMESPEC2USEC(&l->crit_par_2);
72
    crit_3 = TIMESPEC2USEC(&l->crit_par_3);
73
    crit_4 = TIMESPEC2USEC(&l->crit_par_4);
74
  }
75
 
1205 giacomo 76
  #ifdef TASK_OUTPUT
1206 giacomo 77
    printf_xy(exec_shadow % 20 + 60, exec_shadow / 20, GREEN, "R");
1205 giacomo 78
  #endif
79
 
1203 giacomo 80
  if (l->exec_type == PAR_EXEC_CONST)
81
    exec_cycles = (long long)(exec_1 - cal_rit_start - cal_rit_calc_const)
82
                   * CALIBRATION_DELTA / cal_cycles;
83
 
84
  if (l->exec_type == PAR_EXEC_MEAN)
85
    exec_cycles = (long long)(exec_1 - cal_rit_start - cal_rit_calc_mean
86
                   + rand() % exec_2 - exec_2/2) * CALIBRATION_DELTA / cal_cycles;
87
 
88
  if (l->exec_type == PAR_EXEC_GAUSS)
89
    exec_cycles = 0;
90
 
91
  if (l->exec_type == PAR_EXEC_GAUSS_MAX)
92
    exec_cycles = 0;
93
 
1206 giacomo 94
  if (l->crit_type == PAR_CRIT) {
95
    crit_start = crit_1 + rand() % crit_2 - crit_2/2;
96
    crit_len = crit_3 + rand() % crit_4 - crit_4/2;
97
    crit_start_cycles = (long long)(crit_start) * CALIBRATION_DELTA / cal_cycles;
98
    crit_len_cycles = (long long)(crit_len) * CALIBRATION_DELTA / cal_cycles;
99
    exec_cycles -= crit_start_cycles + crit_len_cycles;
100
    if (exec_cycles < 0) {
101
      cprintf("Error: exec_cycles < 0\n");
102
      sys_end();
103
    }
104
  }
1205 giacomo 105
 
1206 giacomo 106
  if (l->crit_type == PAR_NO_CRIT)
107
    for (i=0;i<exec_cycles;i++);
108
  else {
109
    for (i=0;i<crit_start_cycles;i++);
110
    #ifdef TASK_OUTPUT
111
      printf_xy(exec_shadow % 20 + 59, exec_shadow / 20, RED,"B");
112
    #endif
113
    mutex_lock(&mux_table[l->resource]);
114
    for (i=0;i<crit_len_cycles;i++);
115
    mutex_unlock(&mux_table[l->resource]);
116
    #ifdef TASK_OUTPUT
117
      printf_xy(exec_shadow % 20 + 59, exec_shadow / 20, GREEN,"R");
118
    #endif
119
    for (i=0;i<exec_cycles;i++);
120
  }
121
 
1205 giacomo 122
  #ifdef TASK_OUTPUT
123
    printf_xy(exec_shadow % 20 + 60, exec_shadow / 20, WHITE, "E");
124
  #endif
1203 giacomo 125
 
1201 giacomo 126
  return NULL;
1203 giacomo 127
 
1201 giacomo 128
}
129
 
1203 giacomo 130
/* Soft and hard Task */
1201 giacomo 131
TASK test_task(void *arg)
132
{
1203 giacomo 133
  long long i,exec_cycles = 0;
134
  int exec_1,exec_2,exec_3;
135
  int act_1,act_2,act_3,next_act;
1206 giacomo 136
  int crit_1 = 0,crit_2 = 0,crit_3 = 0,crit_4 = 0;
137
  int crit_start,crit_len;
138
  long long crit_start_cycles = 0, crit_len_cycles = 0;
1203 giacomo 139
  struct timespec next_time;
140
  static int act=0;
1205 giacomo 141
  int extra_rit, k;
1203 giacomo 142
  struct loader_task *l = (struct loader_task *)(arg);
143
 
144
  act++;
145
 
146
  act_1 = TIMESPEC2USEC(&l->act_par_2);
147
  act_2 = TIMESPEC2USEC(&l->act_par_3);
148
  act_3 = TIMESPEC2USEC(&l->act_par_4);
149
 
150
  exec_1 = TIMESPEC2USEC(&l->exec_par_1);
151
  exec_2 = TIMESPEC2USEC(&l->exec_par_2);
152
  exec_3 = TIMESPEC2USEC(&l->exec_par_3);
1202 giacomo 153
 
1203 giacomo 154
  extra_rit = cal_rit_start;
1205 giacomo 155
 
1206 giacomo 156
  if (l->crit_type == PAR_CRIT) {
157
    crit_1 = TIMESPEC2USEC(&l->crit_par_1);
158
    crit_2 = TIMESPEC2USEC(&l->crit_par_2);
159
    crit_3 = TIMESPEC2USEC(&l->crit_par_3);
160
    crit_4 = TIMESPEC2USEC(&l->crit_par_4);
161
  }
162
 
1205 giacomo 163
  k = 0;                      
164
 
1201 giacomo 165
  while(1) {
166
 
1203 giacomo 167
    task_testcancel();
1202 giacomo 168
 
1205 giacomo 169
    #ifdef TASK_OUTPUT
170
       k++;
171
       if (k > 15) k = 1;
172
       printf_xy(exec_shadow % 20 + 59, exec_shadow / 20, k,"X");
173
    #endif
174
 
1203 giacomo 175
    if (l->act_type == PAR_ACT_MEAN) {
176
      next_act = act_1 + rand() % act_2 - act_2/2;
177
      kern_gettime(&next_time);
178
      ADDUSEC2TIMESPEC(next_act,&next_time);
179
      kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow);
180
    }
181
 
182
    if (l->act_type == PAR_ACT_GAUSS) {
183
    }
184
 
185
    if (l->act_type == PAR_ACT_GAUSS_MAX) {
186
    }
187
 
188
    if (l->exec_type == PAR_EXEC_CONST)
189
      exec_cycles = (long long)(exec_1 - extra_rit - cal_rit_calc_const)
190
                   * CALIBRATION_DELTA / cal_cycles;
191
 
192
    if (l->exec_type == PAR_EXEC_MEAN)
193
      exec_cycles = (long long)(exec_1 - extra_rit - cal_rit_calc_mean
194
                     + rand() % exec_2 - exec_2/2) * CALIBRATION_DELTA / cal_cycles;
195
 
196
    if (l->exec_type == PAR_EXEC_GAUSS)
197
      exec_cycles = 0;
198
 
199
    if (l->exec_type == PAR_EXEC_GAUSS_MAX)
200
      exec_cycles = 0;
1206 giacomo 201
 
202
    if (l->crit_type == PAR_CRIT) {
203
      crit_start = crit_1 + rand() % crit_2 - crit_2/2;
204
      crit_len = crit_3 + rand() % crit_4 - crit_4/2;
205
      crit_start_cycles = (long long)(crit_start) * CALIBRATION_DELTA / cal_cycles;
206
      crit_len_cycles = (long long)(crit_len) * CALIBRATION_DELTA / cal_cycles;
207
      exec_cycles -= crit_start_cycles + crit_len_cycles;
208
      if (exec_cycles < 0) {
209
        cprintf("Error: exec_cycles < 0\n");
210
        sys_end();
211
      }
212
    }  
213
 
1203 giacomo 214
    extra_rit = 0;
215
 
1206 giacomo 216
    if (l->crit_type == PAR_NO_CRIT)
217
      for (i=0;i<exec_cycles;i++);
218
    else {
219
      for (i=0;i<crit_start_cycles;i++);
220
      #ifdef TASK_OUTPUT
221
        printf_xy(exec_shadow % 20 + 59, exec_shadow / 20, k,"B");
222
      #endif
223
      mutex_lock(&mux_table[l->resource]);
224
      for (i=0;i<crit_len_cycles;i++);
225
      mutex_unlock(&mux_table[l->resource]);
226
      #ifdef TASK_OUTPUT
227
        printf_xy(exec_shadow % 20 + 59, exec_shadow / 20, k,"X");
228
      #endif
229
      for (i=0;i<exec_cycles;i++);
230
    }
1203 giacomo 231
 
1201 giacomo 232
    task_endcycle();
1203 giacomo 233
 
1201 giacomo 234
  }
1203 giacomo 235
 
1201 giacomo 236
  return NULL;
1203 giacomo 237
 
238
}
1201 giacomo 239
 
1203 giacomo 240
/* Delay Calibration */
241
int calibrate_cycle()
242
{
243
  long long i;
244
  struct timespec start,end,diff;
245
  int temp = 1234567;
246
  int temp_1 = 1234567;
247
  int temp_2 = 1234567;
248
 
249
  kern_cli();
250
  kern_gettime(&start);
251
  for (i=0;i<CALIBRATION_DELTA;i++);
252
  kern_gettime(&end);
253
  kern_sti();
254
 
255
  SUBTIMESPEC(&end,&start,&diff);
256
  cal_cycles = TIMESPEC2USEC(&diff);
257
 
258
  cprintf("Calibration usec/[%d cycles] = %d\n",CALIBRATION_DELTA,cal_cycles);
259
 
260
  kern_cli();
261
  kern_gettime(&start);
262
  temp = (long long)(temp_1) * CALIBRATION_DELTA / cal_cycles;
263
  kern_gettime(&end);
264
  kern_sti();
265
 
266
  SUBTIMESPEC(&end,&start,&diff);
267
  cal_rit_calc_const = TIMESPEC2USEC(&diff);
268
 
269
  kern_cli();
270
  kern_gettime(&start);
271
  temp = (long long)(temp_1 + rand() % temp_2 - temp_2/2) * CALIBRATION_DELTA / cal_cycles;
272
  kern_gettime(&end);
273
  kern_sti();
274
 
275
  SUBTIMESPEC(&end,&start,&diff);
276
  cal_rit_calc_mean = TIMESPEC2USEC(&diff);
277
 
278
  kern_cli();
279
  kern_gettime(&start);
280
  temp = TIMESPEC2USEC(&start);
281
  kern_gettime(&end);
282
  kern_sti();
283
 
284
  SUBTIMESPEC(&end,&start,&diff);
285
  cal_rit_start = TIMESPEC2USEC(&diff) * 6 + cal_rit_calc_const;
286
 
287
  cprintf("Calibration delay start = %d const = %d mean = %d gauss = %d\n",
288
           cal_rit_start,cal_rit_calc_const,cal_rit_calc_mean,cal_rit_calc_gauss);
289
 
290
  return 0;
291
 
1201 giacomo 292
}
293
 
1206 giacomo 294
/* Mutex create */
295
void loader_mutex_create(struct loader_task *start_loader_task)
296
{
297
 
298
  struct loader_task *current = start_loader_task;
299
  int res = 0;
300
  PI_mutexattr_t a;
301
 
302
  PI_mutexattr_default(a);
303
 
304
  while (current != NULL) {
305
 
306
    if (current->crit_type == PAR_CRIT) {
307
      mutex_init(&mux_table[current->resource],&a);
308
      res++;
309
    }
310
 
311
    current = current->next;
312
 
313
  }
314
 
315
  cprintf("Created %d mutex\n",res);
316
 
317
}
318
 
1203 giacomo 319
/* Task create */
1201 giacomo 320
void loader_task_create(struct loader_task *start_loader_task)
321
{
322
 
323
  struct loader_task *current = start_loader_task;
1203 giacomo 324
  char tmp[30];
1201 giacomo 325
  int i, total_task;
1202 giacomo 326
  int total_group = 0;
1201 giacomo 327
  PID p;
328
 
329
  total_task = 0;
330
 
331
  while (current != NULL) {
332
 
1202 giacomo 333
    total_group++;
334
    current->group = total_group;
1203 giacomo 335
    current->bandwidth = 0;
1202 giacomo 336
 
1201 giacomo 337
    for (i=0; i < current->number; i++) {
338
 
339
      if (current->task_type == PAR_TASK_NRT) {
340
        NRT_TASK_MODEL nrt;
341
 
342
        nrt_task_default_model(nrt);
343
        nrt_task_def_save_arrivals(nrt);
344
        nrt_task_def_arg(nrt,(void *)(current));
345
        nrt_task_def_ctrl_jet(nrt);
346
        nrt_task_def_level(nrt,current->task_level);
1202 giacomo 347
        nrt_task_def_group(nrt,total_group);
1201 giacomo 348
 
1203 giacomo 349
        sprintf(tmp,"NRT %d:%d",current->group,i);
350
        p = task_create(tmp,nrt_test_task,&nrt,NULL);
1201 giacomo 351
        if (p == NIL) {
352
          cprintf("Error nrt task creating\n");
353
          sys_end();
354
        }
355
 
356
        total_task++;
357
 
358
      }
359
 
360
      if (current->task_type == PAR_TASK_HARD) {
361
        HARD_TASK_MODEL ht;
362
 
363
        hard_task_default_model(ht);
364
        hard_task_def_arg(ht,(void *)(current));
365
        hard_task_def_wcet(ht,TIMESPEC2USEC(&current->wcet));
366
        hard_task_def_ctrl_jet(ht);
367
        hard_task_def_level(ht,current->task_level);
1202 giacomo 368
        hard_task_def_group(ht,total_group);
1201 giacomo 369
 
1203 giacomo 370
        if (current->act_type != PAR_ACT_PERIODIC) {
371
          hard_task_def_mit(ht,TIMESPEC2USEC(&current->deadline));
372
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->deadline)
373
                                 * TIMESPEC2USEC(&current->wcet);
1201 giacomo 374
          hard_task_def_aperiodic(ht);
375
        } else {
1203 giacomo 376
          hard_task_def_mit(ht,TIMESPEC2USEC(&current->act_par_2));
377
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->act_par_2)
378
                                 * TIMESPEC2USEC(&current->wcet);
1201 giacomo 379
        }
1203 giacomo 380
 
381
        sprintf(tmp,"HARD %d:%d",current->group,i);
382
        p = task_create(tmp,test_task,&ht,NULL);
1201 giacomo 383
        if (p == NIL) {
384
          cprintf("Error hard task creating\n");
385
          sys_end();
386
        }
387
 
388
        total_task++;
389
 
390
      }
391
 
392
      if (current->task_type == PAR_TASK_SOFT) {
393
        SOFT_TASK_MODEL st;
394
 
395
        soft_task_default_model(st);
396
        soft_task_def_save_arrivals(st);
397
        soft_task_def_arg(st,(void *)(current));
398
        soft_task_def_met(st,TIMESPEC2USEC(&current->wcet));
399
        soft_task_def_ctrl_jet(st);
400
        soft_task_def_level(st,current->task_level);
1202 giacomo 401
        soft_task_def_group(st,total_group);
402
 
1201 giacomo 403
        if (current->act_type == PAR_ACT_PERIODIC) {
404
          soft_task_def_period(st,TIMESPEC2USEC(&current->act_par_2));
1203 giacomo 405
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->act_par_2)
406
                                 * TIMESPEC2USEC(&current->wcet);
1201 giacomo 407
        } else if (current->act_type != PAR_ACT_SINGLE) {
408
          soft_task_def_period(st,TIMESPEC2USEC(&current->act_par_2));
1203 giacomo 409
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->act_par_2)
410
                                 * TIMESPEC2USEC(&current->wcet);
1201 giacomo 411
          soft_task_def_aperiodic(st);
412
        } else {
1203 giacomo 413
          soft_task_def_period(st,TIMESPEC2USEC(&current->wcet)*1000);
414
          current->bandwidth += MAX_BANDWIDTH / 1000;
1201 giacomo 415
          soft_task_def_aperiodic(st);
416
        }
1203 giacomo 417
 
418
        sprintf(tmp,"SOFT %d:%d",current->group,i);
419
        p = task_create(tmp,test_task,&st,NULL);
1201 giacomo 420
        if (p == NIL) {
421
          cprintf("Error soft task creating\n");
422
          sys_end();
423
        }
424
 
425
        total_task++;
426
 
427
      }
428
 
429
    }
430
 
1203 giacomo 431
    cprintf("Task group %d created. Worst case BW = %d.%d \n",
432
             current->group,(int)( (long long)current->bandwidth * 100 / MAX_BANDWIDTH),
433
             (int)( (long long)current->bandwidth*  100000 / MAX_BANDWIDTH % 1000));
434
 
1201 giacomo 435
    current = current->next;
436
 
437
  }
438
 
439
  cprintf("Created %d tasks\n",total_task);
440
 
441
}
442
 
1203 giacomo 443
/* Set the first extivation events */
1202 giacomo 444
void loader_first_execution(struct loader_task *start_loader_task)
445
{
446
 
447
  struct loader_task *current = start_loader_task;
448
  struct timespec start_time;  
449
 
450
  while (current != NULL) {
451
 
452
    ADDTIMESPEC(&zero_time,&current->act_par_1,&start_time);
453
 
454
    kern_event_post(&start_time, (void *)((void *)group_activate), (void *)(current->group));
455
 
456
    current = current->next;
457
 
458
  }  
459
 
460
}
461
 
1199 giacomo 462
int main()
463
{
464
 
1200 giacomo 465
  struct loader_task *start_loader_task = NULL;
466
  struct timespec total;
1201 giacomo 467
  struct timespec end_time;
1199 giacomo 468
 
1201 giacomo 469
  line_reader(start, end, &total, &start_loader_task);
1200 giacomo 470
 
1203 giacomo 471
  srand(kern_gettime(NULL));
472
 
473
  calibrate_cycle();
474
 
1206 giacomo 475
  loader_mutex_create(start_loader_task);
476
 
1201 giacomo 477
  loader_task_create(start_loader_task);
478
 
479
  kern_gettime(&zero_time);
1202 giacomo 480
 
481
  loader_first_execution(start_loader_task);
482
 
1201 giacomo 483
  ADDTIMESPEC(&zero_time,&total,&end_time);
484
  kern_event_post(&end_time,(void *)((void *)(sys_end)),NULL);
485
 
1199 giacomo 486
  return 0;
487
 
488
}