OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /or1k/trunk/ecos-2.0/packages/services/profile
    from Rev 1254 to Rev 1765
    Reverse comparison

Rev 1254 → Rev 1765

/gprof/v2_0/cdl/profile_gprof.cdl
0,0 → 1,94
# ====================================================================
#
# profile_gprof.cdl
#
# cpu load measurements
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 2002 Gary Thomas
##
## eCos 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 or (at your option) any later version.
##
## eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## As a special exception, if other files instantiate templates or use macros
## or inline functions from this file, or you compile this file and link it
## with other works to produce a work based on this file, this file does not
## by itself cause the resulting work to be covered by the GNU General Public
## License. However the source code for this file must still be made available
## in accordance with section (3) of the GNU General Public License.
##
## This exception does not invalidate any other reasons why a work based on
## this file might be covered by the GNU General Public License.
##
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
## at http://sources.redhat.com/ecos/ecos-license/
## -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
# ====================================================================
######DESCRIPTIONBEGIN####
#
# Author(s): Gary Thomas
# Original data: Gary Thomas
# Contributors:
# Date: 2002-11-14
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_PROFILE_GPROF {
display "Gather runtime profile statistics"
requires CYGPKG_NET
requires CYGPKG_NET_TFTP
requires CYGPKG_MEMALLOC
requires { CYGINT_PROFILE_HAL_TIMER != 0 }
doc ref/services-profile-gprof.html
 
include_dir cyg/profile
compile profile.c
 
description "
This package enables runtime profiling of an application.
The actual profile collection must be turned on by the application,
once it has been initialized. The data collected is exported via
a TFTP connection to the target."
 
cdl_interface CYGINT_PROFILE_HAL_TIMER {
display "High resolution timer, implemented by platform"
description "
Profiling requires access to a high resolution timer which
is platform dependent."
}
 
cdl_option CYGNUM_PROFILE_TFTP_PORT {
display "Port used by TFTP server for profile data"
flavor data
default_value 0
description "
This option sets the port number to use for the TFTP server
which exports the profiling data. A value of 0 will set
the port to be the IETF standard port of 69/udp."
}
 
cdl_option CYGPKG_PROFILE_TESTS {
display "Profiling tests"
flavor data
no_define
calculated { "tests/profile.c" }
}
}
 
/gprof/v2_0/include/profile.h
0,0 → 1,73
#ifndef CYGONCE_PROFILE_H
#define CYGONCE_PROFILE_H
 
//==========================================================================
//
// profile.h
//
// Application profiling support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 2002 Gary Thomas
//
// eCos 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 or (at your option) any later version.
//
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors:
// Date: 2002-11-14
// Purpose: Define profiling support
// Description:
//
// Usage:
// #include <cyg/profile/profile.h>
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/profile_gprof.h>
#include <cyg/infra/cyg_type.h>
 
// Enable profiling
__externC void profile_on(void *start_addr, void *end_addr,
int bucket_size, int sample_resolution);
 
// Callback used by timer routine
__externC void __profile_hit(unsigned long pc);
 
// Timer setup routine, used when enabling profiling
__externC void hal_enable_profile_timer(int resolution);
 
#endif // CYGONCE_PROFILE_H
/gprof/v2_0/include/gmon_out.h
0,0 → 1,54
// Slightly adapted from OpenBSD "/src/gnu/usr.bin/binutils/gprof/gmon_out.h"
// for eCos environment
 
/*
* This file specifies the format of gmon.out files. It should have
* as few external dependencies as possible as it is going to be
* included in many different programs. That is, minimize the
* number of #include's.
*
* A gmon.out file consists of a header (defined by gmon_hdr) followed
* by a sequence of records. Each record starts with a one-byte tag
* identifying the type of records, followed by records specific data.
*/
#ifndef gmon_out_h
#define gmon_out_h
 
