Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

#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);

}