Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1670 pj 1
#include <ctype.h>
2
#include "hlpdemo.h"
3
 
4
extern taskconf_list_t *taskconf;
5
extern mutex_list_t *mutexes;
6
 
7
typedef enum { TT_TASK = 0,
8
               TT_EVERY = 1,
9
               TT_RUNS = 2,
10
               TT_LOCKS = 3,
11
               TT_UNLOCKS = 4,
12
               TT_ID,
13
               TT_INT,
14
               TT_INVALID = -1 } keyword_t;
15
 
16
/* multitype value management */
17
typedef struct value_struct {
18
  int type; /* -1 invalid, 0 int, 1 string, 2 token, 3 eof */
19
  int intval;
20
  char *strval;
21
  keyword_t keyword;
22
} value_t;
23
 
24
value_t *invalid_value (int type)
25
{
26
  value_t *new;
27
  new = (value_t *) kern_alloc(sizeof(value_t));
28
  new->type = type;
29
  new->intval = -1;
30
  new->strval = NULL;
31
  new->keyword = TT_INVALID;
32
  return new;
33
}
34
 
35
char *strdup(char *str)
36
{
37
  char *ret;
38
 
39
  ret = (char *)kern_alloc((strlen(str) + 1) * sizeof(char));
40
  strncpy(ret, str, strlen(str));
41
  ret[strlen(str)] = '\0';
42
 
43
  return ret;
44
}
45
 
46
value_t *keyword_value (char *token)
47
{
48
  int i;
49
  value_t *new = NULL;
50
  char *type_assoc[] = { "task",
51
                         "every",
52
                         "runs",
53
                         "locks",
54
                         "unlocks",
55
                        NULL};
56
  for (i=0; type_assoc[i] != NULL ; i++)
57
    {
58
      if (strcmp(token, type_assoc[i]) == 0)
59
        {
60
          new = (value_t *)kern_alloc(sizeof(value_t));
61
          new->type = 2;
62
          new->intval = -1;
63
          new->strval = strdup(token);
64
          new->keyword = (keyword_t)i;
65
        }
66
    }
67
  return new;
68
}  
69
 
70
value_t *int_value (int n)
71
{
72
  value_t *new;
73
  new = (value_t *) kern_alloc(sizeof(value_t));
74
  new->type = 0;
75
  new->intval = n;
76
  new->strval = NULL;
77
  new->keyword = TT_INT;
78
  return new;
79
}
80
 
81
value_t *str_value (char *str)
82
{
83
  value_t *new;
84
  new = (value_t *) kern_alloc(sizeof(value_t));
85
  new->type = 1;
86
  new->intval = -1;
87
  new->strval = strdup(str);
88
  new->keyword = TT_ID;
89
  return new;
90
}
91
 
92
void dprint(char *str)
93
{
94
#ifdef DEBUG
95
  if (str)
96
    cprintf("%s\n", str);
97
#endif
98
}
99
 
100
void dprint_value(value_t *val)
101
{
102
#ifdef DEBUG
103
  switch (val->type) {
104
  case 0:
105
    cprintf("Value is an integer: %d\n", val->intval);
106
    break;
107
  case 1:
108
    cprintf("Value is a string: '%s'\n", val->strval);
109
    break;
110
  case 2:
111
    cprintf("Value is a keyword: %d\n", (int)val->keyword);
112
    break;
113
  case 3:
114
    cprintf("Value is an eof terminator\n");
115
    break;
116
  }
117
#endif
118
}
119
 
120
int intlen(int val)
121
{
122
  int ret = 1;
123
 
124
  while ( (val = val / 10) >= 1) ret++;
125
 
126
  return ret;
127
}
128
 
