# HG changeset patch # User gthomas # Date 1037320041 0 # Node ID cd7e3413ad01b206f52f3abf0a93fe1cc7fcebd8 # Parent abb983ee4de0f3e8a8512b3a71eb8f00c5f7ef72 Rework profile package to more closely follow standards diff --git a/packages/ecos.db b/packages/ecos.db --- a/packages/ecos.db +++ b/packages/ecos.db @@ -1582,12 +1582,13 @@ and 10 second. All loads are returned as This is only a rough measure." } -package CYGPKG_PROFILE { - alias { "Application profile support" profile } - directory services/profile - script profile.cdl +package CYGPKG_PROFILE_GPROF { + alias { "Application profile support" profile_gprof gprof_profile } + directory services/profile/gprof + script profile_gprof.cdl description " -This package instruments applications to collect profiling data." +This package instruments applications to collect profiling data, +using a methodology compatible with the gprof utility." } package CYGPKG_UITRON { diff --git a/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl b/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl --- a/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl +++ b/packages/hal/powerpc/mpc8xx/current/cdl/hal_powerpc_mpc8xx.cdl @@ -60,7 +60,7 @@ cdl_package CYGPKG_HAL_POWERPC_MPC8xx { for this processor variant. It is also necessary to select a specific target platform HAL package." - implements CYGPKG_PROFILE_TIMER + implements CYGINT_PROFILE_HAL_TIMER cdl_interface CYGINT_HAL_USE_ROM_MONITOR_UNSUPPORTED { display "ROM monitor configuration is unsupported" diff --git a/packages/hal/powerpc/mpc8xx/current/src/var_misc.c b/packages/hal/powerpc/mpc8xx/current/src/var_misc.c --- a/packages/hal/powerpc/mpc8xx/current/src/var_misc.c +++ b/packages/hal/powerpc/mpc8xx/current/src/var_misc.c @@ -206,7 +206,7 @@ cyg_hal_clear_MMU (void) CYGARC_MTSPR (MD_CTR, ctr | CYGARC_REG_MD_CTR_CIDEF); } -#ifdef CYGPKG_PROFILE +#ifdef CYGPKG_PROFILE_GPROF //-------------------------------------------------------------------------- // // Profiling support - uses a separate high-speed timer @@ -215,7 +215,7 @@ cyg_hal_clear_MMU (void) #include #include #include -#include +#include // Can't rely on Cyg_Interrupt class being defined. #define Cyg_InterruptHANDLED 1 diff --git a/packages/services/profile/current/ChangeLog b/packages/services/profile/current/ChangeLog deleted file mode 100644 --- a/packages/services/profile/current/ChangeLog +++ /dev/null @@ -1,41 +0,0 @@ -2002-11-14 Gary Thomas - - * 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#### -//=========================================================================== diff --git a/packages/services/profile/current/cdl/profile.cdl b/packages/services/profile/current/cdl/profile.cdl deleted file mode 100644 --- a/packages/services/profile/current/cdl/profile.cdl +++ /dev/null @@ -1,82 +0,0 @@ -# ==================================================================== -# -# profile.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 { - display "Gather runtime profile statistics" - requires CYGPKG_NET - requires CYGPKG_MEMALLOC - requires { CYGPKG_PROFILE_TIMER != 0 } - - include_dir cyg/infra - - 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 CYGPKG_PROFILE_TIMER { - display "High resolution timer, implemented by platform" - description " - Profiling requires access to a high resolution timer which - is platform dependent." - } - - cdl_option CYGPKG_PROFILE_TESTS { - display "Profiling tests" - flavor data - no_define - calculated { "tests/profile.c" } - } -} - diff --git a/packages/services/profile/current/include/gmon_out.h b/packages/services/profile/current/include/gmon_out.h deleted file mode 100644 --- a/packages/services/profile/current/include/gmon_out.h +++ /dev/null @@ -1,82 +0,0 @@ -// Slightly adapted for eCos environment - -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by David Mosberger . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* 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 _SYS_GMON_OUT_H -#define _SYS_GMON_OUT_H 1 - -//#include - -#define GMON_MAGIC "gmon" /* magic cookie */ -#define GMON_VERSION 1 /* version number */ - -/* For profiling shared object we need a new format. */ -#define GMON_SHOBJ_VERSION 0x1ffff - -//__BEGIN_DECLS - -/* - * Raw header as it appears on file (without padding). This header - * always comes first in gmon.out and is then followed by a series - * records defined below. - */ -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 */ - }; - -//__END_DECLS - -#endif /* sys/gmon_out.h */ diff --git a/packages/services/profile/current/include/profile.h b/packages/services/profile/current/include/profile.h deleted file mode 100644 --- a/packages/services/profile/current/include/profile.h +++ /dev/null @@ -1,70 +0,0 @@ -#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 -// -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -// Enable profiling -extern void profile_on(void *start_addr, void *end_addr, - int bucket_size, int sample_resolution); - -// Callback used by timer routine -extern void profile_hit(unsigned long pc); - -// Timer setup routine, used when enabling profiling -extern void hal_enable_profile_timer(int resolution); - -#endif // CYGONCE_PROFILE_H diff --git a/packages/services/profile/current/src/profile.c b/packages/services/profile/current/src/profile.c deleted file mode 100644 --- a/packages/services/profile/current/src/profile.c +++ /dev/null @@ -1,242 +0,0 @@ -//========================================================================== -// -// 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 - -#include -#include -#include -#include -#include -#include - -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(0, &profile_fileops); -} diff --git a/packages/services/profile/gprof/current/ChangeLog b/packages/services/profile/gprof/current/ChangeLog new file mode 100644 --- /dev/null +++ b/packages/services/profile/gprof/current/ChangeLog @@ -0,0 +1,41 @@ +2002-11-14 Gary Thomas + + * 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#### +//=========================================================================== diff --git a/packages/services/profile/gprof/current/cdl/profile_gprof.cdl b/packages/services/profile/gprof/current/cdl/profile_gprof.cdl new file mode 100644 --- /dev/null +++ b/packages/services/profile/gprof/current/cdl/profile_gprof.cdl @@ -0,0 +1,83 @@ +# ==================================================================== +# +# 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 } + + 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 CYGPKG_PROFILE_TESTS { + display "Profiling tests" + flavor data + no_define + calculated { "tests/profile.c" } + } +} + diff --git a/packages/services/profile/gprof/current/include/gmon_out.h b/packages/services/profile/gprof/current/include/gmon_out.h new file mode 100644 --- /dev/null +++ b/packages/services/profile/gprof/current/include/gmon_out.h @@ -0,0 +1,82 @@ +// Slightly adapted for eCos environment + +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Mosberger . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* 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 _SYS_GMON_OUT_H +#define _SYS_GMON_OUT_H 1 + +//#include + +#define GMON_MAGIC "gmon" /* magic cookie */ +#define GMON_VERSION 1 /* version number */ + +/* For profiling shared object we need a new format. */ +#define GMON_SHOBJ_VERSION 0x1ffff + +//__BEGIN_DECLS + +/* + * Raw header as it appears on file (without padding). This header + * always comes first in gmon.out and is then followed by a series + * records defined below. + */ +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 */ + }; + +//__END_DECLS + +#endif /* sys/gmon_out.h */ diff --git a/packages/services/profile/gprof/current/include/profile.h b/packages/services/profile/gprof/current/include/profile.h new file mode 100644 --- /dev/null +++ b/packages/services/profile/gprof/current/include/profile.h @@ -0,0 +1,70 @@ +#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 +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +// Enable profiling +extern void profile_on(void *start_addr, void *end_addr, + int bucket_size, int sample_resolution); + +// Callback used by timer routine +extern void profile_hit(unsigned long pc); + +// Timer setup routine, used when enabling profiling +extern void hal_enable_profile_timer(int resolution); + +#endif // CYGONCE_PROFILE_H diff --git a/packages/services/profile/gprof/current/src/profile.c b/packages/services/profile/gprof/current/src/profile.c new file mode 100644 --- /dev/null +++ b/packages/services/profile/gprof/current/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 + +#include +#include +#include +#include +#include +#include + +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(0, &profile_fileops); +}