/*****************************************
*功能:利用进程链表遍历当前系统中的所有进程
*同时可以打印出进程的相关信息
*此程序可以将比较信息输出到指定的文件中
*
*author:孟阿龙(XiyouLinux)
*url:http://boyan.cublog.cn
* ***************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/mm.h>
MODULE_AUTHOR( "Along" );
MODULE_LICENSE( "GPL" );
struct task_struct *task = NULL, *p = NULL;
struct list_head *pos = NULL;
struct timeval start, end;
int count = 0;
/*function_use表示使用哪一种方法测试,
* 0:三个方法同时使用,
* 1:list_for_each,
* 2:list_for_each_entry,
* 3:for_each_process
*/
int function_use = 0;
char *method;
char *filename="testlog";
void print_message(void);
void writefile( char* filename, char *data );
void traversal_list_for_each(void);
void traversal_list_for_each_entry(void);
void traversal_for_each_process(void);
static int init_module_list(void)
{
switch(function_use) {
case 1:
traversal_list_for_each();
break;
case 2:
traversal_list_for_each_entry();
break;
case 3:
traversal_for_each_process();
break;
default:
traversal_list_for_each();
traversal_list_for_each_entry();
traversal_for_each_process();
break;
}
return 0;
}
static void exit_module_list(void)
{
printk( KERN_ALERT "GOOD BYE!!\n");
}
module_init( init_module_list );
module_exit( exit_module_list );
module_param(function_use, int, S_IRUGO);
void print_message(void)
{
char *str1 = "the method is: ";
char *str2 = "系统当前共 ";
char *str3 = " 个进程\n";
char *str4 = "开始时间: ";
char *str5 = "\n结束时间: ";
char *str6 = "\n时间间隔: ";
char *str7 = ".";
char *str8 = "ms";
char data[1024];
char tmp[50];
int cost;
printk("系统当前共 %d 个进程!!\n", count);
printk("the method is : %s\n", method);
printk("开始时间:%10i.%06i\n", (int)start.tv_sec, (int)start.tv_usec);
printk("结束时间:%10i.%06i\n", (int)end.tv_sec, (int)end.tv_usec);
printk("时间间隔:%10i\n", (int)end.tv_usec-(int)start.tv_usec);
memset(data, 0, sizeof(data));
memset(tmp, 0, sizeof(tmp));
strcat(data, str1);
strcat(data, method);
strcat(data, str2);
snprintf(tmp, sizeof(count), "%d", count);
strcat(data, tmp);
strcat(data, str3);
strcat(data, str4);
memset(tmp, 0, sizeof(tmp));
/*
* 下面这种转换秒的方法是错误的,因为sizeof最终得到的长度实际是Int类型的
* 长度,而实际的妙数有10位数字,所以最终存到tmp中的字符串也就只有三位
* 数字
* snprintf(tmp, sizeof((int)start.tv_sec),"%d",(int)start.tv_usec );
*/
/*取得开始时间的秒数和毫秒数*/
snprintf(tmp, 10,"%d",(int)start.tv_sec );
strcat(data, tmp);
snprintf(tmp, sizeof(str7),"%s",str7 );
strcat(data, tmp);
snprintf(tmp, 6,"%d",(int)start.tv_usec );
strcat(data, tmp);
strcat(data, str5);
/*取得结束时间的秒数和毫秒数*/
snprintf(tmp, 10,"%d",(int)end.tv_sec );
strcat(data, tmp);
snprintf(tmp, sizeof(str7),"%s",str7 );
strcat(data, tmp);
snprintf(tmp, 6,"%d",(int)end.tv_usec );
strcat(data, tmp);
/*计算时间差,因为可以知道我们这个程序花费的时间是在
*毫秒级别的,所以计算时间差时我们就没有考虑秒,只是
*计算毫秒的差值
*/
strcat(data, str6);
cost = (int)end.tv_usec-(int)start.tv_usec;
snprintf(tmp, sizeof(cost),"%d", cost );
strcat(data, tmp);
strcat(data, str8);
strcat(data, "\n\n");
writefile(filename, data);
printk("%d\n", sizeof(data));
}
void writefile( char* filename, char *data )
{
struct file *filp;
mm_segment_t fs;
filp = filp_open(filename, O_RDWR|O_APPEND|O_CREAT, 0644); ;
if(IS_ERR(filp)) {
printk("open file error...\n");
return ;
}
fs = get_fs();
set_fs(KERNEL_DS);
filp->f_op->write(filp, data, strlen(data), &filp->f_pos);
set_fs(fs);
filp_close(filp, NULL);
}
void traversal_list_for_each(void)
{
task = &init_task;
count = 0;
method="list_for_each\n";
do_gettimeofday(&start);
list_for_each( pos, &task->tasks ) {
p = list_entry( pos, struct task_struct, tasks );
count++;
printk( KERN_ALERT "%d\t%s\n", p->pid, p->comm );
}
do_gettimeofday(&end);
print_message();
}
void traversal_list_for_each_entry(void)
{
task = &init_task;
count = 0;
method="list_for_each_entry\n";
do_gettimeofday(&start);
list_for_each_entry( p, &task->tasks, tasks ) {
count++;
printk( KERN_ALERT "%d\t%s\n", p->pid, p->comm );
}
do_gettimeofday(&end);
print_message();
}
void traversal_for_each_process(void)
{
count = 0;
method="for_each_process\n";
do_gettimeofday(&start);
for_each_process(task) {
count++;
printk( KERN_ALERT "%d\t%s\n", task->pid, task->comm );
}
do_gettimeofday(&end);
print_message();
}
|