<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>cfis : Porting ruby-prof to Windows</title>
    <link>http://cfis.savagexi.com</link>
    <atom:link rel="self" type="application/rss+xml" href="http://cfis.savagexi.com/2006/06/09/porting-ruby-perf-to-windows?format=rss"/>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Charlie Savage's Blog</description>
    <item>
      <title>Comment on Porting ruby-prof to Windows by mfp</title>
      <description>&lt;p&gt;This patch is much easier to read:
&lt;code&gt;&lt;/p&gt;

&lt;pre&gt;
--- ruby_prof.c.orig    2006-06-09 23:06:22.000000000 +0200
+++ ruby_prof.c.new 2006-06-09 23:06:29.000000000 +0200
@@ -73,7 +73,7 @@
 
 #define CLOCK_MODE_CLOCK 0
 #define CLOCK_MODE_GETTIMEOFDAY 1
-#if defined(__GNUC__) &amp;amp;&amp;amp; (defined(__i386__) || defined(__powerpc__) || defined(__ppc__))
+#if defined(_WIN32) || (defined(__GNUC__) &amp;amp;&amp;amp; (defined(__i386__) || defined(__powerpc__) || defined(__ppc__)))
 #define CLOCK_MODE_CPU 2
 static double cpu_frequency;
 #endif
@@ -109,6 +109,9 @@
 
 #ifdef CLOCK_MODE_CPU
 
+
+#if defined(__GNUC__)
+
 static prof_clock_t
 cpu_get_clock()
 {
@@ -130,6 +133,57 @@
 #endif
 }
 
+#elif defined(_WIN32)
+
+static prof_clock_t
+cpu_get_clock()
+{
+    prof_clock_t cycles = 0;
+
+    __asm
+    {
+        rdtsc
+            mov DWORD PTR cycles, eax
+            mov DWORD PTR [cycles + 4], edx
+    }
+    return cycles;
+}
+
+#endif
+
+
+/* The _WIN32 check is needed for msys (and maybe cygwin?) */
+#if defined(__GNUC__) &amp;amp;&amp;amp; !defined(_WIN32)
+
+double get_cpu_frequency()
+{
+    unsigned long long x, y;
+
+    struct timespec ts;
+    ts.tv_sec = 0;
+    ts.tv_nsec = 500000000;
+    x = cpu_get_clock();
+    nanosleep(&amp;amp;ts, NULL);
+    y = cpu_get_clock();
+    return (y - x) * 2;
+}
+
+#elif defined(_WIN32)
+
+double get_cpu_frequency()
+{
+    unsigned long long x, y;
+    double frequency;
+    x = cpu_get_clock();
+    /* Use the windows sleep function, not Ruby's */
+    Sleep(500);
+    y = cpu_get_clock();
+    frequency = 2*(y-x);
+    printf("clock speed: %f", frequency);
+    return frequency;
+}
+#endif
+
 static double
 cpu_clock2sec(prof_clock_t c)
 {
@@ -190,13 +244,13 @@
     }
     return stack-&gt;ptr++;
 }
-
 static inline prof_data_t *
 stack_pop(prof_stack_t *stack)
 {
     if (stack-&gt;ptr == stack-&gt;start)
-        rb_fatal("empty stack");
-    return --stack-&gt;ptr;
+        return NULL;
+    else
+        return --stack-&gt;ptr;
 }
 
 static inline prof_data_t *
@@ -459,6 +513,8 @@
 
        now = get_clock();
        data = stack_pop(stack);