#define GMON_MAGIC "gmon" /* magic cookie */
#define GMON_VERSION 1 /* version number */
 
/*
* Raw header as it appears on file (without padding):
*/
struct gmon_hdr
{
char cookie[4];
char version[4];
char spare[3 * 4];
};
 
/* types of records in this file: */
typedef enum
{
GMON_TAG_TIME_HIST = 0, GMON_TAG_CG_ARC = 1, GMON_TAG_BB_COUNT = 2
}
GMON_Record_Tag;
 
struct gmon_hist_hdr
{
char low_pc[sizeof (char*)]; /* base pc address of sample buffer */
char high_pc[sizeof (char*)]; /* max pc address of sampled buffer */
char hist_size[4]; /* size of sample buffer */
char prof_rate[4]; /* profiling clock rate */
char dimen[15]; /* phys. dim., usually "seconds" */
char dimen_abbrev; /* usually 's' for "seconds" */
};
 
struct gmon_cg_arc_record
{
char from_pc[sizeof (char*)]; /* address within caller's body */
char self_pc[sizeof (char*)]; /* address within callee's body */
char count[4]; /* number of arc traversals */
};
 
#endif /* gmon_out_h */
/gprof/v2_0/doc/profile.sgml
0,0 → 1,98
<PART ID="services-profile-gprof">
<TITLE>Application profiling</TITLE>
<PARTINTRO>
<PARA>
The profile_gprof package provides a mechanism to measure the
runtime performance of an application. This is done by gathering
an execution histogram.
</PARA>
<para>
When profiling is started on the target device, a
<function>TFTP</function>
server will be started
which exports the single file
<filename>PROFILE.DAT</filename>
This analysis data can then be fetched
by connecting to the target with a <function>TFTP</function>
client program
and then be processed by the
<function>gprof</function>
utility program.
<note><title>NOTE</title>
<para>
Be sure and specify binary mode transfers for this data file,
which may not be the default with on some <function>TFTP</function>
client programs.
</para>
</note>
<note><title>NOTE</title>
<para>
The port used for this <function>TFTP</function> server is
configurable. The default will be the IETF standard port
of 69/UDP, but it may be changed to any UDP port via the
<literal>CYGNUM_PROFILE_TFTP_PORT</literal> CDL option.
</para>
</note>
</para>
</PARTINTRO>
<CHAPTER id="profile-functions">
<TITLE>Profiling functions</TITLE>
<SECT1 id="services-profile-api">
<title> API </title>
<para>
In order for profile data to be gathered for an application, the
program has to initiate the process.
Once started, execution histogram data will be collected in a
dynamic memory buffer.
This data can be uploaded to a host using <emphasis>TFTP</emphasis>.
A side effect of the upload of the data is that the histogram
is reset.
This is useful, especially for high resolution histograms, since
the histogram data are collected as 16-bit counters which can be quickly
saturated.
For example, if the histogram is being collected at a rate of 10,000
samples per second, a hot spot in the program could saturate after
only 6.5 seconds.
</para>
<para> The API for the application profiling functions can be
found in the file <filename>&lt;cyg/profile/profile.h&gt;</filename>.
</para>
<sect2 id="services-profile-api-profile-on">
<title>profile_on</title>
<para>
This function is used to initiate the gathering of the
runtime execution histogram data.
</para>
<programlisting>
void profile_on(void *start, void *end, int bucket_size, int resolution);
</programlisting>
<para>
Calling this function will initiate execution profiling.
An execution histogram is collected at the rate of
<parameter>resolution</parameter> times per second.
The area between <parameter>start</parameter> and <parameter>end</parameter>
will be divided up into a number of buckets, each representing
<parameter>bucket_size</parameter>
program bytes in length. Using statistical sampling (via a high speed timer), when
the program counter is found to be within the range
<parameter>start</parameter>..<parameter>end</parameter>, the appropriate
bucket (histogram entry) will be incremented.
</para>
<para>
The choice of <parameter>resolution</parameter> and <parameter>bucket_size</parameter>
control how large the data gathered will be, as well as how much overhead is
encumbered for gathering the histogram.
Smaller values for <parameter>bucket_size</parameter> will garner better
results (<function>gprof</function> can more closely align the data with
actual function names) at the expense of a larger data buffer.
</para>
<note><title>NOTE</title>
<para>
The value of <parameter>bucket_size</parameter> will be rounded up to a power of two.
</para>
</note>
</sect2>
</SECT1>
</CHAPTER>
</PART>
 
