<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:syn="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/">
  <channel rdf:about="http://blog.gmane.org/gmane.linux.oprofile">
    <title>gmane.linux.oprofile</title>
    <link>http://blog.gmane.org/gmane.linux.oprofile</link>
    <description/>
    <syn:updatePeriod>hourly</syn:updatePeriod>
    <syn:updateFrequency>1</syn:updateFrequency>
    <syn:updateBase>1901-01-01T00:00+00:00</syn:updateBase>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10511"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10510"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10509"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10508"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10507"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10506"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10505"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10504"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10503"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10502"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10501"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10500"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10499"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10498"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10497"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10496"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10495"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10494"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10493"/>
        <rdf:li rdf:resource="http://permalink.gmane.org/gmane.linux.oprofile/10492"/>
      </rdf:Seq>
    </items>
    <image rdf:resource="http://gmane.org/img/gmane-25t.png"/>
    <textinput rdf:resource=""/>
  </channel>
  <image rdf:about="http://gmane.org/img/gmane-25t.png">
    <title>Gmane</title>
    <url>http://gmane.org/img/gmane-25t.png</url>
    <link>http://gmane.org</link>
  </image>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10511">
    <title>Re: [PATCH 2/2] Add the event list for Intel IvyBridge</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10511</link>
    <description>&lt;pre&gt;The patch looks fine.  Does it pass 'make distcheck'?

-Maynard


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-25T13:48:32</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10510">
    <title>Re: [PATCH 1/2] Implement the ANY Intel extra bit</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10510</link>
    <description>&lt;pre&gt;Patch applied.

-Maynard


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-25T13:47:48</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10509">
    <title>[PATCH] Fix up anonymous mapping support in operf to include vdso,stack, and heap</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10509</link>
    <description>&lt;pre&gt;[PATCH] Fix up anonymous mapping support in operf to include vdso, stack, and heap


Signed-off-by: Maynard Johnson &amp;lt;maynardj&amp;lt; at &amp;gt;us.ibm.com&amp;gt;

This patch has been pushed to the perf-events branch, but review comments are
welcome.

---
 libperf_events/operf_mangling.cpp |    2 +-
 libperf_events/operf_utils.cpp    |   17 +++++++++++------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/libperf_events/operf_mangling.cpp b/libperf_events/operf_mangling.cpp
index 5b31e29..5165807 100644
--- a/libperf_events/operf_mangling.cpp
+++ b/libperf_events/operf_mangling.cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -63,7 +63,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; mangle_filename(struct operf_sfile * last, struct operf_sfile const * sf, int co
 } else if (sf-&amp;gt;is_anon) {
 values.flags |= MANGLE_ANON;
 values.image_name = mangle_anon(sf);
-values.anon_name = "anon";
+values.anon_name = sf-&amp;gt;image_name;
 } else {
 values.image_name = sf-&amp;gt;image_name;
 }
diff --git a/libperf_events/operf_utils.cpp b/libperf_events/operf_utils.cpp
index 42eecce..9ee9b80 100644
--- a/libperf_events/operf_utils.cpp
+++ b/libperf_events/operf_utils.cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -208,12 +208,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_mmap_event(event_t * event)
 memset(mapping, 0, sizeof(struct operf_mmap));
 mapping-&amp;gt;start_addr = event-&amp;gt;mmap.start;
         strcpy(mapping-&amp;gt;filename, event-&amp;gt;mmap.filename);
-        mapping-&amp;gt;is_anon_mapping = (strncmp(mapping-&amp;gt;filename,
-                                            "//anon",
-                                            strlen("//anon")) == 0) ?
-                                                                     true
-                                                                     : false;
-
+/* Mappings starting with "/" are for either a file or shared memory object.
+ * From the kernel's perf_events subsystem, anon maps have labels like:
+ *     [heap], [stack], [vdso], //anon
+ */
+if (mapping-&amp;gt;filename[0] == '[') {
+mapping-&amp;gt;is_anon_mapping = true;
+} else if ((strncmp(mapping-&amp;gt;filename, "//anon",
+                    strlen("//anon")) == 0)) {
+mapping-&amp;gt;is_anon_mapping = true;
+strcpy(mapping-&amp;gt;filename, "anon");
+}
 mapping-&amp;gt;end_addr = (event-&amp;gt;mmap.len == 0ULL)? 0ULL : mapping-&amp;gt;start_addr + event-&amp;gt;mmap.len - 1;
 mapping-&amp;gt;pgoff = event-&amp;gt;mmap.pgoff;
 
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-25T14:00:32</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10508">
    <title>Re: [PATCH 2/2] Add the event list for Intel IvyBridge</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10508</link>
    <description>&lt;pre&gt;
Yes.

-Andi

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Andi Kleen</dc:creator>
    <dc:date>2012-05-25T13:51:50</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10507">
    <title>[ oprofile-Bugs-3529111 ] opjitconv failed to parse JIT dump header</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10507</link>
    <description>&lt;pre&gt;Bugs item #3529111, was opened at 2012-05-23 08:05
Message generated for change (Tracker Item Submitted) made by 
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&amp;amp;atid=116191&amp;amp;aid=3529111&amp;amp;group_id=16191

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: https://www.google.com/accounts ()
Assigned to: Nobody/Anonymous (nobody)
Summary: opjitconv failed to parse JIT dump header

Initial Comment:
The bug occurs on x86_64 Linux (Fedora 15) with oprofile installed from oprofile-0.9.6-21.fc15.x86_64.rpm while trying to profile JIT code produced by 32-bit application.

The debug output of opjitconv shows:

header: bfd-arch=9, bfd-mach=1, bfd_target_name=2-i386

Note that target name must be "elf32-i386"

I assume that the "u64 timestamp" field of "jitheader" structure is 8-byte aligned and as result field "bfd_target" is shifted 4 bytes forward.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&amp;amp;atid=116191&amp;amp;aid=3529111&amp;amp;group_id=16191

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>SourceForge.net</dc:creator>
    <dc:date>2012-05-23T15:05:08</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10506">
    <title>[PATCH 1/2] Implement the ANY Intel extra bit</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10506</link>
    <description>&lt;pre&gt;From: Andi Kleen &amp;lt;ak&amp;lt; at &amp;gt;linux.intel.com&amp;gt;

Implement the ANY (any thread) extra bit for Intel CPUs. Needed
for some of the new events.

Signed-off-by: Andi Kleen &amp;lt;ak&amp;lt; at &amp;gt;linux.intel.com&amp;gt;
---
 libop/op_events.c |    3 +++
 libop/op_events.h |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/libop/op_events.c b/libop/op_events.c
index bbb0130..49b9563 100644
--- a/libop/op_events.c
+++ b/libop/op_events.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -127,6 +127,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; unsigned parse_extra(const char *s)
 } else if (sscanf(s, "cmask=%x%n", &amp;amp;w, &amp;amp;o) &amp;gt;= 1) {
 v |= (w &amp;amp; EXTRA_CMASK_MASK) &amp;lt;&amp;lt; EXTRA_CMASK_SHIFT;
 s += o;
+} else if (strisprefix(s, "any")) {
+v |= EXTRA_ANY;
+s += 3;
 } else {
 parse_error("Illegal extra field modifier");
 }