+       if (data == NULL)
+           break;
        if (!NIL_P(klass)) {
        if (TYPE(klass) == T_ICLASS) {
            klass = RBASIC(klass)-&gt;klass;
@@ -486,10 +542,10 @@
 static VALUE
 prof_start(VALUE self)
 {
-    prof_data_t *data;
-    
+    prof_clock_t now;
+
     if (stack_tbl) {
-   rb_raise(rb_eRuntimeError, "Prof.start was already called");
+        rb_raise(rb_eRuntimeError, "Prof.start was already called");
     }
     stack_tbl = stack_table_create();
     class_tbl = rb_hash_new();
@@ -497,13 +553,17 @@
     stack = stack_create();
     stack_table_insert(stack_tbl, profiling_thread, stack);
     result_tbl = minfo_table_create();
+
+    now = get_clock();
     toplevel = prof_result_create(Qnil, rb_intern("#toplevel"));
+    toplevel-&gt;count = 1;
+    toplevel-&gt;total_time = now;
+    toplevel-&gt;self_time = 0;
+
     rb_add_event_hook(prof_event_hook,
-             RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
-             RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN);
-    data = stack_push(stack);
-    data-&gt;start_time = get_clock();
-    data-&gt;child_cost = 0;
+        RUBY_EVENT_CALL | RUBY_EVENT_RETURN |
+        RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN);
+
     return Qnil;
 }
 
@@ -528,19 +588,16 @@
 static VALUE
 prof_stop(VALUE self)
 {
-    prof_data_t *data;
     VALUE result_list;
     prof_clock_t now;
 
     if (stack_tbl == NULL) {
-   rb_raise(rb_eRuntimeError, "Prof.start is not called yet");
+        rb_raise(rb_eRuntimeError, "Prof.start is not called yet");
     }
+
     now = get_clock();
-    stack_pop(stack); /* data for Prof.stop */
-    data = stack_pop(stack);
-    toplevel-&gt;count = 1;
-    toplevel-&gt;total_time = now - data-&gt;start_time;
-    toplevel-&gt;self_time = toplevel-&gt;total_time - data-&gt;child_cost;
+    toplevel-&gt;total_time = now - toplevel-&gt;total_time;
+
     st_foreach(stack_tbl, free_stack, 0);
     st_free_table(stack_tbl);
     stack_tbl = NULL;
@@ -581,17 +638,8 @@
    break;
 #ifdef CLOCK_MODE_CPU
     case CLOCK_MODE_CPU:
-   if (cpu_frequency == 0) {
-       unsigned long long x, y;
-       struct timespec ts;
-
-       ts.tv_sec = 0;
-       ts.tv_nsec = 500000000;
-       x = cpu_get_clock();
-       nanosleep(&amp;amp;ts, NULL);
-       y = cpu_get_clock();
-       cpu_frequency = (y - x) * 2;
-   }
+    if (cpu_frequency == 0)
+      cpu_frequency = get_cpu_frequency();
    get_clock = cpu_get_clock;
    clock2sec = cpu_clock2sec;
    break;
@@ -604,6 +652,9 @@
     return val;
 }
 
+#if defined(_WIN32)
+__declspec(dllexport) 
+#endif
 void
 Init_prof()
 {
&lt;/pre&gt;


&lt;p&gt;&lt;/code&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 11 Jun 2006 02:07:03 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:8efd2ecd-3b5f-4c57-99ac-03af842495c6</guid>
      <link>http://cfis.savagexi.com/2006/06/09/porting-ruby-perf-to-windows#comment-2</link>
    </item>
    <item>
      <title>Comment on Porting ruby-prof to Windows by Charlie</title>
      <description>&lt;p&gt;Hi Mauricio,&lt;/p&gt;

&lt;p&gt;Curious what problems you had reading the patch?  Was it due to Unix line endings versus Windows, or something else?&lt;/p&gt;

&lt;p&gt;Great job on &lt;a href="http://eigenclass.org/hiki.rb?rcov+0.5.0" rel="nofollow"&gt;rcov&lt;/a&gt; - I use it almost every day.&lt;/p&gt;</description>
      <pubDate>Sun, 11 Jun 2006 21:11:44 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:75fb189e-0532-4c8f-b3db-eb580807790c</guid>
      <link>http://cfis.savagexi.com/2006/06/09/porting-ruby-perf-to-windows#comment-33</link>
    </item>
    <item>
      <title>Comment on Porting ruby-prof to Windows by Paul Findlay</title>
      <description>&lt;p&gt;I believe the patch is hard to read because if you look closely, the patch is &amp;#8216;removing&amp;#8217; and then &amp;#8216;adding&amp;#8217; the same lines, cancelling each other out - but taking up a whole lot of space.&lt;/p&gt;

&lt;p&gt;Removing the redundant lines, makes the patch much smaller like the above.&lt;/p&gt;</description>
      <pubDate>Wed, 14 Jun 2006 09:44:44 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:dd862cd0-602d-4a3b-b1ee-b57c340ad368</guid>
      <link>http://cfis.savagexi.com/2006/06/09/porting-ruby-perf-to-windows#comment-34</link>
    </item>
    <item>
      <title>Comment on Porting ruby-prof to Windows by Charlie</title>
      <description>&lt;p&gt;Thanks Paul - hadn&amp;#8217;t noticed that.  I&amp;#8217;ve made some more changes in the last couple of days and will post them once they&amp;#8217;re read.&lt;/p&gt;</description>
      <pubDate>Fri, 16 Jun 2006 02:27:44 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:b32a862d-78ef-4dbc-8f94-1252c9b9d61c</guid>
      <link>http://cfis.savagexi.com/2006/06/09/porting-ruby-perf-to-windows#comment-13</link>
    </item>
  </channel>
</rss>
