Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 351 → Rev 352

/shark/trunk/tracer/include/qudp.h
0,0 → 1,50
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#ifndef __TRACE_QUDP_H
#define __TRACE_QUDP_H
 
#include <kernel/model.h>
#include <drivers/udpip.h>
#include "ll/sys/cdefs.h"
 
__BEGIN_DECLS
 
typedef struct TAGtrc_udp_queue_args_t {
int size;
UDP_ADDR local,remote;
TASK_MODEL *model;
} TRC_UDP_PARMS;
 
#define trc_udp_default_parms(m,l,r) (m).size=8192, \
(m).model = NULL, \
(m).local = (l), \
(m).remote = (r);
#define trc_udp_def_size(m,s) (m).size=(s)
#define trc_udp_def_local(m,l) (m).local=(l)
#define trc_udp_def_remote(m,r) (m).remote=(r)
#define trc_udp_def_model(m,mod) (m).model=(mod)
 
 
int trc_register_udp_queue(void);
 
__END_DECLS
#endif
/shark/trunk/tracer/include/qdummy.h
0,0 → 1,31
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#ifndef __TRACE_QDUMMY_H
#define __TRACE_QDUMMY_H
 
#include "ll/sys/cdefs.h"
 
__BEGIN_DECLS
 
int trc_register_dummy_queue(void);
 
__END_DECLS
#endif
/shark/trunk/tracer/include/trace.h
0,0 → 1,81
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 1999 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: trace.h,v 1.1 2003-12-10 16:48:47 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1 $
* Last update: $Date: 2003-12-10 16:48:47 $
*/
 
#ifndef __TRACE_TRACE_H
#define __TRACE_TRACE_H
 
#include "ll/sys/cdefs.h"
 
__BEGIN_DECLS
 
typedef struct trc_parms {
char *path;
} TRC_PARMS;
 
#define trc_default_parms(m) (m).path="/temp"
#define trc_def_path(m,s) (m).path=(s)
 
int TRC_init_phase1(TRC_PARMS *p);
int TRC_init_phase2(void);
 
int trc_assign_event_to_queue(int event, int queue);
int trc_assign_class_to_queue(int class, int queue);
 
int trc_notrace_event(int event);
int trc_trace_event(int event);
int trc_notrace_class(int class);
int trc_trace_class(int class);
 
/* -- */
 
/* Register a "standard" tracer configuration; requires FAT16 filesystem
(see documentation) */
int TRC_init_phase1_standard(void);
int TRC_init_phase2_standard(void);
 
__END_DECLS
#endif
/shark/trunk/tracer/include/tracer.h
0,0 → 1,159
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Giacomo Guidi <giacomo@gandalf.sssup.it>
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#ifndef __TRACER_H__
#define __TRACER_H__
 
#ifdef __OLD_TRACER__
 
#include <ll/sys/types.h>
#include "types.h"
#include "trace.h"
 
#define TRACER_LOGEVENT oldtrace
 
extern int (*trc_register_eventclass)
(int class,int num,int(*func)(trc_event_t *, int event, void *ptr));
 
extern void (*trc_logevent)(int event, void *ptr);
 
extern int (*trc_resume)(void);
extern int (*trc_suspend)(void);
 
#define NOT_DEFINED 0xFF
 
extern __inline__ void oldtrace(BYTE type, BYTE flag, DWORD par1, DWORD par2)
{
 
static int oldtype;
static int oldpar;
extern BYTE conv[256]; // Conversion table: ctable.c
BYTE ttype = 0;
ttype = type & 0x0F;
type = type >> 4;
type |= (ttype << 4);
 
oldtype = conv[type];
 
if (oldtype != NOT_DEFINED) trc_logevent(oldtype,&oldpar);
 
}
 
 
#else
#ifdef __NEW_TRACER__
 
#include <ll/sys/types.h>
#include <ll/i386/hw-instr.h>
#include "FTrace.h"
 
#define TRACER_LOGEVENT fast_logevent
 
#define TRACER_SERIALIZE
 
/* Save bytes => 1(type) + 4(tsc_high) + 4(tsc_low) + 1(size)
if (flag & 1) + 4(par1)
if (flag & 3) + 4(par2)
* Return 0 -> Success
* Return 1 -> Inactive
* Return 2 -> Error
*/
extern __inline__ int fast_logevent(BYTE type, BYTE flag, DWORD par1, DWORD par2)
{
 
extern void *StartTracerBuffer;
extern void *EndTracerBuffer;
extern void *CurrentTracerBuffer;
extern int TracerActive;
extern unsigned long long TracerEventsRecorded;
 
SYS_FLAGS f;
 
DWORD tsc_low, tsc_high;
BYTE size = 10;
 
f = ll_fsave();
 
if (!TracerActive) {
ll_frestore(f);
return 1;
}
 
#ifdef TRACER_SERIALIZE
__asm__("xorl %%eax,%%eax\n\t"
"cpuid\n\t"
"rdtsc\n\t"
:"=a" (tsc_low), "=d" (tsc_high)
:
:"ebx","ecx");
#else
__asm__("rdtsc\n\t"
:"=a" (tsc_low), "=d" (tsc_high)
::);
#endif
 
if (flag & 1) size += 4;
if (flag & 3) size += 4;
 
if ((CurrentTracerBuffer + size - 1) > EndTracerBuffer) {
int i;
//Clear remain memory
for (i=0;i<(EndTracerBuffer-CurrentTracerBuffer+1);i++)
*(BYTE *)(CurrentTracerBuffer + i) = 0;
//Cyclical Buffer implementation
CurrentTracerBuffer = StartTracerBuffer;
}
 
*(BYTE *)CurrentTracerBuffer = type;
CurrentTracerBuffer++;
*(DWORD *)(CurrentTracerBuffer) = tsc_high;
CurrentTracerBuffer+=4;
*(DWORD *)(CurrentTracerBuffer) = tsc_low;
CurrentTracerBuffer+=4;
*(BYTE *)(CurrentTracerBuffer) = size;
CurrentTracerBuffer++;
if (flag & 1) {
*(DWORD *)(CurrentTracerBuffer) = par1;
CurrentTracerBuffer+=4;
}
if (flag & 3) {
*(DWORD *)(CurrentTracerBuffer) = par2;
CurrentTracerBuffer+=4;
}
if (CurrentTracerBuffer > EndTracerBuffer) {
ll_frestore(f);
return 2;
}
 
TracerEventsRecorded++;
 
ll_frestore(f);
return 0;
 
}
 
#else
 
#define TRACER_LOGEVENT(a,b,c,d)
 
#endif
 
#endif
 
#endif
/shark/trunk/tracer/include/qfixed.h
0,0 → 1,47
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#ifndef __TRACE_QFIXED_H
#define __TRACE_QFIXED_H
 
#include "ll/sys/cdefs.h"
 
__BEGIN_DECLS
 
typedef struct TAGtrc_fixed_queue_args_t {
char *filename;
int size;
} TRC_FIXED_PARMS;
 
#define trc_fixed_default_parms(m) (m).filename=NULL,\
(m).size=8192
#define trc_fixed_def_filename(m,s) (m).filename=(s)
#define trc_fixed_def_size(m,s) (m).size=(s)
 
/* Fixed queue, FAT16 filesystem (see kernel/modules/trcfixed.c) */
int trc_register_fixed_queue(void);
 
/* Fixed queue, DOSFS filesystem (see kernel/modules/trcdfix.c)
Note: You MUST specify a valid filename... */
int trc_register_dosfs_fixed_queue(void);
 
__END_DECLS
#endif
 
/shark/trunk/tracer/include/qcirc.h
0,0 → 1,55
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#ifndef __TRACE_QCIRC_H
#define __TRACE_QCIRC_H
 
#include "ll/sys/cdefs.h"
 
__BEGIN_DECLS
 
typedef struct TAGtrc_circular_queue_args_t {
char *filename;
int size;
 
long period;
long slice;
int flags;
} TRC_CIRCULAR_PARMS;
 
#define TRC_CIRCULAR_ONLINETASK 0x0001
 
#define trc_circular_default_parms(m) (m).filename=NULL,\
(m).size=8192,\
(m).period=500000,\
(m).slice=25000,\
(m).flags=0
#define trc_circular_def_filename(m,s) (m).filename=(s)
#define trc_circular_def_size(m,s) (m).size=(s)
#define trc_circular_def_onlinetask(m) (m).flags|=TRC_CIRCULAR_ONLINETASK
#define trc_circular_def_period(m,p) (m).period=p
#define trc_circular_def_slice(m,s) (m).slice=s
int trc_register_circular_queue(void);
 
__END_DECLS
#endif
/shark/trunk/tracer/include/FTrace.h
0,0 → 1,117
/*
 
Events List File, from York University and F.I.R.S.T project
 
*/
 
 
#ifndef __FTrace__
#define __FTrace__
 
 
// List of events, these are 8 bit constants, the
// the low 4 bits, indicates its class,
// the high 4 bits indicate the type of event in the class.
// (This allows an easy mechanisms for filtering events)
 
// general trace events
#define FTrace_EVT_ticks_per_sec 0x00
#define FTrace_EVT_cycles_per_tick 0x10
#define FTrace_EVT_trace_start 0x20
#define FTrace_EVT_trace_stop 0x30
#define FTrace_EVT_blackout_start 0x40
#define FTrace_EVT_blackout_end 0x50
#define FTrace_EVT_id 0x60 //??
#define FTrace_EVT_numeevents 0x70
 
// lightweight tracing events
#define FTrace_EVT_ipoint 0x01
 
// Task related events
#define FTrace_EVT_task_create 0x02
#define FTrace_EVT_task_activate 0x12
#define FTrace_EVT_task_dispatch 0x22
#define FTrace_EVT_task_epilogue 0x32
#define FTrace_EVT_task_end 0x42
#define FTrace_EVT_task_begin_cycle 0x52
#define FTrace_EVT_task_end_cycle 0x62
#define FTrace_EVT_task_sleep 0x72
#define FTrace_EVT_task_schedule 0x82
 
// interrupt events, even more lightweight than ipoints
#define FTrace_EVT_interrupt_start 0x03
#define FTrace_EVT_interrupt_end 0x13
#define FTrace_EVT_interrupt_hit 0x23 // instant where interrupt was hit (no end)
#define FTrace_EVT_interrupt_count 0x33 // number of interrupts raised since last interrupt_count
 
// other CPU specific events
#define FTrace_EVT_to_real_mode 0x04
#define FTrace_EVT_to_protected_mode 0x14
#define FTrace_EVT_CLI 0x24
#define FTrace_EVT_STI 0x34
 
// Changes on task attributes and state
#define FTrace_EVT_set_priority 0x05
#define FTrace_EVT_context_switch 0x15
// mutex events
#define FTrace_EVT_set_mutex_create 0x06
#define FTrace_EVT_set_mutex_lock 0x16
#define FTrace_EVT_set_mutex_inherit 0x26
#define FTrace_EVT_set_mutex_unlock 0x36
 
// signal events
#define FTrace_EVT_signal 0x07
// more here (MarteOS)
 
// specific server events
#define FTrace_EVT_server_create 0x08
#define FTrace_EVT_server_replenish 0x18
#define FTrace_EVT_server_exhaust 0x28
 
// user defined events
#define FTrace_EVT_user_event_0 0x09
#define FTrace_EVT_user_event_1 0x19
#define FTrace_EVT_user_event_2 0x29
#define FTrace_EVT_user_event_3 0x39
#define FTrace_EVT_user_event_4 0x49
#define FTrace_EVT_user_event_5 0x59
#define FTrace_EVT_user_event_6 0x69
#define FTrace_EVT_user_event_7 0x79
#define FTrace_EVT_user_event_8 0x89
#define FTrace_EVT_user_event_9 0x99
#define FTrace_EVT_user_event_10 0xA9
#define FTrace_EVT_user_event_11 0xB9
#define FTrace_EVT_user_event_12 0xC9
#define FTrace_EVT_user_event_13 0xD9
#define FTrace_EVT_user_event_14 0xE9
#define FTrace_EVT_user_event_15 0xF9
 
// Timer Events
#define FTrace_EVT_timer_post 0x0B
#define FTrace_EVT_timer_delete 0x1B
#define FTrace_EVT_timer_wakeup_start 0x2B
#define FTrace_EVT_timer_wakeup_end 0x3B
 
// generic data events
#define FTrace_EVT_data_pointer 0x1A // holds a pointer of data from
// previous event
 
// types of the data pointer
#define FTrace_DATA_int 1
#define FTrace_DATA_char 2
 
// filter definitions
#define FTrace_filter_trace_Events 0xF0
#define FTrace_filter_ipoint 0xF1
#define FTrace_filter_task 0xF2
#define FTrace_filter_interrupt 0xF3
#define FTrace_filter_CPU 0xF4
#define FTrace_filter_priority 0xF5
#define FTrace_filter_mutex 0xF6
#define FTrace_filter_signal 0xF7
#define FTrace_filter_server 0xF8
#define FTrace_filter_user 0xF9
#define FTrace_filter_data 0xFA
#define FTrace_filter_timer 0xFB
 
#endif
/shark/trunk/tracer/include/types.h
0,0 → 1,155
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 1999 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: types.h,v 1.1 2003-12-10 16:48:47 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1 $
* Last update: $Date: 2003-12-10 16:48:47 $
*/
 
#ifndef __TRACE_TYPES_H
#define __TRACE_TYPES_H
 
/*
* EVENTS
*/
 
/* tracer class */
#define TRC_RESERVED 0x00
#define TRC_HOOPS 0x01
 
/* system class */
#define TRC_CREATE 0x02
#define TRC_ACTIVATE 0x03
#define TRC_SCHEDULE 0x04
#define TRC_DELAY 0x05
#define TRC_SLEEP 0x06
#define TRC_ENDCYCLE 0x07
#define TRC_DESTROY 0x08
#define TRC_INTACTIVATION 0x09
#define TRC_DISABLE 0x0a
 
/* user class */
#define TRC_USER0 0x0b
#define TRC_USER1 0x0c
#define TRC_USER2 0x0d
#define TRC_USER3 0x0e
#define TRC_USER4 0x0f
#define TRC_USER5 0x10
#define TRC_USER6 0x11
#define TRC_USER7 0x12
 
/* low level class */
#define TRC_INTR 0x13
 
/* semaphore class */
#define TRC_SEM_WAIT 0x14
#define TRC_SEM_WAITNB 0x15
#define TRC_SEM_SIGNAL 0x16
 
/* used internal by the tracer (the first event of a class) */
#define TRC_F_TRACER TRC_RESERVED
#define TRC_F_SYSTEM TRC_CREATE
#define TRC_F_USER TRC_USER0
#define TRC_F_LL TRC_INTR
#define TRC_F_SEM TRC_SEM_WAIT
#define TRC_F_LAST (TRC_SEM_SIGNAL+1)
 
/* classes */
#define TRC_CLASS_TRACER 0
#define TRC_CLASS_SYSTEM 1
#define TRC_CLASS_USER 2
#define TRC_CLASS_LL 3
#define TRC_CLASS_SEM 4
 
/* max values */
#define TRC_NUMCLASSES 5
#define TRC_NUMEVENTS TRC_F_LAST
 
/*
* STRUCTURES
*/
 
/* tracer class */
typedef struct TAGtrc_tracer_event_t {
u_int32_t n;
} trc_tracer_event_t __attribute__ ((packed));
 
/* system class */
typedef struct TAGtrc_system_event_t {
u_int16_t task;
} trc_system_event_t __attribute__ ((packed));
 
/* user class */
typedef struct TAGtrc_user_event_t {
#define TRC_MAXUSERINFO sizeof(long)
long n;
} trc_user_event_t __attribute__ ((packed));
 
/* low level class */
typedef struct TAGtrc_ll_event_t {
int n;
} trc_ll_event_t __attribute__ ((packed));
 
/* semaphore class */
typedef struct TAGtrc_sem_event_t {
u_int16_t task;
u_int16_t id;
} trc_sem_event_t __attribute__ ((packed));
 
/* generics event */
typedef union TAGtrc_allevents {
trc_tracer_event_t trc;
trc_system_event_t sys;
trc_user_event_t usr;
trc_ll_event_t ll;
trc_sem_event_t sem;
} trc_allevents_t __attribute__ ((packed));;
 
/* event struct */
typedef struct TAGtrc_event_t {
u_int32_t time;
u_int16_t event;
trc_allevents_t x;
} trc_event_t __attribute__ ((packed));
 
 
#endif
/shark/trunk/tracer/include/queues.h
0,0 → 1,92
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 1999 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: queues.h,v 1.1 2003-12-10 16:48:46 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1 $
* Last update: $Date: 2003-12-10 16:48:46 $
*/
 
#ifndef __TRACE_QUEUES_H
#define __TRACE_QUEUES_H
 
#include <ll/sys/types.h>
#include "types.h"
#include "ll/sys/cdefs.h"
 
__BEGIN_DECLS
 
typedef struct TAGtrc_queue_t {
int type;
trc_event_t *(*get)(void *);
int (*post)(void *);
void *data;
} trc_queue_t;
 
#define TRC_DUMMY_QUEUE 0
#include <qdummy.h>
 
#define TRC_FIXED_QUEUE 1
#define TRC_DOSFS_FIXED_QUEUE 2
#include <qfixed.h>
 
#define TRC_CIRCULAR_QUEUE 3
#include <qcirc.h>
 
#define TRC_UDP_QUEUE 4
#include <qudp.h>
 
#define TRC_QUEUETYPESNUMBER 5
 
/* uniq!=0 append a this unique number to name */
void trc_create_name(char *basename, int uniq, char *pathname);
 
/*--*/
 
int trc_register_queuetype(int queuetype,
int(*create)(trc_queue_t *,void *),
int(*activate)(void *,int),
int(*terminate)(void *));
 
int trc_create_queue(int queuetype, void *arg);
 
__END_DECLS
#endif
/shark/trunk/tracer/newtrace/tracer.c
0,0 → 1,130
#include <stdlib.h>
#include <tracer.h>
 
void *StartTracerBuffer;
void *EndTracerBuffer;
void *CurrentTracerBuffer;
int TracerActive = 0;
unsigned long long TracerEventsRecorded;
extern unsigned int clk_per_msec;
 
/* Initialize the tracer
*
* Return 0 => Success
* Return 1 => Fail
*/
int tracer_initialize(int OutputType, int MemorySize)
{
 
SYS_FLAGS f;
 
f = ll_fsave();
 
StartTracerBuffer = malloc(MemorySize);
if (!StartTracerBuffer) {
ll_frestore(f);
return 1;
}
 
EndTracerBuffer = StartTracerBuffer + MemorySize - 1;
CurrentTracerBuffer = StartTracerBuffer;
 
TracerActive = 0;
TracerEventsRecorded = 0;
 
ll_frestore(f);
return 0;
 
}
 
void tracer_enable() {
SYS_FLAGS f;
 
f = ll_fsave();
 
TracerActive = 1;
 
ll_frestore(f);
 
}
 
void tracer_disable() {
SYS_FLAGS f;
f = ll_fsave();
TracerActive = 0;
ll_frestore(f);
}
 
void tracer_print_statistics() {
 
SYS_FLAGS f;
void *p;
int i,t,ctx,pid,ctx_current;
unsigned long long ck,delta;
unsigned long long last_clk;
struct exec_proc {
int ctx;
unsigned long long total_clk;
unsigned long long start_clk;
};
 
struct exec_proc *ec;
 
f = ll_fsave();
 
cprintf("Total Events %d\n",(int)TracerEventsRecorded);
 
for (i=0; i<0xFF; i++) {
p = StartTracerBuffer;
t = 0;
while(p < CurrentTracerBuffer) {
if (*(BYTE *)p == i) t++;
p += *(BYTE *)(p + 9);
}
if (t != 0)
cprintf("Event type %02x => %d\n",i,t);
}
 
ec = malloc(sizeof(struct exec_proc) * MAX_PROC);
ctx_current = 0;
last_clk = 0;
 
cprintf("Context Switch Analisys\n");
p = StartTracerBuffer;
while(p < CurrentTracerBuffer) {
pid = *(int *)(p + 10);
ctx = *(int *)(p + 14);
ck = (unsigned long long)(*(unsigned int *)(p + 1)) << 32;
ck |= *(unsigned int *)(p + 5);
if (*(BYTE *)p == FTrace_EVT_task_create) {
cprintf("Task Create %d %d\n",pid,ctx);
ec[pid].ctx = ctx;
ec[pid].total_clk = 0;
ec[pid].start_clk = ck;
}
if (*(BYTE *)p == FTrace_EVT_context_switch ||
*(BYTE *)p == FTrace_EVT_timer_wakeup_end) {
ctx = *(int *)(p + 10);
if (ctx_current == 0) {
ctx_current = ctx;
last_clk = ck;
} else {
delta = ck - last_clk;
cprintf("Delta Ctx %d = %d us\n",ctx_current,(int)(delta * 1000000 / clk_per_msec / 1000));
last_clk = ck;
ctx_current = ctx;
}
}
p += *(BYTE *)(p + 9);
}
 
ll_frestore(f);
 
}
/shark/trunk/tracer/oldtrace/trcudp.c
0,0 → 1,261
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2002 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* CVS : $Id: trcudp.c,v 1.1 2003-12-10 16:48:48 giacomo Exp $
*/
 
#include <ll/sys/types.h>
#include <ll/stdlib.h>
 
#include <kernel/func.h>
#include <kernel/mem.h>
#include <kernel/log.h>
 
#include <types.h>
#include <trace.h>
#include <queues.h>
 
//#define DEBUG_TRCUDP
 
#define TRCUDP_MAXEVENTS (1500/sizeof(trc_event_t))
//#define TRCUDP_MAXEVENTS 10
 
/* Well... this file is very similar to trccirc.c! */
 
typedef struct TAGtrcudp_queue_t {
/*+ size of the queue +*/
int size;
/*+ index of the next insertion into the queue +*/
int index;
/*+ index of the next item to write (if online_tracer activated) +*/
int windex;
/*+ number of events lost (if online_tracer activated) +*/
long hoops;
/*+ local and remote IP numbers +*/
UDP_ADDR local, remote;
/*+ unique number that identify the queue +*/
int uniq;
/*+ =1 when the system shuts down +*/
int mustgodown;
TASK_MODEL *m;
/*+ dummy, needed for creating a valid packet (dirty trick ;-) +*/
short int dummy;
/*+ events table +*/
trc_event_t table[0];
} trcudp_queue_t;
 
static TASK online_tracer(trcudp_queue_t *queue)
{
int s; /* the socket */
int newwindex; /* new write index after sending the packet */
int n; /* number of packets to send */
short int *pkt;
 
 
s = udp_bind(&queue->local, NULL);
for (;;) {
if (queue->index<queue->windex) {
if (queue->windex+TRCUDP_MAXEVENTS < queue->size) {
newwindex = queue->windex+TRCUDP_MAXEVENTS;
n = TRCUDP_MAXEVENTS;
} else {
newwindex = 0;
n = queue->size-queue->windex;
}
} else {
if (queue->windex+TRCUDP_MAXEVENTS < queue->index) {
newwindex = queue->windex+TRCUDP_MAXEVENTS;
n = TRCUDP_MAXEVENTS;
} else {
newwindex = queue->index;
n = queue->index-queue->windex;
}
}
if (n) {
/* set the number of events into the UDP packet. It works
because the event entry before windex is always empty, or
because we use the dummy field into the struct */
pkt = ((short int *)(queue->table+queue->windex))-1;
*pkt = (short int)n;
udp_sendto(s,(char *)pkt,
n*sizeof(trc_event_t)+2,&queue->remote);
#ifdef DEBUG_TRCUDP
printk(KERN_DEBUG "UDP: SEND %d events,"
" index %d windex %d new %d!!!\n",n,
queue->index, queue->windex, newwindex);
#endif
queue->windex = newwindex;
}
if (queue->mustgodown) {
if (queue->windex == queue->index)
break;
}
else
task_endcycle();
}
 
return NULL;
}
 
 
static trc_event_t *trcudp_get(trcudp_queue_t *queue)
{
if (queue->mustgodown)
return NULL;
 
if (queue->index==queue->size-1) {
if (queue->windex==0) {
queue->hoops++;
return NULL;
}
queue->index=0;
return &queue->table[queue->size-1];
}
if (queue->index+1==queue->windex) {
queue->hoops++;
return NULL;
}
return &queue->table[queue->index++];
}
 
static int trcudp_post(trcudp_queue_t *queue)
{
return 0;
}
 
static void trcudp_shutdown(trcudp_queue_t *queue);
 
static int trcudp_create(trc_queue_t *p, TRC_UDP_PARMS *args)
{
trcudp_queue_t *queue;
 
if (args==NULL) {
printk(KERN_ERR "trcudp_create: you must specify a non-NULL parameter!");
return -1;
}
queue=(trcudp_queue_t*)kern_alloc(sizeof(trcudp_queue_t)+
sizeof(trc_event_t)*args->size);
if (queue==NULL) {
printk(KERN_ERR "trcudp_create: error during memory allocation!");
return -1;
}
 
p->get=(trc_event_t*(*)(void*))trcudp_get;
p->post=(int(*)(void*))trcudp_post;
p->data=queue;
queue->size=args->size;
queue->windex=queue->index=0;
queue->hoops=0;
queue->local=args->local;
queue->remote=args->remote;
/* uniq initialized in trcudp_activate */
queue->mustgodown=0;
queue->m = args->model;
/* dummy unused */
/* AFTER exit because in that way we can hope to be back in text mode... */
sys_atrunlevel((void (*)(void *))trcudp_shutdown, (void *)queue, RUNLEVEL_AFTER_EXIT);
return 0;
}
 
static int trcudp_activate(trcudp_queue_t *queue, int uniq)
{
SOFT_TASK_MODEL model;
TASK_MODEL *m;
PID pid;
 
 
queue->uniq=uniq;
 
if (!queue->m) {
soft_task_default_model(model);
soft_task_def_system(model);
/* soft_task_def_notrace(model); Should we trace the tracer? */
soft_task_def_periodic(model);
soft_task_def_period(model,250000);
soft_task_def_met(model,10000);
soft_task_def_wcet(model,10000);
/* soft_task_def_nokill(model); NOOOOOOO!!!! */
soft_task_def_arg(model,queue);
m = (TASK_MODEL *)&model;
}
else {
m = queue->m;
task_def_arg(*m,queue);
}
 
pid=task_create("trcUDP",online_tracer,m,NULL);
if (pid==-1) {
printk(KERN_ERR "can't start tracer online trcudp trace task");
} else
task_activate(pid);
 
return 0;
}
 
static int trcudp_terminate(trcudp_queue_t *queue)
{
queue->mustgodown = 1;
 
return 0;
}
 
static void trcudp_shutdown(trcudp_queue_t *queue)
{
printk(KERN_NOTICE "tracer: %li events lost into UDP queue %d",
queue->hoops, queue->uniq);
}
 
int trc_register_udp_queue(void)
{
int res;
res=trc_register_queuetype(TRC_UDP_QUEUE,
(int(*)(trc_queue_t*,void*))trcudp_create,
(int(*)(void*,int))trcudp_activate,
(int(*)(void*))trcudp_terminate
);
if (res!=0) printk(KERN_WARNING "can't register tracer trcudp queue");
return res;
}
/shark/trunk/tracer/oldtrace/trcdfix.c
0,0 → 1,152
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#include <ll/sys/types.h>
#include <ll/stdlib.h>
 
#include <kernel/func.h>
#include <kernel/mem.h>
#include <kernel/log.h>
 
#include <types.h>
#include <trace.h>
#include <queues.h>
 
#include <ll/i386/x-dos.h>
 
/* this file implement a fixed queue, that is simply an array that
is filled with the events until it is full. After that, all the other
events are discarded. It uses the DOSFS Filesystem to write all the data
 
This file is derived from the trcfixed.c file; I used a different file
because including trcfixed.c in the executable would have implied the
linking of all the filesystem...
*/
 
 
 
 
typedef struct TAGfixed_queue_t {
int size;
int index;
char *filename;
int uniq;
trc_event_t table[0];
/* Yes, 0!... the elements are allocated
in a dirty way into the kern_alloc into fixed_create */
} dosfs_fixed_queue_t;
 
/* This function simply return an event to fill (only if the fixed table
is not yet full) */
static trc_event_t *dosfs_fixed_get(dosfs_fixed_queue_t *queue)
{
if (queue->index>=queue->size) return NULL;
return &queue->table[queue->index++];
}
 
/* since get returns the correct event address,
the post function does nothing... */
static int dosfs_fixed_post(dosfs_fixed_queue_t *queue)
{
return 0;
}
 
static TRC_FIXED_PARMS defaultargs;
static int once=0;
 
static void dosfs_fixed_flush(void *arg);
 
static int dosfs_fixed_create(trc_queue_t *queue, TRC_FIXED_PARMS *args)
{
dosfs_fixed_queue_t *ptr;
 
/* initialize the default arguments for the fixed queue */
if (!once) {
/* well... this func is called when the system is not running! */
once=1;
trc_fixed_default_parms(defaultargs);
}
if (args==NULL) args=&defaultargs;
/* allocate the fixed queue data structure plus the array of events */
ptr=(dosfs_fixed_queue_t*)kern_alloc(sizeof(dosfs_fixed_queue_t)+
sizeof(trc_event_t)*(args->size+1));
if (ptr==NULL) return -1;
 
/* set the current queue pointers and data */
queue->get=(trc_event_t*(*)(void*))dosfs_fixed_get;
queue->post=(int(*)(void*))dosfs_fixed_post;
queue->data=ptr;
 
ptr->size=args->size;
ptr->index=0;
ptr->filename=args->filename;
 
/* prepare for shutdown ;-) */
sys_atrunlevel(dosfs_fixed_flush, (void *)ptr, RUNLEVEL_AFTER_EXIT);
 
return 0;
}
 
static void dosfs_fixed_flush(void *arg)
{
DOS_FILE *f;
dosfs_fixed_queue_t *queue = (dosfs_fixed_queue_t *)arg;
char pathname[100]; /* it should be PATH_MAX, but we do not use the
filesystem, so the symbol is not defined */
 
if (queue->filename==NULL) trc_create_name("fix",queue->uniq,pathname);
else trc_create_name(queue->filename,0,pathname);
 
printk(KERN_DEBUG "tracer flush index= %d pathname=%s\n",
queue->index, pathname);
 
f = DOS_fopen(pathname,"w");
 
DOS_fwrite(queue->table,1,queue->index*sizeof(trc_event_t),f);
 
DOS_fclose(f);
 
}
 
static int dosfs_fixed_activate(dosfs_fixed_queue_t *queue, int uniq)
{
queue->uniq=uniq;
return 0;
}
 
static int dosfs_fixed_terminate(dosfs_fixed_queue_t *queue)
{
return 0;
}
 
int trc_register_dosfs_fixed_queue(void)
{
int res;
res=trc_register_queuetype(TRC_DOSFS_FIXED_QUEUE,
(int(*)(trc_queue_t*,void*))dosfs_fixed_create,
(int(*)(void*,int))dosfs_fixed_activate,
(int(*)(void*))dosfs_fixed_terminate
);
if (res!=0) printk(KERN_WARNING "can't register tracer DOSFS fixed queue");
return res;
}
/shark/trunk/tracer/oldtrace/trcdummy.c
0,0 → 1,66
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#include <ll/sys/types.h>
#include <ll/stdlib.h>
 
#include <kernel/log.h>
 
#include <types.h>
#include <trace.h>
#include <queues.h>
 
static trc_event_t *dummy_queue_get(void *unused)
{
static trc_event_t event;
return &event;
}
 
static int dummy_queue_post(void *unused)
{
return 0;
}
 
static int create_dummy_queue(trc_queue_t *queue, void *unused)
{
queue->get=dummy_queue_get;
queue->post=dummy_queue_post;
queue->data=NULL;
return 0;
}
 
static int terminate_dummy_queue(void *unused)
{
return 0;
}
 
static int activate_dummy_queue(void *unused, int unused2)
{
return 0;
}
 
int trc_register_dummy_queue(void)
{
int res;
res=trc_register_queuetype(TRC_DUMMY_QUEUE,
create_dummy_queue,
activate_dummy_queue,
terminate_dummy_queue);
if (res!=0) printk(KERN_WARNING "can't register tracer dummy queue");
return res;
}
/shark/trunk/tracer/oldtrace/trcfixed.c
0,0 → 1,171
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
#include <ll/sys/types.h>
#include <ll/stdlib.h>
 
#include <kernel/func.h>
#include <kernel/mem.h>
#include <kernel/log.h>
 
#include <types.h>
#include <trace.h>
#include <queues.h>
 
#include <fs/fs.h>
 
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
 
/* this file implement a fixed queue, that is simply an array that
is filled with the events until it is full. After that, all the other
events are discarded. */
 
 
 
 
typedef struct TAGfixed_queue_t {
int size;
int index;
char *filename;
int uniq;
trc_event_t table[0];
/* Yes, 0!... the elements are allocated
in a dirty way into the kern_alloc into fixed_create */
} fixed_queue_t;
 
/* This function simply return an event to fill (only if the fixed table
is not yet full) */
static trc_event_t *fixed_get(fixed_queue_t *queue)
{
if (queue->index>=queue->size) return NULL;
return &queue->table[queue->index++];
}
 
/* since get returns the correct event address,
the post function does nothing... */
static int fixed_post(fixed_queue_t *queue)
{
return 0;
}
 
static TRC_FIXED_PARMS defaultargs;
static int once=0;
 
static int fixed_create(trc_queue_t *queue, TRC_FIXED_PARMS *args)
{
fixed_queue_t *ptr;
 
/* initialize the default arguments for the fixed queue */
if (!once) {
/* well... this func is called when the system is not running! */
once=1;
trc_fixed_default_parms(defaultargs);
}
if (args==NULL) args=&defaultargs;
/* allocate the fixed queue data structure plus the array of events */
ptr=(fixed_queue_t*)kern_alloc(sizeof(fixed_queue_t)+
sizeof(trc_event_t)*(args->size+1));
if (ptr==NULL) return -1;
 
/* set the current queue pointers and data */
queue->get=(trc_event_t*(*)(void*))fixed_get;
queue->post=(int(*)(void*))fixed_post;
queue->data=ptr;
 
ptr->size=args->size;
ptr->index=0;
ptr->filename=args->filename;
return 0;
}
 
static TASK fixed_shutdown(fixed_queue_t *queue)
{
char pathname[PATH_MAX];
int h;
printk(KERN_DEBUG "<fixed queuesize:%i>",queue->index);
 
if (queue->filename==NULL) trc_create_name("fix",queue->uniq,pathname);
else trc_create_name(queue->filename,0,pathname);
 
h=open("/TEMP/FIX1",O_CREAT|O_TRUNC|O_WRONLY);
if (h!=-1) {
write(h,queue->table,queue->index*sizeof(trc_event_t));
close(h);
printk(KERN_NOTICE "tracer file %s created!",pathname);
} else {
printk(KERN_NOTICE "tracer file %s not created!",pathname);
}
resume_fs_shutdown();
return NULL;
}
 
static int fixed_activate(fixed_queue_t *queue, int uniq)
{
queue->uniq=uniq;
return 0;
}
 
static int fixed_terminate(fixed_queue_t *queue)
{
SOFT_TASK_MODEL model;
PID pid;
 
suspend_fs_shutdown();
//nrt_task_default_model(model);
//nrt_task_def_system(model);
//nrt_task_def_arg(model,queue);
 
soft_task_default_model(model);
soft_task_def_system(model);
soft_task_def_notrace(model);
soft_task_def_periodic(model);
soft_task_def_period(model,50000);
soft_task_def_met(model,10000);
soft_task_def_wcet(model,10000);
soft_task_def_arg(model,queue);
pid=task_create("ShutTrcFix",fixed_shutdown,&model,NULL);
if (pid==-1) {
printk(KERN_ERR "can't start tracer shutdown task (fixed)");
return -1;
} else
task_activate(pid);
 
return 0;
}
 
int trc_register_fixed_queue(void)
{
int res;
res=trc_register_queuetype(TRC_FIXED_QUEUE,
(int(*)(trc_queue_t*,void*))fixed_create,
(int(*)(void*,int))fixed_activate,
(int(*)(void*))fixed_terminate
);
if (res!=0) printk(KERN_WARNING "can't register tracer fixed queue");
return res;
}
/shark/trunk/tracer/oldtrace/trccirc.c
0,0 → 1,393
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
/*
* CVS : $Id: trccirc.c,v 1.1 2003-12-10 16:48:48 giacomo Exp $
*
* File: $File$
* Revision: $Revision: 1.1 $
* Last update: $Date: 2003-12-10 16:48:48 $
*/
 
#include <ll/sys/types.h>
#include <ll/stdlib.h>
 
#include <kernel/func.h>
#include <kernel/mem.h>
#include <kernel/log.h>
 
#include <types.h>
#include <trace.h>
#include <queues.h>
 
#include <fs/fs.h>
 
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
 
/* Well... this file is very similar to trcfixed.c! */
 
typedef struct TAGcircular_queue_t {
/*+ size of the queue +*/
int size;
/*+ index of the next insertion into the queue +*/
int index;
/*+ index of the next item to write (if online_tracer activated) +*/
int windex;
/*+ number of events lost (if online_tracer activated) +*/
long hoops;
/*+ filename of the trace file +*/
char *filename;
/*+ flags from flags field of the initialization struct +*/
int flags;
/*+ some internal models have needed of extra parameters +*/
void *dummy;
/*+ unique number that identify the queue +*/
int uniq;
/*+ events table +*/
trc_event_t table[0];
} circular_queue_t;
 
static int mustgodown=0;
 
static TASK online_tracer(circular_queue_t *queue)
{
char pathname[PATH_MAX];
int handle;
int index;
 
if (queue->filename==NULL) trc_create_name("cir",queue->uniq,pathname);
else trc_create_name(queue->filename,0,pathname);
 
if (wait_for_fs_initialization()) {
printk(KERN_NOTICE "tracer online task not running");
goto BADEND;
}
handle=open(pathname,O_CREAT|O_TRUNC|O_WRONLY);
if (handle==-1) {
printk(KERN_NOTICE "tracer file %s not created!",pathname);
goto BADEND;
}
for (;;) {
while (queue->index!=queue->windex) {
index=queue->index;
if (index<queue->windex) {
write(handle,
queue->table+queue->windex,
(queue->size-queue->windex)*sizeof(trc_event_t)
);
queue->windex=0;
continue;
}
write(handle,
queue->table+queue->windex,
(index-queue->windex)*sizeof(trc_event_t)
);
queue->windex=index;
}
if (mustgodown) break;
task_endcycle();
}
close(handle);
printk(KERN_NOTICE "tracer file %s created!",pathname);
 
if (queue->hoops)
printk(KERN_NOTICE "tracer: %li event lost into %s",queue->hoops,pathname);
 
resume_fs_shutdown();
return NULL;
 
BADEND:
resume_fs_shutdown();
/*Why this? for a little bug on the task_makefree() routine */
for (;;) {
if (mustgodown) break;
task_endcycle();
}
return NULL;
}
 
static trc_event_t *circular_get2(circular_queue_t *queue)
{
if (queue->index==queue->size-1) {
if (queue->windex==0) {
queue->hoops++;
return NULL;
}
queue->index=0;
return &queue->table[queue->size-1];
}
if (queue->index+1==queue->windex) {
queue->hoops++;
return NULL;
}
return &queue->table[queue->index++];
}
 
static trc_event_t *circular_get1(circular_queue_t *queue)
{
if (queue->index==queue->size-1) {
queue->index=0;
return &queue->table[queue->size-1];
}
return &queue->table[queue->index++];
}
 
static int circular_post(circular_queue_t *queue)
{
return 0;
}
 
struct create_args {
long period;
long slice;
circular_queue_t *queue;
};
 
 
/* to remove!!! */
/*
static void circular_create_postponed(void *foo)
{
struct create_args *ptr=(struct create_args *)foo;
SOFT_TASK_MODEL model;
PID pid;
 
printk(KERN_DEBUG "postponed create: START");
soft_task_default_model(model);
soft_task_def_system(model);
soft_task_def_notrace(model);
soft_task_def_periodic(model);
soft_task_def_period(model,ptr->period);
soft_task_def_met(model,ptr->slice);
soft_task_def_wcet(model,ptr->slice);
soft_task_def_arg(model,ptr->queue);
 
printk(KERN_DEBUG "postponed create: A");
kern_free(foo,sizeof(struct create_args));
 
printk(KERN_DEBUG "postponed create: B");
pid=task_create("trcCirc",online_tracer,&model,NULL);
if (pid==-1) {
printk(KERN_ERR "can't start tracer online circular trace task");
} else {
printk(KERN_DEBUG "postponed create: C1");
task_activate(pid);
printk(KERN_DEBUG "postponed create: C2");
suspend_fs_shutdown();
printk(KERN_DEBUG "postponed create: C3");
}
 
printk(KERN_DEBUG "postponed create: END");
}
*/
 
static int circular_create(trc_queue_t *queue, TRC_CIRCULAR_PARMS *args)
{
TRC_CIRCULAR_PARMS defaultargs;
circular_queue_t *ptr;
 
if (args==NULL) {
trc_circular_default_parms(defaultargs);
args=&defaultargs;
}
ptr=(circular_queue_t*)kern_alloc(sizeof(circular_queue_t)+
sizeof(trc_event_t)*args->size);
if (ptr==NULL) return -1;
 
queue->get=(trc_event_t*(*)(void*))circular_get1;
queue->post=(int(*)(void*))circular_post;
queue->data=ptr;
ptr->size=args->size;
ptr->windex=ptr->index=0;
ptr->hoops=0;
ptr->filename=args->filename;
ptr->flags=args->flags;
ptr->dummy=NULL;
if (args->flags&TRC_CIRCULAR_ONLINETASK) {
struct create_args *p;
p=kern_alloc(sizeof(struct create_args));
if (p==NULL) {
printk(KERN_ERR "can't create tracer online circular trace task");
return -1;
}
queue->get=(trc_event_t*(*)(void*))circular_get2;
ptr->dummy=p;
p->period=args->period;
p->slice=args->slice;
p->queue=ptr;
//sys_atrunlevel(circular_create_postponed,(void*)p,RUNLEVEL_INIT);
}
return 0;
}
 
static int circular_activate(circular_queue_t *queue, int uniq)
{
queue->uniq=uniq;
 
if (queue->flags&TRC_CIRCULAR_ONLINETASK) {
struct create_args *ptr=(struct create_args *)queue->dummy;
SOFT_TASK_MODEL model;
PID pid;
 
printk(KERN_DEBUG "postponed create: START");
soft_task_default_model(model);
soft_task_def_system(model);
soft_task_def_notrace(model);
soft_task_def_periodic(model);
soft_task_def_period(model,ptr->period);
soft_task_def_met(model,ptr->slice);
soft_task_def_wcet(model,ptr->slice);
soft_task_def_arg(model,ptr->queue);
 
printk(KERN_DEBUG "postponed create: A");
kern_free(queue->dummy,sizeof(struct create_args));
 
printk(KERN_DEBUG "postponed create: B");
pid=task_create("trcCirc",online_tracer,&model,NULL);
if (pid==-1) {
printk(KERN_ERR "can't start tracer online circular trace task");
} else {
printk(KERN_DEBUG "postponed create: C1");
suspend_fs_shutdown();
printk(KERN_DEBUG "postponed create: C2");
task_activate(pid);
printk(KERN_DEBUG "postponed create: C3");
}
 
printk(KERN_DEBUG "postponed create: END");
}
return 0;
}
 
static TASK circular_shutdown(circular_queue_t *queue)
{
char pathname[PATH_MAX];
int h;
if (queue->filename==NULL) trc_create_name("cir",queue->uniq,pathname);
else trc_create_name(queue->filename,0,pathname);
h=open(pathname,O_CREAT|O_TRUNC|O_WRONLY);
if (h!=-1) {
if (queue->index!=queue->size-1)
write(h,
queue->table+queue->index+1,
(queue->size-queue->index-1)*sizeof(trc_event_t)
);
write(h,
queue->table,
queue->index*sizeof(trc_event_t)
);
close(h);
printk(KERN_NOTICE "tracer file %s created!",pathname);
} else
printk(KERN_NOTICE "tracer file %s NOT created!",pathname);
resume_fs_shutdown();
return NULL;
}
 
static int circular_terminate(circular_queue_t *queue)
{
SOFT_TASK_MODEL model;
PID pid;
 
mustgodown=1;
if (queue->flags&TRC_CIRCULAR_ONLINETASK) return 0;
 
suspend_fs_shutdown();
//nrt_task_default_model(model);
//nrt_task_def_system(model);
//nrt_task_def_arg(model,queue);
 
soft_task_default_model(model);
soft_task_def_system(model);
soft_task_def_notrace(model);
soft_task_def_periodic(model);
soft_task_def_period(model,50000);
soft_task_def_met(model,10000);
soft_task_def_wcet(model,10000);
soft_task_def_arg(model,queue);
pid=task_create("ShutTrcCir",circular_shutdown,&model,NULL);
if (pid==-1) {
printk(KERN_ERR "can't start tracer shutdown task (circular)");
return -1;
} else
task_activate(pid);
 
return 0;
}
 
int trc_register_circular_queue(void)
{
int res;
res=trc_register_queuetype(TRC_CIRCULAR_QUEUE,
(int(*)(trc_queue_t*,void*))circular_create,
(int(*)(void*,int))circular_activate,
(int(*)(void*))circular_terminate
);
if (res!=0) printk(KERN_WARNING "can't register tracer circular queue");
return res;
}
/shark/trunk/tracer/oldtrace/ctable.c
0,0 → 1,260
#include <tracer.h>
 
BYTE conv[256] = {
/* FTrace_EVT_ticks_per_sec 0x00 */ NOT_DEFINED,
/* FTrace_EVT_cycles_per_tick 0x10 */ NOT_DEFINED,
/* FTrace_EVT_trace_start 0x20 */ NOT_DEFINED,
/* FTrace_EVT_trace_stop 0x30 */ NOT_DEFINED,
/* FTrace_EVT_blackout_start 0x40 */ NOT_DEFINED,
/* FTrace_EVT_blackout_end 0x50 */ NOT_DEFINED,
/* FTrace_EVT_id 0x60 */ NOT_DEFINED,
/* FTrace_EVT_numeevents 0x70 */ NOT_DEFINED,
/* 0x80 */ NOT_DEFINED,
/* 0x90 */ NOT_DEFINED,
/* 0xA0 */ NOT_DEFINED,
/* 0xB0 */ NOT_DEFINED,
/* 0xC0 */ NOT_DEFINED,
/* 0xD0 */ NOT_DEFINED,
/* 0xE0 */ NOT_DEFINED,
/* 0xF0 */ NOT_DEFINED,
/* FTrace_EVT_ipoint 0x01 */ NOT_DEFINED,
/* 0x11 */ NOT_DEFINED,
/* 0x21 */ NOT_DEFINED,
/* 0x31 */ NOT_DEFINED,
/* 0x41 */ NOT_DEFINED,
/* 0x51 */ NOT_DEFINED,
/* 0x61 */ NOT_DEFINED,
/* 0x71 */ NOT_DEFINED,
/* 0x81 */ NOT_DEFINED,
/* 0x91 */ NOT_DEFINED,
/* 0xA1 */ NOT_DEFINED,
/* 0xB1 */ NOT_DEFINED,
/* 0xC1 */ NOT_DEFINED,
/* 0xD1 */ NOT_DEFINED,
/* 0xE1 */ NOT_DEFINED,
/* 0xF1 */ NOT_DEFINED,
/* FTrace_EVT_task_create 0x02 */ NOT_DEFINED,
/* FTrace_EVT_task_activate 0x12 */ NOT_DEFINED,
/* FTrace_EVT_task_dispatch 0x22 */ NOT_DEFINED,
/* FTrace_EVT_task_epilogue 0x32 */ NOT_DEFINED,
/* FTrace_EVT_task_end 0x42 */ NOT_DEFINED,
/* FTrace_EVT_task_begin_cycle 0x52 */ NOT_DEFINED,
/* FTrace_EVT_task_end_cycle 0x62 */ NOT_DEFINED,
/* FTrace_EVT_task_sleep 0x72 */ NOT_DEFINED,
/* FTrace_EVT_task_schedule 0x82 */ NOT_DEFINED,
/* 0x92 */ NOT_DEFINED,
/* 0xA2 */ NOT_DEFINED,
/* 0xB2 */ NOT_DEFINED,
/* 0xC2 */ NOT_DEFINED,
/* 0xD2 */ NOT_DEFINED,
/* 0xE2 */ NOT_DEFINED,
/* 0xF2 */ NOT_DEFINED,
/* FTrace_EVT_interrupt_start 0x03 */ NOT_DEFINED,
/* FTrace_EVT_interrupt_end 0x13 */ NOT_DEFINED,
/* FTrace_EVT_interrupt_hit 0x23 */ NOT_DEFINED,
/* FTrace_EVT_interrupt_count 0x33 */ NOT_DEFINED,
/* 0x43 */ NOT_DEFINED,
/* 0x53 */ NOT_DEFINED,
/* 0x63 */ NOT_DEFINED,
/* 0x73 */ NOT_DEFINED,
/* 0x83 */ NOT_DEFINED,
/* 0x93 */ NOT_DEFINED,
/* 0xA3 */ NOT_DEFINED,
/* 0xB3 */ NOT_DEFINED,
/* 0xC3 */ NOT_DEFINED,
/* 0xD3 */ NOT_DEFINED,
/* 0xE3 */ NOT_DEFINED,
/* 0xF3 */ NOT_DEFINED,
/* FTrace_EVT_to_real_mode 0x04 */ NOT_DEFINED,
/* FTrace_EVT_to_protected_mode 0x14 */ NOT_DEFINED,
/* FTrace_EVT_CLI 0x24 */ NOT_DEFINED,
/* FTrace_EVT_STI 0x34 */ NOT_DEFINED,
/* 0x44 */ NOT_DEFINED,
/* 0x54 */ NOT_DEFINED,
/* 0x64 */ NOT_DEFINED,
/* 0x74 */ NOT_DEFINED,
/* 0x84 */ NOT_DEFINED,
/* 0x94 */ NOT_DEFINED,
/* 0xA4 */ NOT_DEFINED,
/* 0xB4 */ NOT_DEFINED,
/* 0xC4 */ NOT_DEFINED,
/* 0xD4 */ NOT_DEFINED,
/* 0xE4 */ NOT_DEFINED,
/* 0xF4 */ NOT_DEFINED,
/* FTrace_EVT_set_priority 0x05 */ NOT_DEFINED,
/* FTrace_EVT_context_switch 0x15 */ NOT_DEFINED,
/* 0x25 */ NOT_DEFINED,
/* 0x35 */ NOT_DEFINED,
/* 0x45 */ NOT_DEFINED,
/* 0x55 */ NOT_DEFINED,
/* 0x65 */ NOT_DEFINED,
/* 0x75 */ NOT_DEFINED,
/* 0x85 */ NOT_DEFINED,
/* 0x95 */ NOT_DEFINED,
/* 0xA5 */ NOT_DEFINED,
/* 0xB5 */ NOT_DEFINED,
/* 0xC5 */ NOT_DEFINED,
/* 0xD5 */ NOT_DEFINED,
/* 0xE5 */ NOT_DEFINED,
/* 0xF5 */ NOT_DEFINED,
/* FTrace_EVT_set_mutex_create 0x06 */ NOT_DEFINED,
/* FTrace_EVT_set_mutex_lock 0x16 */ NOT_DEFINED,
/* FTrace_EVT_set_mutex_inherit 0x26 */ NOT_DEFINED,
/* FTrace_EVT_set_mutex_unlock 0x36 */ NOT_DEFINED,
/* 0x46 */ NOT_DEFINED,
/* 0x56 */ NOT_DEFINED,
/* 0x66 */ NOT_DEFINED,
/* 0x76 */ NOT_DEFINED,
/* 0x86 */ NOT_DEFINED,
/* 0x96 */ NOT_DEFINED,
/* 0xA6 */ NOT_DEFINED,
/* 0xB6 */ NOT_DEFINED,
/* 0xC6 */ NOT_DEFINED,
/* 0xD6 */ NOT_DEFINED,
/* 0xE6 */ NOT_DEFINED,
/* 0xF6 */ NOT_DEFINED,
/* FTrace_EVT_signal 0x07 */ NOT_DEFINED,
/* 0x17 */ NOT_DEFINED,
/* 0x27 */ NOT_DEFINED,
/* 0x37 */ NOT_DEFINED,
/* 0x47 */ NOT_DEFINED,
/* 0x57 */ NOT_DEFINED,
/* 0x67 */ NOT_DEFINED,
/* 0x77 */ NOT_DEFINED,
/* 0x87 */ NOT_DEFINED,
/* 0x97 */ NOT_DEFINED,
/* 0xA7 */ NOT_DEFINED,
/* 0xB7 */ NOT_DEFINED,
/* 0xC7 */ NOT_DEFINED,
/* 0xD7 */ NOT_DEFINED,
/* 0xE7 */ NOT_DEFINED,
/* 0xF7 */ NOT_DEFINED,
/* FTrace_EVT_server_create 0x08 */ NOT_DEFINED,
/* FTrace_EVT_server_replenish 0x18 */ NOT_DEFINED,
/* FTrace_EVT_server_exhaust 0x28 */ NOT_DEFINED,
/* 0x38 */ NOT_DEFINED,
/* 0x48 */ NOT_DEFINED,
/* 0x58 */ NOT_DEFINED,
/* 0x68 */ NOT_DEFINED,
/* 0x78 */ NOT_DEFINED,
/* 0x88 */ NOT_DEFINED,
/* 0x98 */ NOT_DEFINED,
/* 0xA8 */ NOT_DEFINED,
/* 0xB8 */ NOT_DEFINED,
/* 0xC8 */ NOT_DEFINED,
/* 0xD8 */ NOT_DEFINED,
/* 0xE8 */ NOT_DEFINED,
/* 0xF8 */ NOT_DEFINED,
/* FTrace_EVT_user_event_0 0x09 */ NOT_DEFINED,
/* FTrace_EVT_user_event_1 0x19 */ NOT_DEFINED,
/* FTrace_EVT_user_event_2 0x29 */ NOT_DEFINED,
/* FTrace_EVT_user_event_3 0x39 */ NOT_DEFINED,
/* FTrace_EVT_user_event_4 0x49 */ NOT_DEFINED,
/* FTrace_EVT_user_event_5 0x59 */ NOT_DEFINED,
/* FTrace_EVT_user_event_6 0x69 */ NOT_DEFINED,
/* FTrace_EVT_user_event_7 0x79 */ NOT_DEFINED,
/* FTrace_EVT_user_event_8 0x89 */ NOT_DEFINED,
/* FTrace_EVT_user_event_9 0x99 */ NOT_DEFINED,
/* FTrace_EVT_user_event_10 0xA9 */ NOT_DEFINED,
/* FTrace_EVT_user_event_11 0xB9 */ NOT_DEFINED,
/* FTrace_EVT_user_event_12 0xC9 */ NOT_DEFINED,
/* FTrace_EVT_user_event_13 0xD9 */ NOT_DEFINED,
/* FTrace_EVT_user_event_14 0xE9 */ NOT_DEFINED,
/* FTrace_EVT_user_event_15 0xF9 */ NOT_DEFINED,
/* 0x0A */ NOT_DEFINED,
/* 0x1A */ NOT_DEFINED,
/* 0x2A */ NOT_DEFINED,
/* 0x3A */ NOT_DEFINED,
/* 0x4A */ NOT_DEFINED,
/* 0x5A */ NOT_DEFINED,
/* 0x6A */ NOT_DEFINED,
/* 0x7A */ NOT_DEFINED,
/* 0x8A */ NOT_DEFINED,
/* 0x9A */ NOT_DEFINED,
/* 0xAA */ NOT_DEFINED,
/* 0xBA */ NOT_DEFINED,
/* 0xCA */ NOT_DEFINED,
/* 0xDA */ NOT_DEFINED,
/* 0xEA */ NOT_DEFINED,
/* 0xFA */ NOT_DEFINED,
/* FTrace_EVT_timer_post 0x0B */ NOT_DEFINED,
/* FTrace_EVT_timer_delete 0x1B */ NOT_DEFINED,
/* FTrace_EVT_timer_wakeup_start 0x2B */ NOT_DEFINED,
/* FTrace_EVT_timer_wakeup_end 0x3B */ NOT_DEFINED,
/* 0x4B */ NOT_DEFINED,
/* 0x5B */ NOT_DEFINED,
/* 0x6B */ NOT_DEFINED,
/* 0x7B */ NOT_DEFINED,
/* 0x8B */ NOT_DEFINED,
/* 0x9B */ NOT_DEFINED,
/* 0xAB */ NOT_DEFINED,
/* 0xBB */ NOT_DEFINED,
/* 0xCB */ NOT_DEFINED,
/* 0xDB */ NOT_DEFINED,
/* 0xEB */ NOT_DEFINED,
/* 0xFB */ NOT_DEFINED,
/* 0x0C */ NOT_DEFINED,
/* 0x1C */ NOT_DEFINED,
/* 0x2C */ NOT_DEFINED,
/* 0x3C */ NOT_DEFINED,
/* 0x4C */ NOT_DEFINED,
/* 0x5C */ NOT_DEFINED,
/* 0x6C */ NOT_DEFINED,
/* 0x7C */ NOT_DEFINED,
/* 0x8C */ NOT_DEFINED,
/* 0x9C */ NOT_DEFINED,
/* 0xAC */ NOT_DEFINED,
/* 0xBC */ NOT_DEFINED,
/* 0xCC */ NOT_DEFINED,
/* 0xDC */ NOT_DEFINED,
/* 0xEC */ NOT_DEFINED,
/* 0xFC */ NOT_DEFINED,
/* 0x0D */ NOT_DEFINED,
/* 0x1D */ NOT_DEFINED,
/* 0x2D */ NOT_DEFINED,
/* 0x3D */ NOT_DEFINED,
/* 0x4D */ NOT_DEFINED,
/* 0x5D */ NOT_DEFINED,
/* 0x6D */ NOT_DEFINED,
/* 0x7D */ NOT_DEFINED,
/* 0x8D */ NOT_DEFINED,
/* 0x9D */ NOT_DEFINED,
/* 0xAD */ NOT_DEFINED,
/* 0xBD */ NOT_DEFINED,
/* 0xCD */ NOT_DEFINED,
/* 0xDD */ NOT_DEFINED,
/* 0xED */ NOT_DEFINED,
/* 0xFD */ NOT_DEFINED,
/* 0x0E */ NOT_DEFINED,
/* 0x1E */ NOT_DEFINED,
/* 0x2E */ NOT_DEFINED,
/* 0x3E */ NOT_DEFINED,
/* 0x4E */ NOT_DEFINED,
/* 0x5E */ NOT_DEFINED,
/* 0x6E */ NOT_DEFINED,
/* 0x7E */ NOT_DEFINED,
/* 0x8E */ NOT_DEFINED,
/* 0x9E */ NOT_DEFINED,
/* 0xAE */ NOT_DEFINED,
/* 0xBE */ NOT_DEFINED,
/* 0xCE */ NOT_DEFINED,
/* 0xDE */ NOT_DEFINED,
/* 0xEE */ NOT_DEFINED,
/* 0xFE */ NOT_DEFINED,
/* 0x0F */ NOT_DEFINED,
/* 0x1F */ NOT_DEFINED,
/* 0x2F */ NOT_DEFINED,
/* 0x3F */ NOT_DEFINED,
/* 0x4F */ NOT_DEFINED,
/* 0x5F */ NOT_DEFINED,
/* 0x6F */ NOT_DEFINED,
/* 0x7F */ NOT_DEFINED,
/* 0x8F */ NOT_DEFINED,
/* 0x9F */ NOT_DEFINED,
/* 0xAF */ NOT_DEFINED,
/* 0xBF */ NOT_DEFINED,
/* 0xCF */ NOT_DEFINED,
/* 0xDF */ NOT_DEFINED,
/* 0xEF */ NOT_DEFINED,
/* 0xFF */ NOT_DEFINED};
/shark/trunk/tracer/oldtrace/oldtrace.c
0,0 → 1,450
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/*
* Copyright (C) 2000 Massimiliano Giorgi
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
#include <ll/sys/types.h>
 
#include <kernel/types.h>
#include <kernel/var.h>
 
#include <ll/stdlib.h>
#include <ll/string.h>
 
#include <kernel/func.h>
 
#include <types.h>
#include <trace.h>
#include <queues.h>
 
#include <bits/limits.h>
 
#include <tracer.h>
 
static void dummy_logevent(int event, void *ptr)
{
return;
}
 
void (*trc_logevent)
(int event, void *ptr)=dummy_logevent;
static int dummy_suspendresume(void)
{
return 0;
}
 
int (*trc_suspend)(void)=dummy_suspendresume;
int (*trc_resume)(void)=dummy_suspendresume;
 
/* maximum number of different queues where we want to log our events */
#define TRC_MAXQUEUES 5
 
/*
*
*/
 
/* this is the base path that is used as a prologue for all the
filenames that are passed to the tracer */
static char basepath[PATH_MAX];
 
/* used to create the name for a tracer file */
void trc_create_name(char *basename, int uniq, char *pathname)
{
if (uniq) sprintf(pathname,"%s/%s%i",basepath,basename,uniq);
else sprintf(pathname,"%s/%s",basepath,basename);
}
 
/*
*
*/
 
/* the flag used to discriminate if an event have to be traced or not */
#define FLAG_NOTRACE 0x01
 
typedef struct TAGtrc_evtinfo_t {
trc_queue_t *queue; /* the queue responsible for the logging of an event */
unsigned flags; /* if = FLAG_NOTRACE the event must not be logged */
} trc_evtinfo_t;
 
/* -- */
 
/* one entry for each event; this array says for each event the queue to use
and if it must be logged */
trc_evtinfo_t eventstable[TRC_NUMEVENTS];
 
/* For each kind of queue (see include/tracer/queues.h) there is a set of
pointers to the functions that a queue should implement */
int (*createqueue[TRC_QUEUETYPESNUMBER])(trc_queue_t *, void *);
int (*activatequeue[TRC_QUEUETYPESNUMBER])(void *,int);
int (*terminatequeue[TRC_QUEUETYPESNUMBER])(void *);
 
/* for each queue registered in the system,
the functions used to get/post an event
The elements of this table are initialized with calls to createqueue[type]()
(see include/trace/queues.h) */
trc_queue_t queuetable[TRC_MAXQUEUES];
 
/* initialized as a dummy queue, the default value of all the queues */
trc_queue_t queuesink;
 
/* number of registered queues in the system */
int numqueues;
 
/* -- */
 
/* The Dummy queue */
 
static trc_event_t *dummy_get(void *foo)
{
return NULL;
}
 
static int dummy_post(void *foo)
{
return 0;
}
 
static int dummy_createqueue(trc_queue_t *queue, void *unused)
{
queue->get=dummy_get;
queue->post=dummy_post;
queue->data=NULL;
return 0;
}
 
static int dummy_terminatequeue(void *unused)
{
return 0;
}
 
/*
static int dummy_activatequeue(void *unused, int unused2)
{
return 0;
}
*/
 
/* -- */
 
/* this function simply register the functions that are used to
handle a queue */
int trc_register_queuetype(int queuetype,
int(*creat)(trc_queue_t *, void *),
int(*activate)(void *,int),
int(*term)(void *))
{
if (queuetype<0||queuetype>=TRC_QUEUETYPESNUMBER) return -1;
createqueue[queuetype]=creat;
activatequeue[queuetype]=activate;
terminatequeue[queuetype]=term;
return 0;
}
 
/* this function register a queue in the system.
It uses the type to access to the queue handling functions registered
with the previous function (trc_register_queuetype)
numqueue is incremented!
*/
int trc_create_queue(int queuetype, void *args)
{
int res;
 
if (createqueue[queuetype]==dummy_createqueue) return -1;
if (numqueues==TRC_MAXQUEUES) return -1;
res=createqueue[queuetype](&queuetable[numqueues],args);
if (res) return -1;
queuetable[numqueues].type=queuetype;
numqueues++;
return numqueues-1;
}
 
/* -- */
 
static void (*old_logevent)(int event, void *ptr)=NULL;
static void internal_trc_logevent(int, void *ptr);
 
static void trc_end(void *unused)
{
int i;
printk(KERN_INFO "tracer shutdown...");
/* suspend event logging */
trc_suspend();
 
/* for safety: send all events to the sink queue */
for (i=0;i<TRC_NUMEVENTS;i++) {
eventstable[i].queue=&queuesink;
eventstable[i].flags|=FLAG_NOTRACE;
}
/* terminate all queues */
for (i=0;i<numqueues;i++)
terminatequeue[queuetable[i].type](queuetable[i].data);
}
 
static int internal_trc_resume(void);
static int internal_trc_suspend(void);
 
int TRC_init_phase1(TRC_PARMS *parms)
{
int i;
printk(KERN_INFO "initializing tracer...");
/* all the queues are initialized to the dummy queue (sink!) */
for (i=0;i<TRC_QUEUETYPESNUMBER;i++) {
createqueue[i]=dummy_createqueue;
terminatequeue[i]=dummy_terminatequeue;
}
/* the sink queue is initialized */
dummy_createqueue(&queuesink,NULL);
/* no queues registered yet */
numqueues=0;
/* all the events are initialized to put to the sink queue */
for (i=0;i<TRC_NUMEVENTS;i++) {
eventstable[i].queue=&queuesink;
eventstable[i].flags=FLAG_NOTRACE;
}
/* this will end the tracer at shutdown */
i=sys_atrunlevel(trc_end,NULL,RUNLEVEL_SHUTDOWN);
 
/* initialize the parameters if not initialized */
{
TRC_PARMS m;
trc_default_parms(m);
if (parms==NULL) parms=&m;
 
strncpy(basepath,parms->path,sizeof(basepath));
basepath[sizeof(basepath)-1]='\0';
}
 
trc_suspend=internal_trc_suspend;
trc_resume=internal_trc_resume;
/* start the tracer */
trc_resume();
return 0;
}
 
/* this function simply activates all the registered queues.
This is usually called into the init() tasks!!! */
int TRC_init_phase2(void)
{
int i;
for (i=0;i<numqueues;i++)
activatequeue[queuetable[i].type](queuetable[i].data,i+1);
return 0;
}
 
/* saves the current logevent function and set it as
the internal_trc_logevent */
static int internal_trc_resume(void)
{
SYS_FLAGS f;
int ret=-1;
f=kern_fsave();
if (old_logevent==NULL) {
old_logevent=trc_logevent;
trc_logevent=internal_trc_logevent;
ret=0;
}
kern_frestore(f);
return ret;
}
 
/* restores the saved logevent function (initially, the logevent function is
a dummy function) */
static int internal_trc_suspend(void)
{
SYS_FLAGS f;
int ret=-1;
f=kern_fsave();
if (old_logevent!=NULL) {
trc_logevent=old_logevent;
old_logevent=NULL;
ret=0;
}
kern_frestore(f);
return 0;
}
 
static void internal_trc_logevent(int event, void *ptr)
{
trc_event_t *evt;
trc_queue_t *queue;
SYS_FLAGS f;
 
/* disables interrupts (this function can be called also into a task */
f=kern_fsave();
 
/* check if the event has to be logged */
if (eventstable[event].flags&FLAG_NOTRACE) {
kern_frestore(f);
return;
}
queue=eventstable[event].queue;
/* gets a free event descriptor, fills it and post it */
evt=queue->get(queue->data);
if (evt!=NULL) {
evt->event=event;
evt->time=kern_gettime(NULL);
memcpy(&evt->x,ptr,sizeof(trc_allevents_t));
queue->post(queue->data);
}
kern_frestore(f);
}
 
/*
*
*
*
*/
 
/* these set of functions can be used to trace or not single event and classes.
They make use of the classtable structure, that is used to discriminate
the indexes occupied by every class */
 
int classtable[TRC_NUMCLASSES+1]={
TRC_F_TRACER,
TRC_F_SYSTEM,
TRC_F_USER,
TRC_F_LL,
TRC_F_SEM,
TRC_F_LAST
};
 
#define checkevent(x) if ((x)<0||(x)>=TRC_NUMEVENTS) return -1
#define checkqueue(x) if ((x)<0||(x)>=numqueues) return -1
#define checkclass(x) if ((x)<0||(x)>=TRC_NUMCLASSES) return -1
 
int trc_assign_event_to_queue(int event, int queue)
{
checkevent(event);
checkqueue(queue);
eventstable[event].queue=&queuetable[queue];
return 0;
}
 
int trc_assign_class_to_queue(int class, int queue)
{
int i;
checkqueue(queue);
checkclass(class);
for (i=classtable[class];i<classtable[class+1];i++)
eventstable[i].queue=&queuetable[queue];
return 0;
}
 
int trc_notrace_event(int event)
{
checkevent(event);
eventstable[event].flags|=FLAG_NOTRACE;
return 0;
}
 
int trc_trace_event(int event)
{
checkevent(event);
eventstable[event].flags&=~FLAG_NOTRACE;
return 0;
}
 
int trc_notrace_class(int class)
{
int i;
checkclass(class);
for (i=classtable[class];i<classtable[class+1];i++)
eventstable[i].flags|=FLAG_NOTRACE;
return 0;
}
 
int trc_trace_class(int class)
{
int i;
checkclass(class);
for (i=classtable[class];i<classtable[class+1];i++)
eventstable[i].flags&=~FLAG_NOTRACE;
return 0;
}
 
 
/* -- */
 
int TRC_init_phase1_standard(void)
{
int qf,qc;
int res;
 
/* initialize the trace */
res=TRC_init_phase1(NULL);
if (res) return res;
 
/* register two kinds of queues, fixed and circular */
res=trc_register_circular_queue();
if (res) return res;
res=trc_register_fixed_queue();
if (res) return res;
 
/* creates two queues:
a circular queue for the system events,
a fixed queue
*/
qc=trc_create_queue(TRC_CIRCULAR_QUEUE,NULL);
qf=trc_create_queue(TRC_FIXED_QUEUE,NULL);
if (qc==-1||qf==-1) return -97;
 
/* We want to trace all the system events */
res=trc_trace_class(TRC_CLASS_SYSTEM);
if (res) return res;
/* All the system events must be traced into the circular queue */
res=trc_assign_class_to_queue(TRC_CLASS_SYSTEM,qc);
if (res) return res;
 
return 0;
}
 
int TRC_init_phase2_standard(void)
{
return TRC_init_phase2();
}
 
/shark/trunk/tracer/makefile
0,0 → 1,33
# The Tracer Library
 
ifndef BASE
BASE=..
endif
 
include $(BASE)/config/config.mk
include $(BASE)/shark.cfg
 
LIBRARY = tracer
 
INCL += -I./include
 
OBJS_PATH = $(BASE)/tracer
 
# Object files
 
ifeq ($(findstring NEW,$(TRACER)) , NEW)
OBJS = newtrace/tracer.o
CFG_OPT += -D__NEW_TRACER__
endif
ifeq ($(findstring OLD,$(TRACER)) , OLD)
OBJS = oldtrace/oldtrace.o oldtrace/trccirc.o oldtrace/trcdfix.o \
oldtrace/trcudp.o oldtrace/trcfixed.o oldtrace/trcdummy.o oldtrace/ctable.o
CFG_OPT += -D__OLD_TRACER__
endif
 
ifneq ($(findstring NO,$(TRACER)) , NO)
include $(BASE)/config/lib.mk
endif
 
install all clean cleanall depend::