]> sourceware.org Git - systemtap.git/commitdiff
2007-03-14 Martin Hunt <hunt@redhat.com>
authorhunt <hunt>
Wed, 14 Mar 2007 16:13:33 +0000 (16:13 +0000)
committerhunt <hunt>
Wed, 14 Mar 2007 16:13:33 +0000 (16:13 +0000)
* bench2/bench.rb: Updated to work with new transport
and new itest.c.
* bench2/Makefile: Updated for new itest.c
* bench2/itest.c: Rewritten to use multiple threads
and automatically divide the workload among the threads.

* print.c (_stp_print_flush): Move to print_new.c and
print_old.c.
* print_new.c: New file containing _stp_print_flush()
for the new transport.
* print_old.c: Ditto for old transport.

* runtime.h (STP_OLD_TRANSPORT): Define
(errk): Define.
(MAXSTRINGLEN): Define if not already defined.

* io.c (_stp_vlog): Use _stp_ctl_write().

13 files changed:
runtime/ChangeLog
runtime/bench2/Makefile
runtime/bench2/bench.rb
runtime/bench2/itest.c
runtime/bench2/run_bench
runtime/bench2/run_binary_print
runtime/bench2/test_bench [new file with mode: 0755]
runtime/io.c
runtime/map.c
runtime/print.c
runtime/print_new.c [new file with mode: 0644]
runtime/print_old.c [new file with mode: 0644]
runtime/runtime.h

index 56aa0addcf48d1b011f7b690cef5f30c676d6c2d..f21384bed28d3a7c3e5debfee529984148c50bec 100644 (file)
@@ -1,3 +1,23 @@
+2007-03-14  Martin Hunt  <hunt@redhat.com>
+
+       * bench2/bench.rb: Updated to work with new transport
+       and new itest.c.
+       * bench2/Makefile: Updated for new itest.c
+       * bench2/itest.c: Rewritten to use multiple threads
+       and automatically divide the workload among the threads.
+
+       * print.c (_stp_print_flush): Move to print_new.c and 
+       print_old.c.
+       * print_new.c: New file containing _stp_print_flush()
+       for the new transport.
+       * print_old.c: Ditto for old transport.
+
+       * runtime.h (STP_OLD_TRANSPORT): Define
+       (errk): Define.
+       (MAXSTRINGLEN): Define if not already defined.
+
+       * io.c (_stp_vlog): Use _stp_ctl_write().
+
 2007-03-12  Frank Ch. Eigler  <fche@redhat.com>
 
        PR 4179.
index 7fcfcfe4f103e517a08a0d925562b3b8aec6bbe1..ffb2991ac9fd5cf87b76052a18351b2b808189b7 100644 (file)
@@ -1,7 +1,7 @@
 all: itest
 
 itest: itest.c
-       gcc -Wall -O3 -o itest itest.c
+       gcc -D_GNU_SOURCE -Wall -Wextra -Wstrict-prototypes -Werror -O3 -o itest itest.c -lpthread
 
 clean:
        /bin/rm -f itest
index 05c6ee3e5d39d9d0eb65de6fbf8159ccf44e7630..a04582d2f2cd024da89c8c467b65a955c6687fa2 100644 (file)
@@ -1,5 +1,5 @@
 # Benchmark Class for SystemTap
-# Copyright (C) 2006 Red Hat Inc.
+# Copyright (C) 2006, 2007 Red Hat Inc.
 #
 # This file is part of systemtap, and is free software.  You can
 # redistribute it and/or modify it under the terms of the GNU General
@@ -11,9 +11,8 @@ MAXFILE = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
 MINFILE = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq"
 
 # more constants
-PROCFS = 1
-RELAYFS= 2
-UTT = 3
+STREAM = 1
+BULK= 2
 
 at_exit {Bench.done}
 
@@ -22,7 +21,8 @@ class Bench
     @desc = desc
     @code = nil
     @file = nil
-    @trans = 1
+    @trans = STREAM
+    @outfile= "xxx"
     @failures = []
     @results = []
     if @@printed_header == 0
@@ -56,7 +56,7 @@ class Bench
     end
   end
 
-  attr_writer :code, :file, :trans
+  attr_writer :code, :file, :trans, :outfile
   attr_reader :failures, :results
 
   def run
