104 lines
3.0 KiB
C
104 lines
3.0 KiB
C
|
/**********************************************************************************************
|
|||
|
File name : ratelimit.h
|
|||
|
Module : common
|
|||
|
Author :
|
|||
|
Copyright :
|
|||
|
Version : 0.1
|
|||
|
Created on : 2021-11-18
|
|||
|
Creator : amir.liang
|
|||
|
Description :
|
|||
|
以一定的速率执行入参函数, ratelimit(func()); 每次call这个调用,默认每5秒最多执行一次func()
|
|||
|
Modify History:
|
|||
|
1. Date: Author: Modification:
|
|||
|
************************************************************************************************/
|
|||
|
|
|||
|
#ifndef __RATELIMIT_H__
|
|||
|
#define __RATELIMIT_H__
|
|||
|
|
|||
|
#include <stdint.h>
|
|||
|
#include "htime.h"
|
|||
|
|
|||
|
/**
|
|||
|
* 参考linux kernel的 printk_ratelimited
|
|||
|
*
|
|||
|
* 使用方法:
|
|||
|
* 默认5秒只执行1次
|
|||
|
* ratelimit(printf("test\n"));
|
|||
|
* *
|
|||
|
* 设置成10秒可以执行30次
|
|||
|
* ratelimit2(10, 30, printf("test\n"));
|
|||
|
*/
|
|||
|
|
|||
|
struct ratelimit_state {
|
|||
|
//下面是运行时信息
|
|||
|
uint32_t interval_ms;
|
|||
|
uint32_t next_ms;
|
|||
|
};
|
|||
|
|
|||
|
struct task_time_state
|
|||
|
{
|
|||
|
uint32_t task_start;
|
|||
|
uint32_t task_print_time;
|
|||
|
};
|
|||
|
|
|||
|
#define DEFAULT_RATELIMIT_INTERVAL 5
|
|||
|
#define DEFAULT_RATELIMIT_BURST 1
|
|||
|
|
|||
|
//第2个版本,你也可以指定多少秒可以打印多少次
|
|||
|
//ratelimit2(10, 30, printf("test\n"));
|
|||
|
|
|||
|
#define ratelimit2(_sec, _times, _action) \
|
|||
|
({ \
|
|||
|
static struct ratelimit_state _rs = { \
|
|||
|
_sec*1000/_times, 0 \
|
|||
|
}; \
|
|||
|
uint32_t _now = gettimeofday_ms();\
|
|||
|
if (_now >= _rs.next_ms){ \
|
|||
|
_rs.next_ms = _now + _rs.interval_ms; \
|
|||
|
_action; \
|
|||
|
} \
|
|||
|
})
|
|||
|
|
|||
|
//默认允许5秒打印1次log
|
|||
|
//ratelimit(printf("test\n"));
|
|||
|
#define ratelimit(_action) ratelimit2(DEFAULT_RATELIMIT_INTERVAL, 1, _action)
|
|||
|
|
|||
|
|
|||
|
//尝试times,直到action结果等于ifequ,每次延时delayms
|
|||
|
//do_retry2(action(), 10, 100, 0); 尝试10次action结果等于0时即退出,每次延时100ms
|
|||
|
#define do_retry2(_action, _times, _delayms, _ifequ_break)\
|
|||
|
({ \
|
|||
|
int32_t _t = _times;\
|
|||
|
while(_t-->0){\
|
|||
|
if (_ifequ_break)\
|
|||
|
break;\
|
|||
|
ratelimit2(1, 5, printf("waiting %dms:%s\n", _delayms, #_action));\
|
|||
|
usleep(_delayms*1000);\
|
|||
|
}\
|
|||
|
})
|
|||
|
|
|||
|
//默认延时100ms, action结果等于0时退出
|
|||
|
//do_retry(action(), 10); 尝试10次,直到action结果等于0时即退出,每次延时100ms
|
|||
|
#define do_retry(_action, _times) do_retry2(_action, _times, 100, ==0)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#define LOG_TIME2(_start_ts, _action) ({\
|
|||
|
uint64_t pre_ts = _start_ts == -1 ? gettimeofday_ms() : _start_ts;\
|
|||
|
_action;\
|
|||
|
printf("%lu %s take:%llums\n", pre_ts, #_action, gettimeofday_ms() - pre_ts);\
|
|||
|
})
|
|||
|
|
|||
|
/*
|
|||
|
* 计算某个函数或操作所消耗的时间
|
|||
|
* _action, 可以是一个函数如: retalimit_delay()
|
|||
|
* _action, 可以是一个字符串: "imin" 用于时间打印记录
|
|||
|
*/
|
|||
|
#define LOG_TIME(_action) LOG_TIME2(-1, _action)
|
|||
|
|
|||
|
|
|||
|
void retalimit_test();
|
|||
|
|
|||
|
#endif //__RATELIMIT_H__
|
|||
|
|