summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/profiling/monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/profiling/monitor.c')
-rw-r--r--mdk-stage1/dietlibc/profiling/monitor.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/mdk-stage1/dietlibc/profiling/monitor.c b/mdk-stage1/dietlibc/profiling/monitor.c
new file mode 100644
index 000000000..cc06e3465
--- /dev/null
+++ b/mdk-stage1/dietlibc/profiling/monitor.c
@@ -0,0 +1,93 @@
+/**************************************************************
+ Copyright (C) 2001, 2002 Thomas M. Ogrisegg
+
+ This is free software. You can redistribute and modify
+ it under the terms of the GNU General Public License.
+
+ This file is part of the profiling support for dietlibc
+
+ monitor(3) interface
+
+ *************************************************************/
+#include <sys/uio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/gmon.h>
+
+typedef unsigned short u_short;
+
+struct monparam mparam;
+
+void monitor (unsigned long, unsigned long) PROF_SECTION;
+void _stop_monitor (void) PROF_SECTION;
+
+/*
+ monitor is called by _start, to start profiling
+ lowpc -> lowest valid program counter (normally .text)
+ highpc -> highest valid program counter (normally _etext)
+*/
+void
+monitor (unsigned long lowpc, unsigned long highpc)
+{
+ mparam.highpc = highpc;
+ mparam.lowpc = lowpc;
+ mparam.kcountsize = (mparam.textsize = highpc-lowpc) << 1;
+ mparam.kcount = (u_short *) malloc (mparam.kcountsize);
+ mparam.arcs = (struct rawarc *) malloc (MAXARCS*sizeof (struct rawarc));
+ if (!mparam.kcount || !mparam.arcs)
+ exit (42);
+ mparam.arcnum = 0;
+ /* start profiling */
+ profil (mparam.kcount, highpc-lowpc, lowpc, 10000);
+}
+
+/*
+ write_gmon - write all data collected by the helper routines
+ to gmon.out
+*/
+static void
+write_gmon (void)
+{
+ struct gmon_hdr ghdr = { "gmon", 1, "" };
+ int fd = open ("gmon.out", O_CREAT | O_RDWR | O_TRUNC, 0666);
+
+ if (fd < 0) return;
+ write (fd, &ghdr, sizeof (ghdr));
+ if (mparam.kcountsize)
+ {
+ char tag = GMON_TAG_TIME_HIST;
+ struct gmon_hist_hdr ghdr = {
+ mparam.lowpc, mparam.highpc,
+ (mparam.kcountsize >> 1), 100, "seconds", 's'
+ };
+ struct iovec iov[3] = {
+ { &tag, sizeof (tag) },
+ { &ghdr, sizeof (ghdr) },
+ { mparam.kcount, mparam.kcountsize >> 1 << 1 }
+ };
+ writev (fd, iov, 3);
+ }
+ if (mparam.arcnum)
+ {
+ char tag = GMON_TAG_CG_ARC;
+ struct iovec iov[mparam.arcnum*2];
+ unsigned long l;
+ for (l=0;l<mparam.arcnum;l++) {
+ iov[l*2].iov_base = &tag;
+ iov[l*2].iov_len = sizeof (tag);
+ iov[l*2+1].iov_base = &mparam.arcs[l];
+ iov[l*2+1].iov_len = sizeof (mparam.arcs[l]);
+ }
+ writev (fd, iov, mparam.arcnum*2);
+ }
+ close (fd);
+}
+
+/* called by _start before exit */
+void
+_stop_monitor (void)
+{
+ profil (NULL, 0, 0, 0);
+ write_gmon ();
+}