diff --git a/libop/op_events.h b/libop/op_events.h
index 8cbb622..1a65a7a 100644
--- a/libop/op_events.h
+++ b/libop/op_events.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -21,6 +21,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern "C" {
 #include "op_list.h"
 
 #define EXTRA_EDGE (1U &amp;lt;&amp;lt; 18)
+#define EXTRA_ANY  (1U &amp;lt;&amp;lt; 21)
 #define EXTRA_INV  (1U &amp;lt;&amp;lt; 23)
 #define EXTRA_CMASK_SHIFT 24
 #define EXTRA_CMASK_MASK 0xff
&lt;/pre&gt;</description>
    <dc:creator>Andi Kleen</dc:creator>
    <dc:date>2012-05-23T00:48:42</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10505">
    <title>[PATCH 2/2] Add the event list for Intel IvyBridge</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10505</link>
    <description>&lt;pre&gt;From: Andi Kleen &amp;lt;ak&amp;lt; at &amp;gt;linux.intel.com&amp;gt;

This adds the event list for Intel IvyBridge and the model number
for the current IvyBridge systems

Signed-off-by: Andi Kleen &amp;lt;ak&amp;lt; at &amp;gt;linux.intel.com&amp;gt;
---
 events/Makefile.am               |    1 +
 events/i386/ivybridge/events     |   57 ++++++++
 events/i386/ivybridge/unit_masks |  269 ++++++++++++++++++++++++++++++++++++++
 libop/op_cpu_type.c              |    2 +
 libop/op_cpu_type.h              |    1 +
 libop/op_events.c                |    1 +
 libop/op_hw_specific.h           |    2 +
 utils/ophelp.c                   |    1 +
 8 files changed, 334 insertions(+), 0 deletions(-)
 create mode 100644 events/i386/ivybridge/events
 create mode 100644 events/i386/ivybridge/unit_masks

diff --git a/events/Makefile.am b/events/Makefile.am
index 1f7e662..df5215c 100644
--- a/events/Makefile.am
+++ b/events/Makefile.am
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -19,6 +19,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; event_files = \
 i386/nehalem/events i386/nehalem/unit_masks \
 i386/westmere/events i386/westmere/unit_masks \
 i386/sandybridge/events i386/sandybridge/unit_masks \
+i386/ivybridge/events i386/ivybridge/unit_masks \
 ia64/ia64/events ia64/ia64/unit_masks \
 ia64/itanium2/events ia64/itanium2/unit_masks \
 ia64/itanium/events ia64/itanium/unit_masks \
diff --git a/events/i386/ivybridge/events b/events/i386/ivybridge/events
new file mode 100644
index 0000000..46405dd
--- /dev/null
+++ b/events/i386/ivybridge/events
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,57 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#
+# Event masks for the Intel "Ivy Bridge" micro architecture
+#
+# See http://ark.intel.com/ for help in identifying Ivy Bridge based CPUs
+#
+include:i386/arch_perfmon
+event:0x3 counters:cpuid um:ld_blocks minimum:100000 name:ld_blocks : Blocked loads
+event:0x5 counters:cpuid um:misalign_mem_ref minimum:2000000 name:misalign_mem_ref : Misaligned memory references
+event:0x7 counters:cpuid um:ld_blocks_partial minimum:100000 name:ld_blocks_partial : Partial loads
+event:0x8 counters:cpuid um:dtlb_load_misses minimum:2000000 name:dtlb_load_misses : D-TLB misses
+event:0xd counters:cpuid um:int_misc minimum:2000000 name:int_misc : Instruction decoder events
+event:0xe counters:0,1,2,3 um:uops_issued minimum:2000000 name:uops_issued : Uops issued
+event:0x14 counters:cpuid um:arith minimum:2000000 name:arith : Arithmetic
+event:0x24 counters:cpuid um:l2_rqsts minimum:200000 name:l2_rqsts : L2 cache requests
+event:0x27 counters:cpuid um:l2_store_lock_rqsts minimum:200000 name:l2_store_lock_rqsts : L2 cache store lock requests
+event:0x28 counters:cpuid um:l2_l1d_wb_rqsts minimum:200000 name:l2_l1d_wb_rqsts : writebacks from L1D to the L2 cache
+event:0x48 counters:2 um:l1d_pend_miss minimum:2000000 name:l1d_pend_miss : L1D miss oustandings
+event:0x49 counters:cpuid um:dtlb_store_misses minimum:2000000 name:dtlb_store_misses : Store misses in all DTLB levels that cause page walks
+event:0x4c counters:cpuid um:load_hit_pre minimum:100000 name:load_hit_pre :  Load dispatches that hit fill buffer
+event:0x51 counters:cpuid um:l1d minimum:2000000 name:l1d : L1D data line replacements
+event:0x58 counters:cpuid um:move_elimination minimum:1000000 name:move_elimination : Integer move elimination
+event:0x5c counters:cpuid um:cpl_cycles minimum:2000000 name:cpl_cycles : Unhalted core cycles qualified by ring
+event:0x5e counters:cpuid um:rs_events minimum:2000000 name:rs_events : Reservation station
+event:0x5f counters:cpuid um:tlb_access minimum:100000 name:tlb_access : TLB access
+event:0x60 counters:cpuid um:offcore_requests_outstanding minimum:2000000 name:offcore_requests_outstanding : Offcore outstanding transactions
+event:0x63 counters:cpuid um:lock_cycles minimum:2000000 name:lock_cycles : Locked cycles
+event:0x79 counters:0,1,2,3 um:idq minimum:2000000 name:idq : Instruction Decode Queue (IDQ)
+event:0x80 counters:cpuid um:icache minimum:200000 name:icache : Instruction cache
+event:0x85 counters:cpuid um:itlb_misses minimum:2000000 name:itlb_misses : Misses at all ITLB levels that cause page walks
+event:0x87 counters:cpuid um:ild_stall minimum:2000000 name:ild_stall : Stalls caused by changing prefix length of the instruction.
+event:0x88 counters:cpuid um:br_inst_exec minimum:200000 name:br_inst_exec : Branch instructions
+event:0x89 counters:cpuid um:br_misp_exec minimum:200000 name:br_misp_exec : Mispredicted branch instructions
+event:0x9c counters:cpuid um:idq_uops_not_delivered minimum:2000000 name:idq_uops_not_delivered : Uops not delivered by the Frontend to the Backend of the machine, while there is no Backend stall 
+event:0xa1 counters:cpuid um:uops_dispatched_port minimum:2000000 name:uops_dispatched_port : Cycles per thread when uops are dispatched to port
+event:0xa2 counters:cpuid um:resource_stalls minimum:2000000 name:resource_stalls : Resource-related stall cycles
+event:0xa3 counters:2 um:cycle_activity minimum:2000000 name:cycle_activity : Cycle activity
+event:0xab counters:cpuid um:dsb2mite_switches minimum:2000000 name:dsb2mite_switches : Decode Stream Buffer (DSB)-to-MITE switches
+event:0xac counters:cpuid um:dsb_fill minimum:2000000 name:dsb_fill : Decode Stream Buffer (DSB) fill
+event:0xae counters:cpuid um:itlb minimum:10000 name:itlb : Instruction TLB (ITLB)
+event:0xb0 counters:cpuid um:offcore_requests minimum:100000 name:offcore_requests : Uncore requests
+event:0xb1 counters:0,1,2,3 um:uops_executed minimum:2000000 name:uops_executed : Uops executed
+event:0xbd counters:cpuid um:tlb_flush minimum:10000 name:tlb_flush : DTLB flushes
+event:0xc1 counters:cpuid um:other_assists minimum:100000 name:other_assists : Microcode assists.
+event:0xc2 counters:0,1,2,3 um:uops_retired minimum:2000000 name:uops_retired : Retired uops. 
+event:0xc3 counters:cpuid um:machine_clears minimum:100000 name:machine_clears : Machine clears
+event:0xc4 counters:cpuid um:br_inst_retired minimum:400000 name:br_inst_retired : Conditional branch instructions retired. 
+event:0xc5 counters:cpuid um:br_misp_retired minimum:400000 name:br_misp_retired : Mispredicted conditional branch instructions retired. 
+event:0xca counters:0,1,2,3 um:fp_assist minimum:100000 name:fp_assist : FPU assists
+event:0xcc counters:cpuid um:rob_misc_events minimum:2000000 name:rob_misc_events : ROB (Register Order Buffer) events
+event:0xd0 counters:0,1,2,3 um:mem_uops_retired minimum:2000000 name:mem_uops_retired : Memory Uops
+event:0xd1 counters:0,1,2,3 um:mem_load_uops_retired minimum:50000 name:mem_load_uops_retired : Memory load uops
+event:0xd2 counters:0,1,2,3 um:mem_load_uops_llc_hit_retired minimum:20000 name:mem_load_uops_llc_hit_retired : Memory load uops with LLC (Last Level Cache) hit
+event:0xd3 counters:0,1,2,3 um:mem_load_uops_llc_miss_retired minimum:10000 name:mem_load_uops_llc_miss_retired : Memory load uops with LLC (Last Level Cache) miss
+event:0xe6 counters:cpuid um:baclears minimum:100000 name:baclears : Frontend resteering
+event:0xf0 counters:cpuid um:l2_trans minimum:200000 name:l2_trans : L2 cache transactions
+event:0xf1 counters:cpuid um:l2_lines_in minimum:100000 name:l2_lines_in : L2 cache lines in
+event:0xf2 counters:cpuid um:l2_lines_out minimum:100000 name:l2_lines_out : L2 cache lines out
diff --git a/events/i386/ivybridge/unit_masks b/events/i386/ivybridge/unit_masks
new file mode 100644
index 0000000..5363017
--- /dev/null
+++ b/events/i386/ivybridge/unit_masks
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -0,0 +1,269 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
+#
+# Unit masks for the Intel "Ivy Bridge" micro architecture
+#
+# See http://ark.intel.com/ for help in identifying Ivy Bridge based CPUs
+#
+include:i386/arch_perfmon
+name:ld_blocks type:mandatory default:0x2
+0x2 store_forward loads blocked by overlapping with store buffer that cannot be forwarded
+name:misalign_mem_ref type:bitmask default:0x1
+0x1 loads Speculative cache line split load uops dispatched to L1 cache
+0x2 stores Speculative cache line split STA uops dispatched to L1 cache
+name:ld_blocks_partial type:mandatory default:0x1
+0x1 address_alias False dependencies in MOB due to partial compare on address
+name:dtlb_load_misses type:exclusive default:0x81
+0x81 demand_ld_miss_causes_a_walk Demand load Miss in all translation lookaside buffer (TLB) levels causes an page walk of any page size.
+0x82 demand_ld_walk_completed Demand load Miss in all translation lookaside buffer (TLB) levels causes a page walk that completes of any page size.
+0x84 demand_ld_walk_duration Demand load cycles page miss handler (PMH) is busy with this walk.
+name:int_misc type:exclusive default:0x3
+0x3 extra:cmask=1 recovery_cycles Number of cycles waiting for the checkpoints in Resource Allocation Table (RAT) to be recovered after Nuke due to all other cases except JEClear (e.g. whenever a ucode assist is needed like SSE exception, memory disambiguation, etc...)
+0x3 extra:cmask=1,edge recovery_stalls_count Number of occurences waiting for the checkpoints in Resource Allocation Table (RAT) to be recovered after Nuke due to all other cases except JEClear (e.g. whenever a ucode assist is needed like SSE exception, memory disambiguation, etc...)
+name:uops_issued type:exclusive default:0x1
+0x1 any Uops that Resource Allocation Table (RAT) issues to Reservation Station (RS)
+0x1 extra:cmask=1,inv stall_cycles Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for the thread
+0x1 extra:cmask=1,inv,any core_stall_cycles Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for all threads
+0x10 flags_merge Number of flags-merge uops being allocated.
+0x20 slow_lea Number of slow LEA uops being allocated. A uop is generally considered SlowLea if it has 3 sources (e.g. 2 sources + immediate) regardless if as a result of LEA instruction or not.
+0x40 single_mul Number of Multiply packed/scalar single precision uops allocated
+name:arith type:bitmask default:0x1
+0x1 fpu_div_active Cycles when divider is busy executing divide operations
+0x4 extra:cmask=1,edge fpu_div Divide operations executed
+name:l2_rqsts type:exclusive default:0x1
+0x1 demand_data_rd_hit Demand Data Read requests that hit L2 cache
+0x3 all_demand_data_rd Demand Data Read requests
+0x4 rfo_hit RFO requests that hit L2 cache
+0x8 rfo_miss RFO requests that miss L2 cache
+0xc all_rfo RFO requests to L2 cache
+0x10 code_rd_hit L2 cache hits when fetching instructions, code reads.
+0x20 code_rd_miss L2 cache misses when fetching instructions
+0x30 all_code_rd L2 code requests
+0x40 pf_hit Requests from the L2 hardware prefetchers that hit L2 cache
+0x80 pf_miss Requests from the L2 hardware prefetchers that miss L2 cache
+0xc0 all_pf Requests from L2 hardware prefetchers
+name:l2_store_lock_rqsts type:exclusive default:0x1
+0x1 miss RFOs that miss cache lines
+0x8 hit_m RFOs that hit cache lines in M state
+0xf all RFOs that access cache lines in any state
+name:l2_l1d_wb_rqsts type:exclusive default:0x1
+0x1 miss Count the number of modified Lines evicted from L1 and missed L2. (Non-rejected WBs from the DCU.)
+0x4 hit_e Not rejected writebacks from L1D to L2 cache lines in E state
+0x8 hit_m Not rejected writebacks from L1D to L2 cache lines in M state
+0xf all Not rejected writebacks from L1D to L2 cache lines in any state.
+name:l1d_pend_miss type:exclusive default:0x1
+0x1 pending L1D miss oustandings duration in cycles
+0x1 extra:cmask=1 pending_cycles Cycles with L1D load Misses outstanding. 
+0x1 extra:cmask=1,edge occurences This event counts the number of L1D misses outstanding, using an edge detect to count transitions.
+name:dtlb_store_misses type:bitmask default:0x1
+0x1 miss_causes_a_walk Store misses in all DTLB levels that cause page walks
+0x2 walk_completed Store misses in all DTLB levels that cause completed page walks
+0x4 walk_duration Cycles when PMH is busy with page walks
+0x10 stlb_hit Store operations that miss the first TLB level but hit the second and do not cause page walks
+name:load_hit_pre type:bitmask default:0x1
+0x1 sw_pf Not software-prefetch load dispatches that hit forward buffer allocated for software prefetch
+0x2 hw_pf Not software-prefetch load dispatches that hit forward buffer allocated for hardware prefetch
+name:l1d type:mandatory default:0x1
+0x1 replacement L1D data line replacements
+name:move_elimination type:bitmask default:0x1
+0x1 int_not_eliminated Number of integer Move Elimination candidate uops that were not eliminated.
+0x2 simd_not_eliminated Number of SIMD Move Elimination candidate uops that were not eliminated.
+0x4 int_eliminated Number of integer Move Elimination candidate uops that were eliminated.
+0x8 simd_eliminated Number of SIMD Move Elimination candidate uops that were eliminated.
+name:cpl_cycles type:exclusive default:0x1
+0x1 ring0 Unhalted core cycles when the thread is in ring 0
+0x1 extra:cmask=1,edge ring0_trans Number of intervals between processor halts while thread is in ring 0
+0x2 ring123 Unhalted core cycles when thread is in rings 1, 2, or 3
+name:rs_events type:mandatory default:0x1
+0x1 empty_cycles Cycles when Reservation Station (RS) is empty for the thread
+name:tlb_access type:mandatory default:0x4
+0x4 load_stlb_hit Load operations that miss the first DTLB level but hit the second and do not cause page walks
+name:offcore_requests_outstanding type:exclusive default:0x1
+0x1 demand_data_rd Offcore outstanding Demand Data Read transactions in uncore queue.
+0x1 extra:cmask=1 cycles_with_demand_data_rd Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore
+0x2 demand_code_rd Offcore outstanding code reads transactions in SuperQueue (SQ), queue to uncore, every cycle
+0x4 demand_rfo Offcore outstanding RFO store transactions in SuperQueue (SQ), queue to uncore
+0x4 extra:cmask=1 cycles_with_demand_rfo Offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore, every cycle
+0x8 all_data_rd Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore
+0x8 extra:cmask=1 cycles_with_data_rd Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore
+name:lock_cycles type:bitmask default:0x1
+0x1 split_lock_uc_lock_duration Cycles when L1 and L2 are locked due to UC or split lock
+0x2 cache_lock_duration Cycles when L1D is locked
+name:idq type:exclusive default:0x2
+0x2 empty Instruction Decode Queue (IDQ) empty cycles
+0x4 mite_uops Uops delivered to Instruction Decode Queue (IDQ) from MITE path
+0x4 extra:cmask=1 mite_cycles Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from MITE path
+0x8 dsb_uops Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path
+0x8 extra:cmask=1 dsb_cycles Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from Decode Stream Buffer (DSB) path
+0x10 ms_dsb_uops Uops initiated by Decode Stream Buffer (DSB) that are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy
+0x10 extra:cmask=1 ms_dsb_cycles Cycles when uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy
+0x10 extra:cmask=1,edge ms_dsb_occur Deliveries to Instruction Decode Queue (IDQ) initiated by Decode Stream Buffer (DSB) while Microcode Sequenser (MS) is busy
+0x18 extra:cmask=1 all_dsb_cycles_any_uops Cycles Decode Stream Buffer (DSB) is delivering any Uop
+0x18 extra:cmask=4 all_dsb_cycles_4_uops Cycles Decode Stream Buffer (DSB) is delivering 4 Uops
+0x20 ms_mite_uops Uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy
+0x24 extra:cmask=1 all_mite_cycles_any_uops Cycles MITE is delivering any Uop
+0x24 extra:cmask=4 all_mite_cycles_4_uops Cycles MITE is delivering 4 Uops
+0x30 ms_uops Uops delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy
+0x30 extra:cmask=1 ms_cycles Cycles when uops are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy
+0x3c mite_all_uops Uops delivered to Instruction Decode Queue (IDQ) from MITE path
+name:icache type:mandatory default:0x2
+0x2 misses Instruction cache, streaming buffer and victim cache misses
+name:itlb_misses type:bitmask default:0x1
+0x1 miss_causes_a_walk Misses at all ITLB levels that cause page walks
+0x2 walk_completed Misses in all ITLB levels that cause completed page walks
+0x4 walk_duration Cycles when PMH is busy with page walks
+0x10 stlb_hit Operations that miss the first ITLB level but hit the second and do not cause any page walks
+name:ild_stall type:bitmask default:0x1
+0x1 lcp Stalls caused by changing prefix length of the instruction.
+0x4 iq_full Stall cycles because IQ is full
+name:br_inst_exec type:exclusive default:0x41
+0x41 nontaken_conditional Not taken macro-conditional branches
+0x81 taken_conditional Taken speculative and retired macro-conditional branches
+0x82 taken_direct_jump Taken speculative and retired macro-conditional branch instructions excluding calls and indirects
+0x84 taken_indirect_jump_non_call_ret Taken speculative and retired indirect branches excluding calls and returns
+0x88 taken_indirect_near_return Taken speculative and retired indirect branches with return mnemonic
+0x90 taken_direct_near_call Taken speculative and retired direct near calls
+0xa0 taken_indirect_near_call Taken speculative and retired indirect calls
+0xc1 all_conditional Speculative and retired macro-conditional branches
+0xc2 all_direct_jmp Speculative and retired macro-unconditional branches excluding calls and indirects
+0xc4 all_indirect_jump_non_call_ret Speculative and retired indirect branches excluding calls and returns
+0xc8 all_indirect_near_return Speculative and retired indirect return branches.
+0xd0 all_direct_near_call Speculative and retired direct near calls
+0xff all_branches Speculative and retired  branches
+name:br_misp_exec type:exclusive default:0x41
+0x41 nontaken_conditional Not taken speculative and retired mispredicted macro conditional branches
+0x81 taken_conditional Taken speculative and retired mispredicted macro conditional branches
+0x84 taken_indirect_jump_non_call_ret Taken speculative and retired mispredicted indirect branches excluding calls and returns
+0x88 taken_return_near Taken speculative and retired mispredicted indirect branches with return mnemonic
+0xa0 taken_indirect_near_call Taken speculative and retired mispredicted indirect calls
+0xc1 all_conditional Speculative and retired mispredicted macro conditional branches
+0xc4 all_indirect_jump_non_call_ret Mispredicted indirect branches excluding calls and returns
+0xff all_branches Speculative and retired mispredicted macro conditional branches
+name:idq_uops_not_delivered type:exclusive default:0x1
+0x1 core Uops not delivered by the Frontend to the Backend of the machine, while there is no Backend stall 
+0x1 extra:cmask=1 cycles_le_3_uop_deliv.core Cycles with 3 or less uops delivered by the Frontend to the Backend of the machine, while there is no Backend stall
+0x1 extra:cmask=1,inv cycles_fe_was_ok Cycles with 4 uops delivered by the Frontend to the Backend of the machine, or the Backend was stalling
+0x1 extra:cmask=2 cycles_le_2_uop_deliv.core Cycles with 2 or less uops delivered by the Frontend to the Backend of the machine, while there is no Backend stall
+0x1 extra:cmask=3 cycles_le_1_uop_deliv.core Cycles with 1 or less uops delivered by the Frontend to the Backend of the machine, while there is no Backend stall
+0x1 extra:cmask=4 cycles_0_uops_deliv.core Cycles with no uops delivered by the Frontend to the Backend of the machine, while there is no Backend stall
+name:uops_dispatched_port type:exclusive default:0x1
+0x1 port_0 Cycles per thread when uops are dispatched to port 0
+0x1 extra:any port_0_core Cycles per core when uops are dispatched to port 0
+0x2 port_1 Cycles per thread when uops are dispatched to port 1
+0x2 extra:any port_1_core Cycles per core when uops are dispatched to port 1
+0xc port_2 Cycles per thread when load or STA uops are dispatched to port 2
+0xc extra:any port_2_core Cycles per core when load or STA uops are dispatched to port 2
+0x30 port_3 Cycles per thread when load or STA uops are dispatched to port 3
+0x30 extra:any port_3_core Cycles per core when load or STA uops are dispatched to port 3
+0x40 port_4 Cycles per thread when uops are dispatched to port 4
+0x40 extra:any port_4_core Cycles per core when uops are dispatched to port 4
+0x80 port_5 Cycles per thread when uops are dispatched to port 5
+0x80 extra:any port_5_core Cycles per core when uops are dispatched to port 5
+name:resource_stalls type:bitmask default:0x1
+0x1 any Resource-related stall cycles
+0x4 rs Cycles stalled due to no eligible RS entry available.
+0x8 sb Cycles stalled due to no store buffers available. (not including draining form sync).
+0x10 rob Cycles stalled due to re-order buffer full.
+name:cycle_activity type:exclusive default:0x1
+0x1 extra:cmask=1 cycles_l2_pending Cycles with pending L2 cache miss loads.
+0x2 extra:cmask=2 cycles_ldm_pending Cycles with pending memory loads.
+0x4 extra:cmask=4 cycles_no_execute Total execution stalls
+0x5 extra:cmask=5 stalls_l2_pending Execution stalls due to L2 cache misses.
+0x6 extra:cmask=6 stalls_ldm_pending Execution stalls due to memory subsystem.
+0x8 extra:cmask=8 cycles_l1d_pending Cycles with pending L1 cache miss loads.
+0xc extra:cmask=c stalls_l1d_pending Execution stalls due to L1 data cache misses
+name:dsb2mite_switches type:mandatory default:0x1
+0x1 count Decode Stream Buffer (DSB)-to-MITE switches
+name:dsb_fill type:mandatory default:0x8
+0x8 exceed_dsb_lines Cycles when Decode Stream Buffer (DSB) fill encounter more than 3 Decode Stream Buffer (DSB) lines
+name:itlb type:mandatory default:0x1
+0x1 itlb_flush Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages.
+name:offcore_requests type:bitmask default:0x1
+0x1 demand_data_rd Demand Data Read requests sent to uncore
+0x2 demand_code_rd Cacheable and noncachaeble code read requests
+0x4 demand_rfo Demand RFO requests including regular RFOs, locks, ItoM
+0x8 all_data_rd Demand and prefetch data reads
+name:uops_executed type:exclusive default:0x1
+0x1 thread Counts the number of uops to be executed per-thread each cycle.
+0x1 extra:cmask=1 cycles_ge_1_uop_exec Cycles where at least 1 uop was executed per-thread
+0x1 extra:cmask=1,inv stall_cycles Counts number of cycles no uops were dispatched to be executed on this thread.
+0x1 extra:cmask=2 cycles_ge_2_uops_exec Cycles where at least 2 uops were executed per-thread
+0x1 extra:cmask=3 cycles_ge_3_uops_exec Cycles where at least 3 uops were executed per-thread
+0x1 extra:cmask=4 cycles_ge_4_uops_exec Cycles where at least 4 uops were executed per-thread
+0x2 core Number of uops executed on the core.
+name:tlb_flush type:bitmask default:0x1
+0x1 dtlb_thread DTLB flush attempts of the thread-specific entries
+0x20 stlb_any STLB flush attempts
+name:other_assists type:bitmask default:0x8
+0x8 avx_store Number of AVX memory assist for stores. AVX microcode assist is being invoked whenever the hardware is unable to properly handle AVX-256b operations.
+0x10 avx_to_sse Number of transitions from AVX-256 to legacy SSE when penalty applicable.
+0x20 sse_to_avx Number of transitions from SSE to AVX-256 when penalty applicable.
+name:uops_retired type:exclusive default:0x1
+0x1 all Actually retired uops. 
+0x1 extra:cmask=1,inv stall_cycles Cycles without actually retired uops. 
+0x1 extra:cmask=1,inv,any core_stall_cycles Cycles without actually retired uops. 
+0x1 extra:cmask=10,inv total_cycles Cycles with less than 10 actually retired uops. 
+0x2 retire_slots Retirement slots used. 
+name:machine_clears type:bitmask default:0x2
+0x2 memory_ordering Counts the number of machine clears due to memory order conflicts.
+0x4 smc Self-modifying code (SMC) detected.
+0x20 maskmov This event counts the number of executed Intel AVX masked load operations that refer to an illegal address range with the mask bits set to 0. 
+name:br_inst_retired type:exclusive default:0x1
+0x1 conditional Conditional branch instructions retired. 
+0x2 near_call_r3 Direct and indirect macro near call instructions retired (captured in ring 3). 
+0x2 near_call Direct and indirect near call instructions retired. 
+0x8 near_return Return instructions retired. 
+0x10 not_taken Not taken branch instructions retired. 
+0x20 near_taken Taken branch instructions retired. 
+0x40 far_branch Far branch instructions retired. 
+name:br_misp_retired type:bitmask default:0x1
+0x1 conditional Mispredicted conditional branch instructions retired. 
+0x20 near_taken number of near branch instructions retired that were mispredicted and taken. 
+name:fp_assist type:exclusive default:0x1e
+0x2 x87_output Number of X87 assists due to output value.
+0x4 x87_input Number of X87 assists due to input value.
+0x8 simd_output Number of SIMD FP assists due to Output values
+0x10 simd_input Number of SIMD FP assists due to input values
+0x1e extra:cmask=1 any Cycles with any input/output SSE or FP assist
+name:rob_misc_events type:mandatory default:0x20
+0x20 lbr_inserts Count cases of saving new LBR
+name:mem_uops_retired type:exclusive default:0x81
+0x11 stlb_miss_loads Load uops with true STLB miss retired to architected path. 
+0x12 stlb_miss_stores Store uops with true STLB miss retired to architected path. 
+0x21 lock_loads Load uops with locked access retired to architected path. 
+0x41 split_loads Line-splitted load uops retired to architected path. 
+0x42 split_stores Line-splitted store uops retired to architected path. 
+0x81 all_loads Load uops retired to architected path with filter on bits 0 and 1 applied. 
+0x82 all_stores Store uops retired to architected path with filter on bits 0 and 1 applied. 
+name:mem_load_uops_retired type:bitmask default:0x1
+0x1 l1_hit Retired load uops with L1 cache hits as data sources. 
+0x2 l2_hit Retired load uops with L2 cache hits as data sources. 
+0x4 llc_hit Retired load uops which data sources were data hits in LLC without snoops required. 
+0x40 hit_lfb Retired load uops which data sources were load uops missed L1 but hit forward buffer due to preceding miss to the same cache line with data not ready. 
+name:mem_load_uops_llc_hit_retired type:bitmask default:0x1
+0x1 xsnp_miss Retired load uops which data sources were LLC hit and cross-core snoop missed in on-pkg core cache. 
+0x2 xsnp_hit Retired load uops which data sources were LLC and cross-core snoop hits in on-pkg core cache. 
+0x4 xsnp_hitm Retired load uops which data sources were HitM responses from shared LLC. 
+0x8 xsnp_none Retired load uops which data sources were hits in LLC without snoops required. 
+name:mem_load_uops_llc_miss_retired type:mandatory default:0x1
+0x1 local_dram Data from local DRAM either Snoop not needed or Snoop Miss (RspI)
+name:baclears type:mandatory default:0x1f
+0x1f any Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.
+name:l2_trans type:bitmask default:0x80
+0x1 demand_data_rd Demand Data Read requests that access L2 cache
+0x2 rfo RFO requests that access L2 cache
+0x4 code_rd L2 cache accesses when fetching instructions
+0x8 all_pf L2 or LLC HW prefetches that access L2 cache
+0x10 l1d_wb L1D writebacks that access L2 cache
+0x20 l2_fill L2 fill requests that access L2 cache
+0x40 l2_wb L2 writebacks that access L2 cache
+0x80 all_requests Transactions accessing L2 pipe
+name:l2_lines_in type:exclusive default:0x7
+0x1 i L2 cache lines in I state filling L2
+0x2 s L2 cache lines in S state filling L2
+0x4 e L2 cache lines in E state filling L2
+0x7 all L2 cache lines filling L2
+name:l2_lines_out type:exclusive default:0x1
+0x1 demand_clean Clean L2 cache lines evicted by demand
+0x2 demand_dirty Dirty L2 cache lines evicted by demand
+0x4 pf_clean Clean L2 cache lines evicted by L2 prefetch
+0x8 pf_dirty Dirty L2 cache lines evicted by L2 prefetch
+0xa dirty_all Dirty L2 cache lines filling the L2
diff --git a/libop/op_cpu_type.c b/libop/op_cpu_type.c
index 9ecbc65..750202b 100644
--- a/libop/op_cpu_type.c
+++ b/libop/op_cpu_type.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -99,6 +99,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct cpu_descr const cpu_descrs[MAX_CPU_TYPE] = {
 { "TILE-GX", "tile/tilegx", CPU_TILE_TILEGX, 4 },
 { "IBM System z10", "s390/z10", CPU_S390_Z10, 1 },
 { "IBM zEnterprise z196", "s390/z196", CPU_S390_Z196, 1 },
+{ "Intel Ivy Bridge microarchitecture", "i386/ivybridge", CPU_IVYBRIDGE, 8 },
 };
  
 static size_t const nr_cpu_descrs = sizeof(cpu_descrs) / sizeof(struct cpu_descr);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -124,6 +125,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; op_cpu op_cpu_base_type(op_cpu cpu_type)
 case CPU_NEHALEM:
 case CPU_WESTMERE:
 case CPU_SANDYBRIDGE:
+case CPU_IVYBRIDGE:
 return CPU_ARCH_PERFMON;
 default:
 /* assume processor in a class by itself */
diff --git a/libop/op_cpu_type.h b/libop/op_cpu_type.h
index 5eb7af5..81f6b15 100644
--- a/libop/op_cpu_type.h
+++ b/libop/op_cpu_type.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -96,6 +96,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef enum {
 CPU_TILE_TILEGX, /**&amp;lt; Tilera TILE-GX family */
 CPU_S390_Z10, /* IBM System z10 */
 CPU_S390_Z196, /* IBM zEnterprise z196 */
+CPU_IVYBRIDGE, /* Intel Ivy-Bridge microarchitecture */
 MAX_CPU_TYPE
 } op_cpu;
 
diff --git a/libop/op_events.c b/libop/op_events.c
index 49b9563..aeefde6 100644
--- a/libop/op_events.c
+++ b/libop/op_events.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1080,6 +1080,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void op_default_event(op_cpu cpu_type, struct op_default_event_descr * descr)
 case CPU_NEHALEM:
 case CPU_WESTMERE:
 case CPU_SANDYBRIDGE:
+case CPU_IVYBRIDGE:
 case CPU_MIPS_LOONGSON2:
 case CPU_FAMILY12H:
 case CPU_FAMILY14H:
diff --git a/libop/op_hw_specific.h b/libop/op_hw_specific.h
index d9f505f..36e47d8 100644
--- a/libop/op_hw_specific.h
+++ b/libop/op_hw_specific.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -141,6 +141,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static inline op_cpu op_cpu_specific_type(op_cpu cpu_type)
 case 0x2a:
 case 0x2d:
 return CPU_SANDYBRIDGE;
+case 0x3a:
+return CPU_IVYBRIDGE;
 }
 }
 return cpu_type;
