mirror of
https://github.com/cuberite/libevent.git
synced 2025-08-04 01:36:23 -04:00
test-ratelim: calculate timers bias (for slow CPUs) to avoid false-positive
This can be/should be done for regression tests too. Refs: https://ci.appveyor.com/project/libevent/libevent/builds/28916689/job/kg621aa194a0qbym Refs: https://github.com/libevent/libevent/pull/917#issuecomment-553811834 v2: EVENT_BASE_FLAG_PRECISE_TIMER (cherry picked from commit 8a34869984c470fb243fc9587c469b316add2f7e)
This commit is contained in:
parent
ffc528e99f
commit
8ad26d0b11
@ -50,6 +50,10 @@
|
|||||||
#include "event2/listener.h"
|
#include "event2/listener.h"
|
||||||
#include "event2/thread.h"
|
#include "event2/thread.h"
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct evutil_weakrand_state weakrand_state;
|
static struct evutil_weakrand_state weakrand_state;
|
||||||
|
|
||||||
static int cfg_verbose = 0;
|
static int cfg_verbose = 0;
|
||||||
@ -85,6 +89,18 @@ struct client_state {
|
|||||||
};
|
};
|
||||||
static const struct timeval *ms100_common=NULL;
|
static const struct timeval *ms100_common=NULL;
|
||||||
|
|
||||||
|
/* Timers bias for slow CPUs, affects:
|
||||||
|
* - cfg_connlimit_tolerance (--check-connlimit)
|
||||||
|
* - cfg_grouplimit_tolerance (--check-grouplimit)
|
||||||
|
* - cfg_stddev_tolerance (--check-stddev)
|
||||||
|
*/
|
||||||
|
static int timer_bias_events;
|
||||||
|
static struct timeval timer_bias_start;
|
||||||
|
double timer_bias_spend;
|
||||||
|
/* Real cost is less (approximately ~5 usec),
|
||||||
|
* this macros adjusted to make the bias less */
|
||||||
|
#define TIMER_MAX_COST_USEC 10
|
||||||
|
|
||||||
/* info from check_bucket_levels_cb */
|
/* info from check_bucket_levels_cb */
|
||||||
static int total_n_bev_checks = 0;
|
static int total_n_bev_checks = 0;
|
||||||
static ev_int64_t total_rbucket_level=0;
|
static ev_int64_t total_rbucket_level=0;
|
||||||
@ -244,6 +260,62 @@ group_drain_cb(evutil_socket_t fd, short events, void *arg)
|
|||||||
bufferevent_rate_limit_group_decrement_write(ratelim_group, cfg_group_drain);
|
bufferevent_rate_limit_group_decrement_write(ratelim_group, cfg_group_drain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
timer_bias_cb(evutil_socket_t fd, short events, void *arg)
|
||||||
|
{
|
||||||
|
struct event *event = arg;
|
||||||
|
struct timeval end;
|
||||||
|
struct timeval diff;
|
||||||
|
|
||||||
|
/** XXX: use rdtsc? (portability issues?) */
|
||||||
|
evutil_gettimeofday(&end, NULL);
|
||||||
|
evutil_timersub(&end, &timer_bias_start, &diff);
|
||||||
|
timer_bias_spend += diff.tv_sec + diff.tv_usec * 1e6;
|
||||||
|
timer_bias_start = end;
|
||||||
|
|
||||||
|
if (++timer_bias_events == 100)
|
||||||
|
event_del(event);
|
||||||
|
}
|
||||||
|
static double
|
||||||
|
timer_bias_calculate(void)
|
||||||
|
{
|
||||||
|
struct event_config *cfg = NULL;
|
||||||
|
struct event_base *base = NULL;
|
||||||
|
struct event *timer = NULL;
|
||||||
|
struct timeval tv = { 0, 1 };
|
||||||
|
|
||||||
|
cfg = event_config_new();
|
||||||
|
if (!cfg)
|
||||||
|
goto err;
|
||||||
|
if (event_config_set_flag(cfg, EVENT_BASE_FLAG_PRECISE_TIMER))
|
||||||
|
goto err;
|
||||||
|
base = event_base_new_with_config(cfg);
|
||||||
|
if (!base)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
timer = event_new(base, -1, EV_PERSIST, timer_bias_cb, event_self_cbarg());
|
||||||
|
if (!timer || event_add(timer, &tv)) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
evutil_gettimeofday(&timer_bias_start, NULL);
|
||||||
|
event_base_dispatch(base);
|
||||||
|
event_free(timer);
|
||||||
|
|
||||||
|
return MIN(timer_bias_spend / 1e6 / timer_bias_events / TIMER_MAX_COST_USEC, 5);
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (cfg)
|
||||||
|
event_config_free(cfg);
|
||||||
|
if (timer)
|
||||||
|
event_free(timer);
|
||||||
|
if (base)
|
||||||
|
event_base_free(base);
|
||||||
|
|
||||||
|
fprintf(stderr, "Couldn't create event for CPU cycle counter bias\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
test_ratelimiting(void)
|
test_ratelimiting(void)
|
||||||
{
|
{
|
||||||
@ -266,6 +338,7 @@ test_ratelimiting(void)
|
|||||||
struct event_config *base_cfg;
|
struct event_config *base_cfg;
|
||||||
struct event *periodic_level_check;
|
struct event *periodic_level_check;
|
||||||
struct event *group_drain_event=NULL;
|
struct event *group_drain_event=NULL;
|
||||||
|
double timer_bias;
|
||||||
|
|
||||||
memset(&sin, 0, sizeof(sin));
|
memset(&sin, 0, sizeof(sin));
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
@ -275,6 +348,16 @@ test_ratelimiting(void)
|
|||||||
if (0)
|
if (0)
|
||||||
event_enable_debug_mode();
|
event_enable_debug_mode();
|
||||||
|
|
||||||
|
timer_bias = timer_bias_calculate();
|
||||||
|
if (timer_bias > 1) {
|
||||||
|
fprintf(stderr, "CPU is slow, timers bias is %f\n", timer_bias);
|
||||||
|
cfg_connlimit_tolerance *= timer_bias;
|
||||||
|
cfg_grouplimit_tolerance *= timer_bias;
|
||||||
|
cfg_stddev_tolerance *= timer_bias;
|
||||||
|
} else {
|
||||||
|
printf("CPU is fast enough, timers bias is %f\n", timer_bias);
|
||||||
|
}
|
||||||
|
|
||||||
base_cfg = event_config_new();
|
base_cfg = event_config_new();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
Loading…
x
Reference in New Issue
Block a user