@@ -66,12 +66,10 @@ class Bench
     @@num_threads.each do |threads|
       load
       sum=0
-      threads.times {|cpu| fork {exec "./itest #{threads} > #{@dir}/bench#{cpu}"}}
-      threads.times {Process.waitpid(-1)}      # wait for itest(s) to exit
+      `./itest #{threads} > #{@dir}/bench`
       `sudo killall -HUP staprun`
       Process.wait     # wait for staprun to exit
-      threads.times {|x| sum = sum + `cat #{@dir}/bench#{x}`.split[0].to_i - @@ftime}
-      @results[threads] = sum / (threads * threads)
+      @results[threads] = `cat #{@dir}/bench`.split[0].to_i - @@ftime[threads]
       File.open("#{@dir}/xxx.out") do |file|
        file.each_line do |line|
          m = line.match(/WARNING: There were ([\d]*)/)
@@ -92,10 +90,13 @@ class Bench
       else
        printf("R")
       end
-      if @trans == RELAYFS
-       printf("R")
-      elsif @trans == UTT
-       printf("U""")
+      if @trans == BULK
+       printf("B")
+      else
+       printf(" ")
+      end
+      if @outfile == "/dev/null"
+       printf("N")
       else
        printf(" ")
       end
@@ -120,7 +121,7 @@ class Bench
 
   protected
 
-  @@ftime = 0
+  @@ftime = []
   @@printed_header = 0
   @@staprun = nil
   @@runtime = nil
@@ -137,11 +138,9 @@ class Bench
   end
 
   def load
-    args = "-q -b 8"
-    if @trans == RELAYFS then args = "-q" end
-    if @trans == UTT then args = "-lq" end
-    fork do exec "sudo #{@@staprun} #{args} #{@dir}/bench.ko > #{@dir}/xxx 2> #{@dir}/xxx.out" end
-    sleep 5
+    args = "-q"
+    fork do exec "sudo #{@@staprun} #{args} -o #{@outfile} #{@dir}/bench.ko &> #{@dir}/xxx.out" end
+    sleep 10
   end
 
   def compile
@@ -183,6 +182,7 @@ void probe_exit (void)\n{\n  unregister_kprobe (&kp); \n}\n"
 CFLAGS += -I \"#{@@runtime}\"
 obj-m := bench.o
 "
+      if @trans == BULK then makefile << "CFLAGS += -DSTP_BULKMODE" end
       makefile.close
     else
       puts "NO CODE!"
@@ -227,14 +227,15 @@ obj-m := bench.o
     end
     puts "-"*64
     check_cpuspeed
-    @@ftime = `./itest 1`.to_i
-    @@ftime = `./itest 1`.to_i
-    puts "For comparison, function call overhead is #@@ftime nsecs."
-      puts "Times below are nanoseconds per probe and include kprobe overhead."
+    @@num_threads.each do |threads|
+      @@ftime[threads] = `./itest #{threads} 10000000`.to_i
+    end
+    puts "Times below are nanoseconds per probe and include kprobe overhead."
     puts "-"*64
-    puts "+--- S = Script, R = Runtime"
-    puts "|+-- R = Relayfs, U = UTT  \tThreads"
-    printf "|| NAME                 "
+    puts "+---- S = Script, R = Runtime"
+    puts "|+--- B = Bulk"
+    puts "||+-- N = No output\t\t  Threads"
+    printf "||| NAME                 "
     @@num_threads.each {|n| printf("\t    %d",n)}
     printf "\n"
   end
@@ -251,6 +252,8 @@ obj-m := bench.o
   end
 end
 
+#### STAPBENCH ######
+
 class Stapbench < Bench
 
   def run
@@ -260,12 +263,10 @@ class Stapbench < Bench
     @@num_threads.each do |threads|
       load
       sum=0
-      threads.times {|cpu| fork {exec "./itest #{threads} > bench#{cpu}"}}
-      threads.times {Process.waitpid(-1)}      # wait for itest(s) to exit
+      `./itest #{threads} > bench`
       `sudo killall -HUP staprun`
