Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 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
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/*
22
 * Copyright (C) 2000 Massimiliano Giorgi
23
 *
24
 * This program is free software; you can redistribute it and/or modify
25
 * it under the terms of the GNU General Public License as published by
26
 * the Free Software Foundation; either version 2 of the License, or
27
 * (at your option) any later version.
28
 *
29
 * This program is distributed in the hope that it will be useful,
30
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
 * GNU General Public License for more details.
33
 *
34
 * You should have received a copy of the GNU General Public License
35
 * along with this program; if not, write to the Free Software
36
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
37
 *
38
 */
39
 
40
/*
41
 * CVS :        $Id: trccirc.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $
42
 *
43
 * File:        $File$
44
 * Revision:    $Revision: 1.1.1.1 $
45
 * Last update: $Date: 2002-03-29 14:12:52 $
46
 */
47
 
48
#include <ll/sys/types.h>
49
#include <ll/stdlib.h>
50
 
51
#include <kernel/func.h>
52
#include <kernel/mem.h>
53
#include <kernel/log.h>
54
 
55
#include <trace/types.h>
56
#include <trace/trace.h>
57
#include <trace/queues.h>
58
 
59
#include <fs/fs.h>
60
 
61
#include <unistd.h>
62
#include <fcntl.h>
63
#include <limits.h>
64
 
65
/* Well... this file is very similar to trcfixed.c! */
66
 
67
typedef struct TAGcircular_queue_t {
68
  /*+ size of the queue +*/
69
  int         size;
70
  /*+ index of the next insertion into the queue +*/
71
  int         index;
72
  /*+ index of the next item to write (if online_tracer activated) +*/
73
  int         windex;
74
  /*+ number of events lost (if online_tracer activated) +*/
75
  long        hoops;
76
  /*+ filename of the trace file +*/
77
  char        *filename;
78
  /*+ flags from flags field of the initialization struct +*/
79
  int         flags;
80
  /*+ some internal models have needed of extra parameters +*/
81
  void        *dummy;
82
  /*+ unique number that identify the queue +*/
83
  int         uniq;
84
 
85
  /*+ events table +*/
86
  trc_event_t table[0];  
87
} circular_queue_t;
88
 
89
static int mustgodown=0;
90
 
91
static TASK online_tracer(circular_queue_t *queue)
92
{
93
  char pathname[PATH_MAX];
94
  int handle;
95
  int index;
96
 
97
  if (queue->filename==NULL) trc_create_name("cir",queue->uniq,pathname);
98
  else trc_create_name(queue->filename,0,pathname);
99
 
100
  if (wait_for_fs_initialization()) {
101
    printk(KERN_NOTICE "tracer online task not running");
102
    goto BADEND;
103
  }
104
 
105
  handle=open(pathname,O_CREAT|O_TRUNC|O_WRONLY);
106
  if (handle==-1) {
107
    printk(KERN_NOTICE "tracer file %s not created!",pathname);
108
    goto BADEND;
109
  }
110
 
111
  for (;;) {
112
    while (queue->index!=queue->windex) {
113
      index=queue->index;
114
      if (index<queue->windex) {
115
        write(handle,
116
              queue->table+queue->windex,
117
              (queue->size-queue->windex)*sizeof(trc_event_t)
118
              );
119
        queue->windex=0;
120
        continue;
121
      }
122
      write(handle,
123
            queue->table+queue->windex,
124
            (index-queue->windex)*sizeof(trc_event_t)
125
            );
126
      queue->windex=index;
127
    }
128
    if (mustgodown) break;
129
 
130
    task_endcycle();
131
  }
132
 
133
  close(handle);
134
  printk(KERN_NOTICE "tracer file %s created!",pathname);
135
 
136
  if (queue->hoops)
137
    printk(KERN_NOTICE "tracer: %li event lost into %s",queue->hoops,pathname);
138
 
139
  resume_fs_shutdown();
140
  return NULL;
141
 
142
BADEND:
143
  resume_fs_shutdown();
144
 
145
  /*Why this? for a little bug on the task_makefree() routine */
146
  for (;;) {
147
    if (mustgodown) break;
148
    task_endcycle();
149
  }
150
 
151
  return NULL;  
152
}
153
 
