oprof.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 180 行

C
180
字号
/** * @file oprof.c * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author John Levon <levon@movementarian.org> */#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/oprofile.h>#include <linux/moduleparam.h>#include <asm/semaphore.h>#include "oprof.h"#include "event_buffer.h"#include "cpu_buffer.h"#include "buffer_sync.h"#include "oprofile_stats.h" struct oprofile_operations * oprofile_ops;unsigned long oprofile_started;static unsigned long is_setup;static DECLARE_MUTEX(start_sem);/* timer   0 - use performance monitoring hardware if available   1 - use the timer int mechanism regardless */static int timer = 0;int oprofile_setup(void){	int err; 	down(&start_sem);	if ((err = alloc_cpu_buffers()))		goto out;	if ((err = alloc_event_buffer()))		goto out1; 	if (oprofile_ops->setup && (err = oprofile_ops->setup()))		goto out2; 	/* Note even though this starts part of the	 * profiling overhead, it's necessary to prevent	 * us missing task deaths and eventually oopsing	 * when trying to process the event buffer.	 */	if ((err = sync_start()))		goto out3;	is_setup = 1;	up(&start_sem);	return 0; out3:	if (oprofile_ops->shutdown)		oprofile_ops->shutdown();out2:	free_event_buffer();out1:	free_cpu_buffers();out:	up(&start_sem);	return err;}/* Actually start profiling (echo 1>/dev/oprofile/enable) */int oprofile_start(void){	int err = -EINVAL; 	down(&start_sem); 	if (!is_setup)		goto out;	err = 0;  	if (oprofile_started)		goto out; 	oprofile_reset_stats();	if ((err = oprofile_ops->start()))		goto out;	oprofile_started = 1;out:	up(&start_sem); 	return err;} /* echo 0>/dev/oprofile/enable */void oprofile_stop(void){	down(&start_sem);	if (!oprofile_started)		goto out;	oprofile_ops->stop();	oprofile_started = 0;	/* wake up the daemon to read what remains */	wake_up_buffer_waiter();out:	up(&start_sem);}void oprofile_shutdown(void){	down(&start_sem);	sync_stop();	if (oprofile_ops->shutdown)		oprofile_ops->shutdown(); 	is_setup = 0;	free_event_buffer();	free_cpu_buffers();	up(&start_sem);}extern void timer_init(struct oprofile_operations ** ops);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 (err == -ENODEV || timer) {		timer_init(&oprofile_ops);		err = 0;	} else if (err) {		goto out;	}	if (!oprofile_ops->cpu_type) {		printk(KERN_ERR "oprofile: cpu_type not set !\n");		err = -EFAULT;	} else {		err = oprofilefs_register();	} 	if (err)		goto out_exit;out:	return err;out_exit:	oprofile_arch_exit();	goto out;}static void __exit oprofile_exit(void){	oprofilefs_unregister();	oprofile_arch_exit();} module_init(oprofile_init);module_exit(oprofile_exit);module_param_named(timer, timer, int, 0644);MODULE_PARM_DESC(timer, "force use of timer interrupt"); MODULE_LICENSE("GPL");MODULE_AUTHOR("John Levon <levon@movementarian.org>");MODULE_DESCRIPTION("OProfile system profiler");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?