summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-10-06 19:24:22 +0200
committerMark Wielaard <mjw@redhat.com>2009-10-06 19:24:57 +0200
commit47f025139d1c2e75781cdab40dc9195396133754 (patch)
treed160760fdea8095f82cfd382eb7640deb95918a7
parent2155081e1d9888cf57334bc57abb3fff9b49d8e1 (diff)
downloadsystemtap-steved-47f025139d1c2e75781cdab40dc9195396133754.tar.gz
systemtap-steved-47f025139d1c2e75781cdab40dc9195396133754.tar.xz
systemtap-steved-47f025139d1c2e75781cdab40dc9195396133754.zip
Add proc_mem tapset, functions to query memory usage of the current process.
* tapset/proc_mem.stp: New tapset. * testsuite/buildok/proc_mem.stp * doc/SystemTap_Tapset_Reference/tapsets.tmpl (memory_stp): Include tapset/proc_mem.stp.
-rw-r--r--doc/SystemTap_Tapset_Reference/tapsets.tmpl4
-rw-r--r--tapset/proc_mem.stp194
-rwxr-xr-xtestsuite/buildok/proc_mem.stp13
3 files changed, 210 insertions, 1 deletions
diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl
index 99f72727..705cd3b5 100644
--- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl
+++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl
@@ -138,10 +138,12 @@
<chapter id="memory_stp">
<title>Memory Tapset</title>
<para>
- This family of probe points is used to probe memory-related events.
+ This family of probe points is used to probe memory-related events
+ or query the memory usage of the current process.
It contains the following probe points:
</para>
!Itapset/memory.stp
+!Itapset/proc_mem.stp
</chapter>
<chapter id="iosched.stp">
diff --git a/tapset/proc_mem.stp b/tapset/proc_mem.stp
new file mode 100644
index 00000000..1493bd92
--- /dev/null
+++ b/tapset/proc_mem.stp
@@ -0,0 +1,194 @@
+// Process memory query and utility functions.
+// Copyright (C) 2009 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+// <tapsetdescription>
+// Process memory query and utility functions provide information about
+// the memory usage of the current application. These functions provide
+// information about the full size, resident, shared, code and data used
+// by the current process. And provide utility functions to query the
+// page size of the current architecture and create human readable string
+// representations of bytes and pages used.
+// </tapsetdescription>
+
+%{
+/* PF_BORROWED_MM got renamed to PF_KTHREAD with same semantics somewhere. */
+#ifdef PF_BORROWED_MM
+#define _STP_PF_KTHREAD PF_BORROWED_MM
+#else
+#define _STP_PF_KTHREAD PF_KTHREAD
+#endif
+ /* Returns the mm for the current proc. Slightly paranoid. Only returns
+ if the task isn't starting, exiting or (coopted by) a kernel thread. */
+ static struct mm_struct *_stp_proc_mm(void)
+ {
+ if (current->flags & (_STP_PF_KTHREAD | PF_EXITING | PF_STARTING))
+ return NULL;
+ return current->mm;
+ }
+%}
+
+/**
+ * sfunction proc_mem_size - Total program virtual memory size in pages.
+ *
+ * Description: Returns the total virtual memory size in pages of the
+ * current process, or zero when there is no current process or the
+ * number of pages couldn't be retrieved.
+ */
+function proc_mem_size:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = mm->total_vm;
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_rss - Program resident set size in pages.
+ *
+ * Description: Returns the resident set size in pages of the current
+ * process, or zero when there is no current process or the number of
+ * pages couldn't be retrieved.
+ */
+function proc_mem_rss:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = (get_mm_counter(mm, file_rss)
+ + get_mm_counter(mm, anon_rss));
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_shr - Program shared pages (from shared mappings).
+ *
+ * Description: Returns the shared pages (from shared mappings) of the
+ * current process, or zero when there is no current process or the
+ * number of pages couldn't be retrieved.
+ */
+function proc_mem_shr:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = get_mm_counter(mm, file_rss);
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_txt - Program text (code) size in pages.
+ *
+ * Description: Returns the current process text (code) size in pages,
+ * or zero when there is no current process or the number of pages
+ * couldn't be retrieved.
+ */
+function proc_mem_txt:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = (PAGE_ALIGN(mm->end_code)
+ - (mm->start_code & PAGE_MASK)) >> PAGE_SHIFT;
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction proc_mem_data - Program data size (data + stack) in pages.
+ *
+ * Description: Returns the current process data size (data + stack)
+ * in pages, or zero when there is no current process or the number of
+ * pages couldn't be retrieved.
+ */
+function proc_mem_data:long ()
+%{ /* pure */ /* unprivileged */
+ struct mm_struct *mm = _stp_proc_mm ();
+ if (mm)
+ THIS->__retvalue = mm->total_vm - mm->shared_vm;
+ else
+ THIS->__retvalue = 0;
+%}
+
+/**
+ * sfunction mem_page_size - Number of bytes in a page for this architecture.
+ */
+function mem_page_size:long ()
+%{ /* pure */ /* unprivileged */
+ THIS->__retvalue = PAGE_SIZE;
+%}
+
+// Return a 5 character wide string " x.yyp", " xx.yp", " xxxp", "xxxxp".
+function _stp_number_to_string_postfix:string (x:long, y:long, p:string)
+{
+ if (x < 10)
+ return sprintf("%d.%.2d%s", x, y * 100 / 1024, p);
+ if (x < 100)
+ return sprintf("%2d.%d%s", x, y * 10 / 1024, p);
+ return sprintf("%4d%s", x, p);
+}
+
+/**
+ * sfunction bytes_to_string - Human readable string for given bytes.
+ *
+ * Description: Returns a string representing the number of bytes (up
+ * to 1024 bytes), the number of kilobytes (when less than 1024K)
+ * postfixed by 'K', the number of megabytes (when less than 1024M)
+ * postfixed by 'M' or the number of gigabytes postfixed by 'G'. If
+ * representing K, M or G, and the number is amount is less than 100,
+ * it includes a '.' plus the remainer. The returned string will be 5
+ * characters wide (padding with whitespace at the front) unless
+ * negative or representing more than 9999G bytes.
+ */
+function bytes_to_string:string (bytes:long)
+{
+ if (bytes < 1024)
+ return sprintf("%5d", bytes);
+
+ remain = bytes % 1024;
+ bytes = bytes / 1024;
+ if (bytes < 1024)
+ return _stp_number_to_string_postfix(bytes, remain, "K");
+
+ remain = bytes % 1024;
+ bytes = bytes / 1024;
+ if (bytes < 1024)
+ return _stp_number_to_string_postfix(bytes, remain, "M");
+
+ remain = bytes % 1024;
+ bytes = bytes / 1024;
+ return _stp_number_to_string_postfix(bytes, remain, "G");
+}
+
+/**
+ * sfunction pages_to_string - Turns pages into a human readable string.
+ *
+ * Description: Multiplies pages by page_size() to get the number of
+ * bytes and returns the result of bytes_to_string().
+ */
+function pages_to_string:string (pages:long)
+{
+ bytes = pages * mem_page_size();
+ return bytes_to_string (bytes);
+}
+
+/**
+ * sfunction proc_mem_string - Human readable string of current proc memory usage.
+ *
+ * Description: Returns a human readable string showing the size, rss,
+ * shr, txt and data of the memory used by the current process.
+ * For example "size: 301m, rss: 11m, shr: 8m, txt: 52k, data: 2248k".
+ */
+function proc_mem_string:string ()
+{
+ return sprintf ("size: %s, rss: %s, shr: %s, txt: %s, data: %s",
+ pages_to_string(proc_mem_size()),
+ pages_to_string(proc_mem_rss()),
+ pages_to_string(proc_mem_shr()),
+ pages_to_string(proc_mem_txt()),
+ pages_to_string(proc_mem_data()));
+}
diff --git a/testsuite/buildok/proc_mem.stp b/testsuite/buildok/proc_mem.stp
new file mode 100755
index 00000000..8fc2512a
--- /dev/null
+++ b/testsuite/buildok/proc_mem.stp
@@ -0,0 +1,13 @@
+#! stap -p4
+
+probe begin {
+ printf("%d\n", proc_mem_size());
+ printf("%d\n", proc_mem_rss());
+ printf("%d\n", proc_mem_shr());
+ printf("%d\n", proc_mem_txt());
+ printf("%d\n", proc_mem_data());
+ printf("%d\n", mem_page_size())
+ printf("%s\n", bytes_to_string(0));
+ printf("%s\n", pages_to_string(0));
+ printf("%s\n", proc_mem_string());
+}