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: step2.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
    pattern_iter[i] = tune_CPU_speed(w);
90
  }
91
}
92
 
93
 
94
 
95
 
96
// Shape modification
97
 
98
#define DEFAULT_SHIFT 1000000
99
#define MAX_SHAPE 1000
100
 
101
bandwidth_t shape=0; // current shape threshold
102
 
103
int current_shape = 0;
104
bandwidth_t shape_B[MAX_SHAPE];
105
TIME shape_T[MAX_SHAPE];
106
int max_shape;
107
 
108
void shape_event(void *arg)
109
{
110
  struct timespec t;
111
 
112
  shape = shape_B[current_shape];
113
 
114
  current_shape++;
115
 
116
  if (current_shape == max_shape)
117
    ending = 1;
118
 
119
  NULL_TIMESPEC(&t);
120
  ADDUSEC2TIMESPEC((shape_T[current_shape]*1000000+DEFAULT_SHIFT),&t);
121
 
122
//  cprintf("At Time=%10ld.%10ld T=%10d Shape=%10d\n",t.tv_sec,t.tv_nsec,
123
//          shape_T[current_shape],shape_B[current_shape]);
124
 
125
  kern_event_post(&t,shape_event,NULL);
126
}
127
 
128
void start_shape(void)
129
{
130
  struct timespec t;
131
 
132
  NULL_TIMESPEC(&t);
133
  ADDUSEC2TIMESPEC(DEFAULT_SHIFT,&t);
134
  kern_cli();
135
  kern_event_post(&t,shape_event,NULL);
136
  kern_sti();
137
}
138
 
139
// Hard task
140
#define ASTER_LIM 80
141
void *hard_task(void *arg)
142
{
143
  int j, x, y;
144
  char s[2];
145
 
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
 
161
  return (void *)0;
162
}
163
 
164
 
165
#define MAX_PERIOD 100
166
// Load creation
167
void *create_load(void *arg)
168
{
169
    PID p;
170
 
171
    HARD_TASK_MODEL m;
172
    TIME period = 0;
173
    TIME wcet = 0;
174
    int x; // adaptive bandwidth...
175
    int counter=0;
176
 
177
    char buf[100];
178
 
179
    hard_task_default_model(m);
180
 
181
    x = MAX_PERIOD/3;
182
 
183
    place(0,11);
184
 
185
    // waiting for the start time :-)
186
    while (sys_gettime(NULL)<DEFAULT_SHIFT);
187
 
188
    while (1) {
189
      sprintf(buf,"Shape: %5.3f Band: %5.3f period: %10ld wcet: %10ld Time: %d",
190
              (double)shape/(double)MAX_BANDWIDTH,
191
              (double)EDF_usedbandwidth(0)/(double)MAX_BANDWIDTH,
192
              period, wcet, sys_gettime(NULL)/1000000);
193
      puts_xy(0,10,WHITE,buf);
194
 
195
      period = (x+rand() % (MAX_PERIOD-x+1))*1000;
196
      wcet = rand()%1000 * (period/1500);
197
 
198
      if ((MAX_BANDWIDTH/period)*wcet > shape - EDF_usedbandwidth(0))
199
        wcet = (shape - EDF_usedbandwidth(0))/period;
200
 
201
      if (wcet < period/40) wcet=period/40;
202
      if (wcet < 500) wcet=500;
203
 
204
      if (EDF_usedbandwidth(0) + (MAX_BANDWIDTH/period)*wcet < shape) {
205
 
206
        hard_task_def_mit(m, period);
207
        hard_task_def_wcet(m, wcet);
208
        p = task_create("hard_task",hard_task,&m,NULL);
209
        if (p == -1) {
210
          x += rand()%10-4;
211
        }
212
        else {
213
          record_pattern(sys_gettime(NULL),period,wcet);
214
          cprintf("%d ",++counter);
215
          task_activate(p);
216
          x *= 3;
217
          x /= 4;
218
        }
219
        if (x<MAX_PERIOD/3) x = MAX_PERIOD/3;
220
        if (x > MAX_PERIOD) x = MAX_PERIOD;
221
      }
222
 
223
      if (ending) return (void *)0;
224
    }
225
}
226
 
227
 
228
// Read/Write part
229
 
230
#define FILEBUF_DIM 10000
231
 
232
/* This is the buffer used by read_myfile */
233
char myfilebuf[FILEBUF_DIM];
234
 
235
/* This is the number of bytes read by read_myfile */
236
int myfilebuf_length;
237
 
238
/* the buffer b is scannedc to search for numbers
239
   at the first non-number the function stops */
240
int geti(char *b, int *pos, int maxpos)
241
{
242
  int res = 0;
243
 
244
  // skip first chars
245
  while (!isdigit(b[*pos])) {
246
    (*pos)++;
247
    if (*pos == maxpos) return -1;  // Error!!!
248
  }
249
 
250
 
251
  // read the numbers
252
  do {
253
    res = (res * 10) + b[*pos] - '0';
254
    (*pos)++;
255
  } while (isdigit(b[*pos]));
256
 
257
  return res;
258
}
259
 
260
 
261
void parse_shape(void)
262
{
263
  int curr_filepos = 0;
264
  int i = 0;
265
 
266
  // read the number of tasks into the data file
267
  max_shape = geti(myfilebuf, &curr_filepos, myfilebuf_length);
268
  if (max_shape == -1) {
269
    cprintf("Error parsing shape.dat file...\n");
270
    sys_end();
271
  }
272
 
273
  for (i=0; i<max_shape; i++) {
274
      // read the seven datas
275
      shape_T[i]      = geti(myfilebuf, &curr_filepos, myfilebuf_length);
276
      shape_B[i]      = geti(myfilebuf, &curr_filepos, myfilebuf_length);
277
 
278
      // check the last one for an error
279
      if (shape_B[i] == -1) {
280
        cprintf("Error parsing shape %d...\n",i);
281
        sys_end();
282
      }
283
  }
284
}
285
 