154
static trc_event_t *circular_get2(circular_queue_t *queue)
155
{
156
  if (queue->index==queue->size-1) {
157
    if (queue->windex==0) {
158
      queue->hoops++;
159
      return NULL;
160
    }
161
    queue->index=0;
162
    return &queue->table[queue->size-1];
163
  }  
164
  if (queue->index+1==queue->windex) {
165
    queue->hoops++;
166
    return NULL;
167
  }
168
  return &queue->table[queue->index++];
169
}
170
 
171
static trc_event_t *circular_get1(circular_queue_t *queue)
172
{
173
  if (queue->index==queue->size-1) {
174
    queue->index=0;
175
    return &queue->table[queue->size-1];
176
  }
177
  return &queue->table[queue->index++];
178
}
179
 
180
static int circular_post(circular_queue_t *queue)
181
{
182
  return 0;
183
}
184
 
185
struct create_args {
186
  long             period;
187
  long             slice;
188
  circular_queue_t *queue;
189
};
190
 
191
 
192
/* to remove!!! */
193
/*
194
static void circular_create_postponed(void *foo)
195
{
196
  struct create_args *ptr=(struct create_args *)foo;
197
  SOFT_TASK_MODEL model;
198
  PID pid;
199
 
200
  printk(KERN_DEBUG "postponed create: START");
201
 
202
  soft_task_default_model(model);
203
  soft_task_def_system(model);
204
  soft_task_def_notrace(model);
205
  soft_task_def_periodic(model);
206
  soft_task_def_period(model,ptr->period);
207
  soft_task_def_met(model,ptr->slice);
208
  soft_task_def_wcet(model,ptr->slice);
209
  soft_task_def_arg(model,ptr->queue);
210
 
211
  printk(KERN_DEBUG "postponed create: A");
212
 
213
  kern_free(foo,sizeof(struct create_args));
214
 
215
  printk(KERN_DEBUG "postponed create: B");
216
 
217
  pid=task_create("trcCirc",online_tracer,&model,NULL);
218
  if (pid==-1) {
219
    printk(KERN_ERR "can't start tracer online circular trace task");
220
  } else {
221
    printk(KERN_DEBUG "postponed create: C1");
222
    task_activate(pid);
223
    printk(KERN_DEBUG "postponed create: C2");
224
    suspend_fs_shutdown();
225
    printk(KERN_DEBUG "postponed create: C3");
226
  }
227
 
228
  printk(KERN_DEBUG "postponed create: END");
229
}
230
*/
231
 
232
static int circular_create(trc_queue_t *queue, TRC_CIRCULAR_PARMS *args)
233
{
234
  TRC_CIRCULAR_PARMS defaultargs;
235
  circular_queue_t *ptr;
236
 
237
  if (args==NULL) {
238
    trc_circular_default_parms(defaultargs);
239
    args=&defaultargs;
240
  }
241
 
242
  ptr=(circular_queue_t*)kern_alloc(sizeof(circular_queue_t)+
243
                                    sizeof(trc_event_t)*args->size);
244
  if (ptr==NULL) return -1;
245
 
246
  queue->get=(trc_event_t*(*)(void*))circular_get1;
247
  queue->post=(int(*)(void*))circular_post;
248
  queue->data=ptr;
249
 
250
  ptr->size=args->size;
251
  ptr->windex=ptr->index=0;
252
  ptr->hoops=0;
253
  ptr->filename=args->filename;
254
  ptr->flags=args->flags;
255
  ptr->dummy=NULL;
256
 
257
  if (args->flags&TRC_CIRCULAR_ONLINETASK) {
258
    struct create_args *p;
259
    p=kern_alloc(sizeof(struct create_args));
260
    if (p==NULL) {
261
      printk(KERN_ERR "can't create tracer online circular trace task");
262
      return -1;
263
    }
264
    queue->get=(trc_event_t*(*)(void*))circular_get2;
265
    ptr->dummy=p;
266
 
267
    p->period=args->period;
268
    p->slice=args->slice;
269
    p->queue=ptr;
270
    //sys_atrunlevel(circular_create_postponed,(void*)p,RUNLEVEL_INIT);    
271
  }
272
 
273
  return 0;
274
}
275
 
