Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1663 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/**
20
 ------------
21
 CVS :        $Id: step2b.c,v 1.1 2004-07-05 14:17:15 pj Exp $
22
 
23
 File:        $File$
24
 Revision:    $Revision: 1.1 $
25
 Last update: $Date: 2004-07-05 14:17:15 $
26
 ------------
27
**/
28
 
29
/*
30
 * Copyright (C) 2000 Paolo Gai
31
 *
32
 * This program is free software; you can redistribute it and/or modify
33
 * it under the terms of the GNU General Public License as published by
34
 * the Free Software Foundation; either version 2 of the License, or
35
 * (at your option) any later version.
36
 *
37
 * This program is distributed in the hope that it will be useful,
38
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40
 * GNU General Public License for more details.
41
 *
42
 * You should have received a copy of the GNU General Public License
43
 * along with this program; if not, write to the Free Software
44
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
45
 *
46
 */
47
 
48
#include "kernel/kern.h"
49
#include "string.h"
50
#include "ll/i386/x-dos.h"
51
#include "modules/rr.h"
52
#include "modules/dummy.h"
53
#include "modules/edf.h"
54
#include "modules/sem.h"
55
#include "modules/hartport.h"
56
#include "drivers/keyb.h"
57
#include "ctype.h"
58
#include "tune.h"
59
 
60
 
61
int ending=0;
62
 
63
 
64
// Patterns
65
#define MAX_PATTERN 10000
66
int max_pattern = 0;
67
TIME pattern_t[MAX_PATTERN];
68
TIME pattern_period[MAX_PATTERN];
69
TIME pattern_wcet[MAX_PATTERN];
70
TIME pattern_iter[MAX_PATTERN];
71
 
72
void record_pattern(TIME t, TIME period, TIME wcet)
73
{
74
  pattern_t[max_pattern] = t;
75
  pattern_period[max_pattern] = period;
76
  pattern_wcet[max_pattern] = wcet;
77
  max_pattern++;
78
}
79
 
80
#define WCET_SLACK 500
81
 
82
void tune_pattern(void)
83
{
84
  int i,w;
85
 
86
  for (i=0; i<max_pattern; i++) {
87
    w = (pattern_wcet[i]*80)/100-WCET_SLACK;
88
    // if (w>pattern_wcet[i]-WCET_SLACK) w=pattern_wcet[i]-WCET_SLACK;
89
    if (w<0) w=WCET_SLACK/2;
90
    pattern_iter[i] = tune_CPU_speed(w);
91
  }
92
}
93
 
94
 
95
 
96
 
97
// Shape modification
98
 
99
#define DEFAULT_SHIFT 1000000
100
#define MAX_SHAPE 1000
101
 
102
bandwidth_t shape=0; // current shape threshold
103
 
104
int current_shape = 0;
105
bandwidth_t shape_B[MAX_SHAPE];
106
TIME shape_T[MAX_SHAPE];
107
int max_shape;
108
 
109
void shape_event(void *arg)
110
{
111
  shape = shape_B[0];
112
}
113
 
114
void end_event(void *arg)
115
{
116
  ending = 1;
117
}
118
 
119
void start_shape(void)
120
{
121
  struct timespec t;
122
 
123
  NULL_TIMESPEC(&t);
124
  kern_cli();
125
  kern_event_post(&t,shape_event,NULL);
126
  ADDUSEC2TIMESPEC(DEFAULT_SHIFT,&t);
127
  kern_event_post(&t,end_event,NULL);
128
  kern_sti();
129
}
130
 
131
// Hard task
132
#define ASTER_LIM 80
133
void *hard_task(void *arg)
134
{
135
  int j, x, y;
136
  char s[2];
137
 
138
  struct timespec t;
139
  int b;
140
  NULL_TIMESPEC(&t);
141
  ADDUSEC2TIMESPEC((DEFAULT_SHIFT*2)/3,&t);
142
 
143
  b = TIMESPEC_A_LT_B(&proc_table[exec_shadow].request_time,&t);
144
 
145
  do {
146
    x = 0;
147
    y = rand() % 6 + 3;
148
    s[0] = '*'; s[1] = 0;
149
    while (x < ASTER_LIM) {
150
      for (j=0; j<50; j++) {
151
        s[0] = '*' + rand() % 100;
152
        puts_xy(x,y,rand()%15+1,s);
153
      }
154
 
155
      task_endcycle();
156
 
157
      puts_xy(x,y,WHITE," ");
158
      x++;
159
    }
160
  } while (b && !ending);
161
 
162
  return (void *)0;
163
}
164
 
165
 
