]> gitweb.factorcode.org Git - factor.git/commitdiff
vm: parameterize sampling rate
authorJoe Groff <arcata@gmail.com>
Tue, 1 Nov 2011 04:31:41 +0000 (21:31 -0700)
committerJoe Groff <arcata@gmail.com>
Wed, 2 Nov 2011 20:23:15 +0000 (13:23 -0700)
basis/tools/profiler/sampling/sampling.factor
vm/os-unix.cpp
vm/os-windows.cpp
vm/sampling_profiler.cpp
vm/sampling_profiler.hpp
vm/vm.hpp

index 4d71a14bc59ab8ab90ac93102990fe5e9eaaeb43..021284b4a1eb18029b8d95d1656794bb8acaea34 100644 (file)
@@ -1,19 +1,23 @@
 ! (c)2011 Joe Groff bsd license
 USING: assocs calendar continuations kernel math.statistics
-namespaces sequences tools.profiler.sampling.private ;
+math namespaces sequences tools.profiler.sampling.private ;
 IN: tools.profiler.sampling
 
-: TIME-PER-SAMPLE ( -- n ) 1 milliseconds ; inline
-
 SYMBOL: raw-profile-data
+SYMBOL: samples-per-second
+
+CONSTANT: default-samples-per-second 1000
 
 : get-raw-profile-data ( -- data )
     raw-profile-data get-global [ "No profile data" throw ] unless* ;
 
-: profile ( quot -- )
-    t profiling [ f profiling ] [ ] cleanup
+: profile* ( rate quot -- )
+    [ [ samples-per-second set-global ] [ profiling ] bi ] dip
+    [ 0 profiling ] [ ] cleanup
     (get-samples) raw-profile-data set-global ; inline
 
+: profile ( quot -- ) default-samples-per-second swap profile* ; inline
+
 : total-sample-count ( sample -- count ) first ;
 : gc-sample-count ( sample -- count ) second ;
 : foreign-sample-count ( sample -- count ) third ;
@@ -22,7 +26,7 @@ SYMBOL: raw-profile-data
 : sample-callstack ( sample -- array ) 5 swap nth ;
 
 : samples>time ( samples -- time )
-    TIME-PER-SAMPLE time* ;
+    samples-per-second get-global / seconds ;
 
 : (total-time) ( samples -- n )
     [ total-sample-count ] map-sum samples>time ;
index 4533741267822b73fd61a6e55dfc05051b318146..41b3b13c1a1ab4b85830a269228822f7ab9d6c41 100755 (executable)
@@ -157,8 +157,8 @@ void factor_vm::start_sampling_profiler_timer()
 {
        struct itimerval timer;
        memset((void*)&timer, 0, sizeof(struct itimerval));
-       timer.it_value.tv_usec = 1000000/FACTOR_PROFILE_SAMPLES_PER_SECOND;
-       timer.it_interval.tv_usec = 1000000/FACTOR_PROFILE_SAMPLES_PER_SECOND;
+       timer.it_value.tv_usec = 1000000/samples_per_second;
+       timer.it_interval.tv_usec = 1000000/samples_per_second;
        setitimer(ITIMER_REAL, &timer, NULL);
 }
 
index cfbbf666df9475b33457f5c17c7cdfd2f3883e47..ad0343cc7880873b01597e06c6bdd734d5fe5f67 100755 (executable)
@@ -308,12 +308,12 @@ void factor_vm::sampler_thread_loop()
        assert(QueryPerformanceFrequency(&units_per_second));
 
        assert(QueryPerformanceCounter(&counter));