diff --git a/utils/ophelp.c b/utils/ophelp.c
index 32af015..fc0c00a 100644
--- a/utils/ophelp.c
+++ b/utils/ophelp.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -539,6 +539,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int main(int argc, char const * argv[])
 case CPU_NEHALEM:
 case CPU_WESTMERE:
 case CPU_SANDYBRIDGE:
+case CPU_IVYBRIDGE:
 case CPU_ATOM:
 event_doc =
 "See Intel Architecture Developer's Manual Volume 3B, Appendix A and\n"
&lt;/pre&gt;</description>
    <dc:creator>Andi Kleen</dc:creator>
    <dc:date>2012-05-23T00:48:43</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10504">
    <title>[PATCH] Change operf to create oprofile sample files during profilinginstead of afterwards</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10504</link>
    <description>&lt;pre&gt;[PATCH] Change operf to create oprofile sample files during profiling instead of afterwards

Previously, the 'operf-record' process read the perf_events sample data from the kernel
and wrote it to a temporary output file (operf.data).  Then, once the profiling session
was completed, a conversion was performed on that data to put it into oprofile format,
stored in the usual sample files in &amp;lt;session-dir&amp;gt;/samples/current.  I noticed that when
operf was run in system-wide mode, the temporary operf.data file was very large, and the
conversion step was taking inordinately long (from several seconds on a laptop to over
a minute on a large, busy server system.

I've had a TODO comment in the operf.cpp code to investigate performing the conversion
step in-flight (while profiling) versus waiting for the profiling to end.  So I changed
the operf-record process from writing the perf_events sample data to a file to writing
to a pipe.  Then I created a new operf-read process to read from the other end of that
pipe and perform the conversion to oprofile format.  Doing the conversion during the
profiling run allowed me to identify the hot spots in the opreport output. I found several
areas (especially involving the inefficiency of the operf_sfile hash algorithm) where
improvements were needed.  The conversion step now takes about 15% of the time it used
to! A wonderful result!

This patch has been committed to the perf-events branch, but review comments are welcome.

Signed-off-by: Maynard Johnson &amp;lt;maynardj&amp;lt; at &amp;gt;us.ibm.com&amp;gt;
---
 libperf_events/operf_counter.cpp |  214 ++++++++++++++++++----------------
 libperf_events/operf_counter.h   |   12 +-
 libperf_events/operf_event.h     |   11 --
 libperf_events/operf_sfile.cpp   |   74 ++++++------
 libperf_events/operf_sfile.h     |    2 +
 libperf_events/operf_utils.cpp   |  237 +++++++++++++-------------------------
 libperf_events/operf_utils.h     |   12 +--
 pe_profiling/operf.cpp           |  168 ++++++++++++++++++++-------
 8 files changed, 366 insertions(+), 364 deletions(-)

diff --git a/libperf_events/operf_counter.cpp b/libperf_events/operf_counter.cpp
index 1ceb012..5d1f016 100644
--- a/libperf_events/operf_counter.cpp
+++ b/libperf_events/operf_counter.cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -36,6 +36,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; using namespace OP_perf_utils;
 
 
 volatile bool quit;
+volatile bool read_quit;
 int sample_reads;
 unsigned int pagesize;
 verbose vperf("perf_events");
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -121,17 +122,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int operf_counter::perf_event_open(pid_t ppid, int cpu, unsigned event, operf_re
 operf_record::~operf_record()
 {
 cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf_record::~operf_record()" &amp;lt;&amp;lt; endl;
-opHeader.data_size = total_bytes_recorded;
-if (total_bytes_recorded)
-write_op_header_info();
 delete[] poll_data;
-close(outputFile);
+close(output_fd);
 samples_array.clear();
 evts.clear();
 perfCounters.clear();
 }
 
-operf_record::operf_record(string outfile, bool sys_wide, pid_t the_pid, bool pid_running,
+operf_record::operf_record(int out_fd, bool sys_wide, pid_t the_pid, bool pid_running,
                            vector&amp;lt;operf_event_t&amp;gt; &amp;amp; events, vmlinux_info_t vi, bool do_cg,
                            bool separate_by_cpu)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -154,14 +152,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; operf_record::operf_record(string outfile, bool sys_wide, pid_t the_pid, bool pi
 if (system_wide &amp;amp;&amp;amp; (pid != -1 || pid_started))
 return;  // object is not valid
 
-opHeader.data_size = 0;
-outputFile = open(outfile.c_str(), flags, S_IRUSR|S_IWUSR);
-if (outputFile &amp;lt; 0) {
-string errmsg = "Internal error:  Could not create output file. errno is ";
-errmsg += strerror(errno);
-throw runtime_error(errmsg);
-}
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf_record ctor: successfully opened output file " &amp;lt;&amp;lt; outfile &amp;lt;&amp;lt; endl;
+output_fd = out_fd;
+cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf_record ctor using output fd " &amp;lt;&amp;lt; output_fd &amp;lt;&amp;lt; endl;
 
 memset(&amp;amp;sa, 0, sizeof(struct sigaction));
 sa.sa_sigaction = op_perfrecord_sigusr1_handler;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -198,37 +190,25 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void operf_record::write_op_header_info()
 struct OP_file_header f_header;
 struct op_file_attr f_attr;
 
-lseek(outputFile, sizeof(f_header), SEEK_SET);
-
-for (unsigned i = 0; i &amp;lt; evts.size(); i++) {
-opHeader.h_attrs[i].id_offset = lseek(outputFile, 0, SEEK_CUR);
-add_to_total(op_write_output(outputFile, &amp;amp;opHeader.h_attrs[i].ids[0],
-opHeader.h_attrs[i].ids.size() * sizeof(u64)));
-}
+f_header.magic = OP_MAGIC;
+f_header.size = sizeof(f_header);
+f_header.attr_size = sizeof(f_attr);
+f_header.attrs.size = evts.size() * sizeof(f_attr);
+f_header.data.size = 0;
 
-opHeader.attr_offset = lseek(outputFile, 0, SEEK_CUR);
+add_to_total(op_write_output(output_fd, &amp;amp;f_header, sizeof(f_header)));
 
 for (unsigned i = 0; i &amp;lt; evts.size(); i++) {
 struct op_header_evt_info attr = opHeader.h_attrs[i];
 f_attr.attr = attr.attr;
-f_attr.ids.offset = attr.id_offset;
-f_attr.ids.size =attr.ids.size() * sizeof(u64);
-add_to_total(op_write_output(outputFile, &amp;amp;f_attr, sizeof(f_attr)));
+f_attr.ids.size = attr.ids.size() * sizeof(u64);
+add_to_total(op_write_output(output_fd, &amp;amp;f_attr, sizeof(f_attr)));
 }
 
-opHeader.data_offset = lseek(outputFile, 0, SEEK_CUR);
-
-f_header.magic = OP_MAGIC;
-f_header.size = sizeof(f_header);
-f_header.attr_size = sizeof(f_attr);
-f_header.attrs.offset = opHeader.attr_offset;
-f_header.attrs.size = evts.size() * sizeof(f_attr);
-f_header.data.offset = opHeader.data_offset;
-f_header.data.size = opHeader.data_size;
-
-lseek(outputFile, 0, SEEK_SET);
-add_to_total(op_write_output(outputFile, &amp;amp;f_header, sizeof(f_header)));
-lseek(outputFile, opHeader.data_offset + opHeader.data_size, SEEK_SET);
+for (unsigned i = 0; i &amp;lt; evts.size(); i++) {
+add_to_total(op_write_output(output_fd, &amp;amp;opHeader.h_attrs[i].ids[0],
+                             opHeader.h_attrs[i].ids.size() * sizeof(u64)));
+}
 }
 
 int operf_record::prepareToRecord(int counter, int cpu, int fd)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -360,7 +340,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void operf_record::setup()
 closedir(dir);
 write_op_header_info();
 if (pid_started || system_wide) {
-if (op_record_process_info(system_wide, pid, this, outputFile) &amp;lt; 0) {
+if (op_record_process_info(system_wide, pid, this, output_fd) &amp;lt; 0) {
 for (int i = 0; i &amp;lt; num_cpus; i++) {
 for (unsigned int evt = 0; evt &amp;lt; evts.size(); evt++)
 ioctl(perfCounters[i][evt].get_fd(), PERF_EVENT_IOC_DISABLE);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -368,7 +348,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void operf_record::setup()
 goto error;
 }
 }
-op_record_kernel_info(vmlinux_file, kernel_start, kernel_end, outputFile, this);
+op_record_kernel_info(vmlinux_file, kernel_start, kernel_end, output_fd, this);
 
 // Set bit to indicate we're set to go.
 valid = true;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -376,7 +356,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void operf_record::setup()
 
 error:
 delete[] poll_data;
-close(outputFile);
+close(output_fd);
 if (rc != OP_PERF_HANDLED_ERROR)
 throw runtime_error(err_msg);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -409,15 +389,33 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void operf_record::recordPerfData(void)
 cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf_record::recordPerfData received signal to quit." &amp;lt;&amp;lt; endl;
 }
 }
+close(output_fd);
 cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "operf recording finished." &amp;lt;&amp;lt; endl;
 }
 
-void operf_read::init(string infilename, string samples_loc,  op_cpu cputype, vector&amp;lt;operf_event_t&amp;gt; &amp;amp; events)
+void operf_read::init(int sample_data_pipe_fd, string samples_loc,  op_cpu cputype, vector&amp;lt;operf_event_t&amp;gt; &amp;amp; events)
 {
-inputFname = infilename;
+struct sigaction sa;
+sigset_t ss;
+sample_data_fd = sample_data_pipe_fd;
 sampledir = samples_loc;
 evts = events;
 cpu_type = cputype;
+memset(&amp;amp;sa, 0, sizeof(struct sigaction));
+sa.sa_sigaction = op_perfread_sigusr1_handler;
+sigemptyset(&amp;amp;sa.sa_mask);
+sigemptyset(&amp;amp;ss);
+sigaddset(&amp;amp;ss, SIGUSR1);
+sigprocmask(SIG_UNBLOCK, &amp;amp;ss, NULL);
+sa.sa_mask = ss;
+sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf-read calling sigaction" &amp;lt;&amp;lt; endl;
+if (sigaction(SIGUSR1, &amp;amp;sa, NULL) == -1) {
+cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf-read init: sigaction failed; errno is: "
+      &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
+_exit(EXIT_FAILURE);
+}
+
 }
 
 operf_read::~operf_read()
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -427,72 +425,66 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; operf_read::~operf_read()
 
 int operf_read::readPerfHeader(void)
 {
-int ret = 0;
-
-opHeader.data_size = 0;
-istrm.open(inputFname.c_str(), ios_base::in);
-if (!istrm.good()) {
-return -1;
-}
-istrm.peek();
-if (istrm.eof()) {
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf_read::readPerfHeader:  Empty profile data file." &amp;lt;&amp;lt; endl;
-valid = false;
-return OP_PERF_HANDLED_ERROR;
-}
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf_read: successfully opened input file " &amp;lt;&amp;lt; inputFname &amp;lt;&amp;lt; endl;
-read_op_header_info_with_ifstream();
-valid = true;
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Successfully read perf header" &amp;lt;&amp;lt; endl;
-
-return ret;
-}
-
-void operf_read::read_op_header_info_with_ifstream(void)
-{
 struct OP_file_header fheader;
-istrm.seekg(0, ios_base::beg);
-
-if (op_read_from_stream(istrm, (char *)&amp;amp;fheader, sizeof(fheader)) != sizeof(fheader)) {
-throw runtime_error("Error: input file " + inputFname + " does not have enough data for header");
+string errmsg;
+int num_fattrs;
+size_t fattr_size;
+vector&amp;lt;struct op_file_attr&amp;gt; f_attr_cache;
+
+errno = 0;
+if (read(sample_data_fd, &amp;amp;fheader, sizeof(fheader)) != sizeof(fheader)) {
+errmsg = "Error reading header on sample data pipe: " + string(strerror(errno));
+goto fail;
 }
 
-if (memcmp(&amp;amp;fheader.magic, __op_magic, sizeof(fheader.magic)))
-throw runtime_error("Error: input file " + inputFname + " does not have expected header data");
+if (memcmp(&amp;amp;fheader.magic, __op_magic, sizeof(fheader.magic))) {
+errmsg = "Error: operf sample data does not have expected header data";
+goto fail;
+}
 
 cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "operf magic number " &amp;lt;&amp;lt; (char *)&amp;amp;fheader.magic &amp;lt;&amp;lt; " matches expected __op_magic " &amp;lt;&amp;lt; __op_magic &amp;lt;&amp;lt; endl;
-opHeader.attr_offset = fheader.attrs.offset;
-opHeader.data_offset = fheader.data.offset;
-opHeader.data_size = fheader.data.size;
-size_t fattr_size = sizeof(struct op_file_attr);
+fattr_size = sizeof(struct op_file_attr);
 if (fattr_size != fheader.attr_size) {
-string msg = "Error: perf_events binary incompatibility. Event data collection was apparently "
+errmsg = "Error: perf_events binary incompatibility. Event data collection was apparently "
 "performed under a different kernel version than current.";
-throw runtime_error(msg);
+goto fail;
 }
-int num_fattrs = fheader.attrs.size/fheader.attr_size;
+num_fattrs = fheader.attrs.size/fheader.attr_size;
 cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "num_fattrs  is " &amp;lt;&amp;lt; num_fattrs &amp;lt;&amp;lt; endl;
-istrm.seekg(opHeader.attr_offset, ios_base::beg);
 for (int i = 0; i &amp;lt; num_fattrs; i++) {
 struct op_file_attr f_attr;
 streamsize fattr_size = sizeof(f_attr);
-if (op_read_from_stream(istrm, (char *)&amp;amp;f_attr, fattr_size) != fattr_size)
-throw runtime_error("Error: Unexpected end of input file " + inputFname + ".");
+if (read(sample_data_fd, (char *)&amp;amp;f_attr, fattr_size) != fattr_size) {
+errmsg = "Error reading file attr on sample data pipe: " + string(strerror(errno));
+goto fail;
+}
 opHeader.h_attrs[i].attr = f_attr.attr;
-streampos next_f_attr = istrm.tellg();
+f_attr_cache.push_back(f_attr);
+}
+for (int i = 0; i &amp;lt; num_fattrs; i++) {
+vector&amp;lt;struct op_file_attr&amp;gt;::iterator it = f_attr_cache.begin();
+struct op_file_attr f_attr = *(it);
 int num_ids = f_attr.ids.size/sizeof(u64);
-istrm.seekg(f_attr.ids.offset, ios_base::beg);
+
 for (int id = 0; id &amp;lt; num_ids; id++) {
 u64 perf_id;
 streamsize perfid_size = sizeof(perf_id);
-if (op_read_from_stream(istrm, (char *)&amp;amp; perf_id, perfid_size) != perfid_size)
-throw runtime_error("Error: Unexpected end of input file " + inputFname + ".");
+if (read(sample_data_fd, (char *)&amp;amp; perf_id, perfid_size) != perfid_size) {
+errmsg = "Error reading perf ID on sample data pipe: " + string(strerror(errno));
+goto fail;
+}
 cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Perf header: id = " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; (unsigned long long)perf_id &amp;lt;&amp;lt; endl;
 opHeader.h_attrs[i].ids.push_back(perf_id);
 }
-istrm.seekg(next_f_attr, ios_base::beg);
+
 }
-istrm.close();
+valid = true;
+cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Successfully read perf header" &amp;lt;&amp;lt; endl;
+return 0;
+
+fail:
+cerr &amp;lt;&amp;lt; errmsg;
+return -1;
 }
 
 int operf_read::get_eventnum_by_perf_event_id(u64 id) const
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -507,32 +499,50 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int operf_read::get_eventnum_by_perf_event_id(u64 id) const
 return -1;
 }
 
+int operf_read::_get_one_perf_event(event_t * event)
+{
+static size_t pe_header_size = sizeof(perf_event_header);
+char * evt = (char *)event;
+ssize_t num_read;
+perf_event_header * header = (perf_event_header *)event;
+errno = 0;
+if ((num_read = read(sample_data_fd, header, pe_header_size)) &amp;lt; 0) {
+cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "Read 1 of sample data pipe returned with " &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
+return -1;
+} else if (num_read == 0) {
+return -1;
+}
+evt += pe_header_size;
+if (!header-&amp;gt;size)
+return -1;
+if ((num_read = read(sample_data_fd, evt, header-&amp;gt;size - pe_header_size)) &amp;lt; 0) {
+cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "Read 2 of sample data pipe returned with " &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
+return -1;
+} else if (num_read == 0) {
+return -1;
+}
+return 0;
+}
+
 
 int operf_read::convertPerfData(void)
 {
 int num_bytes = 0;
-struct mmap_info info;
-info.file_data_offset = opHeader.data_offset;
-info.file_data_size = opHeader.data_size;
-info.traceFD = open(inputFname.c_str(), O_RDONLY);
-if (op_mmap_trace_file(info) &amp;lt; 0) {
-close(info.traceFD);
-throw runtime_error("Error: Unable to mmap operf data file");
-}
+// Allocate way more than enough space for a really big event with a long callchain
+event_t * event = (event_t *)xmalloc(65536);
 
-cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "Converting operf.data to oprofile sample data format" &amp;lt;&amp;lt; endl;
-cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "data size is " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; info.file_data_size &amp;lt;&amp;lt; "; data offset is " &amp;lt;&amp;lt; info.file_data_offset &amp;lt;&amp;lt; endl;
-cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "head is " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; info.head &amp;lt;&amp;lt; endl;
+cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "Converting operf data to oprofile sample data format" &amp;lt;&amp;lt; endl;
 cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "sample type is " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt;  opHeader.h_attrs[0].attr.sample_type &amp;lt;&amp;lt; endl;
 first_time_processing = true;
+memset(event, '\0', 65536);
 while (1) {
 streamsize rec_size = 0;
-event_t * event = op_get_perf_event(info);
-if (event == NULL) {
+if (_get_one_perf_event(event) &amp;lt; 0) {
 break;
 }
 rec_size = event-&amp;gt;header.size;
-op_write_event(event, opHeader.h_attrs[0].attr.sample_type);
+if (op_write_event(event, opHeader.h_attrs[0].attr.sample_type) &amp;lt; 0)
+break;
 num_bytes += rec_size;
 }
 first_time_processing = false;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -548,12 +558,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int operf_read::convertPerfData(void)
 delete images_it++-&amp;gt;second;
 all_images_map.clear();
 
-close(info.traceFD);
 char * cbuf;
 cbuf = (char *)xmalloc(operf_options::session_dir.length() + 5);
 strcpy(cbuf, operf_options::session_dir.c_str());
 strcat(cbuf, "/abi");
 op_write_abi_to_file(cbuf);
 free(cbuf);
+free(event);
 return num_bytes;
 }
diff --git a/libperf_events/operf_counter.h b/libperf_events/operf_counter.h
index 984fc01..ce1198e 100644
--- a/libperf_events/operf_counter.h
+++ b/libperf_events/operf_counter.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -77,12 +77,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; public:
  * For single app profiling, set sys_wide=false, the_pid=&amp;lt;processID-to-profile&amp;gt;,
  * and pid_running=true if profiling an already active process; otherwise false.
  */
-operf_record(std::string outfile, bool sys_wide, pid_t the_pid, bool pid_running,
+operf_record(int output_pipe_fd, bool sys_wide, pid_t the_pid, bool pid_running,
              std::vector&amp;lt;operf_event_t&amp;gt; &amp;amp; evts, OP_perf_utils::vmlinux_info_t vi,
              bool callgraph, bool separate_by_cpu);
 ~operf_record();
 void recordPerfData(void);
-int out_fd(void) const { return outputFile; }
+int out_fd(void) const { return output_fd; }
 void add_to_total(int n) { total_bytes_recorded += n; }
 int get_total_bytes_recorded(void) const { return total_bytes_recorded; }
 void register_perf_event_id(unsigned counter, u64 id, perf_event_attr evt_attr);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -93,7 +93,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; private:
 void setup(void);
 int prepareToRecord(int counter, int cpu, int fd);
 void write_op_header_info(void);
-int outputFile;
+int output_fd;
 struct pollfd * poll_data;
 std::vector&amp;lt; std::vector&amp;lt;struct mmap_data&amp;gt; &amp;gt; samples_array;
 int num_cpus;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -115,7 +115,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; private:
 class operf_read {
 public:
 operf_read(void) { valid = false; }
-void init(std::string infile, std::string samples_dir, op_cpu cputype,
+void init(int sample_data_pipe_fd, std::string samples_dir, op_cpu cputype,
           std::vector&amp;lt;operf_event_t&amp;gt; &amp;amp; evts);
 ~operf_read();
 int readPerfHeader(void);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -125,14 +125,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; public:
 inline const operf_event_t * get_event_by_counter(u32 counter) { return &amp;amp;evts[counter]; }
 
 private:
-std::string inputFname;
+int sample_data_fd;
 std::string sampledir;
 std::ifstream istrm;
 struct OP_header opHeader;
 std::vector&amp;lt;operf_event_t&amp;gt; evts;
 bool valid;
 op_cpu cpu_type;
-void read_op_header_info_with_ifstream(void);
+int _get_one_perf_event(event_t *);
 };
 
 
diff --git a/libperf_events/operf_event.h b/libperf_events/operf_event.h
index 1513b0e..95feb9b 100644
--- a/libperf_events/operf_event.h
+++ b/libperf_events/operf_event.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -107,12 +107,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct sample_data {
 struct ip_callchain * callchain;
 };
 
-struct mmap_info {
-u64 offset, file_data_size, file_data_offset, head;
-char * buf;
-int traceFD;
-};
-
 
 typedef struct operf_event {
 char name[OP_MAX_EVT_NAME_LEN];
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -130,7 +124,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; typedef struct operf_event {
 } operf_event_t;
 
 struct op_file_section {
-u64 offset;
 u64 size;
 };
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -142,7 +135,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct op_file_attr {
 struct op_header_evt_info {
 struct perf_event_attr attr;
 std::vector&amp;lt;u64&amp;gt; ids;
-off_t id_offset;
 };
 
 struct OP_file_header {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -155,9 +147,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct OP_file_header {
 
 struct OP_header {
 struct op_header_evt_info h_attrs[OP_MAX_NUM_EVENTS];
-off_tattr_offset;
-off_tdata_offset;
-u64data_size;
 };
 /* Some of the above definitions were borrowed from the perf tool's util/event.h file. */
 
diff --git a/libperf_events/operf_sfile.cpp b/libperf_events/operf_sfile.cpp
index cc71439..ada47e1 100644
--- a/libperf_events/operf_sfile.cpp
+++ b/libperf_events/operf_sfile.cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -41,17 +41,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static unsigned long
 sfile_hash(struct operf_transient const * trans, struct operf_kernel_image * ki)
 {
 unsigned long val = 0;
-size_t fname_len = strlen(trans-&amp;gt;image_name);
 
-/* fname_ptr will point at the first character in the image name
- * which we'll use for hashing.  We don't need to hash on the whole
- * image name to get a decent hash.  Arbitrarily, we'll hash on the
- * first 16 chars or fname_len (if fname_len &amp;lt; 16).
- */
-unsigned int fname_hash_len = (fname_len &amp;lt; 16) ? fname_len : 16;
-const char * fname_ptr = trans-&amp;gt;image_name + fname_len - fname_hash_len;
-
-val ^= trans-&amp;gt;tid &amp;lt;&amp;lt; 2;
 val ^= trans-&amp;gt;tgid &amp;lt;&amp;lt; 2;
 
 if (operf_options::separate_cpu)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -61,12 +51,28 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; sfile_hash(struct operf_transient const * trans, struct operf_kernel_image * ki)
 val ^= ki-&amp;gt;start &amp;gt;&amp;gt; 14;
 val ^= ki-&amp;gt;end &amp;gt;&amp;gt; 7;
 }
-for (unsigned int i = 0; i &amp;lt; fname_hash_len; i++)
-val = ((val &amp;lt;&amp;lt; 5) + val) ^ fname_ptr[i];
 
 if (trans-&amp;gt;is_anon) {
 val ^= trans-&amp;gt;start_addr &amp;gt;&amp;gt; VMA_SHIFT;
 val ^= trans-&amp;gt;end_addr &amp;gt;&amp;gt; (VMA_SHIFT + 1);
+} else {
+size_t fname_len = trans-&amp;gt;app_len;
+/* fname_ptr will point at the first character in the binary file's name
+ * which we'll use for hashing.  We don't need to hash on the whole
+ * pathname to get a decent hash.  Arbitrarily, we'll hash on the
+ * last 16 chars (or last fname_len chars if fname_len &amp;lt; 16).
+ */
+unsigned int fname_hash_len = (fname_len &amp;lt; 16) ? fname_len : 16;
+const char * fname_ptr = trans-&amp;gt;app_filename + fname_len - fname_hash_len;
+for (unsigned int i = 0; i &amp;lt; fname_hash_len; i++)
+val = ((val &amp;lt;&amp;lt; 5) + val) ^ fname_ptr[i];
+
+// Now do the same for image name
+fname_len = trans-&amp;gt;image_len;
+fname_hash_len = (fname_len &amp;lt; 16) ? fname_len : 16;
+fname_ptr = trans-&amp;gt;image_name + fname_len - fname_hash_len;
+for (unsigned int i = 0; i &amp;lt; fname_hash_len; i++)
+val = ((val &amp;lt;&amp;lt; 5) + val) ^ fname_ptr[i];
 }
 
 return val &amp;amp; HASH_BITS;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -75,10 +81,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; sfile_hash(struct operf_transient const * trans, struct operf_kernel_image * ki)
 
 static int
 do_match(struct operf_sfile const * sf, struct operf_kernel_image const * ki,
-         bool is_anon, const char * image_name, const char * appname, pid_t tgid,
-         pid_t tid, unsigned int cpu)
+         bool is_anon, const char * image_name, size_t image_len,
+         const char * appname, size_t app_len,
+         pid_t tgid, pid_t tid, unsigned int cpu)
 {
-size_t len1, len2;
+size_t shortest_image_len, shortest_app_len;
 
 /* this is a simplified check for "is a kernel image" AND
  * "is the right kernel image". Also handles no-vmlinux
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -87,15 +94,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do_match(struct operf_sfile const * sf, struct operf_kernel_image const * ki,
 if (sf-&amp;gt;kernel != ki)
 return 0;
 
-if (sf-&amp;gt;is_anon != is_anon)
+if (sf-&amp;gt;tid != tid || sf-&amp;gt;tgid != tgid)
 return 0;
 
-len1 = strlen(sf-&amp;gt;app_filename);
-len2 = strlen(appname);
-if ((len1 != len2) || strncmp(sf-&amp;gt;app_filename, appname, len1))
+if (sf-&amp;gt;is_anon != is_anon)
 return 0;
 
-if (sf-&amp;gt;tid != tid || sf-&amp;gt;tgid != tgid)
+if ((sf-&amp;gt;app_len != app_len) || (sf-&amp;gt;image_len != image_len))
 return 0;
 
 if (operf_options::separate_cpu) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -106,28 +111,22 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; do_match(struct operf_sfile const * sf, struct operf_kernel_image const * ki,
 if (ki)
 return 1;
 
-return (!strncmp(sf-&amp;gt;image_name, image_name, len1));
+shortest_image_len = sf-&amp;gt;image_len &amp;lt; image_len ? sf-&amp;gt;image_len : image_len;
+if (strncmp(sf-&amp;gt;image_name, image_name, shortest_image_len))
+return 0;
 
-}
-
-static int
-trans_match(struct operf_transient const * trans, struct operf_sfile const * sfile,
-            struct operf_kernel_image const * ki)
-{
-return do_match(sfile, ki,
-                trans-&amp;gt;is_anon,
-                trans-&amp;gt;image_name, trans-&amp;gt;app_filename,
-                trans-&amp;gt;tgid, trans-&amp;gt;tid, trans-&amp;gt;cpu);
+shortest_app_len = sf-&amp;gt;app_len &amp;lt; app_len ? sf-&amp;gt;app_len : app_len;
+return !strncmp(sf-&amp;gt;app_filename, appname, shortest_app_len);
 
 }
 
-
 int
 operf_sfile_equal(struct operf_sfile const * sf, struct operf_sfile const * sf2)
 {
 return do_match(sf, sf2-&amp;gt;kernel,
                 sf2-&amp;gt;is_anon,
-                sf2-&amp;gt;image_name, sf2-&amp;gt;app_filename,
+                sf2-&amp;gt;image_name, sf2-&amp;gt;image_len,
+                sf2-&amp;gt;app_filename, sf2-&amp;gt;app_len,
                 sf2-&amp;gt;tgid, sf2-&amp;gt;tid, sf2-&amp;gt;cpu);
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -143,13 +142,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; create_sfile(unsigned long hash, struct operf_transient const * trans,
 sf = (operf_sfile *)xmalloc(sizeof(struct operf_sfile));
 
 sf-&amp;gt;hashval = hash;
-
 sf-&amp;gt;tid = trans-&amp;gt;tid;
 sf-&amp;gt;tgid = trans-&amp;gt;tgid;
 sf-&amp;gt;cpu = 0;
 sf-&amp;gt;kernel = ki;
 sf-&amp;gt;image_name = trans-&amp;gt;image_name;
 sf-&amp;gt;app_filename = trans-&amp;gt;app_filename;
+sf-&amp;gt;image_len = trans-&amp;gt;image_len;
+sf-&amp;gt;app_len = trans-&amp;gt;app_len;
 sf-&amp;gt;is_anon = trans-&amp;gt;is_anon;
 sf-&amp;gt;start_addr = trans-&amp;gt;start_addr;
 sf-&amp;gt;end_addr = trans-&amp;gt;end_addr;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -196,7 +196,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct operf_sfile * operf_sfile_find(struct operf_transient const * trans)
 hash = sfile_hash(trans, ki);
 list_for_each(pos, &amp;amp;hashes[hash]) {
 sf = list_entry(pos, struct operf_sfile, hash);
-if (trans_match(trans, sf, ki)) {
+if (do_match(sf, ki,
+             trans-&amp;gt;is_anon,
+             trans-&amp;gt;image_name, trans-&amp;gt;image_len,
+             trans-&amp;gt;app_filename, trans-&amp;gt;app_len,
+             trans-&amp;gt;tgid, trans-&amp;gt;tid, trans-&amp;gt;cpu)) {
 operf_sfile_get(sf);
 goto lru;
 }
diff --git a/libperf_events/operf_sfile.h b/libperf_events/operf_sfile.h
index 5ea02e5..9b91180 100644
--- a/libperf_events/operf_sfile.h
+++ b/libperf_events/operf_sfile.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -41,6 +41,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct operf_sfile {
 unsigned long hashval;
 const char * image_name;
 const char * app_filename;
+size_t image_len, app_len;
 /** thread ID, -1 if not set */
 pid_t tid;
 /** thread group ID, -1 if not set */
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -89,6 +90,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; struct operf_transient {
 vma_t pc;
 const char * image_name;
 const char * app_filename;
+size_t image_len, app_len;
 vma_t last_pc;
 int event;
 u64 sample_id;
diff --git a/libperf_events/operf_utils.cpp b/libperf_events/operf_utils.cpp
index 4ff99c0..42eecce 100644
--- a/libperf_events/operf_utils.cpp
+++ b/libperf_events/operf_utils.cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,6 +38,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt;
 
 extern verbose vmisc;
 extern volatile bool quit;
+extern volatile bool read_quit;
 extern operf_read operfRead;
 extern int sample_reads;
 extern unsigned int pagesize;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -161,22 +162,26 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_comm_event(event_t * event)
 return;
 }
 #endif
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "PERF_RECORD_COMM for " &amp;lt;&amp;lt; event-&amp;gt;comm.comm &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "PERF_RECORD_COMM for " &amp;lt;&amp;lt; event-&amp;gt;comm.comm &amp;lt;&amp;lt; endl;
 map&amp;lt;pid_t, operf_process_info *&amp;gt;::iterator it;
 it = process_map.find(event-&amp;gt;comm.pid);
 if (it == process_map.end()) {
 operf_process_info * proc = new operf_process_info(event-&amp;gt;comm.pid,
                                                    app_name ? app_name : event-&amp;gt;comm.comm,
                                                    app_name != NULL, true);
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Adding new proc info to collection for PID " &amp;lt;&amp;lt; event-&amp;gt;comm.pid &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Adding new proc info to collection for PID " &amp;lt;&amp;lt; event-&amp;gt;comm.pid &amp;lt;&amp;lt; endl;
 process_map[event-&amp;gt;comm.pid] = proc;
 } else {
 // sanity check -- should not get a second COMM event for same PID
 if (it-&amp;gt;second-&amp;gt;is_valid()) {
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Received extraneous COMM event for " &amp;lt;&amp;lt; event-&amp;gt;comm.comm
-      &amp;lt;&amp;lt; ", PID " &amp;lt;&amp;lt; event-&amp;gt;comm.pid &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Received extraneous COMM event for " &amp;lt;&amp;lt; event-&amp;gt;comm.comm
+      &amp;lt;&amp;lt; ", PID " &amp;lt;&amp;lt; event-&amp;gt;comm.pid &amp;lt;&amp;lt; endl;
 } else {
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Processing deferred mappings" &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Processing deferred mappings" &amp;lt;&amp;lt; endl;
 it-&amp;gt;second-&amp;gt;process_deferred_mappings(event-&amp;gt;comm.comm);
 }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -212,9 +217,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_mmap_event(event_t * event)
 mapping-&amp;gt;end_addr = (event-&amp;gt;mmap.len == 0ULL)? 0ULL : mapping-&amp;gt;start_addr + event-&amp;gt;mmap.len - 1;
 mapping-&amp;gt;pgoff = event-&amp;gt;mmap.pgoff;
 
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "PERF_RECORD_MMAP for " &amp;lt;&amp;lt; event-&amp;gt;mmap.filename &amp;lt;&amp;lt; endl;
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "\tstart_addr: " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; mapping-&amp;gt;start_addr;
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "; end addr: " &amp;lt;&amp;lt; mapping-&amp;gt;end_addr &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf) {
+cout &amp;lt;&amp;lt; "PERF_RECORD_MMAP for " &amp;lt;&amp;lt; event-&amp;gt;mmap.filename &amp;lt;&amp;lt; endl;
+cout &amp;lt;&amp;lt; "\tstart_addr: " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; mapping-&amp;gt;start_addr;
+cout &amp;lt;&amp;lt; "; end addr: " &amp;lt;&amp;lt; mapping-&amp;gt;end_addr &amp;lt;&amp;lt; endl;
+}
 
 if (event-&amp;gt;header.misc &amp;amp; PERF_RECORD_MISC_USER)
 all_images_map.insert(pair&amp;lt;string, struct operf_mmap *&amp;gt;(image_basename, mapping));
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -244,8 +251,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_mmap_event(event_t * event)
 operf_process_info * proc = new operf_process_info(event-&amp;gt;mmap.pid, app_name ? app_name : NULL,
                                                                              app_name != NULL, false);
 proc-&amp;gt;add_deferred_mapping(mapping);
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Added deferred mapping " &amp;lt;&amp;lt; event-&amp;gt;mmap.filename
-&amp;lt;&amp;lt; " for new process_info object" &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Added deferred mapping " &amp;lt;&amp;lt; event-&amp;gt;mmap.filename
+      &amp;lt;&amp;lt; " for new process_info object" &amp;lt;&amp;lt; endl;
 process_map[event-&amp;gt;mmap.pid] = proc;
 #ifdef _TEST_DEFERRED_MAPPING
 if (!do_comm_event) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -255,8 +263,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_mmap_event(event_t * event)
 #endif
 } else if (!it-&amp;gt;second-&amp;gt;is_valid()) {
 it-&amp;gt;second-&amp;gt;add_deferred_mapping(mapping);
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Added deferred mapping " &amp;lt;&amp;lt; event-&amp;gt;mmap.filename
-&amp;lt;&amp;lt; " for existing but incomplete process_info object" &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Added deferred mapping " &amp;lt;&amp;lt; event-&amp;gt;mmap.filename
+      &amp;lt;&amp;lt; " for existing but incomplete process_info object" &amp;lt;&amp;lt; endl;
 } else {
 it-&amp;gt;second-&amp;gt;process_new_mapping(mapping);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -271,7 +280,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct operf_transient * __get_operf_trans(struct sample_data * data)
 
 if (trans.tgid == data-&amp;gt;pid) {
 proc = trans.cur_procinfo;
-cverb &amp;lt;&amp;lt; vmisc &amp;lt;&amp;lt; "trans.tgid == data-&amp;gt;pid : " &amp;lt;&amp;lt; data-&amp;gt;pid &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vmisc)
+cout &amp;lt;&amp;lt; "trans.tgid == data-&amp;gt;pid : " &amp;lt;&amp;lt; data-&amp;gt;pid &amp;lt;&amp;lt; endl;
 
 } else {
 // Find operf_process info for data.tgid.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -330,9 +340,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static struct operf_transient * __get_operf_trans(struct sample_data * data)
 op_mmap = proc-&amp;gt;find_mapping_for_sample(data-&amp;gt;ip);
 }
 if (op_mmap) {
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Found mmap for sample; image_name is " &amp;lt;&amp;lt; op_mmap-&amp;gt;filename &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Found mmap for sample; image_name is " &amp;lt;&amp;lt; op_mmap-&amp;gt;filename &amp;lt;&amp;lt; endl;
 trans.image_name = op_mmap-&amp;gt;filename;
 trans.app_filename = proc-&amp;gt;get_app_name().c_str();
+trans.image_len = strlen(trans.image_name);
+trans.app_len = strlen(trans.app_filename);
 trans.start_addr = op_mmap-&amp;gt;start_addr;
 trans.end_addr = op_mmap-&amp;gt;end_addr;
 trans.tgid = data-&amp;gt;pid;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -367,7 +380,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_callchain(u64 * array, struct sample_data * data)
 {
 data-&amp;gt;callchain = (struct ip_callchain *) array;
 if (data-&amp;gt;callchain-&amp;gt;nr) {
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Processing callchain" &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Processing callchain" &amp;lt;&amp;lt; endl;
 for (int i = 0; i &amp;lt; data-&amp;gt;callchain-&amp;gt;nr; i++) {
 data-&amp;gt;ip = data-&amp;gt;callchain-&amp;gt;ips[i];
 if (data-&amp;gt;ip &amp;gt;= PERF_CONTEXT_MAX) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -402,7 +416,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_callchain(u64 * array, struct sample_data * data)
 static void __handle_sample_event(event_t * event, u64 sample_type)
 {
 struct sample_data data;
-bool early_match = false;
+bool found_trans = false;
 const struct operf_mmap * op_mmap = NULL;
 
 u64 *array = event-&amp;gt;sample.array;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -457,9 +471,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_sample_event(event_t * event, u64 sample_type)
 goto out;
 }
 
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "(IP, " &amp;lt;&amp;lt;  event-&amp;gt;header.misc &amp;lt;&amp;lt; "): " &amp;lt;&amp;lt; dec &amp;lt;&amp;lt; data.pid &amp;lt;&amp;lt; "/"
-      &amp;lt;&amp;lt; data.tid &amp;lt;&amp;lt; ": " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; (unsigned long long)data.ip
-      &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; "\tdata ID: " &amp;lt;&amp;lt; data.id &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "(IP, " &amp;lt;&amp;lt;  event-&amp;gt;header.misc &amp;lt;&amp;lt; "): " &amp;lt;&amp;lt; dec &amp;lt;&amp;lt; data.pid &amp;lt;&amp;lt; "/"
+      &amp;lt;&amp;lt; data.tid &amp;lt;&amp;lt; ": " &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; (unsigned long long)data.ip
+      &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; "\tdata ID: " &amp;lt;&amp;lt; data.id &amp;lt;&amp;lt; endl;
 
 // Verify the sample.
 trans.event = operfRead.get_eventnum_by_perf_event_id(data.id);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -471,42 +486,46 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void __handle_sample_event(event_t * event, u64 sample_type)
 /* Check for the common case first -- i.e., where the current sample is from
  * the same context as the previous sample.  For the "no-vmlinux" case, start_addr
  * and end_addr will be zero, so need to make sure we detect that.
+ * The last resort (and most expensive) is to call __get_operf_trans() if the
+ * sample cannot be matched up with a previous tran object.
  */
 if (trans.in_kernel) {
 if (trans.image_name &amp;amp;&amp;amp; trans.tgid == data.pid) {
 // For the no-vmlinux case . . .
 if ((trans.start_addr == 0ULL) &amp;amp;&amp;amp; (trans.end_addr == 0ULL)) {
 trans.pc = data.ip;
-early_match = true;
+found_trans = true;
 // For the case where a vmlinux file is passed in . . .
 } else if (data.ip &amp;gt;= trans.start_addr &amp;amp;&amp;amp; data.ip &amp;lt; trans.end_addr) {
 trans.pc = data.ip;
-early_match = true;
+found_trans = true;
 }
 }
 } else {
 if (trans.tgid == data.pid &amp;amp;&amp;amp; data.ip &amp;gt;= trans.start_addr &amp;amp;&amp;amp; data.ip &amp;lt; trans.end_addr) {
 trans.tid = data.tid;
 trans.pc = data.ip - trans.start_addr;
-early_match = true;
+found_trans = true;
+} else if (__get_operf_trans(&amp;amp;data)) {
+trans.current = operf_sfile_find(&amp;amp;trans);
+found_trans = true;
 }
+
 }
-if (early_match || __get_operf_trans(&amp;amp;data)) {
-trans.current = operf_sfile_find(&amp;amp;trans);
-/*
- * trans.current may be NULL if a kernel sample falls through
- * the cracks, or if it's a sample from an anon region we couldn't find
- */
-if (trans.current) {
-/* log the sample or arc */
-operf_sfile_log_sample(&amp;amp;trans);
+/*
+ * trans.current may be NULL if a kernel sample falls through
+ * the cracks, or if it's a sample from an anon region we couldn't find
+ */
+if (found_trans &amp;amp;&amp;amp; trans.current) {
+/* log the sample or arc */
+operf_sfile_log_sample(&amp;amp;trans);
 
-update_trans_last(&amp;amp;trans);
-if (sample_type &amp;amp; PERF_SAMPLE_CALLCHAIN)
-__handle_callchain(array, &amp;amp;data);
-goto out;
-}
+update_trans_last(&amp;amp;trans);
+if (sample_type &amp;amp; PERF_SAMPLE_CALLCHAIN)
+__handle_callchain(array, &amp;amp;data);
+goto out;
 }
+
 if (first_time_processing) {
 event_t * ev = (event_t *)xmalloc(event-&amp;gt;header.size);
 memcpy(ev, event, event-&amp;gt;header.size);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -519,17 +538,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 
 
 /* This function is used by operf_read::convertPerfData() to convert perf-formatted
- * data to oprofile sample data files.  After the header information in the perf data file,
- * the next piece of data is the PERF_RECORD_COMM record which tells us the name of the
+ * data to oprofile sample data files.  After the header information in the perf sample data,
+ * the next piece of data is typically the PERF_RECORD_COMM record which tells us the name of the
  * application/command being profiled.  This is followed by PERF_RECORD_MMAP records
  * which indicate what binary executables and libraries were mmap'ed into process memory
  * when profiling began.  Additional PERF_RECORD_MMAP records may appear later in the data
  * stream (e.g., dlopen for single-process profiling or new process startup for system-wide
- * profiling.  For such additional PERF_RECORD_MMAP records, it's possible that samples
- * may be collected and written to the perf data file for those mmap'ed binaries prior
- * to the reception/recording of the corresponding PERF_RECORD_MMAP record, in which case,
- * those samples are discarded and we increment the appropriate "lost sample" stat.
- * TODO:   What's the name of the stat we increment?
+ * profiling.
  */
 int OP_perf_utils::op_write_event(event_t * event, u64 sample_type)
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -554,7 +569,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int OP_perf_utils::op_write_event(event_t * event, u64 sample_type)
 __handle_comm_event(event);
 return 0;
 case PERF_RECORD_EXIT:
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "PERF_RECORD_EXIT found in trace" &amp;lt;&amp;lt; endl;
 return 0;
 default:
 // OK, ignore all other header types.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -586,17 +600,11 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void OP_perf_utils::op_perfrecord_sigusr1_handler(int sig __attribute__((unused)
 quit = true;
 }
 
-int OP_perf_utils::op_read_from_stream(ifstream &amp;amp; is, char * buf, streamsize sz)
+void OP_perf_utils::op_perfread_sigusr1_handler(int sig __attribute__((unused)),
+siginfo_t * siginfo __attribute__((unused)),
+void *u_context __attribute__((unused)))
 {
-int rc = 0;
-is.read(buf, sz);
-if (!is.eof() &amp;amp;&amp;amp; is.fail()) {
-cerr &amp;lt;&amp;lt; "Internal error:  Failed to read from input file." &amp;lt;&amp;lt; endl;
-rc = -1;
-} else {
-rc = is.gcount();
-}
-return rc;
+read_quit = true;
 }
 
 int OP_perf_utils::op_write_output(int output, void *buf, size_t size)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -606,7 +614,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int OP_perf_utils::op_write_output(int output, void *buf, size_t size)
 int ret = write(output, buf, size);
 
 if (ret &amp;lt; 0) {
-string errmsg = "Internal error:  Failed to write to output file. errno is ";
+string errmsg = "Internal error:  Failed to write sample data to pipe. errno is ";
 errmsg += strerror(errno);
 throw runtime_error(errmsg);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -670,7 +678,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void op_record_process_exec_mmaps(pid_t pid, pid_t tgid, int output_fd, o
 mmap.header.size = (sizeof(mmap) -
 (sizeof(mmap.filename) - size));
 int num = OP_perf_utils::op_write_output(output_fd, &amp;amp;mmap, mmap.header.size);
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Created MMAP event for " &amp;lt;&amp;lt; imagename &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Created MMAP event for " &amp;lt;&amp;lt; imagename &amp;lt;&amp;lt; endl;
 pr-&amp;gt;add_to_total(num);
 }
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -769,11 +778,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; out:
 op_record_process_exec_mmaps(pid, tgid, output_fd, pr);
 
 fclose(fp);
-if (ret)
+if (ret) {
 cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "couldn't get app name and tgid for pid "
       &amp;lt;&amp;lt; dec &amp;lt;&amp;lt; pid &amp;lt;&amp;lt; " from /proc fs." &amp;lt;&amp;lt; endl;
-else
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Created COMM event for " &amp;lt;&amp;lt; comm.comm &amp;lt;&amp;lt; endl;
+} else {
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Created COMM event for " &amp;lt;&amp;lt; comm.comm &amp;lt;&amp;lt; endl;
+}
 return ret;
 
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -787,7 +798,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int OP_perf_utils::op_record_process_info(bool system_wide, pid_t pid, operf_rec
                                           int output_fd)
 {
 int ret;
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "op_record_process_info" &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "op_record_process_info" &amp;lt;&amp;lt; endl;
 if (!system_wide) {
 ret = _record_one_process_info(pid, system_wide, pr, output_fd);
 } else {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -883,8 +895,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void _record_module_info(int output_fd, operf_record * pr)
 mmap.header.size = (sizeof(mmap) -
 (sizeof(mmap.filename) - size));
 int num = OP_perf_utils::op_write_output(output_fd, &amp;amp;mmap, mmap.header.size);
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Created MMAP event for " &amp;lt;&amp;lt; module_name &amp;lt;&amp;lt; ". Size: "
-      &amp;lt;&amp;lt; module_size &amp;lt;&amp;lt; "; start addr: " &amp;lt;&amp;lt; start_address &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Created MMAP event for " &amp;lt;&amp;lt; module_name &amp;lt;&amp;lt; ". Size: "
+      &amp;lt;&amp;lt; module_size &amp;lt;&amp;lt; "; start addr: " &amp;lt;&amp;lt; start_address &amp;lt;&amp;lt; endl;
 pr-&amp;gt;add_to_total(num);
 free(line);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -917,8 +930,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void OP_perf_utils::op_record_kernel_info(string vmlinux_file, u64 start_addr, u
 mmap.header.size = (sizeof(mmap) -
 (sizeof(mmap.filename) - size));
 int num = op_write_output(output_fd, &amp;amp;mmap, mmap.header.size);
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Created MMAP event for " &amp;lt;&amp;lt;mmap.filename &amp;lt;&amp;lt; ". Size: "
-      &amp;lt;&amp;lt; mmap.len &amp;lt;&amp;lt; "; start addr: " &amp;lt;&amp;lt; mmap.start &amp;lt;&amp;lt; endl;
+if (cverb &amp;lt;&amp;lt; vperf)
+cout &amp;lt;&amp;lt; "Created MMAP event of size " &amp;lt;&amp;lt; mmap.header.size &amp;lt;&amp;lt; " for " &amp;lt;&amp;lt;mmap.filename &amp;lt;&amp;lt; ". length: "
+      &amp;lt;&amp;lt; mmap.len &amp;lt;&amp;lt; "; start addr: " &amp;lt;&amp;lt; mmap.start &amp;lt;&amp;lt; endl;
 pr-&amp;gt;add_to_total(num);
 _record_module_info(output_fd, pr);
 }
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -965,101 +979,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void OP_perf_utils::op_get_kernel_event_data(struct mmap_data *md, operf_record
 }
 
 
-static size_t mmap_size;
-static size_t pg_sz;
-
-static int __mmap_trace_file(struct mmap_info &amp;amp; info)
-{
-int mmap_prot  = PROT_READ;
-int mmap_flags = MAP_SHARED;
-
-info.buf = (char *) mmap(NULL, mmap_size, mmap_prot,
-mmap_flags, info.traceFD, info.offset);
-if (info.buf == MAP_FAILED) {
-cerr &amp;lt;&amp;lt; "Error: mmap failed with errno:\n\t" &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
-return -1;
-}
-else {
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; hex &amp;lt;&amp;lt; "mmap with the following parameters" &amp;lt;&amp;lt; endl
-      &amp;lt;&amp;lt; "\tinfo.head: " &amp;lt;&amp;lt; info.head &amp;lt;&amp;lt; endl
-      &amp;lt;&amp;lt; "\tinfo.offset: " &amp;lt;&amp;lt; info.offset &amp;lt;&amp;lt; endl;
-return 0;
-}
-}
-
-int OP_perf_utils::op_mmap_trace_file(struct mmap_info &amp;amp; info)
-{
-u64 shift;
-if (!pg_sz)
-pg_sz = sysconf(_SC_PAGESIZE);
-if (!mmap_size) {
-if (MMAP_WINDOW_SZ &amp;gt; info.file_data_size) {
-mmap_size = info.file_data_size;
-} else {
-mmap_size = MMAP_WINDOW_SZ;
-}
-}
-info.offset = 0;
-info.head = info.file_data_offset;
-shift = pg_sz * (info.head / pg_sz);
-info.offset += shift;
-info.head -= shift;
-return __mmap_trace_file(info);
-}
-
-event_t * OP_perf_utils::op_get_perf_event(struct mmap_info &amp;amp; info)
-{
-uint32_t size;
-event_t * event;
-
-if (info.offset + info.head &amp;gt;= info.file_data_offset + info.file_data_size)
-return NULL;
-
-if (!pg_sz)
-pg_sz = sysconf(_SC_PAGESIZE);
-
-try_again:
-event = (event_t *)(info.buf + info.head);
-
-if ((mmap_size != info.file_data_size) &amp;amp;&amp;amp;
-(((info.head + sizeof(event-&amp;gt;header)) &amp;gt; mmap_size) ||
-(info.head + event-&amp;gt;header.size &amp;gt; mmap_size))) {
-int ret;
-u64 shift = pg_sz * (info.head / pg_sz);
-cverb &amp;lt;&amp;lt; vperf &amp;lt;&amp;lt; "Remapping perf data file" &amp;lt;&amp;lt; endl;
-ret = munmap(info.buf, mmap_size);
-if (ret) {
-string errmsg = "Internal error:  munmap of perf data file failed with errno: ";
-errmsg += strerror(errno);
-throw runtime_error(errmsg);
-}
-
-info.offset += shift;
-info.head -= shift;
-ret = __mmap_trace_file(info);
-if (ret) {
-string errmsg = "Internal error:  mmap of perf data file failed with errno: ";
-errmsg += strerror(errno);
-throw runtime_error(errmsg);
-}
-goto try_again;
-}
-
-size = event-&amp;gt;header.size;
-
-// The tail end of the operf data file may be zero'ed out, so we assume if we
-// find size==0, we're now in that area of the file, so we're done.
-if (size == 0)
-return NULL;
-
-info.head += size;
-if (info.offset + info.head &amp;gt;= info.file_data_offset + info.file_data_size)
-return NULL;
-
-return event;
-}
-
-
 int OP_perf_utils::op_get_next_online_cpu(DIR * dir, struct dirent *entry)
 {
 #define OFFLINE 0x30
diff --git a/libperf_events/operf_utils.h b/libperf_events/operf_utils.h
index 060ee2b..9359c82 100644
--- a/libperf_events/operf_utils.h
+++ b/libperf_events/operf_utils.h
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -38,12 +38,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; extern bool no_vmlinux;
 
 #define OP_APPNAME_LEN 1024
 
-#if BITS_PER_LONG == 64
-#define MMAP_WINDOW_SZ ULLONG_MAX
-#else
-#define MMAP_WINDOW_SZ (32 * 1024 * 1024ULL)
-#endif
-
 extern unsigned int op_nr_counters;
 
 static inline size_t align_64bit(u64 x)
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -64,12 +58,12 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; void op_get_kernel_event_data(struct mmap_data *md, operf_record * pr);
 void op_perfrecord_sigusr1_handler(int sig __attribute__((unused)),
 siginfo_t * siginfo __attribute__((unused)),
 void *u_context __attribute__((unused)));
+void op_perfread_sigusr1_handler(int sig __attribute__((unused)),
+siginfo_t * siginfo __attribute__((unused)),
+void *u_context __attribute__((unused)));
 int op_record_process_info(bool system_wide, pid_t pid, operf_record * pr, int output_fd);
 int op_write_output(int output, void *buf, size_t size);
 int op_write_event(event_t * event, u64 sample_type);
-int op_read_from_stream(std::ifstream &amp;amp; is, char * buf, std::streamsize sz);
-int op_mmap_trace_file(struct mmap_info &amp;amp; info);
-event_t * op_get_perf_event(struct mmap_info &amp;amp; info);
 int op_get_next_online_cpu(DIR * dir, struct dirent *entry);
 bool op_convert_event_vals(std::vector&amp;lt;operf_event_t&amp;gt; * evt_vec);
 void op_reprocess_unresolved_events(u64 sample_type);
diff --git a/pe_profiling/operf.cpp b/pe_profiling/operf.cpp
index 95bf183..ee4e3ba 100644
--- a/pe_profiling/operf.cpp
+++ b/pe_profiling/operf.cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -47,8 +47,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; using namespace std;
 
 typedef enum END_CODE {
 ALL_OK = 0,
-APP_ABNORMAL_END = -2,
-PERF_RECORD_ERROR = -3
+APP_ABNORMAL_END =  1,
+PERF_RECORD_ERROR = 2,
+PERF_READ_ERROR   = 4,
+PERF_BOTH_ERROR   = 8
 } end_code_t;
 
 // Globals
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -60,9 +62,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; double cpu_speed;
 char op_samples_current_dir[PATH_MAX];
 uint op_nr_counters;
 verbose vmisc("misc");
+static void convert_sample_data(void);
+static int sample_data_pipe[2];
 
 
-#define DEFAULT_OPERF_OUTFILE "operf.data"
 #define CALLGRAPH_MIN_COUNT_SCALE 15
 
 static char full_pathname[PATH_MAX];
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -72,10 +75,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static pid_t app_PID = -1;
 static pid_t jitconv_pid = -1;
 static bool app_started;
 static pid_t operf_pid;
+static pid_t convert_pid;
 static string samples_dir;
-static string outputfile;
 static bool startApp;
-static bool reset_done = false;
 static char start_time_str[32];
 static vector&amp;lt;operf_event_t&amp;gt; events;
 static bool jit_conversion_running;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -255,6 +257,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int start_profiling_app(void)
 perror("Internal error: fork failed");
 _exit(EXIT_FAILURE);
 } else if (app_PID == 0) { // child process for exec'ing app
+close(sample_data_pipe[0]);
+close(sample_data_pipe[1]);
 run_app();
 }
 // parent
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -270,6 +274,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int start_profiling_app(void)
 return -1;
 } else if (operf_pid == 0) { // operf-record process
 int ready = 0;
+close(sample_data_pipe[0]);
 /*
  * Since an informative message will be displayed to the user if
  * an error occurs, we don't want to blow chunks here; instead, we'll
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -281,7 +286,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int start_profiling_app(void)
 vi.image_name = operf_options::vmlinux;
 vi.start = kernel_start;
 vi.end = kernel_end;
-operf_record operfRecord(outputfile, operf_options::system_wide, app_PID,
+operf_record operfRecord(sample_data_pipe[1], operf_options::system_wide, app_PID,
                          (operf_options::pid == app_PID), events, vi,
                          operf_options::callgraph,
                          operf_options::separate_cpu);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -308,7 +313,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int start_profiling_app(void)
 
 // start recording
 operfRecord.recordPerfData();
-cerr &amp;lt;&amp;lt; "Total bytes recorded from perf events: "
+cverb &amp;lt;&amp;lt; vmisc &amp;lt;&amp;lt; "Total bytes recorded from perf events: " &amp;lt;&amp;lt; dec
 &amp;lt;&amp;lt; operfRecord.get_total_bytes_recorded() &amp;lt;&amp;lt; endl;
 
 operfRecord.~operf_record();
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -319,9 +324,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int start_profiling_app(void)
 goto fail_out;
 }
 fail_out:
-ofstream of;
-of.open(outputfile.c_str(), ios_base::trunc);
-of.close();
 if (startApp &amp;amp;&amp;amp; !ready){
 /* ready==0 means we've not yet told parent we're ready,
  * but the parent is reading our pipe.  So we tell the
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -376,6 +378,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static end_code_t _kill_operf_pid(void)
 {
 int waitpid_status = 0;
 end_code_t rc = ALL_OK;
+struct timeval tv;
+long long start_time_sec;
+long long usec_timer;
+bool keep_trying = true;
 
 // stop operf-record process
 if (kill(operf_pid, SIGUSR1) &amp;lt; 0) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -387,14 +393,67 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static end_code_t _kill_operf_pid(void)
 rc = PERF_RECORD_ERROR;
 } else {
 if (WIFEXITED(waitpid_status) &amp;amp;&amp;amp; (!WEXITSTATUS(waitpid_status))) {
-cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "waitpid for operf-record process returned OK" &amp;lt;&amp;lt; endl;
+cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "operf-record process returned OK" &amp;lt;&amp;lt; endl;
 } else {
 cerr &amp;lt;&amp;lt;  "operf-record process ended abnormally: "
-&amp;lt;&amp;lt; WEXITSTATUS(waitpid_status) &amp;lt;&amp;lt; endl;
+     &amp;lt;&amp;lt; WEXITSTATUS(waitpid_status) &amp;lt;&amp;lt; endl;
 rc = PERF_RECORD_ERROR;
 }
 }
 }
+
+// Now stop the operf-read process (aka "convert_pid")
+waitpid_status = 0;
+gettimeofday(&amp;amp;tv, NULL);
+start_time_sec = tv.tv_sec;
+usec_timer = tv.tv_usec;
+/* We'll initially try the waitpid with WNOHANG once every 100,000 usecs.
+ * If it hasn't ended within 5 seconds, we'll kill it and do one
+ * final wait.
+ */
+while (keep_trying) {
+int option = WNOHANG;
+gettimeofday(&amp;amp;tv, NULL);
+if (tv.tv_sec &amp;gt; start_time_sec + 5) {
+keep_trying = false;
+option = 0;
+cerr &amp;lt;&amp;lt; "now trying to kill convert pid..." &amp;lt;&amp;lt; endl;
+
+if (kill(convert_pid, SIGUSR1) &amp;lt; 0) {
+perror("Attempt to stop operf-read process failed");
+rc = rc ? PERF_BOTH_ERROR : PERF_READ_ERROR;
+break;
+}
+} else {
+/* If we exceed the 100000 usec interval or if the tv_usec
+ * value has rolled over to restart at 0, then we reset
+ * the usec_timer to current tv_usec and try waitpid.
+ */
+if ((tv.tv_usec % 1000000) &amp;gt; (usec_timer + 100000)
+|| (tv.tv_usec &amp;lt; usec_timer))
+usec_timer = tv.tv_usec;
+else
+continue;
+}
+if (waitpid(convert_pid, &amp;amp;waitpid_status, option) &amp;lt; 0) {
+keep_trying = false;
+if (errno != ECHILD) {
+perror("waitpid for operf-read process failed");
+rc = rc ? PERF_BOTH_ERROR : PERF_READ_ERROR;
+}
+} else {
+if (WIFEXITED(waitpid_status)) {
+keep_trying = false;
+if (!WEXITSTATUS(waitpid_status)) {
+cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "operf-read process returned OK" &amp;lt;&amp;lt; endl;
+} else {
+cerr &amp;lt;&amp;lt;  "operf-read process ended abnormally.  Status = "
+     &amp;lt;&amp;lt; WEXITSTATUS(waitpid_status) &amp;lt;&amp;lt; endl;
+rc = rc ? PERF_BOTH_ERROR : PERF_READ_ERROR;
+}
+}
+}
+}
 return rc;
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -408,13 +467,40 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static end_code_t _run(void)
 sigfillset(&amp;amp;ss);
 sigprocmask(SIG_BLOCK, &amp;amp;ss, NULL);
 
+// Create pipe to which operf-record process writes sample data and
+// from which the operf-read process reads.
+if (pipe(sample_data_pipe) &amp;lt; 0) {
+perror("Internal error: operf-record could not create pipe");
+_exit(EXIT_FAILURE);
+}
+
 if (start_profiling_app() &amp;lt; 0) {
 return PERF_RECORD_ERROR;
 }
 // parent continues here
 if (startApp)
 cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "app " &amp;lt;&amp;lt; app_PID &amp;lt;&amp;lt; " is running" &amp;lt;&amp;lt; endl;
+
+/* If we're not doing system wide profiling and no app is started, then
+ * there's no profile data to convert. So if this condition is NOT true,
+ * then we'll do the convert.
+ */
+if (!(!app_started &amp;amp;&amp;amp; !operf_options::system_wide)) {
+convert_pid = fork();
+if (convert_pid &amp;lt; 0) {
+perror("Internal error: fork failed");
+_exit(EXIT_FAILURE);
+} else if (convert_pid == 0) { // child process
+close(sample_data_pipe[1]);
+convert_sample_data();
+}
+// parent
+close(sample_data_pipe[0]);
+close(sample_data_pipe[1]);
+}
+
 set_signals();
+cout &amp;lt;&amp;lt; "operf: Profiler started" &amp;lt;&amp;lt; endl;
 if (startApp) {
 // User passed in command or program name to start
 cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "going into waitpid on profiled app " &amp;lt;&amp;lt; app_PID &amp;lt;&amp;lt; endl;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -438,6 +524,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static end_code_t _run(void)
 rc = _kill_operf_pid();
 } else {
 // User passed in --pid or --system-wide
+cout &amp;lt;&amp;lt; "operf: Press Ctl-c to stop profiling" &amp;lt;&amp;lt; endl;
 cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "going into waitpid on operf record process " &amp;lt;&amp;lt; operf_pid &amp;lt;&amp;lt; endl;
 if (waitpid(operf_pid, &amp;amp;waitpid_status, 0) &amp;lt; 0) {
 if (errno == EINTR) {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -453,7 +540,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static end_code_t _run(void)
 cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "waitpid for operf-record process returned OK" &amp;lt;&amp;lt; endl;
 } else if (WIFEXITED(waitpid_status)) {
 cerr &amp;lt;&amp;lt;  "operf-record process ended abnormally: "
-&amp;lt;&amp;lt; WEXITSTATUS(waitpid_status) &amp;lt;&amp;lt; endl;
+     &amp;lt;&amp;lt; WEXITSTATUS(waitpid_status) &amp;lt;&amp;lt; endl;
 rc = PERF_RECORD_ERROR;
 } else if (WIFSIGNALED(waitpid_status)) {
 cerr &amp;lt;&amp;lt; "operf-record process killed by signal "
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -467,12 +554,10 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static end_code_t _run(void)
 
 static void cleanup(void)
 {
-string cmd = "rm -f " + outputfile;
 free(app_name_SAVE);
 free(app_args);
 events.clear();
 verbose_string.clear();
-system(cmd.c_str());
 }
 
 static void _jitconv_complete(int val __attribute__((unused)))
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -572,17 +657,17 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int __delete_old_previous_sample_data(const char *fpath,
 }
 }
 
-static void complete(void)
+/* Read perf_events sample data written by the operf-record process
+ * through the sample_data_pipe and convert this to oprofile format
+ * sample files.
+ */
+static void convert_sample_data(void)
 {
 int rc;
 string current_sampledir = samples_dir + "/current/";
 string previous_sampledir = samples_dir + "/previous";
 current_sampledir.copy(op_samples_current_dir, current_sampledir.length(), 0);
 
-if (!app_started &amp;amp;&amp;amp; !operf_options::system_wide) {
-cleanup();
-return;
-}
 if (!operf_options::append) {
                 int flags = FTW_DEPTH | FTW_ACTIONRETVAL;
 errno = 0;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -592,47 +677,40 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void complete(void)
 if (errno)
 cerr &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
 cleanup();
-exit(1);
+_exit(EXIT_FAILURE);
 }
 if (rename(current_sampledir.c_str(), previous_sampledir.c_str()) &amp;lt; 0) {
 if (errno &amp;amp;&amp;amp; (errno != ENOENT)) {
 cerr &amp;lt;&amp;lt; "Unable to move old profile data to " &amp;lt;&amp;lt; previous_sampledir &amp;lt;&amp;lt; endl;
 cerr &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
 cleanup();
-exit(1);
+_exit(EXIT_FAILURE);
 }
 }
-reset_done = true;
 }
 rc = mkdir(current_sampledir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
 if (rc &amp;amp;&amp;amp; (errno != EEXIST)) {
 cerr &amp;lt;&amp;lt; "Error trying to create " &amp;lt;&amp;lt; current_sampledir &amp;lt;&amp;lt; " dir." &amp;lt;&amp;lt; endl;
 perror("mkdir failed with");
-exit(EXIT_FAILURE);
+_exit(EXIT_FAILURE);
 }
 
-operfRead.init(outputfile, current_sampledir, cpu_type, events);
+operfRead.init(sample_data_pipe[0], current_sampledir, cpu_type, events);
 if ((rc = operfRead.readPerfHeader()) &amp;lt; 0) {
 if (rc != OP_PERF_HANDLED_ERROR)
-cerr &amp;lt;&amp;lt; "Error: Cannot create read header info for sample file " &amp;lt;&amp;lt; outputfile &amp;lt;&amp;lt; endl;
+cerr &amp;lt;&amp;lt; "Error: Cannot create read header info for sample data " &amp;lt;&amp;lt; endl;
 cleanup();
-exit(1);
+_exit(EXIT_FAILURE);
 }
-cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "Successfully read header info for sample file " &amp;lt;&amp;lt; outputfile &amp;lt;&amp;lt; endl;
-// TODO:  We may want to do incremental conversion of the perf data, since the perf sample format
-// is very inefficient to store.  For example, using a simple test program that does many
-// millions of memcpy's over a 12 second span of time, a profile taken via legacy oprofile,
-// with --separate=all and --image=&amp;lt;app_name&amp;gt; requires ~300K of storage.  Using the perf tool
-// (not operf) to profile the same application creates an 18MB perf.data file!!
+cverb &amp;lt;&amp;lt; vdebug &amp;lt;&amp;lt; "Successfully read header info for sample data " &amp;lt;&amp;lt; endl;
 if (operfRead.is_valid()) {
 try {
 operfRead.convertPerfData();
-cerr &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; "Use '--session-dir=" &amp;lt;&amp;lt; operf_options::session_dir &amp;lt;&amp;lt; "'" &amp;lt;&amp;lt; endl
-     &amp;lt;&amp;lt; "with opreport and other post-processing tools to view your profile data."
-     &amp;lt;&amp;lt; endl;
 } catch (runtime_error e) {
 cerr &amp;lt;&amp;lt; "Caught exception from operf_read::convertPerfData" &amp;lt;&amp;lt; endl;
 cerr &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; endl;
+cleanup();
+_exit(EXIT_FAILURE);
 }
 }
 // Invoke opjitconv and set up a SIGCHLD signal for when it's done
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -645,7 +723,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void complete(void)
 if (jit_conversion_running) {
 kill(jitconv_pid, SIGKILL);
 }
-cleanup();
+_exit(EXIT_SUCCESS);
+
 }
 
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1072,7 +1151,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void process_args(int argc, char const ** argv)
 }
 
 _process_session_dir();
-outputfile = samples_dir + "/" + DEFAULT_OPERF_OUTFILE;
 
 if (operf_options::evts.empty()) {
 // Use default event
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1137,6 +1215,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void _precheck_permissions_to_samplesdir(string sampledir, bool for_curre
 cleanup();
 exit(1);
 }
+afile.close();
 
 }
 
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1200,13 +1279,18 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int main(int argc, char const *argv[])
 perror("Attempt to kill profiled app failed.");
 }
 }
-if (run_result == PERF_RECORD_ERROR) {
+if ((run_result == PERF_RECORD_ERROR) || (run_result == PERF_BOTH_ERROR)) {
 cerr &amp;lt;&amp;lt;  "Error running profiler" &amp;lt;&amp;lt; endl;
-exit(1);
+} else if (run_result == PERF_READ_ERROR) {
+cerr &amp;lt;&amp;lt; "Error converting operf sample data to oprofile sample format" &amp;lt;&amp;lt; endl;
 } else {
 cerr &amp;lt;&amp;lt; "WARNING: Profile results may be incomplete due to to abend of profiled app." &amp;lt;&amp;lt; endl;
 }
+} else {
+cout &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; "Use '--session-dir=" &amp;lt;&amp;lt; operf_options::session_dir &amp;lt;&amp;lt; "'" &amp;lt;&amp;lt; endl
+     &amp;lt;&amp;lt; "with opreport and other post-processing tools to view your profile data."
+     &amp;lt;&amp;lt; endl;
 }
-complete();
-return 0;
+cleanup();
+return run_result;;
 }
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-22T22:05:40</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10503">
    <title>[PATCH] Remove reset option from operf and replace with append option</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10503</link>
    <description>&lt;pre&gt;[PATCH] Remove reset option from operf and replace with append option.

By default, operf will now move old profile data from &amp;lt;session_dir&amp;gt;/samples/current
to &amp;lt;session_dir&amp;gt;/samples/previous.  If a 'previous' profile already existed,
it will be replaced.  If the --append option is passed, old profile data is left
in place and new profile data will be added to it, and the 'previous' profile
(if one existed) will remain untouched.

operf man page updates:
Aside from replacing the --reset option with the --append option, several unrelated
fixes were made, including adding the missing --vmlinux option.

This patch has been pushed up to the perf-events branch, but review comments are
as always, welcome.

Signed-off-by: Maynard Johnson &amp;lt;maynardj&amp;lt; at &amp;gt;us.ibm.com&amp;gt;
---
 doc/operf.1.in         |   36 ++++++++++++----
 pe_profiling/operf.cpp |  109 +++++++++++++++++++++++++++--------------------
 2 files changed, 90 insertions(+), 55 deletions(-)

diff --git a/doc/operf.1.in b/doc/operf.1.in
index 00b6b2c..00fb5f3 100644
--- a/doc/operf.1.in
+++ b/doc/operf.1.in
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -44,8 +44,9 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; is required, but
 be used simultaneously.
 .br
 .TP
-.BI "--pid / -p [PID]"
-This option enables operf to profile a running application. &amp;lt;PID&amp;gt;
+.BI "--pid / -p " PID
+This option enables operf to profile a running application.
+.I PID
 should be the process ID of the process you wish to profile.  When
 finished profiling (e.g., when the profiled process ends), press
 Ctrl-c to stop operf.
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -71,21 +72,38 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; directory should be /root or a subdirectory of /root to avoid
 storing sample data files in locations accessible by regular users.
 .br
 .TP
+.BI "--vmlinux / k " vmlinux_path
+A vmlinux file that matches the running kernel that has symbol and/or debuginfo.
+Kernel samples will be attributed to this binary, allowing post-processing tools
+(like opreport) to attribute samples to the appropriate kernel symbols.
+.TP
 .BI "--callgraph / -g"
 This option enables the callgraph to be saved during profiling. NOTE: The
 full callchain is recorded, so there is no depth limit.
 .br
 .TP
-.BI "--reset / -r"
-This option clears out old profile data. You should almost always do this.
+.BI "--append / -a"
+By default,
+.I operf
+moves old profile data from &amp;lt;session_dir&amp;gt;/samples/current to
+&amp;lt;session_dir&amp;gt;/samples/previous.  If a 'previous' profile already existed,
+it will be replaced.  If the
+.I --append
+option is passed, old profile data is left in place and new profile data will
+be added to it, and the 'previous' profile (if one existed) will remain untouched.
+To access the 'previous' profile, simply add a session specification to the normal
+invocation of oprofile post-processing tools.  For example:
+.br
+.I "   opreport --session-dir=`pwd`/oprofile_data session:previous"
 .br
 .TP
-.BI "--kernel-buffersize-multiplier / -k [buffersize]"
+.BI "--kernel-buffersize-multiplier / -k " buffersize
 This option enables operf to increase the kernel buffer size by a
-factor of &amp;lt;buffersize&amp;gt;.
+factor of
+.I buffersize.
 .br
 .TP
-.BI "--events / -e [event1[,event2[,...]]]"
+.BI "--events / -e " event1[,event2[,...]]
 This option is for passing a comma-separated list of event specifications
 for profiling. Each event spec is of the form:
 .br
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -108,14 +126,14 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; executing the same program during a profiling run.
 This option categorizes samples by cpu.
 .br
 .TP
-.BI "--session-dir [path]"
+.BI "--session-dir / -d " path
 This option specifies the session path to hold the sample data. If not specified,
 the data is saved in the
 .I oprofile_data
 directory on the current path.
 .br
 .TP
-.BI "--verbose / -V [level]"
+.BI "--verbose / -V " level
 A comma-separated list of debugging control values, used to increase the verbosity of the output.
 Valid values are:  debug, perf_events, misc, sfile, arcs, or the special value, 'all'.
 .br
diff --git a/pe_profiling/operf.cpp b/pe_profiling/operf.cpp
index 4b2c65f..95bf183 100644
--- a/pe_profiling/operf.cpp
+++ b/pe_profiling/operf.cpp
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -84,7 +84,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static uid_t my_uid;
 
 namespace operf_options {
 bool system_wide;
-bool reset;
+bool append;
 int pid;
 bool callgraph;
 int mmap_pages_mult;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -109,8 +109,8 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; popt::option options_array[] = {
              "enable callgraph recording"),
 popt::option(operf_options::system_wide, "system-wide", 's',
              "profile entire system"),
-popt::option(operf_options::reset, "reset", 'r',
-             "clear out old profile data"),
+popt::option(operf_options::append, "append", 'a',
+             "add new profile data to old profile data"),
 popt::option(operf_options::pid, "pid", 'p',
              "process ID to profile", "PID"),
 popt::option(operf_options::mmap_pages_mult, "kernel-buffersize-multiplier", 'b',
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -475,19 +475,6 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void cleanup(void)
 system(cmd.c_str());
 }
 
-static int __delete_sample_data(const char *fpath,
-                                const struct stat *sb  __attribute__((unused)),
-                                int tflag  __attribute__((unused)),
-                                struct FTW *ftwbuf __attribute__((unused)))
-{
-if (remove(fpath)) {
-perror("sample data removal error");
-return FTW_STOP;
-} else {
-return FTW_CONTINUE;
-}
-}
-
 static void _jitconv_complete(int val __attribute__((unused)))
 {
 int child_status;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -572,29 +559,49 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static void _do_jitdump_convert()
 
 }
 
+static int __delete_old_previous_sample_data(const char *fpath,
+                                const struct stat *sb  __attribute__((unused)),
+                                int tflag  __attribute__((unused)),
+                                struct FTW *ftwbuf __attribute__((unused)))
+{
+if (remove(fpath)) {
+perror("sample data removal error");
+return FTW_STOP;
+} else {
+return FTW_CONTINUE;
+}
+}
 
 static void complete(void)
 {
 int rc;
 string current_sampledir = samples_dir + "/current/";
+string previous_sampledir = samples_dir + "/previous";
 current_sampledir.copy(op_samples_current_dir, current_sampledir.length(), 0);
 
 if (!app_started &amp;amp;&amp;amp; !operf_options::system_wide) {
 cleanup();
 return;
 }
-if (operf_options::reset) {
-int flags = FTW_DEPTH | FTW_ACTIONRETVAL;
+if (!operf_options::append) {
+                int flags = FTW_DEPTH | FTW_ACTIONRETVAL;
 errno = 0;
-if (nftw(current_sampledir.c_str(), __delete_sample_data, 32, flags) !=0 &amp;amp;&amp;amp;
+if (nftw(previous_sampledir.c_str(), __delete_old_previous_sample_data, 32, flags) !=0 &amp;amp;&amp;amp;
 errno != ENOENT) {
-cerr &amp;lt;&amp;lt; "Unable to remove old sample data at "
-     &amp;lt;&amp;lt; current_sampledir &amp;lt;&amp;lt; "." &amp;lt;&amp;lt; endl;
+cerr &amp;lt;&amp;lt; "Unable to remove old sample data at " &amp;lt;&amp;lt; previous_sampledir &amp;lt;&amp;lt; "." &amp;lt;&amp;lt; endl;
 if (errno)
 cerr &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
 cleanup();
 exit(1);
 }
+if (rename(current_sampledir.c_str(), previous_sampledir.c_str()) &amp;lt; 0) {
+if (errno &amp;amp;&amp;amp; (errno != ENOENT)) {
+cerr &amp;lt;&amp;lt; "Unable to move old profile data to " &amp;lt;&amp;lt; previous_sampledir &amp;lt;&amp;lt; endl;
+cerr &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
+cleanup();
+exit(1);
+}
+}
 reset_done = true;
 }
 rc = mkdir(current_sampledir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1104,6 +1111,35 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int _check_perf_events_cap(void)
 
 }
 
+static void _precheck_permissions_to_samplesdir(string sampledir, bool for_current)
+{
+/* Pre-check to make sure we have permission to remove old sample data
+ * or to create new sample data in the specified sample data directory.
+ * If the user wants us to remove old data, we don't actually do it now,
+ * since the profile session may fail for some reason or the user may do ctl-c.
+ * We should exit without unnecessarily removing the old sample data as
+ * the user may expect it to still be there after an aborted run.
+ */
+string sampledir_testfile = sampledir + "/.xxxTeStFiLe";
+ofstream afile;
+errno = 0;
+afile.open(sampledir_testfile.c_str());
+if (!afile.is_open() &amp;amp;&amp;amp; (errno != ENOENT)) {
+if (operf_options::append &amp;amp;&amp;amp; for_current)
+cerr &amp;lt;&amp;lt; "Unable to write to sample data directory at "
+     &amp;lt;&amp;lt; sampledir &amp;lt;&amp;lt; "." &amp;lt;&amp;lt; endl;
+else
+cerr &amp;lt;&amp;lt; "Unable to remove old sample data at "
+     &amp;lt;&amp;lt; sampledir &amp;lt;&amp;lt; "." &amp;lt;&amp;lt; endl;
+if (errno)
+cerr &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
+cerr &amp;lt;&amp;lt; "Try a manual removal of " &amp;lt;&amp;lt; sampledir &amp;lt;&amp;lt; endl;
+cleanup();
+exit(1);
+}
+
+}
+
 bool no_vmlinux;
 int main(int argc, char const *argv[])
 {
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1140,30 +1176,13 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int main(int argc, char const *argv[])
 op_nr_counters = op_get_nr_counters(cpu_type);
 
 if (my_uid != 0) {
-/* Pre-check to make sure we have permission to remove old sample data
- * or to create new sample data in the specified sample data directory.
- * If the user wants us to remove old data, we don't actually do it now,
- * since the profile session may fail for some reason or the user may do ctl-c.
- * We should exit without unnecessarily removing the old sample data as
- * the user may expect it to still be there after an aborted run.
- */
+bool for_current = true;
 string current_sampledir = samples_dir + "/current";
-string current_sampledir_testfile = current_sampledir + "/.xxxTeStFiLe";
-ofstream afile;
-errno = 0;
-afile.open(current_sampledir_testfile.c_str());
-if (!afile.is_open() &amp;amp;&amp;amp; (errno != ENOENT)) {
-if (operf_options::reset)
-cerr &amp;lt;&amp;lt; "Unable to remove old sample data at "
-     &amp;lt;&amp;lt; current_sampledir &amp;lt;&amp;lt; "." &amp;lt;&amp;lt; endl;
-else
-cerr &amp;lt;&amp;lt; "Unable to write to sample data directory at "
-     &amp;lt;&amp;lt; current_sampledir &amp;lt;&amp;lt; "." &amp;lt;&amp;lt; endl;
-if (errno)
-cerr &amp;lt;&amp;lt; strerror(errno) &amp;lt;&amp;lt; endl;
-cerr &amp;lt;&amp;lt; "Try a manual removal of " &amp;lt;&amp;lt; current_sampledir &amp;lt;&amp;lt; endl;
-cleanup();
-exit(1);
+_precheck_permissions_to_samplesdir(current_sampledir, for_current);
+if (!operf_options::append) {
+string previous_sampledir = samples_dir + "/previous";
+for_current = false;
+_precheck_permissions_to_samplesdir(previous_sampledir, for_current);
 }
 }
 end_code_t run_result;
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -1189,7 +1208,5 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; int main(int argc, char const *argv[])
 }
 }
 complete();
-if (operf_options::reset &amp;amp;&amp;amp; reset_done == false)
-cerr &amp;lt;&amp;lt; "Requested reset was not performed due to problem running operf command." &amp;lt;&amp;lt; endl;
 return 0;
 }
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-22T14:15:32</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10502">
    <title>Re: Getting Data from Oprofile within JVM</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10502</link>
    <description>&lt;pre&gt;i want to be able to obtain the data in real time. i.e. i would like to use
that data for optimizations in the JVM.

Thanks

X

On Mon, May 21, 2012 at 9:00 AM, Maynard Johnson &amp;lt;maynardj&amp;lt; at &amp;gt;us.ibm.com&amp;gt;wrote:

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/_______________________________________________
oprofile-list mailing list
oprofile-list&amp;lt; at &amp;gt;lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oprofile-list
&lt;/pre&gt;</description>
    <dc:creator>Xin Tong</dc:creator>
    <dc:date>2012-05-21T17:22:49</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10501">
    <title>Re: Getting Data from Oprofile within JVM</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10501</link>
    <description>&lt;pre&gt;
OProfile has no official API for retrieving sample data.  What are you trying to do that can't be done with existing oprofile functionality?

-Maynard



------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-21T13:00:05</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10500">
    <title>Re: BR_INST_RETIRED on Intel microarchitecture</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10500</link>
    <description>&lt;pre&gt;At the top of ophelp output, you'll see a reference to Intel documentation:
   http://download.intel.com/products/processor/manual/325462.pdf
Chapter 19 of Vol 3 lists events for different types of Intel processors, so you should be able to find the information there.

No.  A quick google search turned up something called "hw-branch-tracer" (ftrace-based tool).  I believe kprobes can also do branch tracing.  I have no experience with either one, though.

-Maynard


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-21T12:58:44</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10499">
    <title>Re: Should operf clear old profile data by default?</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10499</link>
    <description>&lt;pre&gt;Yeah, I think that would be good, too.  Will post a patch to make it so.

-Maynard


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Maynard Johnson</dc:creator>
    <dc:date>2012-05-21T12:04:38</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10498">
    <title>[ oprofile-Bugs-3528383 ] oprofied failed to open device on mpc8572linux version 2.6.</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10498</link>
    <description>&lt;pre&gt;Bugs item #3528383, was opened at 2012-05-20 04:43
Message generated for change (Comment added) made by maynardj
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&amp;amp;atid=116191&amp;amp;aid=3528383&amp;amp;group_id=16191

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Priority: 5
Private: No
Submitted By: tombkeeper (tombkeeper)
Assigned to: Nobody/Anonymous (nobody)
Summary: oprofied failed to open device on mpc8572 linux version 2.6.

Initial Comment:
Linux version: 2.6.31
CPU: mpc8572, e500 core
oprofile version: 0.9.7

1&amp;gt;oprofile --init is ok

2&amp;gt;oprofile --start failed, error output:
Using 2.6+ OProfile kernel interface.
Failed to open device. Possibly you have passed incorrect
parameters. Check /var/log/messages.Couldn't start oprofiled.
Check the log file "/var/lib/oprofile/samples/oprofiled.log" and kernel syslog

3&amp;gt;check /var/log/message, nothing there. check  oprofiled.log, no such file exist.
4&amp;gt;oprofile -l: list all features supported by e500

I tried to use strace to find which open failed and got lots of /dev/oprofile/* opened, not sure which failed. Also walking through oprofile code is not helpful, only see opening /dev/oprofile/buffer code will output such errors.
Anyone knows how to debug this, to figure out if the issue is in kernel or application, if it is some incorrect parameter?
Thanks.
John




----------------------------------------------------------------------

Date: 2012-05-21 05:00

Message:
Opening a bug report for situations like this won't help you.  You need to
ask for help from the community by posting a message to the list and/or
using #oprofile IRC on OFTC.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&amp;amp;atid=116191&amp;amp;aid=3528383&amp;amp;group_id=16191

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>SourceForge.net</dc:creator>
    <dc:date>2012-05-21T12:00:35</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10497">
    <title>Re: Build error: oprofile with CONFIG_CPUMASK_OFFSTACK=y &amp;&amp; SMP</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10497</link>
    <description>&lt;pre&gt;Hi Russell,

On Sat, May 19, 2012 at 08:32:11AM +0100, Russell King - ARM Linux wrote:

I suspect we can just use NR_CPUS directly here although we could allocate
the array dynamically if somebody is using this on a machine that would
benefit.

Anybody object to this?

diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c
index da14432..efc4b7f 100644
--- a/drivers/oprofile/oprofile_perf.c
+++ b/drivers/oprofile/oprofile_perf.c
&amp;lt; at &amp;gt;&amp;lt; at &amp;gt; -25,7 +25,7 &amp;lt; at &amp;gt;&amp;lt; at &amp;gt; static int oprofile_perf_enabled;
 static DEFINE_MUTEX(oprofile_perf_mutex);
 
 static struct op_counter_config *counter_config;
-static struct perf_event **perf_events[nr_cpumask_bits];
+static struct perf_event **perf_events[NR_CPUS];
 static int num_counters;
 
 /*

Will

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Will Deacon</dc:creator>
    <dc:date>2012-05-21T10:44:47</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10496">
    <title>Getting Data from Oprofile within JVM</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10496</link>
    <description>&lt;pre&gt;What would be a good place to start to be able to get data from oprofile
within JVM. i.e. i want to have JVM spawn a thread running the task of
oprofiled. The data is then passed to and processed by the thread.

Thanks

Xin
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/_______________________________________________
oprofile-list mailing list
oprofile-list&amp;lt; at &amp;gt;lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oprofile-list
&lt;/pre&gt;</description>
    <dc:creator>Xin Tong</dc:creator>
    <dc:date>2012-05-21T04:16:15</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10495">
    <title>BR_INST_RETIRED on Intel microarchitecture</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10495</link>
    <description>&lt;pre&gt;I am using oprofile in a JVM environment. I have 2 questions

1. I am not very familiar with intel microarchitecrure, BR_INST_RETIRED
means the branch decision is correct and the branch instruction is
committed ?
2. Can one obtain the address branched to in the PMU registers ? Oprofile
does not seem to provide it.

Thanks

Xin
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/_______________________________________________
oprofile-list mailing list
oprofile-list&amp;lt; at &amp;gt;lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oprofile-list
&lt;/pre&gt;</description>
    <dc:creator>Xin Tong</dc:creator>
    <dc:date>2012-05-20T17:28:28</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10494">
    <title>[ oprofile-Bugs-3528383 ] oprofied failed to open device on mpc8572linux version 2.6.</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10494</link>
    <description>&lt;pre&gt;Bugs item #3528383, was opened at 2012-05-20 04:43
Message generated for change (Tracker Item Submitted) made by tombkeeper
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&amp;amp;atid=116191&amp;amp;aid=3528383&amp;amp;group_id=16191

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: tombkeeper (tombkeeper)
Assigned to: Nobody/Anonymous (nobody)
Summary: oprofied failed to open device on mpc8572 linux version 2.6.

Initial Comment:
Linux version: 2.6.31
CPU: mpc8572, e500 core
oprofile version: 0.9.7

1&amp;gt;oprofile --init is ok

2&amp;gt;oprofile --start failed, error output:
Using 2.6+ OProfile kernel interface.
Failed to open device. Possibly you have passed incorrect
parameters. Check /var/log/messages.Couldn't start oprofiled.
Check the log file "/var/lib/oprofile/samples/oprofiled.log" and kernel syslog

3&amp;gt;check /var/log/message, nothing there. check  oprofiled.log, no such file exist.
4&amp;gt;oprofile -l: list all features supported by e500

I tried to use strace to find which open failed and got lots of /dev/oprofile/* opened, not sure which failed. Also walking through oprofile code is not helpful, only see opening /dev/oprofile/buffer code will output such errors.
Anyone knows how to debug this, to figure out if the issue is in kernel or application, if it is some incorrect parameter?
Thanks.
John




----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&amp;amp;atid=116191&amp;amp;aid=3528383&amp;amp;group_id=16191

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>SourceForge.net</dc:creator>
    <dc:date>2012-05-20T11:43:24</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10493">
    <title>Re: Should operf clear old profile data by default?</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10493</link>
    <description>&lt;pre&gt;

I think the new semantics are good, but I would default to keeping a
backup of the old data. So rename it to something else, then create a
new session.

-Andi
&lt;/pre&gt;</description>
    <dc:creator>Andi Kleen</dc:creator>
    <dc:date>2012-05-19T15:32:43</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10492">
    <title>Build error: oprofile with CONFIG_CPUMASK_OFFSTACK=y &amp;&amp; SMP</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10492</link>
    <description>&lt;pre&gt;My OMAP randconfig build found this build error last night:

arch/arm/oprofile/../../../drivers/oprofile/oprofile_perf.c:28: error: variably modified 'perf_events' at file scope

This is caused because nr_cpumask_bits is a variable when we're building
for a SMP system and CONFIG_CPUMASK_OFFSTACK is set.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Russell King - ARM Linux</dc:creator>
    <dc:date>2012-05-19T07:32:11</dc:date>
  </item>
  <item rdf:about="http://permalink.gmane.org/gmane.linux.oprofile/10491">
    <title>Need help in cross compiling oprofile</title>
    <link>http://permalink.gmane.org/gmane.linux.oprofile/10491</link>
    <description>&lt;pre&gt;Hello everyone

I need some help in cross compiling oprofile for ARM V7 architecture.
Some hints would be really helpful.

Regards

Abdul

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
&lt;/pre&gt;</description>
    <dc:creator>Abdul Wahid Memon</dc:creator>
    <dc:date>2012-05-18T20:18:20</dc:date>
  </item>
  <textinput rdf:about="http://search.gmane.org/?group=$group=gmane.linux.oprofile">
    <title>Search Engine</title>
    <description>Search the mailing list at Gmane</description>
    <name>query</name>
    <link>http://search.gmane.org/?group=$group=gmane.linux.oprofile</link>
  </textinput>
</rdf:RDF>

