From 27ac4c60f41801f33fed5779a539c5131b129517 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Mon, 31 Oct 2011 18:27:51 -0700 Subject: [PATCH] vm: factor out sample counting code --- vm/errors.cpp | 8 ++-- vm/sampling_profiler.cpp | 81 +++++++++++++++++----------------------- vm/sampling_profiler.hpp | 39 ++++++++++++++++--- vm/vm.cpp | 4 -- vm/vm.hpp | 5 +-- 5 files changed, 73 insertions(+), 64 deletions(-) diff --git a/vm/errors.cpp b/vm/errors.cpp index a5c066b8a2..e5a2f385a5 100755 --- a/vm/errors.cpp +++ b/vm/errors.cpp @@ -174,14 +174,14 @@ void factor_vm::enqueue_safepoint_sample(cell samples, cell pc, bool foreign_thr { if (FACTOR_MEMORY_BARRIER(), sampling_profiler_p) { - FACTOR_ATOMIC_ADD(&safepoint_sample_count, samples); + FACTOR_ATOMIC_ADD(&safepoint_sample_counts.sample_count, samples); if (foreign_thread_p) - FACTOR_ATOMIC_ADD(&safepoint_foreign_thread_sample_count, samples); + FACTOR_ATOMIC_ADD(&safepoint_sample_counts.foreign_thread_sample_count, samples); else { if (FACTOR_MEMORY_BARRIER(), current_gc) - FACTOR_ATOMIC_ADD(&safepoint_gc_sample_count, samples); + FACTOR_ATOMIC_ADD(&safepoint_sample_counts.gc_sample_count, samples); if (pc != 0 && !code->seg->in_segment_p(pc)) - FACTOR_ATOMIC_ADD(&safepoint_foreign_sample_count, samples); + FACTOR_ATOMIC_ADD(&safepoint_sample_counts.foreign_sample_count, samples); } code->guard_safepoint(); } diff --git a/vm/sampling_profiler.cpp b/vm/sampling_profiler.cpp index 9a7a4685b4..07c61afbfb 100644 --- a/vm/sampling_profiler.cpp +++ b/vm/sampling_profiler.cpp @@ -3,17 +3,35 @@ namespace factor { +profiling_sample_count profiling_sample_count::record_counts() volatile +{ + FACTOR_MEMORY_BARRIER(); + profiling_sample_count returned( + sample_count, + gc_sample_count, + foreign_sample_count, + foreign_thread_sample_count); + FACTOR_ATOMIC_SUB(&sample_count, returned.sample_count); + FACTOR_ATOMIC_SUB(&gc_sample_count, returned.gc_sample_count); + FACTOR_ATOMIC_SUB(&foreign_sample_count, returned.foreign_sample_count); + FACTOR_ATOMIC_SUB(&foreign_thread_sample_count, returned.foreign_thread_sample_count); + return returned; +} + +void profiling_sample_count::clear() volatile +{ + sample_count = 0; + gc_sample_count = 0; + foreign_sample_count = 0; + foreign_thread_sample_count = 0; + FACTOR_MEMORY_BARRIER(); +} + profiling_sample::profiling_sample(factor_vm *vm, - fixnum sample_count, - fixnum gc_sample_count, - fixnum foreign_sample_count, - fixnum foreign_thread_sample_count, + profiling_sample_count const &counts, context *ctx) : - sample_count(sample_count), - gc_sample_count(gc_sample_count), - foreign_sample_count(foreign_sample_count), - foreign_thread_sample_count(foreign_thread_sample_count), + counts(counts), ctx(ctx) { vm->record_callstack_sample(&callstack_begin, &callstack_end); @@ -21,37 +39,9 @@ profiling_sample::profiling_sample(factor_vm *vm, void factor_vm::record_sample() { - fixnum recorded_sample_count; - fixnum recorded_gc_sample_count; - fixnum recorded_foreign_sample_count; - fixnum recorded_foreign_thread_sample_count; - - FACTOR_MEMORY_BARRIER(); - recorded_sample_count = safepoint_sample_count; - recorded_gc_sample_count = safepoint_gc_sample_count; - recorded_foreign_sample_count = safepoint_foreign_sample_count; - recorded_foreign_thread_sample_count = safepoint_foreign_thread_sample_count; - if (recorded_sample_count - + recorded_gc_sample_count - + recorded_foreign_sample_count - + recorded_foreign_thread_sample_count - == 0) - return; - - /* Another sample signal could be raised while we record these counts */ - FACTOR_ATOMIC_SUB(&safepoint_sample_count, recorded_sample_count); - FACTOR_ATOMIC_SUB(&safepoint_gc_sample_count, recorded_gc_sample_count); - FACTOR_ATOMIC_SUB(&safepoint_foreign_sample_count, recorded_foreign_sample_count); - FACTOR_ATOMIC_SUB(&safepoint_foreign_thread_sample_count, recorded_foreign_thread_sample_count); - - samples.push_back(profiling_sample( - this, - recorded_sample_count, - recorded_gc_sample_count, - recorded_foreign_sample_count, - recorded_foreign_thread_sample_count, - ctx - )); + profiling_sample_count counts = safepoint_sample_counts.record_counts(); + if (!counts.empty()) + samples.push_back(profiling_sample(this, counts, ctx)); } void factor_vm::record_callstack_sample(cell *begin, cell *end) @@ -90,10 +80,7 @@ void factor_vm::clear_samples() void factor_vm::start_sampling_profiler() { - safepoint_sample_count = 0; - safepoint_gc_sample_count = 0; - safepoint_foreign_sample_count = 0; - safepoint_foreign_thread_sample_count = 0; + safepoint_sample_counts.clear(); clear_samples(); samples.reserve(10*FACTOR_PROFILE_SAMPLES_PER_SECOND); sample_callstacks.reserve(100*FACTOR_PROFILE_SAMPLES_PER_SECOND); @@ -127,10 +114,10 @@ void factor_vm::primitive_get_samples() { data_root sample(allot_array(6, false_object),this); - set_array_nth(sample.untagged(),0,from_unsigned_cell(from_iter->sample_count)); - set_array_nth(sample.untagged(),1,from_unsigned_cell(from_iter->gc_sample_count)); - set_array_nth(sample.untagged(),2,from_unsigned_cell(from_iter->foreign_sample_count)); - set_array_nth(sample.untagged(),3,from_unsigned_cell(from_iter->foreign_thread_sample_count)); + set_array_nth(sample.untagged(),0,from_unsigned_cell(from_iter->counts.sample_count)); + set_array_nth(sample.untagged(),1,from_unsigned_cell(from_iter->counts.gc_sample_count)); + set_array_nth(sample.untagged(),2,from_unsigned_cell(from_iter->counts.foreign_sample_count)); + set_array_nth(sample.untagged(),3,from_unsigned_cell(from_iter->counts.foreign_thread_sample_count)); set_array_nth(sample.untagged(),4,allot_alien((void*)from_iter->ctx)); cell callstack_size = from_iter->callstack_end - from_iter->callstack_begin; diff --git a/vm/sampling_profiler.hpp b/vm/sampling_profiler.hpp index 861eb9c089..ca2b32893a 100644 --- a/vm/sampling_profiler.hpp +++ b/vm/sampling_profiler.hpp @@ -3,7 +3,7 @@ namespace factor #define FACTOR_PROFILE_SAMPLES_PER_SECOND 1000 -struct profiling_sample +struct profiling_sample_count { // Number of samples taken before the safepoint that recorded the sample fixnum sample_count; @@ -13,6 +13,38 @@ struct profiling_sample fixnum foreign_sample_count; // Number of samples taken during code execution in non-Factor threads fixnum foreign_thread_sample_count; + + profiling_sample_count() : + sample_count(0), + gc_sample_count(0), + foreign_sample_count(0), + foreign_thread_sample_count(0) {} + + profiling_sample_count(fixnum sample_count, + fixnum gc_sample_count, + fixnum foreign_sample_count, + fixnum foreign_thread_sample_count) : + sample_count(sample_count), + gc_sample_count(gc_sample_count), + foreign_sample_count(foreign_sample_count), + foreign_thread_sample_count(foreign_thread_sample_count) {} + + bool empty() const + { + return sample_count + + gc_sample_count + + foreign_sample_count + + foreign_thread_sample_count == 0; + } + + profiling_sample_count record_counts() volatile; + void clear() volatile; +}; + +struct profiling_sample +{ + // Sample counts + profiling_sample_count counts; // Active context during sample context *ctx; /* The callstack at safepoint time. Indexes to the beginning and ending @@ -20,10 +52,7 @@ struct profiling_sample cell callstack_begin, callstack_end; profiling_sample(factor_vm *vm, - fixnum sample_count, - fixnum gc_sample_count, - fixnum foreign_sample_count, - fixnum foreign_thread_sample_count, + profiling_sample_count const &counts, context *ctx); }; diff --git a/vm/vm.cpp b/vm/vm.cpp index 29161ed723..287db660e5 100755 --- a/vm/vm.cpp +++ b/vm/vm.cpp @@ -10,10 +10,6 @@ factor_vm::factor_vm() : counting_profiler_p(false), sampling_profiler_p(false), safepoint_fep(false), - safepoint_sample_count(0), - safepoint_gc_sample_count(0), - safepoint_foreign_sample_count(0), - safepoint_foreign_thread_sample_count(0), gc_off(false), current_gc(NULL), gc_events(NULL), diff --git a/vm/vm.hpp b/vm/vm.hpp index ec88640555..1e53b04e23 100755 --- a/vm/vm.hpp +++ b/vm/vm.hpp @@ -75,10 +75,7 @@ struct factor_vm /* State kept by the sampling profiler */ std::vector samples; std::vector sample_callstacks; - volatile fixnum safepoint_sample_count; - volatile fixnum safepoint_gc_sample_count; - volatile fixnum safepoint_foreign_sample_count; - volatile fixnum safepoint_foreign_thread_sample_count; + volatile profiling_sample_count safepoint_sample_counts; /* GC is off during heap walking */ bool gc_off;