-      Process.wait     # wait for stap to exit
-      threads.times {|x| sum = sum + `cat bench#{x}`.split[0].to_i - @@ftime}
-      @results[threads] = sum / (threads * threads)
+      Process.wait     # wait for staprun to exit
+      @results[threads] = `cat bench`.split[0].to_i - @@ftime[threads]
       File.open("xxx.out") do |file|
        file.each_line do |line|
          m = line.match(/WARNING: There were ([\d]*)/)
@@ -283,9 +284,8 @@ class Stapbench < Bench
 
   def load
     args = "-vv"
-    if @trans == RELAYFS then args = "-bMvv" end
-    if @trans == UTT then args = "-lvv" end
-    fork do exec "stap #{args} bench.stp > xxx 2> xxx.out" end
+    if @trans == BULK then args = "-bvv" end
+    fork do exec "stap #{args} -o #{@outfile} bench.stp &> xxx.out" end
     sleep 10
   end
   
index efba623aee289ae2984c559eb64f1858edd5d2f6..0578cf40abae782930c50c32fa57f86cb38849cd 100644 (file)
@@ -1,3 +1,13 @@
+/*
+ * itest - timed test program for use with bench2
+ * Copyright (C) 2007 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <sys/resource.h>
 #include <unistd.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
 
 typedef unsigned long long uint64;
 struct timeval tstart, tstop;
+pthread_t tester[256];
+sem_t go;
+int ncpus;
+int iterations;
 
-void start()
+void start(void)
 {
   gettimeofday (&tstart, NULL);
 }
@@ -20,7 +37,7 @@ uint64 usecs (struct timeval *tv)
   return tv->tv_sec * 1000000 + tv->tv_usec;
 }
 
-uint64 stop()
+uint64 stop(void)
 {
   gettimeofday (&tstop, NULL);
   return  usecs(&tstop) - usecs(&tstart);
@@ -28,31 +45,115 @@ uint64 stop()
 
 void usage(char *name)
 {
-    printf ("Usage %s [num_threads]\nitest will call sys_getuid() 1000000/num_threads times.\n", name);
-    exit(1);
+  printf ("Usage %s [num_threads] [total_iterations]\n", name);
+  printf("%s will call sys_getuid() total_iterations [default 2,000,000]\n", name);
+  printf("times divided across num_threads [default 1].\n\n");
+  exit(1);
+}
+
+
+void *null_thread (void *data)
+{
+  int cpu;
+  cpu_set_t cpu_mask;
+  int thread_num  = (int)(long)data;
+
+  cpu = thread_num % ncpus;
+  CPU_ZERO(&cpu_mask);
+  CPU_SET(cpu, &cpu_mask);
+  if( sched_setaffinity( 0, sizeof(cpu_mask), &cpu_mask ) < 0 ) {
+    perror("sched_setaffinity");
+  }
+
+
+  // fprintf(stderr, "starting thread %d on cpu %d num=%d\n", thread_num, cpu, iterations);
+  while (sem_wait(&go) == -1) ;
+
+  return NULL;
+}
+
+void *caller_thread (void *data)
+{
+  int i, cpu;
+  cpu_set_t cpu_mask;
+  int thread_num  = (int)(long)data;
+
+  /* Force threads to be distributed across all cpus. */
+  /* The scheduler would probably do the right thing without this. */
+  cpu = thread_num % ncpus;
+  CPU_ZERO(&cpu_mask);
+  CPU_SET(cpu, &cpu_mask);
+  if( sched_setaffinity( 0, sizeof(cpu_mask), &cpu_mask ) < 0 ) {
+    perror("sched_setaffinity");
+  }
+  
+  // fprintf(stderr, "starting thread %d on cpu %d num=%d\n", thread_num, cpu, iterations);
+  while (sem_wait(&go) == -1) ;
+
+  for (i = 0; i < iterations; i++)
+    getuid();
+
+  return NULL;
 }
 
 int main(int argc, char *argv[])
 {
   int i, n = 1;
-  uint64 nsecs;
+  uint64 nsecs, null_usecs, caller_usecs;
+  int total_iterations = 2000000;
 
-  if (argc > 2)
+  if (argc > 3)
     usage(argv[0]);
 
-  if (argc == 2) {
+  if (argc >= 2) {
     n = strtol(argv[1], NULL, 10);
     if (n <= 0)
       usage(argv[0]);
   }
+  if (argc > 2) {
+    total_iterations = strtol(argv[2], NULL, 10);  
+    if (total_iterations < 100000)
+      usage(argv[0]);
+  }
+
+  ncpus = sysconf(_SC_NPROCESSORS_ONLN);
+  sem_init (&go, 0, 0);
+  iterations = total_iterations/n;
+
+  for (i = 0; i < n; i++) {
+    if (pthread_create(&tester[i], NULL, null_thread, (void *)(long)i) < 0) {
+      perror("Error creating thread");
+      return -1;
+    }
+  }
 
   start();
-  for (i = 0; i < 1000000/n; i++)
-    getuid();
+  for (i = 0; i < n; i++)
+    sem_post (&go);
+  
+  for (i = 0; i < n; i++)
+    pthread_join(tester[i], NULL);
+
+  null_usecs = stop();
 
-  nsecs = stop() * n / 1000;
+  for (i = 0; i < n; i++) {
+    if (pthread_create(&tester[i], NULL, caller_thread, (void *)(long)i) < 0) {
+      perror("Error creating thread");
+      return -1;
+    }
+  }
+
+  start();
+  for (i = 0; i < n; i++)
+    sem_post (&go);
+  
+  for (i = 0; i < n; i++)
+    pthread_join(tester[i], NULL);
 
+  caller_usecs = stop();
+  
   /* returns nanosecs per call  */
+  nsecs = ((caller_usecs - null_usecs) * 1000LL) / ((uint64)(n * iterations));
   printf("%lld\n", nsecs);
   return 0;
 }
index dad8c8ae48a78bc0134cccc6ab841b818c45c299..b77b9497386b8f6b07483ae3f8404e7581aa6ac2 100755 (executable)
@@ -10,31 +10,21 @@ test.print
 # script test with empty probe
 test0 = Stapbench.new("empty probe")
 test0.code = ""
+test0.trans=BULK
 test0.run
 test0.print
 
-# script test to print 100 chars
-test2a = Stapbench.new("printf 100 chars")
-test2a.code = "printf(\"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\\n\")"
-test2a.run
-test2a.print
-
-test2a.trans = RELAYFS
-test2a.run
-test2a.print
-
-# runtime test to print 100 chars
-test2 = Bench.new("printf 100 chars")
-test2.code = "(void)_stp_printf (\"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\\n\");
-  _stp_print_flush();"
+# script test to printf 100 chars
+test2 = Stapbench.new("printf 100 chars")
+test2.code = "printf(\"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\\n\")"
+test2.trans=BULK
 test2.run
 test2.print
 
-
-# runtime test to print 5 integers
-test3 = Bench.new("printf 5 integers")
-test3.code = "_stp_printf (\"%lld, %lld, %lld, %lld, %lld\\n\", 1LL, 0xffffLL, 0x8000ffffLL, 0xffff000011112222LL, 0x7000000000000000LL);
-  _stp_print_flush();"
+# script test to print 100 chars
+test3 = Stapbench.new("print 100 chars")
+test3.code = "print(\"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\\n\")"
+test3.trans=BULK
 test3.run
 test3.print
 
@@ -42,4 +32,5 @@ test3.print
 test4 = Stapbench.new("printf 5 integers")
 test4.code = "printf(\"%d, %d, %d, %d, %d\\n\", 1, 0xffff, 0x8000ffff, 0xffff000011112222, 0x7000000000000000)"
 test4.run
+test4.trans=BULK
 test4.print
index bbd831801381ff9e6c086e17d260393c32c1bcaa..c42bba9868ca73521e359070bbc83acbc70618d8 100755 (executable)
@@ -1,31 +1,12 @@
 #!/usr/bin/env ruby
 load './bench.rb'
 
-# script test with empty probe
-test0 = Stapbench.new("empty probe")
-test0.code = ""
-test0.run
-test0.print
-
-# script test to binary print 4 integers
-test1 = Stapbench.new("binary printf 4 integers (%8b)")
-test1.code = "printf(\"%8b%8b%8b%8b\", 111,22,333,444)"
-test1.run
-test1.print
-
-# script test to binary print 4 integers
-test2 = Stapbench.new("binary printf 4 integers (%4b)")
-test2.code = "printf(\"%4b%4b%4b%4b\", 111,22,333,444)"
-test2.run
-test2.print
-
-
 # script test to binary print 4 integers
 test3 = Stapbench.new("binary printf 4 integers (%b)")
 test3.code = "printf(\"%b%b%b%b\", 111,22,333,444)"
 test3.run
 test3.print
-test3.trans = RELAYFS
+test3.trans = BULK
 test3.run
 test3.print
 
@@ -34,7 +15,7 @@ test4 = Stapbench.new("_stp_print_binary 4 integers")
 test4.code = "stp_print_binary(4,111,22,333,444)"
 test4.run
 test4.print
-test4.trans = RELAYFS
+test4.trans = BULK
 test4.run
 test4.print
 
diff --git a/runtime/bench2/test_bench b/runtime/bench2/test_bench
new file mode 100755 (executable)
index 0000000..4bf9074
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+load './bench.rb'
+
+
+# script test to printf 100 chars
+test3 = Stapbench.new("printf 100 chars")
+test3.code = "printf(\"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\\n\")"
+test3.run
+test3.print
+
+test3.trans = BULK
+test3.run
+test3.print
+
+test3.trans = STREAM
+test3.outfile="/dev/null"
+test3.run
+test3.print
+
+test3.trans = BULK
+test3.outfile="/dev/null"
+test3.run
+test3.print
+
+
index 34c6972784866e533534f78a0c56a15b869d474c..e36381bd6408e6adf899c506304938c1e26df328 100644 (file)
@@ -47,7 +47,7 @@ static void _stp_vlog (enum code type, const char *func, int line, const char *f
                }
 
                if (type != DBUG)
-                       _stp_write(STP_OOB_DATA, buf, start + num + 1);
+                       _stp_ctl_write(STP_OOB_DATA, buf, start + num + 1);
                else {
                        _stp_print(buf);
                        _stp_print_flush();
@@ -93,7 +93,7 @@ void _stp_warn (const char *fmt, ...)
  * unload the module and exit. The module will not be 
  * unloaded until after the current probe returns.
  * @note Be careful to not treat this like the Linux exit() 
- * call. You should probably call return immediately after
+ * call. You should probably call return immediately after 
  * calling _stp_exit().
  */
 void _stp_exit (void)
index dfef2f73f6d0ecb27a22d519f6a97b4da17e8ddd..5748c79799825450bad67a845dc5509230203378 100644 (file)
@@ -217,7 +217,7 @@ static int _stp_map_init(MAP m, unsigned max_entries, int type, int key_size, in
                        else
                                _stp_allocated_memory += size * num_online_cpus();
                                
-                       dbug ("allocated %lx\n", (long)tmp);
+//                     dbug ("allocated %lx\n", (long)tmp);
                        list_add((struct list_head *)tmp, &m->pool);
                        ((struct map_node *)tmp)->map = m;
                }
index b4c7bc49ff3ff5581f9304934dbc5496a35279ea..c100bbfed645e65ab627f8b796f38cd3ba917b19 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- linux-c -*- 
  * Print Functions
- * Copyright (C) 2005, 2006, 2007 Red Hat Inc.
+ * Copyright (C) 2007 Red Hat Inc.
  *
  * This file is part of systemtap, and is free software.  You can
  * redistribute it and/or modify it under the terms of the GNU General
@@ -11,6 +11,7 @@
 #ifndef _PRINT_C_
 #define _PRINT_C_
 
+
 #include "string.h"
 #include "vsprintf.c"
 #include "transport/transport.c"
  * @{
  */
 
-#ifdef STP_RELAYFS
-#define STP_TIMESTAMP_SIZE (sizeof(uint32_t))
-#else
-#define STP_TIMESTAMP_SIZE 0
-#endif /* STP_RELAYFS */
-
-
-#define STP_PRINT_BUF_START (STP_TIMESTAMP_SIZE)
-
 typedef struct __stp_pbuf {
        uint32_t len;                   /* bytes used in the buffer */
-       char timestamp[STP_TIMESTAMP_SIZE];
        char buf[STP_BUFFER_SIZE];
 } _stp_pbuf;
 
@@ -81,37 +72,15 @@ void _stp_print_cleanup (void)
                free_percpu(Stp_lbuf);
 }
 
-/** Send the print buffer to the transport now.
- * Output accumulates in the print buffer until it
- * is filled, or this is called. This MUST be called before returning
- * from a probe or accumulated output in the print buffer will be lost.
- *
- * @note Preemption must be disabled to use this.
- */
-void _stp_print_flush (void)
-{
-       _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id());
-
-       /* check to see if there is anything in the buffer */
-       if (likely (pb->len == 0))
-               return;
-
-#ifdef STP_RELAYFS_MERGE
-       /* In merge-mode, staprun expects relayfs data to start with a 4-byte length */
-       /* followed by a 4-byte sequence number. In non-merge mode, anything goes. */
+/* The relayfs API changed between 2.6.15 and 2.6.16. */
+/* Use the appropriate print flush function. */
 
-       *((uint32_t *)pb->timestamp) = _stp_seq_inc();
-
-       if (unlikely(_stp_transport_write(pb, pb->len+4+STP_TIMESTAMP_SIZE) < 0))
-               atomic_inc (&_stp_transport_failures);
+#ifdef STP_OLD_TRANSPORT
+#include "print_old.c"
 #else
-       if (unlikely(_stp_transport_write(pb->buf, pb->len) < 0))
-               atomic_inc (&_stp_transport_failures);
+#include "print_new.c"
 #endif
 
-       pb->len = 0;
-}
-
 #ifndef STP_MAXBINARYARGS
 #define STP_MAXBINARYARGS 127
 #endif
@@ -119,16 +88,6 @@ void _stp_print_flush (void)
 
 /** Reserves space in the output buffer for direct I/O.
  */
-
-#if defined STP_RELAYFS && !defined STP_RELAYFS_MERGE
-static void * _stp_reserve_bytes (int numbytes)
-{
-       if (unlikely(numbytes == 0))
-               return NULL;
-       _stp_print_flush();
-       return relay_reserve(_stp_chan, numbytes);
-}
-#else
 static void * _stp_reserve_bytes (int numbytes)
 {
        _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id());
@@ -145,7 +104,7 @@ static void * _stp_reserve_bytes (int numbytes)
        pb->len += numbytes;
        return ret;
 }
