From: Vsevolod Stakhov Date: Sat, 23 Apr 2022 11:39:40 +0000 (+0100) Subject: [Project] Implement runtime creation X-Git-Tag: 3.3~293^2~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a77ee995fdda516bace366413d3b279f78e9f453;p=thirdparty%2Frspamd.git [Project] Implement runtime creation --- diff --git a/src/libserver/rspamd_symcache.cxx b/src/libserver/rspamd_symcache.cxx index e1e9ade4eb..35fa0588f8 100644 --- a/src/libserver/rspamd_symcache.cxx +++ b/src/libserver/rspamd_symcache.cxx @@ -55,13 +55,6 @@ INIT_LOG_MODULE(symcache) -/* At least once per minute */ -#define PROFILE_MAX_TIME (60.0) -/* For messages larger than 2Mb enable profiling */ -#define PROFILE_MESSAGE_SIZE_THRESHOLD (1024 * 1024 * 2) -/* Enable profile at least once per this amount of messages processed */ -#define PROFILE_PROBABILITY (0.01) - /* weight, frequency, time */ #define TIME_ALPHA (1.0) #define WEIGHT_ALPHA (0.1) diff --git a/src/libserver/symcache/symcache_impl.cxx b/src/libserver/symcache/symcache_impl.cxx index e2032c063f..535fe57b9e 100644 --- a/src/libserver/symcache/symcache_impl.cxx +++ b/src/libserver/symcache/symcache_impl.cxx @@ -879,4 +879,21 @@ symcache::~symcache() } } +auto symcache::maybe_resort() -> bool +{ + if (items_by_order->generation_id != cur_order_gen) { + /* + * Cache has been modified, need to resort it + */ + msg_info_cache("symbols cache has been modified since last check:" + " old id: %ud, new id: %ud", + items_by_order->generation_id, cur_order_gen); + resort(); + + return true; + } + + return false; +} + } \ No newline at end of file diff --git a/src/libserver/symcache/symcache_internal.hxx b/src/libserver/symcache/symcache_internal.hxx index a45ae88b9e..0862476f68 100644 --- a/src/libserver/symcache/symcache_internal.hxx +++ b/src/libserver/symcache/symcache_internal.hxx @@ -144,6 +144,8 @@ private: lua_State *L; double reload_time; double last_profile; + +private: int peak_cb; int cache_id; @@ -331,6 +333,45 @@ public: f(sym_it.second.get()); } } + + /** + * Resort cache if anything has been changed since last time + * @return + */ + auto maybe_resort() -> bool; + + /** + * Returns number of items with ids + * @return + */ + auto get_items_count() const -> auto { + return items_by_id.size(); + } + + /** + * Returns current set of items ordered for sharing ownership + * @return + */ + auto get_cache_order() const -> auto { + return items_by_order; + } + + /** + * Get last profile timestamp + * @return + */ + auto get_last_profile() const -> auto { + return last_profile; + } + + /** + * Sets last profile timestamp + * @param last_profile + * @return + */ + auto set_last_profile(double last_profile){ + symcache::last_profile = last_profile; + } }; diff --git a/src/libserver/symcache/symcache_runtime.cxx b/src/libserver/symcache/symcache_runtime.cxx index a87dad2598..b1b5f5b99f 100644 --- a/src/libserver/symcache/symcache_runtime.cxx +++ b/src/libserver/symcache/symcache_runtime.cxx @@ -20,9 +20,44 @@ namespace rspamd::symcache { -auto cache_savepoint::create_savepoint(struct rspamd_task *task, const symcache &cache) -> cache_savepoint * +/* At least once per minute */ +constexpr static const auto PROFILE_MAX_TIME = 60.0; +/* For messages larger than 2Mb enable profiling */ +constexpr static const auto PROFILE_MESSAGE_SIZE_THRESHOLD = 1024ul * 1024 * 2; +/* Enable profile at least once per this amount of messages processed */ +constexpr static const auto PROFILE_PROBABILITY = 0.01; + +auto +cache_savepoint::create_savepoint(struct rspamd_task *task, symcache &cache) -> cache_savepoint * { - return nullptr; + struct cache_savepoint *checkpoint; + + cache.maybe_resort(); + + checkpoint = (struct cache_savepoint *) rspamd_mempool_alloc0 (task->task_pool, + sizeof(*checkpoint) + + sizeof(struct cache_dynamic_item) * cache.get_items_count()); + + checkpoint->order = cache.get_cache_order(); + rspamd_mempool_add_destructor(task->task_pool, + cache_savepoint::savepoint_dtor, checkpoint); + + /* Calculate profile probability */ + ev_now_update_if_cheap(task->event_loop); + ev_tstamp now = ev_now(task->event_loop); + checkpoint->profile_start = now; + + if ((cache.get_last_profile() == 0.0 || now > cache.get_last_profile() + PROFILE_MAX_TIME) || + (task->msg.len >= PROFILE_MESSAGE_SIZE_THRESHOLD) || + (rspamd_random_double_fast() >= (1 - PROFILE_PROBABILITY))) { + msg_debug_cache_task("enable profiling of symbols for task"); + checkpoint->profile = true; + cache.set_last_profile(now); + } + + task->checkpoint = (void *)checkpoint; + + return checkpoint; } } diff --git a/src/libserver/symcache/symcache_runtime.hxx b/src/libserver/symcache/symcache_runtime.hxx index 3a7da615d8..4d43a7015c 100644 --- a/src/libserver/symcache/symcache_runtime.hxx +++ b/src/libserver/symcache/symcache_runtime.hxx @@ -44,8 +44,7 @@ struct cache_dynamic_item { static_assert(sizeof(cache_dynamic_item) == sizeof(std::uint64_t)); static_assert(std::is_trivial_v); -struct cache_savepoint { - unsigned order_gen; +class cache_savepoint { unsigned items_inflight; bool profile; bool has_slow; @@ -59,9 +58,17 @@ struct cache_savepoint { order_generation_ptr order; /* Dynamically expanded as needed */ struct cache_dynamic_item dynamic_items[]; + /* We allocate this structure merely in memory pool, so destructor is absent */ + ~cache_savepoint() = delete; + /* Dropper for a shared ownership */ + static auto savepoint_dtor(void *ptr) -> void { + auto *real_savepoint = (cache_savepoint *)ptr; + /* Drop shared ownership */ + real_savepoint->order.reset(); + } public: - static auto create_savepoint(struct rspamd_task *task, const symcache &cache) -> cache_savepoint *; + static auto create_savepoint(struct rspamd_task *task, symcache &cache) -> cache_savepoint *; };