public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] profiling
@ 2001-02-22  2:43 Natarajan, Mekala (CTS)
  2001-02-22  2:59 ` Andrew Lunn
  0 siblings, 1 reply; 2+ messages in thread
From: Natarajan, Mekala (CTS) @ 2001-02-22  2:43 UTC (permalink / raw)
  To: 'ecos-discuss@sources.redhat.com'

Hi all,
	Can someone suggest the profiling & analysis tools  available for
ECOS.
Thanks,
mekala



This e-mail and any files transmitted with it are for the sole use of the intended recipient(s) and may contain confidential and privileged information.
If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message. 
Any unauthorised review, use, disclosure, dissemination, forwarding, printing or copying of this email or any action taken in reliance on this e-mail is strictly 
prohibited and may be unlawful.

		Visit us at http://www.cognizant.com

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [ECOS] profiling
  2001-02-22  2:43 [ECOS] profiling Natarajan, Mekala (CTS)
@ 2001-02-22  2:59 ` Andrew Lunn
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Lunn @ 2001-02-22  2:59 UTC (permalink / raw)
  To: Natarajan, Mekala (CTS); +Cc: 'ecos-discuss@sources.redhat.com'

On Thu, Feb 22, 2001 at 04:07:25PM +0530, Natarajan, Mekala (CTS) wrote:
> Hi all,
> 	Can someone suggest the profiling & analysis tools  available for
> ECOS.
> Thanks,
> mekala

I wrote a quick and dirty profiler. It directly uses the hardware
timers on the EBSA SA110 board so you will have to do some work to
port it to other platforms. It uses the same scheme as the Linux
kernel profiler. It builds up a profile table in the same way and its
compatible with the readprofile program. The hard bit is getting the
table off the target hardware and onto a Linux box where is can be
processed. You have to use some sort of network.

        Andrew

/* A quick and dirty profiler. Andrew.Lunn@ascom.ch */

#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_ebsa285.h>
#include <cyg/hal/hal_arch.h>
#include "cfg.h"
#include "dbgprint.h"
#include "assert.h"
#include "profiler.h"

/* This is the table we store the date in. Each entry tells you have
   often the CPU has in the range of addresses PROF_RESOLUTION bits
   wide when the timer went off.*/
volatile cyg_uint32 prof_table [PROF_TABLE_SIZE]; 

static volatile cyg_uint32 prof_table_misses;  /* How many times did we miss
                                                  the table */
static volatile cyg_uint32 prof_ticks;         /* How many ticks the profiler
                                                  has received */

static cyg_interrupt intr;            /* eCos control structure */
static cyg_handle_t  intr_handle;    
static profile_states_t prof_state = PROF_UNINIT;

/* Reset the profile table back into a clean state. Also sets the
   number of misses to zero */
void
prof_table_clear(void)
{
  memset((void *)prof_table,0,sizeof(prof_table));
  prof_table_misses = 0;
  prof_ticks = 0;

  /* The Linux profiler tool wants the first word to contain the resoluton. */
  prof_table[0] = 1 << PROF_RESOLUTION;
}

/* Give an address increment the count in the profile table. If the
   address misses the table incremenet the miss count */
static void __inline__ 
prof_table_increment(cyg_addrword_t addr)
{
  prof_ticks++;

  if ( (addr < PROF_MEMORY_BOTTOM) || 
       (addr > PROF_MEMORY_TOP)) {
    prof_table_misses++;
  } else {
    addr -= PROF_MEMORY_BOTTOM;
    addr = addr >> PROF_RESOLUTION;
    
    if (prof_table[addr] != 0xffffffff) {
      prof_table[addr]++;
    }
  }
}

/* Start the timer used by the profiler code. This uses TIMER2 on the
   EBSA. */
static void 
prof_start_timer(void) {

  *SA110_TIMER2_CONTROL = 0; /* Disable while playing with it */
  *SA110_TIMER2_LOAD = TIMER2_FREQ / PROF_FREQ;
  *SA110_TIMER2_CLEAR = 0; /* Clear any pending interrupts */
  *SA110_TIMER2_CONTROL = (SA110_TIMER_CONTROL_SCALE_1 |
                           SA110_TIMER_CONTROL_MODE |
                           SA110_TIMER_CONTROL_ENABLE );
  *SA110_TIMER2_CLEAR = 0; /* Clear any pending interrupts again */
}

/* Stop the timer used by the profiler. */
static void
prof_stop_timer(void) {

  *SA110_TIMER2_CONTROL = 0;
}

/* Clear timer interrupt */
static void __inline__
prof_clear_timer_intr(void) {
  *SA110_TIMER2_CLEAR = 0;
}

/* This is the interrupt handler. It finds out the PC address before
   the interrupt and calls the increment. It then clears the interrupt
   and returns */
static cyg_uint32 
prof_ISR(cyg_vector_t vector, cyg_addrword_t data,HAL_SavedRegisters *regs) {

  prof_table_increment(regs->pc-4); /* Current instruction, not next */
  
  prof_clear_timer_intr();
  
  cyg_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_TIMER_2);
  
  return (CYG_ISR_HANDLED);
}

/* Install the interrupt handler for the timer used by the profiler */
static void 
prof_install_ISR (void) {
  
  cyg_interrupt_create(CYGNUM_HAL_INTERRUPT_TIMER_2,
                       0,
                       0,
                       prof_ISR,
                       NULL,
                       &intr_handle,
                       &intr);

  cyg_interrupt_attach(intr_handle);
  cyg_interrupt_unmask(CYGNUM_HAL_INTERRUPT_TIMER_2);
}

/* This function initialises the profiler */
void 
prof_init(void) {
  prof_table_clear();
  prof_install_ISR();
  prof_state = PROF_INIT;
}

/* This function starts the profiler running. */
void
prof_start(void) {
  prof_start_timer();
  prof_state = PROF_START;
}

/* Stop the profiler. Its a good idea to do this before you
   read the data from the table or you also profile the reading 
   process */
void 
prof_stop(void) {
  prof_stop_timer();
  prof_state = PROF_STOP;
}

/* Interface to the profiler code */

#ifndef PROFILER_H
#define PROFILER_H
typedef enum {PROF_UNINIT = 0, PROF_INIT, PROF_START, PROF_STOP} profile_states_t;

/* Reset the profile table back into a clean state. Also sets the
   number of misses to zero */
void prof_table_clear(void);

/* This function initialises the profiler and sets its running */
void prof_init(void);

/* Stop the profiler. Its a good idea to do this before you
   read the data from the table or you also profile the reading 
   process */
void prof_stop(void);

#define PROF_MEMORY_BOTTOM 0x00000000
#define PROF_MEMORY_TOP    0x000F0000
#define PROF_MEMORY_SIZE   (PROF_MEMORY_TOP - PROF_MEMORY_BOTTOM)
#define PROF_RESOLUTION    2   /* This is the number of bits we discard from
                                  from the bottom of the address. */
#define PROF_TABLE_SIZE    (PROF_MEMORY_SIZE >> PROF_RESOLUTION)
#define PROF_FREQ          1111     /* How many times a second */
#define TIMER2_FREQ        50000000 /* The clock frequency of timer 2 */

extern volatile cyg_uint32 prof_table [PROF_TABLE_SIZE];
#endif




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2001-02-22  2:59 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-02-22  2:43 [ECOS] profiling Natarajan, Mekala (CTS)
2001-02-22  2:59 ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).