129
/*
130
   @desc Tokenizza uno stream, riconoscendo interi, identificatori e
131
   token del linguaggio. Ad ogni chiamata restituisce il prossimo
132
   token.
133
   @return il prossimo token come multitype value (esistono i value di errore)
134
*/
135
value_t *get_token_from_str (char *stream, unsigned int size)
136
{
137
  int c, intval;
138
  static int pos = 0;
139
 
140
  /* Ignore white space, get first nonwhite character.  */
141
  while ((c = stream[pos++]) == ' ' || c == '\t' || c == '\n');
142
 
143
  if (c == EOF || c == '\0' || pos == size - 1)
144
    return invalid_value(3);
145
 
146
  /* Char starts a number => parse the number.         */
147
  if (c == '.' || isdigit (c))
148
    {
149
      pos--;
150
      sscanf (&stream[pos], "%d", &intval);
151
      pos += intlen(intval);
152
      return int_value(intval);
153
    }
154
 
155
  /* Char starts an identifier => read the name.       */
156
  if (isalpha (c))
157
    {
158
      value_t *keyword_val;
159
      static char *symbuf = 0;
160
      static int length = 0;
161
      int i;
162
 
163
      /* Initially make the buffer long enough
164
         for a 40-character symbol name.  */
165
      if (length == 0)
166
        length = 40, symbuf = (char *)kern_alloc (length + 1);
167
 
168
      i = 0;
169
      do
170
        {
171
          /* If buffer is full, make it bigger.        */
172
          if (i == length)
173
            {
174
              length *= 2;
175
              symbuf = (char *) realloc (symbuf, length + 1);
176
            }
177
          /* Add this character to the buffer.         */
178
          symbuf[i++] = c;
179
          /* Get another character.                    */
180
          c = stream[pos++];
181
        }
182
      while (isalnum (c));
183
 
184
      pos--;
185
      symbuf[i] = '\0';
186
 
187
      keyword_val = keyword_value(symbuf);
188
 
189
      if (keyword_val->type == 2)
190
        {
191
          dprint("found a keyword");
192
          return keyword_val;
193
        }
194
      else
195
        {
196
          dprint("found an identifier");
197
          return str_value(symbuf);
198
        }
199
    }
200
 
201
  /* Any other character is a token by itself.        */
202
#ifdef DEBUG
203
  cprintf("Invalid Token: '%c'\n", c);
204
#endif
205
  return invalid_value(-1);
206
}
207
 
208
 
209
/*
210
   @desc Ricerca un mutex di un dato nome in una mutex_list_t
211
   @return il mutex trovato o NULL in caso di mutex non trovato
212
*/
213
mutex_list_t *in_mutex_list(char *needle, mutex_list_t *list)
214
{
215
  while (list)
216
    {
217
      if (!strcmp(needle, list->name))
218
        break;
219
      list = list->next;
220
    }
221
 
222
  return list;
223
}
224
 
225
/* @return Calcola il wcet sommando tutte le azioni di load */
226
DWORD calc_wcet(taskconf_list_t *task)
227
{
228
  action_list_t *scan = task->actionlist;
229
  DWORD wcet = 0;
230
 
231
  while(scan)
232
    {
233
      wcet += (scan->type == LOAD ? scan->time : 0);
234
      scan = scan->next;
235
    }
236
 
237
  return wcet;
238
}
239
 