276
static int circular_activate(circular_queue_t *queue, int uniq)
277
{
278
  queue->uniq=uniq;
279
 
280
  if (queue->flags&TRC_CIRCULAR_ONLINETASK) {
281
 
282
    struct create_args *ptr=(struct create_args *)queue->dummy;
283
    SOFT_TASK_MODEL model;
284
    PID pid;
285
 
286
    printk(KERN_DEBUG "postponed create: START");
287
 
288
    soft_task_default_model(model);
289
    soft_task_def_system(model);
290
    soft_task_def_notrace(model);
291
    soft_task_def_periodic(model);
292
    soft_task_def_period(model,ptr->period);
293
    soft_task_def_met(model,ptr->slice);
294
    soft_task_def_wcet(model,ptr->slice);
295
    soft_task_def_arg(model,ptr->queue);
296
 
297
    printk(KERN_DEBUG "postponed create: A");
298
 
299
    kern_free(queue->dummy,sizeof(struct create_args));
300
 
301
    printk(KERN_DEBUG "postponed create: B");
302
 
303
    pid=task_create("trcCirc",online_tracer,&model,NULL);
304
    if (pid==-1) {
305
      printk(KERN_ERR "can't start tracer online circular trace task");
306
    } else {
307
      printk(KERN_DEBUG "postponed create: C1");
308
      suspend_fs_shutdown();
309
      printk(KERN_DEBUG "postponed create: C2");      
310
      task_activate(pid);
311
      printk(KERN_DEBUG "postponed create: C3");
312
    }
313
 
314
    printk(KERN_DEBUG "postponed create: END");    
315
  }
316
 
317
  return 0;
318
}
319
 
320
static TASK circular_shutdown(circular_queue_t *queue)
321
{
322
  char pathname[PATH_MAX];
323
  int h;
324
 
325
  if (queue->filename==NULL) trc_create_name("cir",queue->uniq,pathname);
326
  else trc_create_name(queue->filename,0,pathname);
327
 
328
  h=open(pathname,O_CREAT|O_TRUNC|O_WRONLY);
329
  if (h!=-1) {
330
    if (queue->index!=queue->size-1)
331
      write(h,
332
            queue->table+queue->index+1,
333
            (queue->size-queue->index-1)*sizeof(trc_event_t)
334
            );
335
    write(h,
336
          queue->table,
337
          queue->index*sizeof(trc_event_t)
338
          );
339
    close(h);
340
    printk(KERN_NOTICE "tracer file %s created!",pathname);
341
  }  else
342
    printk(KERN_NOTICE "tracer file %s NOT created!",pathname);
343
 
344
  resume_fs_shutdown();
345
  return NULL;
346
}
347
 
348
static int circular_terminate(circular_queue_t *queue)
349
{
350
  SOFT_TASK_MODEL model;
351
  PID pid;
352
 
353
  mustgodown=1;
354
  if (queue->flags&TRC_CIRCULAR_ONLINETASK) return 0;
355
 
356
  suspend_fs_shutdown();
357
 
358
  //nrt_task_default_model(model);
359
  //nrt_task_def_system(model);
360
  //nrt_task_def_arg(model,queue);
361
 
362
  soft_task_default_model(model);
363
  soft_task_def_system(model);
364
  soft_task_def_notrace(model);
365
  soft_task_def_periodic(model);
366
  soft_task_def_period(model,50000);
367
  soft_task_def_met(model,10000);
368
  soft_task_def_wcet(model,10000);
369
  soft_task_def_arg(model,queue);
370
 
371
  pid=task_create("ShutTrcCir",circular_shutdown,&model,NULL);
372
  if (pid==-1) {
373
    printk(KERN_ERR "can't start tracer shutdown task (circular)");
374
    return -1;
375
  } else
376
    task_activate(pid);
377
 
378
  return 0;
379
}
380
 
381
int trc_register_circular_queue(void)
382
{
383
  int res;
384
 
385
  res=trc_register_queuetype(TRC_CIRCULAR_QUEUE,
386
                             (int(*)(trc_queue_t*,void*))circular_create,
387
                             (int(*)(void*,int))circular_activate,
388
                             (int(*)(void*))circular_terminate
389
                             );
390
 
391
  if (res!=0) printk(KERN_WARNING "can't register tracer circular queue");
392
  return res;
393
}