From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 0BB7D2DED8 for ; Fri, 26 Apr 2019 17:44:47 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id e4YMpE7kpHM6 for ; Fri, 26 Apr 2019 17:44:46 -0400 (EDT) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 50735274B4 for ; Fri, 26 Apr 2019 17:44:46 -0400 (EDT) From: Vladislav Shpilevoy Subject: [tarantool-patches] [PATCH 1/1] core: introduce tt_static_sized_buf() Date: Sat, 27 Apr 2019 00:44:42 +0300 Message-Id: <687f8dc3342a3e9b6d8138837646837d60e63ed8.1556315009.git.v.shpilevoy@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Currently Tarantool has a global thread local array of 4 static buffers, each 1028 bytes. It provides an API tt_static_buf() allowing to return them one by one in a cycle. But sometimes it is needed to obtain a bit bigger buffer. For example, to store a UDP packet - ~1.5Kb. Technically these 4 static buffers are an array of ~4Kb and nothing prevents from allowing to take several contiguous buffers at once to store 'big' data. This commit introduces function tt_static_sized_buf() allowing to take up to 1028 * 4 bytes at once. It rotates the buffer index in the same way as tt_static_buf() does. A main motivation for this commit is a wish to use a single global out-of-stack buffer to read UDP packets into it in the SWIM library, and on the other hand do not pad out BSS section with a new SWIM-special static buffer. Now SWIM uses stack for this and in the incoming cryptography SWIM component it will need more. --- Branch: https://github.com/tarantool/tarantool/tree/gerold103/tt_static_sized_buf src/trivia/util.h | 33 +++++++++++++++- test/unit/CMakeLists.txt | 3 ++ test/unit/misc.c | 83 ++++++++++++++++++++++++++++++++++++++++ test/unit/misc.result | 28 ++++++++++++++ 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 test/unit/misc.c create mode 100644 test/unit/misc.result diff --git a/src/trivia/util.h b/src/trivia/util.h index d17badff3..351e92c7b 100644 --- a/src/trivia/util.h +++ b/src/trivia/util.h @@ -490,8 +490,11 @@ extern __thread char tt_static_buf_storage[TT_STATIC_BUF_COUNT] extern __thread int tt_static_buf_i; /** - * Return a thread-local statically allocated temporary buffer of size - * \a TT_STATIC_BUF_LEN + * Return a thread-local statically allocated temporary buffer of + * size @a TT_STATIC_BUF_LEN. The buffers are rotated on each call + * of this function in a cycle. It allows to use multiple static + * buffers sequentially to store several different temporary data + * parts. */ static inline char * tt_static_buf(void) @@ -500,6 +503,32 @@ tt_static_buf(void) return tt_static_buf_storage[tt_static_buf_i]; } +/** + * Return a thread-local statically allocated temporary buffer + * with at least @a size continuous bytes. @a size should not + * be bigger than total size of all tt static buffers. This call + * also rotates static buffer index with respect to the allocated + * block count. + */ +static inline char * +tt_static_sized_buf(int size) +{ + assert(size <= TT_STATIC_BUF_COUNT * TT_STATIC_BUF_LEN); + if (size <= TT_STATIC_BUF_LEN) + return tt_static_buf(); + int block_count = size / TT_STATIC_BUF_LEN + + ((size % TT_STATIC_BUF_LEN) != 0); + assert(block_count <= TT_STATIC_BUF_COUNT); + int block_first = (tt_static_buf_i + 1) % TT_STATIC_BUF_COUNT; + int block_last = block_first + block_count - 1; + if (block_last < TT_STATIC_BUF_COUNT) { + tt_static_buf_i = block_last; + return tt_static_buf_storage[block_first]; + } + tt_static_buf_i = block_count - 1; + return tt_static_buf_storage[0]; +} + /** * Return a null-terminated string for \a str of length \a len */ diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 368ceb649..9aa9364e6 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -216,6 +216,9 @@ target_link_libraries(sio.test unit core) add_executable(crypto.test crypto.c) target_link_libraries(crypto.test crypto unit) +add_executable(misc.test misc.c) +target_link_libraries(misc.test misc unit core) + add_executable(swim.test swim.c swim_test_transport.c swim_test_ev.c swim_test_utils.c ${PROJECT_SOURCE_DIR}/src/version.c) target_link_libraries(swim.test unit swim) diff --git a/test/unit/misc.c b/test/unit/misc.c new file mode 100644 index 000000000..4d025c201 --- /dev/null +++ b/test/unit/misc.c @@ -0,0 +1,83 @@ +/* + * Copyright 2010-2019, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "trivia/util.h" +#include "unit.h" + +static inline void +check_static_sized_buf(int size, int first_pos, int last_pos) +{ + char *b = tt_static_sized_buf(size); + is(b, tt_static_buf_storage[first_pos], "allocated %d from %d", + size, first_pos); + is(tt_static_buf_i, last_pos, "to %d", last_pos); +} + +static void +test_static_buffers(void) +{ + header(); + plan(21); + + check_static_sized_buf(10, 0, 0); + check_static_sized_buf(TT_STATIC_BUF_LEN, 1, 1); + check_static_sized_buf(TT_STATIC_BUF_LEN, 2, 2); + check_static_sized_buf(TT_STATIC_BUF_LEN + 1, 0, 1); + + is(tt_static_buf(), tt_static_buf_storage[2], + "not sized buf() takes 2"); + check_static_sized_buf(10, 3, 3); + + check_static_sized_buf(TT_STATIC_BUF_LEN * 2, 0, 1); + check_static_sized_buf(TT_STATIC_BUF_LEN * 2, 2, 3); + is(tt_static_buf(), tt_static_buf_storage[0], + "sized_buf() and buf() use the same counter"); + is(tt_static_buf_i, 0, "buf() occupied 0 after sized_buf() "\ + "had occupied 3"); + + check_static_sized_buf(TT_STATIC_BUF_LEN * TT_STATIC_BUF_COUNT, 0, 3); + check_static_sized_buf(0, 0, 0); + + check_plan(); + footer(); +} + +int +main(void) +{ + header(); + plan(1); + + test_static_buffers(); + + int rc = check_plan(); + footer(); + return rc; +} diff --git a/test/unit/misc.result b/test/unit/misc.result new file mode 100644 index 000000000..12341fdee --- /dev/null +++ b/test/unit/misc.result @@ -0,0 +1,28 @@ + *** main *** +1..1 + *** test_static_buffers *** + 1..21 + ok 1 - allocated 10 from 0 + ok 2 - to 0 + ok 3 - allocated 1028 from 1 + ok 4 - to 1 + ok 5 - allocated 1028 from 2 + ok 6 - to 2 + ok 7 - allocated 1029 from 0 + ok 8 - to 1 + ok 9 - not sized buf() takes 2 + ok 10 - allocated 10 from 3 + ok 11 - to 3 + ok 12 - allocated 2056 from 0 + ok 13 - to 1 + ok 14 - allocated 2056 from 2 + ok 15 - to 3 + ok 16 - sized_buf() and buf() use the same counter + ok 17 - buf() occupied 0 after sized_buf() had occupied 3 + ok 18 - allocated 4112 from 0 + ok 19 - to 3 + ok 20 - allocated 0 from 0 + ok 21 - to 0 +ok 1 - subtests + *** test_static_buffers: done *** + *** main: done *** -- 2.20.1 (Apple Git-117)