-       counter.QuadPart *= FACTOR_PROFILE_SAMPLES_PER_SECOND;
+       counter.QuadPart *= samples_per_second;
        while (atomic::fence(), sampling_profiler_p)
        {
                SwitchToThread();
                assert(QueryPerformanceCounter(&new_counter));
-               new_counter.QuadPart *= FACTOR_PROFILE_SAMPLES_PER_SECOND;
+               new_counter.QuadPart *= samples_per_second;
                cell samples = 0;
                while (new_counter.QuadPart - counter.QuadPart > units_per_second.QuadPart) {
                        // We would have to suspend the thread to sample the PC
@@ -348,7 +348,7 @@ void factor_vm::end_sampling_profiler_timer()
        sampling_profiler_p = false;
        atomic::fence();
        DWORD wait_result = WaitForSingleObject(sampler_thread,
-               3000/FACTOR_PROFILE_SAMPLES_PER_SECOND);
+               3000/samples_per_second);
        if (wait_result != WAIT_OBJECT_0)
                TerminateThread(sampler_thread, 0);
        sampler_thread = NULL;
index 738616dc3c8bc093b1c0fde8b95808ab5fffc27b..34fc22f4c2f1f21c20be2047f4d28cbca4e587a6 100644 (file)
@@ -57,13 +57,14 @@ void factor_vm::record_callstack_sample(cell *begin, cell *end)
        *end = sample_callstacks.size();
 }
 
-void factor_vm::set_sampling_profiler(bool sampling_p)
+void factor_vm::set_sampling_profiler(int rate)
 {
+       bool sampling_p = !!rate;
        if (sampling_p == sampling_profiler_p)
                return;
        
        if (sampling_p)
-               start_sampling_profiler();
+               start_sampling_profiler(rate);
        else
                end_sampling_profiler();
 }
@@ -78,12 +79,13 @@ void factor_vm::clear_samples()
        sample_callstacks.swap(sample_callstack_graveyard);
 }
 
-void factor_vm::start_sampling_profiler()
+void factor_vm::start_sampling_profiler(int rate)
 {
+       samples_per_second = rate;
        safepoint_sample_counts.clear();
        clear_samples();
-       samples.reserve(10*FACTOR_PROFILE_SAMPLES_PER_SECOND);
-       sample_callstacks.reserve(100*FACTOR_PROFILE_SAMPLES_PER_SECOND);
+       samples.reserve(10*rate);
+       sample_callstacks.reserve(100*rate);
        sampling_profiler_p = true;
        start_sampling_profiler_timer();
 }
@@ -98,7 +100,7 @@ void factor_vm::end_sampling_profiler()
 
 void factor_vm::primitive_sampling_profiler()
 {
-       set_sampling_profiler(to_boolean(ctx->pop()));
+       set_sampling_profiler(to_fixnum(ctx->pop()));
 }
 
 void factor_vm::primitive_get_samples()
index ca2b32893aec4711923e64da84a30eae999dd81d..8a599938cb48bef5dfb55069b16e59fac8e99b69 100644 (file)
@@ -1,8 +1,6 @@
 namespace factor
 {
 
-#define FACTOR_PROFILE_SAMPLES_PER_SECOND 1000
-
 struct profiling_sample_count
 {
        // Number of samples taken before the safepoint that recorded the sample
index 6d08ca2041eb465065d17a717ea7f7c39b7197ee..4b829c1dd965a97f8d8bec9455e450896e2c06ce 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -63,6 +63,7 @@ struct factor_vm
        /* Is profiling enabled? */
        bool counting_profiler_p;
        volatile bool sampling_profiler_p;
+       int samples_per_second;
 
        /* Global variables used to pass fault handler state from signal handler
        to VM */
@@ -194,9 +195,9 @@ struct factor_vm
        void clear_samples();
        void record_sample();
        void record_callstack_sample(cell *begin, cell *end);
-       void start_sampling_profiler();
+       void start_sampling_profiler(int rate);
        void end_sampling_profiler();
-       void set_sampling_profiler(bool sampling);
+       void set_sampling_profiler(int rate);
        void enqueue_safepoint_sample(cell samples, cell pc, bool foreign_thread_p);
        void primitive_sampling_profiler();
        void primitive_get_samples();