/gprof/v2_0/ChangeLog
0,0 → 1,61
2003-02-24 Jonathan Larmour <jifl@eCosCentric.com>
 
* cdl/profile_gprof.cdl: Add doc link.
 
2002-11-15 Gary Thomas <gthomas@ecoscentric.com>
 
* include/gmon_out.h: Import non-GPL version from OpenBSD.
 
* doc/profile.sgml: Improve description of host/client and
target/server roles.
 
* src/profile.c:
* cdl/profile_gprof.cdl: Allow TFTP port number to be configured.
 
* src/profile.c:
* include/profile.h: Add proper C++ protections. Change timer
callback function to be __profile_hit() - less polluting.
 
* doc/profile.sgml: New file.
 
2002-11-14 Gary Thomas <gthomas@ecoscentric.com>
 
* src/profile.c:
* include/profile.h:
* include/gmon_out.h:
* cdl/profile.cdl: New package to support application profiling.
 
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 2002 Gary Thomas
//
// eCos 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 or (at your option) any later version.
//
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//===========================================================================
/gprof/v2_0/src/profile.c
0,0 → 1,242
//==========================================================================
//
// profile.c
//
// Application profiling support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 2002 Gary Thomas
//
// eCos 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 or (at your option) any later version.
//
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): Gary Thomas
// Contributors:
// Date: 2002-11-14
// Purpose: Application profiling support
// Description:
//
//####DESCRIPTIONEND####
//
//===========================================================================
#include <pkgconf/profile_gprof.h>
 
#include <stdlib.h>
#include <cyg/infra/diag.h>
#include <network.h>
#include <tftp_support.h>
#include <cyg/profile/profile.h>
#include <cyg/profile/gmon_out.h>
 
static int num_buckets;
static unsigned short *profile;
static int bucket_size, bucket_shift;
static unsigned long start_addr, end_addr;
static int enabled;
static int tftp_server_id;
static int prof_rate;
 
static int profile_open(const char *, int);
static int profile_close(int);
static int profile_write(int, const void *, int);
static int profile_read(int, void *, int);
 
struct tftpd_fileops profile_fileops = {
profile_open, profile_close, profile_write, profile_read
};
 
struct _file {
unsigned char *pos, *eof, *data;
int flags;
int mode;
};
#define FILE_OPEN 0x0001
 
#define NUM_FILES 1
static struct _file files[NUM_FILES];
 
static inline struct _file *
profile_fp(int fd)
{
struct _file *fp;
if ((fd < 0) || (fd >= NUM_FILES)) return (struct _file *)0;
fp = &files[fd];
if (!(fp->flags & FILE_OPEN)) return (struct _file *)0;
return fp;
}
 
