Subversion Repositories shark

Rev

Go to most recent revision | 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) 1999 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: trace.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
#include <ll/string.h>
51
 
52
#include <kernel/func.h>
53
#include <kernel/trace.h>
54
 
55
#include <trace/types.h>
56
#include <trace/trace.h>
57
#include <trace/queues.h>
58
 
59
#include <bits/limits.h>
60
 
61
#define TRC_MAXQUEUES 5
62
 
63
/*
64
 *
65
 */
66
 
67
static char basepath[PATH_MAX];
68
 
69
void trc_create_name(char *basename, int uniq, char *pathname)
70
{
71
  if (uniq) sprintf(pathname,"%s/%s%i",basepath,basename,uniq);
72
  else      sprintf(pathname,"%s/%s",basepath,basename);
73
}
74
 
75
/*
76
 *
77
 */
78
 
79
#define FLAG_NOTRACE 0x01
80
 
81
typedef struct TAGtrc_evtinfo_t {
82
  trc_queue_t *queue;
83
  unsigned    flags;
84
} trc_evtinfo_t;
85
 
86
/* -- */
87
 
88
trc_evtinfo_t eventstable[TRC_NUMEVENTS];
89
 
90
int (*createqueue[TRC_QUEUETYPESNUMBER])(trc_queue_t *, void *);
91
int (*activatequeue[TRC_QUEUETYPESNUMBER])(void *,int);
92
int (*terminatequeue[TRC_QUEUETYPESNUMBER])(void *);
93
 
94
trc_queue_t queuetable[TRC_MAXQUEUES];
95
trc_queue_t queuesink;
96
int numqueues;
97
 
98
/* -- */
99
 
100
static trc_event_t *dummy_get(void *foo)
101
{  
102
  return NULL;
103
}
104
 
105
static int dummy_post(void *foo)
106
{
107
  return 0;
108
}
109
 
110
static int dummy_createqueue(trc_queue_t *queue, void *unused)
111
{
112
  queue->get=dummy_get;
113
  queue->post=dummy_post;
114
  queue->data=NULL;
115
  return 0;
116
}
117
 
118
static int dummy_terminatequeue(void *unused)
119
{
120
  return 0;
121
}
122
 
123
static int dummy_activatequeue(void *unused, int unused2)
124
{
125
  return 0;
126
}
127
 
128
/* -- */
129
 
130
int trc_register_queuetype(int queuetype,
131
                           int(*creat)(trc_queue_t *, void *),
132
                           int(*activate)(void *,int),
133
                           int(*term)(void *))
134
{
135
  if (queuetype<0||queuetype>=TRC_QUEUETYPESNUMBER) return -1;
136
  createqueue[queuetype]=creat;
137
  activatequeue[queuetype]=activate;
138
  terminatequeue[queuetype]=term;
139
  return 0;
140
}
141
 
142
int trc_create_queue(int queuetype, void *args)
143
{
144
  int res;
145
 
146
  if (createqueue[queuetype]==dummy_createqueue) return -1;
147
  if (numqueues==TRC_MAXQUEUES) return -1;
148
  res=createqueue[queuetype](&queuetable[numqueues],args);
149
  if (res) return -1;
150
  queuetable[numqueues].type=queuetype;
151
  numqueues++;
152
  return numqueues-1;
153
}
154
 
155
/* -- */
156
 
157
static void (*old_logevent)(int event, void *ptr)=NULL;
158
static void internal_trc_logevent(int, void *ptr);
159
 
160
static void trc_end(void *unused)
161
{
162
  int i;
163
 
164
  printk(KERN_INFO "tracer shutdown...");
165
 
166
  /* suspend event logging */
167
  trc_suspend();
168
 
169
  /* for safety: send all events to the sink queue */
170
  for (i=0;i<TRC_NUMEVENTS;i++) {
171
    eventstable[i].queue=&queuesink;
172
    eventstable[i].flags|=FLAG_NOTRACE;
173
  }
174
 
175
  /* terminate all queues */
176
  for (i=0;i<numqueues;i++)
177
    terminatequeue[queuetable[i].type](queuetable[i].data);
178
}
179
 
180
static int internal_trc_resume(void);
181
static int internal_trc_suspend(void);
182
 
183
int TRC_init_phase1(TRC_PARMS *parms)
184
{
185
  int i;
186
 
187
  printk(KERN_INFO "initializing tracer...");
188
 
189
  for (i=0;i<TRC_QUEUETYPESNUMBER;i++) {
190
    createqueue[i]=dummy_createqueue;
191
    terminatequeue[i]=dummy_terminatequeue;
192
  }
193
  dummy_createqueue(&queuesink,NULL);
194
  numqueues=0;
195
 
196
  for (i=0;i<TRC_NUMEVENTS;i++) {
197
    eventstable[i].queue=&queuesink;
198
    eventstable[i].flags=FLAG_NOTRACE;
199
  }
200
 
201
  i=sys_atrunlevel(trc_end,NULL,RUNLEVEL_SHUTDOWN);
202
 
203
  {
204
    TRC_PARMS m;
205
    trc_default_parms(m);
206
    if (parms==NULL) parms=&m;
207
 
208
    strncpy(basepath,parms->path,sizeof(basepath));
209
    basepath[sizeof(basepath)-1]='\0';
210
  }
211
 
212
  trc_suspend=internal_trc_suspend;
213
  trc_resume=internal_trc_resume;
214
 
215
  trc_resume();
216
  return 0;
217
}
218
 
