diff --git a/iocore/eventsystem/I_ProxyAllocator.h b/iocore/eventsystem/I_ProxyAllocator.h index 613b08f0638..cfd16075c1e 100644 --- a/iocore/eventsystem/I_ProxyAllocator.h +++ b/iocore/eventsystem/I_ProxyAllocator.h @@ -83,10 +83,11 @@ void thread_freeup(Allocator &a, ProxyAllocator &l); #endif -#define THREAD_FREE(_p, _a, _t) \ +#define THREAD_FREE(_p, _a, _tin) \ do { \ ::_a.destroy_if_enabled(_p); \ if (!cmd_disable_pfreelist) { \ + Thread *_t = (_tin); \ *(char **)_p = (char *)_t->_a.freelist; \ _t->_a.freelist = _p; \ _t->_a.allocated++; \ diff --git a/iocore/eventsystem/Makefile.am b/iocore/eventsystem/Makefile.am index 3421eb40167..dbffb1098b5 100644 --- a/iocore/eventsystem/Makefile.am +++ b/iocore/eventsystem/Makefile.am @@ -72,7 +72,8 @@ libinkevent_a_SOURCES = \ check_PROGRAMS = test_IOBuffer \ test_EventSystem \ - test_MIOBufferWriter + test_MIOBufferWriter \ + benchmark_ProxyAllocator test_LD_FLAGS = \ @AM_LDFLAGS@ \ @@ -114,6 +115,11 @@ test_MIOBufferWriter_SOURCES = unit_tests/test_MIOBufferWriter.cc test_MIOBufferWriter_CPPFLAGS = $(test_CPP_FLAGS) test_MIOBufferWriter_LDFLAGS = $(test_LD_FLAGS) +benchmark_ProxyAllocator_SOURCES = unit_tests/benchmark_ProxyAllocator.cc +benchmark_ProxyAllocator_CPPFLAGS = $(test_CPP_FLAGS) +benchmark_ProxyAllocator_LDFLAGS = $(test_LD_FLAGS) +benchmark_ProxyAllocator_LDADD = $(test_LD_ADD) + include $(top_srcdir)/build/tidy.mk clang-tidy-local: $(DIST_SOURCES) diff --git a/iocore/eventsystem/unit_tests/benchmark_ProxyAllocator.cc b/iocore/eventsystem/unit_tests/benchmark_ProxyAllocator.cc new file mode 100644 index 00000000000..660ddcc3c71 --- /dev/null +++ b/iocore/eventsystem/unit_tests/benchmark_ProxyAllocator.cc @@ -0,0 +1,112 @@ +/** @file + +Simple benchmark for ProxyAllocator + +@section license License + +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#define CATCH_CONFIG_ENABLE_BENCHMARKING +#define CATCH_CONFIG_MAIN +#include "catch.hpp" + +#include "I_EventSystem.h" +#include "I_Thread.h" +#include "tscore/Allocator.h" + +namespace +{ +class BThread : public Thread +{ +public: + void + set_specific() override + { + Thread::set_specific(); + } + + void + execute() override + { + } +}; + +struct BItem { + char buffer[128]; +}; + +} // namespace + +// THREAD_ALLOC/FREE requires allocators be global variables and are named after one of the defined ProxyAllocator members +ClassAllocator ioAllocator("io"); + +#define OLD_THREAD_FREE(_p, _a, _t) \ + do { \ + ::_a.destroy_if_enabled(_p); \ + if (!cmd_disable_pfreelist) { \ + *(char **)_p = (char *)_t->_a.freelist; \ + _t->_a.freelist = _p; \ + _t->_a.allocated++; \ + if (thread_freelist_high_watermark > 0 && _t->_a.allocated > thread_freelist_high_watermark) \ + thread_freeup(::_a.raw(), _t->_a); \ + } else { \ + ::_a.raw().free_void(_p); \ + } \ + } while (0) + +TEST_CASE("ProxyAllocator", "[iocore]") +{ + Thread *bench_thread = new BThread(); + bench_thread->set_specific(); + int count = 10000; + + // set higher than iteration count so the freeup doesn't run during benchmark + thread_freelist_high_watermark = count + 1; + + BENCHMARK("thread_free old") + { + auto items = std::vector(); + items.reserve(count); + for (int i = 0; i < count; i++) { + auto *item = THREAD_ALLOC(ioAllocator, this_thread()); + items.push_back(item); + } + + for (auto item : items) { + OLD_THREAD_FREE(item, ioAllocator, this_thread()); + } + return bench_thread->ioAllocator.allocated; + }; + + BENCHMARK("thread_free new") + { + auto items = std::vector(); + items.reserve(count); + for (int i = 0; i < count; i++) { + auto *item = THREAD_ALLOC(ioAllocator, this_thread()); + items.push_back(item); + } + + for (auto item : items) { + THREAD_FREE(item, ioAllocator, this_thread()); + } + return bench_thread->ioAllocator.allocated; + }; + + delete bench_thread; +} diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index 1a1236bbce5..fbecbe70a6b 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -5748,8 +5748,8 @@ HttpSM::handle_http_server_open() vc->apply_options(); } } + server_txn->set_inactivity_timeout(get_server_inactivity_timeout()); } - server_txn->set_inactivity_timeout(get_server_inactivity_timeout()); int method = t_state.hdr_info.server_request.method_get_wksidx(); if (method != HTTP_WKSIDX_TRACE &&