static int
profile_open(const char *fn, int flags)
{
int fd = 0;
struct _file *fp;
int len = sizeof(struct gmon_hdr) + sizeof(struct gmon_hist_hdr) + (num_buckets*2) + 1;
struct gmon_hdr _hdr;
struct gmon_hist_hdr _hist_hdr;
unsigned char *bp;
int version = GMON_VERSION;
int hist_size = num_buckets;
int file_type = -1;
 
fp = files;
if (fp->flags & FILE_OPEN) {
// File already open
return -1;
}
if (!(flags & O_RDONLY)) {
// Only read supported
return -1;
}
if (strcmp(fn, "PROFILE.DAT") == 0) {
file_type = 0;
}
if (file_type < 0) {
// No supported file
return -1;
}
// Set up file info
enabled = 0;
switch (file_type) { // In case another type ever supported
case 0: // profile data
fp->data = malloc(len);
if (!fp->data) {
diag_printf("Can't allocate buffer for profile data!\n");
return -1;
}
fp->flags = FILE_OPEN;
fp->mode = flags;
fp->pos = fp->data;
fp->eof = fp->pos + len;
// Fill in profile data
bp = fp->data;
memset(&_hdr, 0, sizeof(_hdr));
strcpy(_hdr.cookie, GMON_MAGIC);
memcpy(_hdr.version, &version, sizeof(version));
memcpy(bp, &_hdr, sizeof(_hdr));
bp += sizeof(_hdr);
memcpy(&_hist_hdr.low_pc, &start_addr, sizeof(start_addr));
memcpy(&_hist_hdr.high_pc, &end_addr, sizeof(end_addr));
memcpy(&_hist_hdr.hist_size, &hist_size, sizeof(hist_size));
memcpy(&_hist_hdr.prof_rate, &prof_rate, sizeof(prof_rate));
strcpy(_hist_hdr.dimen, "seconds");
_hist_hdr.dimen_abbrev = 's';
*bp++ = GMON_TAG_TIME_HIST;
memcpy(bp, &_hist_hdr, sizeof(_hist_hdr));
bp += sizeof(_hist_hdr);
memcpy(bp, profile, (num_buckets*2));
memset(profile, 0, (num_buckets*2));
break;
}
return fd;
}
 
static int
profile_close(int fd)
{
struct _file *fp = profile_fp(fd);
if (!fp) return -1;
if (fp->data) free(fp->data);
fp->flags = 0; // No longer open
enabled = 1;
return 0;
}
 
static int
profile_write(int fd, const void *buf, int len)
{
return -1;
}
 
static int
profile_read(int fd, void *buf, int len)
{
struct _file *fp = profile_fp(fd);
int res;
if (!fp) return -1;
res = fp->eof - fp->pos; // Number of bytes left in "file"
if (res > len) res = len;
if (res <= 0) return 0; // End of file
bcopy(fp->pos, buf, res);
fp->pos += res;
return res;
}
 
void
__profile_hit(unsigned long pc)
{
int bucket;
if (enabled) {
if ((pc >= start_addr) && (pc <= end_addr)) {
bucket = (pc - start_addr) >> bucket_shift;
if (profile[bucket] < (unsigned short)0xFFFF) {
profile[bucket]++;
}
}
}
}
 
void
profile_on(void *_start, void *_end, int _bucket_size, int resolution)
{
start_addr = (unsigned long)_start;
end_addr = (unsigned long)_end;
// Adjust bucket size to be a power of 2
bucket_size = 1;
bucket_shift = 0;
while (bucket_size < _bucket_size) {
bucket_size <<= 1;
bucket_shift++;
}
if (bucket_size != _bucket_size) {
bucket_size <<= 1;
bucket_shift++;
}
// Calculate number of buckets
num_buckets = ((end_addr - start_addr) + (bucket_size - 1)) / bucket_size;
// Adjust end address so calculations come out
end_addr = start_addr + (bucket_size * num_buckets);
prof_rate = 1000000 / resolution;
// Allocate buffer for profile data
if (!(profile = malloc(num_buckets*2))) {
diag_printf("Can't allocate profile buffer - ignored\n");
return;
}
enabled = 1;
diag_printf("Profile from %p..%p[%p], in %d buckets of size %d\n",
start_addr, end_addr, _end, num_buckets, bucket_size);
 
hal_enable_profile_timer(resolution);
 
// Create a TFTP server to provide the data
tftp_server_id = tftpd_start(CYGNUM_PROFILE_TFTP_PORT, &profile_fileops);
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.