-#endif /* STP_RELAYFS */
+
 
 /** Write 64-bit args directly into the output stream.
  * This function takes a variable number of 64-bit arguments
diff --git a/runtime/print_new.c b/runtime/print_new.c
new file mode 100644 (file)
index 0000000..a1f1274
--- /dev/null
@@ -0,0 +1,64 @@
+/* -*- linux-c -*- 
+ * Print Flush Function
+ * Copyright (C) 2007 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+/** Send the print buffer to the transport now.
+ * Output accumulates in the print buffer until it
+ * is filled, or this is called. This MUST be called before returning
+ * from a probe or accumulated output in the print buffer will be lost.
+ *
+ * @note Preemption must be disabled to use this.
+ */
+spinlock_t _stp_print_lock = SPIN_LOCK_UNLOCKED;
+
+void _stp_print_flush (void)
+{
+       _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id());
+       uint32_t len = pb->len;
+
+       /* check to see if there is anything in the buffer */
+       if (likely (len == 0))
+               return;
+
+       pb->len = 0;
+
+       if (unlikely(!_stp_utt || _stp_utt->trace_state != Utt_trace_running))
+               return;
+
+#ifdef STP_BULKMODE
+       {
+#ifdef NO_PERCPU_HEADERS
+               void *buf = relay_reserve(_stp_utt->rchan, len);                
+               if (likely(buf))
+                       memcpy(buf, pb->buf, len);
+               else
+                       atomic_inc (&_stp_transport_failures);
+#else
+               struct _stp_trace *t = relay_reserve(_stp_utt->rchan, sizeof(*t) + len);
+               if (likely(t)) {
+                       t->sequence = _stp_seq_inc();
+                       t->pdu_len = len;
+                       memcpy((void *) t + sizeof(*t), pb->buf, len);
+               } else 
+                       atomic_inc (&_stp_transport_failures);
+#endif
+       } 
+#else
+       {
+               void *buf;
+               spin_lock(&_stp_print_lock);
+               buf = relay_reserve(_stp_utt->rchan, len);              
+               if (likely(buf))
+                       memcpy(buf, pb->buf, len);
+               else
+                       atomic_inc (&_stp_transport_failures);
+               spin_unlock(&_stp_print_lock);
+       }
+#endif /* STP_BULKMODE */
+}
diff --git a/runtime/print_old.c b/runtime/print_old.c
new file mode 100644 (file)
index 0000000..401d1af
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- linux-c -*- 
+ * Print Flush Function
+ * Copyright (C) 2007 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+/** Send the print buffer to the transport now.
+ * Output accumulates in the print buffer until it
+ * is filled, or this is called. This MUST be called before returning
+ * from a probe or accumulated output in the print buffer will be lost.
+ *
+ * @note Preemption must be disabled to use this.
+ */
+
+void _stp_print_flush (void)
+{
+       _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id());
+       uint32_t len = pb->len;
+
+       /* check to see if there is anything in the buffer */
+       if (likely (len == 0))
+               return;
+
+       pb->len = 0;
+
+#ifdef STP_BULKMODE
+       {
+#ifdef NO_PERCPU_HEADERS
+               void *buf = relay_reserve(_stp_utt->rchan, len);                
+               if (likely(buf))
+                       memcpy(buf, pb->buf, len);
+               else
+                       atomic_inc (&_stp_transport_failures);
+#else
+               struct _stp_trace *t = relay_reserve(_stp_utt->rchan, sizeof(*t) + len);
+               if (likely(t)) {
+                       t->sequence = _stp_seq_inc();
+                       t->pdu_len = len;
+                       memcpy((void *) t + sizeof(*t), pb->buf, len);
+               } else 
+                       atomic_inc (&_stp_transport_failures);
+#endif
+       } 
+#else
+       {
+               if (unlikely(_stp_ctl_write(STP_REALTIME_DATA, pb->buf, len) <= 0))
+                       atomic_inc (&_stp_transport_failures);
+       }
+#endif /* STP_BULKMODE */
+}
index 4d741cf48e11049a7f90ce48e8b95ee6305ac553..6fa168dc4b31a82d266e12308affe4f800776253 100644 (file)
@@ -1,5 +1,5 @@
 /* main header file
- * Copyright (C) 2005, 2006 Red Hat Inc.
+ * Copyright (C) 2005-2007 Red Hat Inc.
  * Copyright (C) 2005, 2006 Intel Corporation.
  *
  * This file is part of systemtap, and is free software.  You can
@@ -10,9 +10,6 @@
 
 #ifndef _RUNTIME_H_
 #define _RUNTIME_H_
-/** @file runtime.h
- * @brief Main include file for runtime functions.
- */
 
 #include <linux/module.h>
 #include <linux/ctype.h>
 #include <linux/compat.h>
 #include <linux/mm.h>
 