166
#define MAX_PERIOD 100
167
// Load creation
168
void *create_load(void *arg)
169
{
170
    PID p;
171
 
172
    HARD_TASK_MODEL m;
173
    TIME period = 0;
174
    TIME wcet = 0;
175
    int x; // adaptive bandwidth...
176
    int counter=0;
177
 
178
    char buf[100];
179
 
180
    hard_task_default_model(m);
181
 
182
    x = MAX_PERIOD/3;
183
 
184
    place(0,11);
185
 
186
    // waiting for the start time :-)
187
    while (sys_gettime(NULL)<DEFAULT_SHIFT/2);
188
 
189
    while (1) {
190
      sprintf(buf,"Shape: %5.3f Band: %5.3f period: %10ld wcet: %10ld Time: %d",
191
              (double)shape/(double)MAX_BANDWIDTH,
192
              (double)EDF_usedbandwidth(0)/(double)MAX_BANDWIDTH,
193
              period, wcet, sys_gettime(NULL)/1000000);
194
      puts_xy(0,10,WHITE,buf);
195
 
196
      period = (x+rand() % (MAX_PERIOD-x+1))*1000;
197
      wcet = rand()%1000 * (period/1500);
198
 
199
      if ((MAX_BANDWIDTH/period)*wcet > shape - EDF_usedbandwidth(0))
200
        wcet = (shape - EDF_usedbandwidth(0))/period;
201
 
202
      if (wcet < period/40) wcet=period/40;
203
      if (wcet < 500) wcet=500;
204
 
205
      if (EDF_usedbandwidth(0) + (MAX_BANDWIDTH/period)*wcet < shape) {
206
 
207
        hard_task_def_mit(m, period);
208
        hard_task_def_wcet(m, wcet);
209
        p = task_create("hard_task",hard_task,&m,NULL);
210
        if (p == -1) {
211
          x += rand()%10-4;
212
        }
213
        else {
214
          record_pattern(sys_gettime(NULL),period,wcet);
215
          cprintf("%d ",++counter);
216
          task_activate(p);
217
          x *= 3;
218
          x /= 4;
219
        }
220
        if (x<MAX_PERIOD/3) x = MAX_PERIOD/3;
221
        if (x > MAX_PERIOD) x = MAX_PERIOD;
222
      }
223
 
224
      if (ending) return (void *)0;
225
    }
226
}
227
 
228
 
229
// Read/Write part
230
 
231
#define FILEBUF_DIM 10000
232
 
233
/* This is the buffer used by read_myfile */
234
char myfilebuf[FILEBUF_DIM];
235
 
236
/* This is the number of bytes read by read_myfile */
237
int myfilebuf_length;
238
 
239
/* the buffer b is scannedc to search for numbers
240
   at the first non-number the function stops */
241
int geti(char *b, int *pos, int maxpos)
242
{
243
  int res = 0;
244
 
245
  // skip first chars
246
  while (!isdigit(b[*pos])) {
247
    (*pos)++;
248
    if (*pos == maxpos) return -1;  // Error!!!
249
  }
250
 
251
 
252
  // read the numbers
253
  do {
254
    res = (res * 10) + b[*pos] - '0';
255
    (*pos)++;
256
  } while (isdigit(b[*pos]));
257
 
258
  return res;
259
}
260
 
261
 
262
void parse_shape(void)
263
{
264
  int curr_filepos = 0;
265
  int i = 0;
266
 
267
  // read the number of tasks into the data file
268
  max_shape = geti(myfilebuf, &curr_filepos, myfilebuf_length);
269
  if (max_shape == -1) {
270
    cprintf("Error parsing shape.dat file...\n");
271
    sys_end();
272
  }
273
 
274
  for (i=0; i<max_shape; i++) {
275
      // read the seven datas
276
      shape_T[i]      = geti(myfilebuf, &curr_filepos, myfilebuf_length);
277
      shape_B[i]      = geti(myfilebuf, &curr_filepos, myfilebuf_length);
278
 
279
      // check the last one for an error
280
      if (shape_B[i] == -1) {
281
        cprintf("Error parsing shape %d...\n",i);
282
        sys_end();
283
      }
284
  }
285
}
286
 