286
void read_shapes(void)
287
{
288
  char name[]="shape.dat";
289
 
290
  /* DOS file descriptor */
291
  DOS_FILE *f;
292
 
293
  /* Error code */
294
  int err;
295
 
296
  /* open the DOS file for reading  (you can specify only "r" or "w") */
297
  f = DOS_fopen(name,"r");
298
 
299
  /* check for open errors */
300
  if (!f) {
301
    /* error!! */
302
    err = DOS_error();
303
 
304
    /* note that if you call DOS_error() here, it return 0!!! */
305
    cprintf("Error %d opening %s...\n", err, name);
306
    myfilebuf_length = 0;
307
    return;
308
  }
309
 
310
  /* read up to 1000 chars */
311
  myfilebuf_length = DOS_fread(&myfilebuf,1,FILEBUF_DIM,f);
312
 
313
  /* check for errors */
314
  err = DOS_error();
315
 
316
  cprintf("Read %d bytes from %s...\n", myfilebuf_length, name);
317
 
318
  if (err) {
319
    cprintf("Error %d reading %s...\n", err, name);
320
    myfilebuf_length = 0;
321
   /* there is not return because I want to close the file! */
322
  }
323
 
324
  /* Close the file */
325
  DOS_fclose(f);
326
}
327
 
328
 
329
/* This function write myfile.out (up to 30 chars) */
330
void write_hpattern(void *arg)
331
{
332
  DOS_FILE *f;  /* DOS file descriptor */
333
  int err=0;  /* Error code */
334
  int writtenbytes = 0;  /* number of files written */
335
  char buf[100];
336
  int i;
337
 
338
  /* open the DOS file for writing  (you can specify only "r" or "w") */
339
  f = DOS_fopen("hpattern.dat","w");
340
 
341
  /* check for open errors */
342
  if (!f) {
343
    /* error!! */
344
    err = DOS_error();
345
 
346
    /* note that if you call DOS_error() here, it return 0!!! */
347
    cprintf("Error %d opening hpattern.dat...\n", err);
348
    return;
349
  }
350
 
351
  sprintf(buf,"%d\r\n",max_pattern);
352
  writtenbytes += DOS_fwrite(buf,1,strlen(buf),f);
353
 
354
  for (i=0; i<max_pattern; i++) {
355
    sprintf(buf,"%ld %ld %ld %ld\r\n", pattern_t[i], pattern_period[i],
356
                            pattern_wcet[i], pattern_iter[i]);
357
 
358
    writtenbytes += DOS_fwrite(buf,1,strlen(buf),f);
359
 
360
    /* check for errors */
361
    err = DOS_error();
362
    if (err) break;
363
  }
364
 
365
 
366
  cprintf("Written %d bytes into hpattern.dat...\n", writtenbytes);
367
 
368
  if (err) {
369
    cprintf("Error %d writing hpattern.dat...\n", err);
370
    /* there is not return because I want to close the file! */
371
  }
372
 
373
  /* Close the file */
374
  DOS_fclose(f);
375
}
376
 
377
 
378
 
379
 
380
 
381
 
382
 
383
 
384
 
385
/*+ sysyem tick in us +*/
386
#define TICK 0
387
 
388
/*+ RR tick in us +*/
389
#define RRTICK 10000
390
 
391
void read_myfile(void);
392
 
393
TIME __kernel_register_levels__(void *arg)
394
{
395
  struct multiboot_info *mb = (struct multiboot_info *)arg;
396
 
397
  EDF_register_level(EDF_ENABLE_ALL);
398
  RR_register_level(RRTICK, RR_MAIN_NO, mb);
399
  RR_register_level(RRTICK, RR_MAIN_YES, mb);
400
  dummy_register_level();
401
 
402
  SEM_register_module();
403
 
404
  read_shapes();
405
 
406
  return TICK;
407
}
408
 
409
 
410
NRT_TASK_MODEL keyb_model;
411
 
412
TASK __init__(void *arg)
413
{
414
  NRT_TASK_MODEL nrt;
415
 
416
  KEYB_PARMS kparms = BASE_KEYB;
417
 
418
  HARTPORT_init();
419
 
420
  nrt_task_default_model(keyb_model);
421
  nrt_task_def_system(keyb_model);
422
  nrt_task_def_nokill(keyb_model);
423
  keyb_def_task(kparms,(TASK_MODEL *)&keyb_model);
424
  KEYB_init(&kparms);
425
 
426
  set_exchandler_grx();
427
 
428
  nrt_task_default_model(nrt);
429
 
430
  srand(sys_gettime(NULL));
431
 
432
  clear();
433
 
434
  sys_atrunlevel(write_hpattern, NULL, RUNLEVEL_AFTER_EXIT);
435
 
436
  parse_shape();
437
 
438
  start_shape();
439
 
440
  task_activate(task_create("create_load",create_load,&nrt,NULL));
441
 
442
  cputs("\nWaiting the end of the periodic tasks...\n");
443
  while (task_counter != 1);
444
 
445
  // the task create_load preempt __init__ until all is finished!
446
  tune_pattern();
447
 
448
  return (void *)0;
449
}
450
 
451
// never called!!!
452
int main()
453
{
454
  return 0;
455
}