+/* the new transport requires debugfs and a newer relayfs */
+#if !defined (CONFIG_DEBUG_FS) || (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15))
+#define STP_OLD_TRANSPORT
+#endif
+
 #ifndef for_each_cpu
 #define for_each_cpu(cpu)  for_each_cpu_mask((cpu), cpu_possible_map)
 #endif
@@ -51,18 +53,17 @@ static void _stp_dbug (const char *func, int line, const char *fmt, ...);
 #define dbug(args...) ;
 #define kbug(args...) ;
 #endif /* DEBUG */
+#define errk(args...) {printk("Systemtap Error at %s:%d ",__FUNCTION__, __LINE__); printk(args); }
 
 /* atomic globals */
 static atomic_t _stp_transport_failures = ATOMIC_INIT (0);
 
-#ifdef STP_RELAYFS
 static struct
 {
        atomic_t ____cacheline_aligned_in_smp seq;
 } _stp_seq = { ATOMIC_INIT (0) };
 
 #define _stp_seq_inc() (atomic_inc_return(&_stp_seq.seq))
-#endif /* RELAYFS */
 
 /* TEST_MODE is always defined by systemtap */
 #ifdef TEST_MODE
@@ -72,6 +73,10 @@ static struct
 #define TRYLOCKDELAY 100
 #endif
 
+#ifndef MAXSTRINGLEN
+#define MAXSTRINGLEN 128
+#endif
+
 #include "alloc.c"
 #include "print.c"
 #include "string.c"
This page took 0.056195 seconds and 5 git commands to generate.