vserver 1.9.5.x5
[linux-2.6.git] / drivers / oprofile / oprof.c
index a85d33d..b3f1cd6 100644 (file)
 #include "buffer_sync.h"
 #include "oprofile_stats.h"
  
-struct oprofile_operations * oprofile_ops;
+struct oprofile_operations oprofile_ops;
+
 unsigned long oprofile_started;
+unsigned long backtrace_depth;
 static unsigned long is_setup;
 static DECLARE_MUTEX(start_sem);
 
@@ -43,7 +45,7 @@ int oprofile_setup(void)
        if ((err = alloc_event_buffer()))
                goto out1;
  
-       if (oprofile_ops->setup && (err = oprofile_ops->setup()))
+       if (oprofile_ops.setup && (err = oprofile_ops.setup()))
                goto out2;
  
        /* Note even though this starts part of the
@@ -59,8 +61,8 @@ int oprofile_setup(void)
        return 0;
  
 out3:
-       if (oprofile_ops->shutdown)
-               oprofile_ops->shutdown();
+       if (oprofile_ops.shutdown)
+               oprofile_ops.shutdown();
 out2:
        free_event_buffer();
 out1:
@@ -88,7 +90,7 @@ int oprofile_start(void)
  
        oprofile_reset_stats();
 
-       if ((err = oprofile_ops->start()))
+       if ((err = oprofile_ops.start()))
                goto out;
 
        oprofile_started = 1;
@@ -104,7 +106,7 @@ void oprofile_stop(void)
        down(&start_sem);
        if (!oprofile_started)
                goto out;
-       oprofile_ops->stop();
+       oprofile_ops.stop();
        oprofile_started = 0;
        /* wake up the daemon to read what remains */
        wake_up_buffer_waiter();
@@ -117,8 +119,8 @@ void oprofile_shutdown(void)
 {
        down(&start_sem);
        sync_stop();
-       if (oprofile_ops->shutdown)
-               oprofile_ops->shutdown(); 
+       if (oprofile_ops.shutdown)
+               oprofile_ops.shutdown();
        is_setup = 0;
        free_event_buffer();
        free_cpu_buffers();
@@ -126,38 +128,45 @@ void oprofile_shutdown(void)
 }
 
 
-extern void timer_init(struct oprofile_operations ** ops);
+int oprofile_set_backtrace(unsigned long val)
+{
+       int err = 0;
 
+       down(&start_sem);
 
-static int __init oprofile_init(void)
-{
-       /* Architecture must fill in the interrupt ops and the
-        * logical CPU type, or we can fall back to the timer
-        * interrupt profiler.
-        */
-       int err = oprofile_arch_init(&oprofile_ops);
+       if (oprofile_started) {
+               err = -EBUSY;
+               goto out;
+       }
 
-       if (err == -ENODEV || timer) {
-               timer_init(&oprofile_ops);
-               err = 0;
-       } else if (err) {
+       if (!oprofile_ops.backtrace) {
+               err = -EINVAL;
                goto out;
        }
 
-       if (!oprofile_ops->cpu_type) {
-               printk(KERN_ERR "oprofile: cpu_type not set !\n");
-               err = -EFAULT;
-       } else {
-               err = oprofilefs_register();
+       backtrace_depth = val;
+
+out:
+       up(&start_sem);
+       return err;
+}
+
+static int __init oprofile_init(void)
+{
+       int err;
+
+       err = oprofile_arch_init(&oprofile_ops);
+
+       if (err < 0 || timer) {
+               printk(KERN_INFO "oprofile: using timer interrupt.\n");
+               oprofile_timer_init(&oprofile_ops);
        }
+
+       err = oprofilefs_register();
        if (err)
-               goto out_exit;
-out:
+               oprofile_arch_exit();
+
        return err;
-out_exit:
-       oprofile_arch_exit();
-       goto out;
 }