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><cyg/profile/profile.h></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); |
} |