287
void read_shapes(void)
288
{
289
  char name[]="shape.dat";
290
 
291
  /* DOS file descriptor */
292
  DOS_FILE *f;
293
 
294
  /* Error code */
295
  int err;
296
 
297
  /* open the DOS file for reading  (you can specify only "r" or "w") */
298
  f = DOS_fopen(name,"r");
299
 
300
  /* check for open errors */
301
  if (!f) {
302
    /* error!! */
303
    err = DOS_error();
304
 
305
    /* note that if you call DOS_error() here, it return 0!!! */
306
    cprintf("Error %d opening %s...\n", err, name);
307
    myfilebuf_length = 0;
308
    return;
309
  }
310
 
311
  /* read up to 1000 chars */
312
  myfilebuf_length = DOS_fread(&myfilebuf,1,FILEBUF_DIM,f);
313
 
314
  /* check for errors */
315
  err = DOS_error();
316
 
317
  cprintf("Read %d bytes from %s...\n", myfilebuf_length, name);
318
 
319
  if (err) {
320
    cprintf("Error %d reading %s...\n", err, name);
321
    myfilebuf_length = 0;
322
   /* there is not return because I want to close the file! */
323
  }
324
 
325
  /* Close the file */
326
  DOS_fclose(f);
327
}
328
 
329
 
330
/* This function write myfile.out (up to 30 chars) */
331
void write_hpattern(void *arg)
332
{
333
  DOS_FILE *f;  /* DOS file descriptor */
334
  int err=0;  /* Error code */
335
  int writtenbytes = 0;  /* number of files written */
336
  char buf[100];
337
  int i;
338
 
339
  /* open the DOS file for writing  (you can specify only "r" or "w") */
340
  f = DOS_fopen("hpattern.dat","w");
341
 
342
  /* check for open errors */
343
  if (!f) {
344
    /* error!! */
345
    err = DOS_error();
346
 
347
    /* note that if you call DOS_error() here, it return 0!!! */
348
    cprintf("Error %d opening hpattern.dat...\n", err);
349
    return;
350
  }
351
 
352
  sprintf(buf,"%d\r\n",max_pattern);
353
  writtenbytes += DOS_fwrite(buf,1,strlen(buf),f);
354
 
355
  for (i=0; i<max_pattern; i++) {
356
    sprintf(buf,"%ld %ld %ld %ld\r\n", pattern_t[i], pattern_period[i],
357
                            pattern_wcet[i], pattern_iter[i]);
358
 
359
    writtenbytes += DOS_fwrite(buf,1,strlen(buf),f);
360
 
361
    /* check for errors */
362
    err = DOS_error();
363
    if (err) break;
364
  }
365
 
366
 
367
  cprintf("Written %d bytes into hpattern.dat...\n", writtenbytes);
368
 
369
  if (err) {
370
    cprintf("Error %d writing hpattern.dat...\n", err);
371
    /* there is not return because I want to close the file! */
372
  }
373
 
374
  /* Close the file */
375
  DOS_fclose(f);
376
}
377
 
378
 
379
 
380
 
381
 
382
 
383
 
384
 
385
 
386
/*+ sysyem tick in us +*/
387
#define TICK 0
388
 
389
/*+ RR tick in us +*/
390
#define RRTICK 10000
391
 
392
void read_myfile(void);
393
 
394
TIME __kernel_register_levels__(void *arg)
395
{
396
  struct multiboot_info *mb = (struct multiboot_info *)arg;
397
 
398
  EDF_register_level(EDF_ENABLE_ALL);
399
  RR_register_level(RRTICK, RR_MAIN_NO, mb);
400
  RR_register_level(RRTICK, RR_MAIN_YES, mb);
401
  dummy_register_level();
402
 
403
  SEM_register_module();
404
 
405
  read_shapes();
406
 
407
  return TICK;
408
}
409
 
410
 
411
NRT_TASK_MODEL keyb_model;
412
 
413
TASK __init__(void *arg)
414
{
415
  NRT_TASK_MODEL nrt;
416
 
417
  KEYB_PARMS kparms = BASE_KEYB;
418
 
419
  HARTPORT_init();
420
 
421
  nrt_task_default_model(keyb_model);
422
  nrt_task_def_system(keyb_model);
423
  nrt_task_def_nokill(keyb_model);
424
  keyb_def_task(kparms,(TASK_MODEL *)&keyb_model);
425
  KEYB_init(&kparms);
426
 
427
  set_exchandler_grx();
428
 
429
  nrt_task_default_model(nrt);
430
 
431
  srand(sys_gettime(NULL));
432
 
433
  clear();
434
 
435
  sys_atrunlevel(write_hpattern, NULL, RUNLEVEL_AFTER_EXIT);
436
 
437
  parse_shape();
438
 
439
  start_shape();
440
 
441
  task_activate(task_create("create_load",create_load,&nrt,NULL));
442
 
443
  cputs("\nWaiting the end of the periodic tasks...\n");
444
  while (task_counter != 1);
445
 
446
  // the task create_load preempt __init__ until all is finished!
447
  tune_pattern();
448
 
449
  return (void *)0;
450
}
451
 
452
// never called!!!
453
int main()
454
{
455
  return 0;
456
}