240
/*
241
   @desc Legge la configurazione dal buffer esterno myfilebuf
242
         Riempie la struttura dati esterna taskconf
243
   @return 0  ok
244
           -1 errore nel parsing
245
*/
246
int read_conf(char *stream, unsigned int size)
247
{
248
  value_t *tmpval, *curval = get_token_from_str(stream, size);
249
  taskconf_list_t *tcnew, *tccur = taskconf;
250
  action_list_t *acnew, *accur = NULL;
251
  mutex_list_t *mutnew, *mutcur = NULL;
252
  TIME seme;
253
 
254
  dprint(stream);
255
 
256
  while (curval->type != 3) /* until eof */
257
    {
258
      switch (curval->keyword)
259
        {
260
        case TT_TASK: /* create new task */
261
          tmpval = get_token_from_str(stream, size);  /* get the name */
262
 
263
          if (tmpval->type != 1) {
264
            dprint("No name after task");
265
            return -1;
266
          }
267
 
268
          /* alloc mem and set default data */
269
          tcnew = (taskconf_list_t *)kern_alloc((sizeof(taskconf_list_t)));
270
          tcnew->name = strdup(tmpval->strval);
271
          tcnew->period = -1;
272
          tcnew->wcet = 0;
273
          tcnew->next = NULL;
274
          tcnew->mutexlist = NULL;
275
          tcnew->actionlist = NULL;
276
 
277
          /* reset current mutex and current action */
278
          mutcur = NULL;
279
          accur = NULL;
280
 
281
          /* fill the first taskconf */
282
          if (taskconf == NULL)
283
            taskconf = tcnew;
284
 
285
          if (tccur != NULL)
286
            tccur->next = tcnew;
287
 
288
          tccur = tcnew;
289
 
290
          break;
291
 
292
        case TT_EVERY:
293
          tmpval = get_token_from_str(stream, size);
294
          if (tmpval->type != 0) {
295
            dprint("No period after every");
296
            return -1;
297
          }
298
          tccur->period = tmpval->intval;
299
          break;
300
 
301
        case TT_RUNS:
302
          /* making new action */
303
          tmpval = get_token_from_str(stream, size);
304
          if (tmpval->type != 0) {
305
            dprint("No period after runs");
306
            return -1;
307
          }
308
 
309
          acnew = (action_list_t *)kern_alloc((sizeof(action_list_t)));
310
          acnew->type = LOAD;
311
          acnew->time = tmpval->intval;
312
          acnew->next = NULL;
313
          acnew->mutex = NULL;
314
 
315
          if (tccur->actionlist == NULL)
316
            tccur->actionlist = acnew;
317
          else
318
            accur->next = acnew;
319
 
320
          accur = acnew;
321
 
322
          /* calculate wcet for the former task */
323
          if (tccur != NULL)
324
          {
325
            /* calc the wcet */
326
            tccur->wcet = calc_wcet(tccur);
327
          }
328
 
329
          break;
330
 
331
        case TT_LOCKS:
332
 
333
          tmpval = get_token_from_str(stream, size);
334
 
335
          if (tmpval->type != 1)
336
            return -1;
337
 
338
          acnew = (action_list_t *)kern_alloc(sizeof(action_list_t));
339
          acnew->type = LOCK;
340
          acnew->time = -1;
341
          acnew->next = NULL;
342
 
343
          /* create new mutex if does not exist*/
344
          if ( !(mutnew = in_mutex_list(tmpval->strval, mutexes)))
345
            {
346
              mutnew = (mutex_list_t *)kern_alloc(sizeof(mutex_list_t));
347
              mutnew->name = strdup(tmpval->strval);
348
 
349
              seme = sys_gettime(NULL);
350
              srand(seme);
351
              mutnew->color = rgb16(rand() % 255,
352
                                    rand() % 255,
353
                                    rand() % 255);
354
              mutnew->next = NULL;
355
 
356
              /* adding to mutexes */
357
              if (mutexes == NULL)
358
                mutexes = mutnew;
359
              else
360
                mutexes->next = mutnew;
361
            }
362
          acnew->mutex = mutnew;
363
 
364
          /* add mutex to the list of tasks using it */
365
          if (tccur->mutexlist == NULL)
366
            {
367
              tccur->mutexlist = mutnew;
368
            }
369
          else
370
            {
371
              if (in_mutex_list(tmpval->strval, tccur->mutexlist))
372
                mutcur->next = mutnew;
373
            }
374
 
375
          mutcur = mutnew;
376
 
377
          /* updating action list */
378
          if (tccur->actionlist == NULL)
379
            tccur->actionlist = acnew;
380
          else
381
            accur->next = acnew;
382
 
383
          accur = acnew;
384
          break;
385
 
386
        case TT_UNLOCKS:
387
 
388
          tmpval = get_token_from_str(stream, size);
389
          if (tmpval->type != 1)
390
            return -1;
391
 
392
          acnew = (action_list_t *)kern_alloc((sizeof(action_list_t)));
393
          acnew->type = UNLOCK;
394
          acnew->time = -1;
395
          acnew->next = NULL;
396
 
397
          if ( (mutnew = in_mutex_list(tmpval->strval, tccur->mutexlist)) == NULL)
398
            {
399
#ifdef DEBUG
400
              cprintf("Mutex %s unlocked but never locked\n", tmpval->strval);
401
#endif        
402
            return -1;
403
            }
404
 
405
          acnew->mutex = mutnew;
406
 
407
          if (tccur->actionlist == NULL)
408
            tccur->actionlist = acnew;
409
          else
410
            accur->next = acnew;
411
 
412
          accur = acnew;
413
          break;
414
 
415
        case TT_ID:
416
          dprint_value(curval);
417
          break;
418
 
419
        case TT_INT:
420
          dprint_value(curval);
421
          break;
422
 
423
        case TT_INVALID:
424
          break;
425
        }
426
      curval = get_token_from_str(stream, size);
427
    }
428
  return 0;
429
}
430
 
431
void print_taskconf(taskconf_list_t *tc)
432
{
433
  action_list_t *action;
434
  mutex_list_t *mutex;
435
 
436
  if (tc == NULL)
437
    return;
438
 
439
  cprintf("Task: %s, period %ld, wcet %ld\n", tc->name, tc->period, tc->wcet);
440
  cprintf("Actions:\n");
441
 
442
  action = tc->actionlist;
443
 
444
  while (action)
445
    {
446
      cprintf("---Type %d, time %d, mutex %s\n", action->type, action->time, (action->mutex == NULL ? "" : action->mutex->name));
447
      action = action->next;
448
    }
449
 
450
  cprintf("Mutex used:\n");
451
  mutex = tc->mutexlist;
452
 
453
  while (mutex)
454
    {
455
      cprintf("---Name %s, Color %d\n", mutex->name, mutex->color);
456
      mutex = mutex->next;
457
    }
458
 
459
  print_taskconf(tc->next);
460
}