From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Subject: [tarantool-patches] [PATCH 1/1] core: introduce tt_static_sized_buf() Date: Sat, 27 Apr 2019 00:44:42 +0300 [thread overview] Message-ID: <687f8dc3342a3e9b6d8138837646837d60e63ed8.1556315009.git.v.shpilevoy@tarantool.org> (raw) 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 <COPYRIGHT HOLDER> ``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 + * <COPYRIGHT HOLDER> 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)
next reply other threads:[~2019-04-26 21:44 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-04-26 21:44 Vladislav Shpilevoy [this message] 2019-04-27 21:18 ` [tarantool-patches] " Konstantin Osipov 2019-04-28 16:56 ` Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=687f8dc3342a3e9b6d8138837646837d60e63ed8.1556315009.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 1/1] core: introduce tt_static_sized_buf()' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox