Subversion Repositories shark

Rev

Rev 370 | Rev 375 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * 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"
#include "FTrace.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_NO_OUTPUT  0
#define TRACER_UDP_OUTPUT 1

#define TRACER_LOGEVENT fast_logevent

int tracer_initialize(int MemorySize);
void tracer_enable();
void tracer_disable();
void tracer_print_statistics();

int tracer_send_logged_events(int NumberOfEvents);
void tracer_flush_sent_events();

//UDP

int tracer_init_udp(int flag, char *local_ip, char *target_ip);
int tracer_create_udp_task(void *m, int EventsForPeriod);

#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 *LastBeforeEndTracerBuffer;
  extern void *CurrentTracerBuffer;
  extern void *FirstTracerBuffer;

  extern int TracerActive;
  extern unsigned long long TracerEventsRecorded;
  extern unsigned int TracerEventsPresent;

  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;

  // Adjust FirstTracerBuffer
  if (FirstTracerBuffer >= CurrentTracerBuffer && TracerEventsPresent != 0) {
    while ((CurrentTracerBuffer + size - 1) >= FirstTracerBuffer &&
            FirstTracerBuffer != StartTracerBuffer) {
      FirstTracerBuffer += *(BYTE *)(FirstTracerBuffer + 9);
      if (FirstTracerBuffer >= LastBeforeEndTracerBuffer) FirstTracerBuffer = StartTracerBuffer;
    }
  } else {
    TracerEventsPresent++;
  }

  // Check if we overcome EndTracerBuffer
  if ((CurrentTracerBuffer + size - 1) > EndTracerBuffer) {
    //Cyclical Buffer implementation
    LastBeforeEndTracerBuffer = CurrentTracerBuffer;
    CurrentTracerBuffer = StartTracerBuffer;
    //Set the First Event
    while ((CurrentTracerBuffer + size - 1) >= FirstTracerBuffer) {
      FirstTracerBuffer += *(BYTE *)(FirstTracerBuffer + 9);
      if (FirstTracerBuffer >= LastBeforeEndTracerBuffer) FirstTracerBuffer = StartTracerBuffer;
    }
  }

  // Add the new event
  *(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