今天在看ldd网卡驱动的时候,发现一个有趣的函数 printk_ratelimit()
他的主要做用和 prco文件系统下的,这两个接口有关系
printk_ratelimit
定义了消息之间允许的最小时间间隔。
printk_ratelimit_burst
定义消息数量
于是我机器上显示的就是 5s 内最多10条。
只是一个非常有意义的函数。 我们知道
ldd3 写道
hundreds or thousands of console messages per second is a good way to bog down
the system entirely and hide the real source of problems
以前在做 服务器的时候 ,都是通过一个信号 重定向 a:打屏 b:dev/null c:文件 ,压力测试的时候打屏一直是瓶颈。我们来看看内核怎么处理大量的prink的。
#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init) \
\
struct ratelimit_state name = { \
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \
.interval = interval_init, \
.burst = burst_init,
.begin = // long \
}
这里的 interval_init 就是 5 , burst_init 是10
___ratelimit(&printk_ratelimit_state, func);
/*func 就是当前执行的函数
*printk_ratelimit_state 就是那个初始化过的结构体*/
主要代码和分析如下
int ___ratelimit(struct ratelimit_state *rs, const char *func)
{
unsigned long flags;
int ret;
if (!rs->interval)
return 1;
/*这里当然要用 非阻塞的自选锁 ,保存并且禁止了本地中断 */
if (!spin_trylock_irqsave(&rs->lock, flags))
return 0;
/*如果之前过了一个 打印时间点 就继续记录当前jiffies*/
if (!rs->begin)
rs->begin = jiffies;
/*这里其实 用了宏 time_after,用来判断当前的jiffies 有没有流逝过 打印时间点 */
if (time_is_before_jiffies(rs->begin + rs->interval)) {
if (rs->missed)
printk(KERN_WARNING "%s: %d callbacks suppressed\n",
func, rs->missed);
/*正好过了 就开始清零*/
rs->begin = 0;
rs->printed = 0;
rs->missed = 0;
}
/*没过的话 就继续看rs->printed 剩余的
*过了的话肯定打印*/
if (rs->burst && rs->burst > rs->printed) {
rs->printed++;//打印计数
ret = 1;
} else {
rs->missed++;//忽略掉的
ret = 0;
}
/*恢复 */
spin_unlock_irqrestore(&rs->lock, flags);
return ret;
}
从以上的步骤可以看出,我们很容易在应用中,实现类似的功能。
#define DEBUG_ONE(a) {
if( printk_ratelimit()){\
printf("*** %s DEBUG[%s:%d]: ", nowtime(time(NULL)), __FILE__, __LINE__); \
printf a; printf("\n");} \
}
#define time_after(now,after)宏
也很容易通过
static long get_time()
{
struct timeb tm;
long Req_Begin=0,Req_Begin_ms=0,Res_Begin_Time=0;
ftime(&tm);
Req_Begin = tm.time;
Req_Begin_ms = tm.millitm;
Res_Begin_Time = ((long)Req_Begin*1000 +(long)Req_Begin_ms);
return Res_Begin_Time;
}
这样的函数实现。
- 大小: 14.7 KB
- 大小: 14.7 KB
分享到:
相关推荐
lcd_gpio_0 = port:PH07<1><0><default><0> 2、 W:\liuxing_csdn_tinav2.1\target\allwinner\astar-parrot\configs\sys_config.fex 生成的SPI的设备名: ;----------------------------------------------------...
if((dev->dev_qty > 1) && (input_num+1<dev->dev_qty)) { if((!strcmp(dev->ccm_cfg[input_num]->ccm,dev->ccm_cfg[input_num+1]->ccm))) dev->is_same_module = 1; } if(dev->vip_define_sensor_...
if((dev->dev_qty > 1) && (input_num+1<dev->dev_qty)) { if((!strcmp(dev->ccm_cfg[input_num]->ccm,dev->ccm_cfg[input_num+1]->ccm))) dev->is_same_module = 1; } if(dev->vip_define_sensor_...
<integer name="def_screen_off_timeout">1800000</integer> <bool name="def_lockscreen_disabled">true</bool> 7、请严重注意,全志在这里埋坑了!(坑爹无敌!) Android里面调入配置文件:nvram.txt,里面...
linux-1.0.tar.gz,早期linux源码,可用于linux的学习
#include <linux/kernel.h> /* printk() */ #include <linux/slab.h> /* kmalloc() */ #include <linux/errno.h> /* error codes */ #include <linux/types.h> /* size_t */ #include <linux/interrupt.h> /* mark_...
if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm))) return -EFAULT; set_time(&tm); } return 0; case RTC_IRQP_READ: return put_user(rtc_freq, (unsigned long *)arg); ...
代码如下:#include <linux>#include <linux>#include <linux>#include <linux>#include <linux> static __init int printPid(void) //安装模块函数{ struct task_struct *task,*p; struct list_head *ps; int ...
if(cap->status == OFF && cap->cmd == START_STREAMMING){ hv_dbg("capture start streaming\n"); type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(videofh, VIDIOC_STREAMON, &type;) == -1) { hv_err(...
<item>"bt-pan"</item> </string-array> 3、 R:\wyb\ap6212a0_a33_sc3817r\android\device\softwinner\astar-y3\astar_y3.mk # ap6181/6210/6330 sdio wifi fw and nvram #$(call inherit-product-if-exists, ...
<item>"bt-pan"</item> </string-array> 3、 R:\wyb\ap6212a0_a33_sc3817r\android\device\softwinner\astar-y3\astar_y3.mk # ap6181/6210/6330 sdio wifi fw and nvram #$(call inherit-product-if-exists, ...
在Linux内核中,current 指针指... <span xss=removed> </span>printk(KERN_INFO The cuurent process commond : %s the pid :%i , current->comm, current->pid); <p style=color: rgb(51, 51, 51); font
下面就介绍这个内核模块... #include <linux> #include <linux> #include <linux> MODULE_LICENSE("GPL"); static int hello_init(void) { printk(KERN_ALERT "hello module init\n"); retur
下面就介绍这个内核模块... #include <linux> #include <linux> #include <linux> MODULE_LICENSE("GPL"); static int hello_init(void) { printk(KERN_ALERT "hello module init\n"); retur
#include <unistd.h> // *.h 头文件所在的默认目录是include/,则在代码中就不用明确指明位置。 // 如果不是UNIX 的标准头文件,则需要指明所在的目录,并用双引号括住。 // 标准符号常数与类型文件。定义了各种...
1、查看当前打印级别 ... # echo 8 > /proc/sys/kernel/printk //这样串口才能打印数据 3、内核函数printk的打印级别宏定义:Include/linux/kernel.h #define KERN_EMERG /* system is unusable */ #define KERN_ALERT
npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL); if (!npd) printk(KERN_ERR "%s: no memory for platform data\n", __func__); else if (!npd->cfg_gpio) npd->cfg_gpio = s3c_i2c0...
内核层使用printk打印,应用层调用C库的printf打印。在内核层是调用不了文件系统中C库的printf只能用printk。 两者之间的一个显著区别在于printk允许通过指定一个标志来设置优先级(在include/linux/kern_levels.h...
Kernel-Debug-Series-Part3-printk