219
int TRC_init_phase2(void)
220
{
221
  int i;
222
  for (i=0;i<numqueues;i++)
223
    activatequeue[queuetable[i].type](queuetable[i].data,i+1);
224
  return 0;
225
}
226
 
227
static int internal_trc_resume(void)
228
{
229
  SYS_FLAGS f;
230
  int ret=-1;
231
  f=kern_fsave();
232
  if (old_logevent==NULL) {  
233
    old_logevent=trc_logevent;
234
    trc_logevent=internal_trc_logevent;
235
    ret=0;
236
  }
237
  kern_frestore(f);
238
  return ret;
239
}
240
 
241
static int internal_trc_suspend(void)
242
{
243
  SYS_FLAGS f;
244
  int ret=-1;
245
  f=kern_fsave();
246
  if (old_logevent!=NULL) {    
247
    trc_logevent=old_logevent;
248
    old_logevent=NULL;
249
    ret=0;
250
  }
251
  kern_frestore(f);
252
  return 0;
253
}
254
 
255
static void internal_trc_logevent(int event, void *ptr)
256
{
257
  trc_event_t   *evt;
258
  trc_queue_t   *queue;
259
  SYS_FLAGS f;
260
 
261
  f=kern_fsave();
262
 
263
  if (eventstable[event].flags&FLAG_NOTRACE) {
264
    kern_frestore(f);
265
    return;
266
  }
267
  queue=eventstable[event].queue;
268
 
269
  evt=queue->get(queue->data);
270
  if (evt!=NULL) {
271
    evt->event=event;
272
    evt->time=ll_gettime(TIME_EXACT,NULL);
273
    memcpy(&evt->x,ptr,sizeof(trc_allevents_t));
274
    queue->post(queue->data);
275
  }
276
 
277
  kern_frestore(f);
278
}
279
 
280
/*
281
 *
282
 *
283
 *
284
 */
285
 
286
int classtable[TRC_NUMCLASSES+1]={
287
  TRC_F_TRACER,
288
  TRC_F_SYSTEM,
289
  TRC_F_USER,
290
  TRC_F_LL,
291
  TRC_F_SEM,
292
  TRC_F_LAST
293
};
294
 
295
#define checkevent(x)   if ((x)<0||(x)>=TRC_NUMEVENTS) return -1
296
#define checkqueue(x)   if ((x)<0||(x)>=numqueues) return -1
297
#define checkclass(x)   if ((x)<0||(x)>=TRC_NUMCLASSES) return -1
298
 
299
int trc_assign_event_to_queue(int event, int queue)
300
{
301
  checkevent(event);
302
  checkqueue(queue);
303
  eventstable[event].queue=&queuetable[queue];
304
  return 0;
305
}
306
 
307
int trc_assign_class_to_queue(int class, int queue)
308
{
309
  int i;
310
  checkqueue(queue);
311
  checkclass(class);
312
  for (i=classtable[class];i<classtable[class+1];i++)
313
    eventstable[i].queue=&queuetable[queue];
314
  return 0;
315
}
316
 
317
int trc_notrace_event(int event)
318
{
319
  checkevent(event);
320
  eventstable[event].flags|=FLAG_NOTRACE;
321
  return 0;
322
}
323
 
324
int trc_trace_event(int event)
325
{
326
  checkevent(event);
327
  eventstable[event].flags&=~FLAG_NOTRACE;
328
  return 0;
329
}
330
 
331
int trc_notrace_class(int class)
332
{
333
  int i;
334
  checkclass(class);
335
  for (i=classtable[class];i<classtable[class+1];i++)
336
    eventstable[i].flags|=FLAG_NOTRACE;
337
  return 0;
338
}
339
 
340
int trc_trace_class(int class)
341
{
342
  int i;
343
  checkclass(class);
344
  for (i=classtable[class];i<classtable[class+1];i++)
345
    eventstable[i].flags&=~FLAG_NOTRACE;
346
  return 0;
347
}
348
 
349
 
350
/* -- */
351
 
352
int TRC_init_phase1_standard(void)
353
{
354
  int qf,qc;
355
  int res;
356
 
357
  res=TRC_init_phase1(NULL);
358
  if (res) return res;
359
 
360
  res=trc_register_circular_queue();
361
  if (res) return res;
362
  res=trc_register_fixed_queue();
363
  if (res) return res;
364
 
365
  qc=trc_create_queue(TRC_CIRCULAR_QUEUE,NULL);
366
  qf=trc_create_queue(TRC_FIXED_QUEUE,NULL);
367
  if (qc==-1||qf==-1) return -97;
368
 
369
  res=trc_trace_class(TRC_CLASS_SYSTEM);
370
  if (res) return res;
371
  res=trc_assign_class_to_queue(TRC_CLASS_SYSTEM,qc);
372
  if (res) return res;
373
 
374
  return 0;
375
}
376
 
377
int TRC_init_phase2_standard(void)
378
{
379
  return TRC_init_phase2();
380
}
381
 
382