Tarantool development patches archive
 help / color / mirror / Atom feed
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: kostja@tarantool.org
Subject: [tarantool-patches] [PATCH 1/3] small: introduce small/static
Date: Sun, 28 Apr 2019 19:56:25 +0300	[thread overview]
Message-ID: <7a0ec60e4d19756f3a6ab1588b1b1dda860c1749.1556470563.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1556470563.git.v.shpilevoy@tarantool.org>

Before the patch Tarantool had a thread- and C-file- local array
of 4 static buffers, each 1028 bytes. It provided an API
tt_static_buf() allowing to return them one by one in a cycle.

Firstly, it consumed totally 200Kb of BSS memory in summary over
all C-files using these buffers. Obviously, it was a bug and was
not made intentionally. The buffers were supposed to be a one
process-global array.

Secondly, even if the bug above had been fixed somehow, sometimes
it would have been needed to obtain a bit bigger buffer. For
example, to store a UDP packet - ~1.5Kb.

This commit replaces these 4 buffers with small/ static allocator
which does basically the same, but in more granulated and
manoeuvrable way. This commit frees ~188Kb of BSS section.

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.
---
 src/box/call.c                |   1 +
 src/box/identifier.c          |   2 +-
 src/box/identifier.h          |   1 -
 src/box/iproto.cc             |   1 +
 src/box/opt_def.c             |   1 +
 src/box/relay.cc              |   2 +-
 src/box/session.cc            |   1 +
 src/box/space_def.c           |   1 +
 src/box/space_def.h           |   2 +-
 src/box/sql/sqlLimit.h        |   2 +-
 src/box/tuple.h               |   1 +
 src/box/tuple_format.c        |   1 +
 src/box/user.cc               |   1 +
 src/box/vclock.c              |   2 +-
 src/box/vy_log.c              |   2 +-
 src/box/xrow.c                |   2 +-
 src/lib/coll/coll.c           |   2 +-
 src/lib/core/fio.c            |   2 +-
 src/lib/core/say.c            |   1 +
 src/lib/core/sio.c            |   9 +--
 src/lib/core/tt_static.h      | 118 ++++++++++++++++++++++++++++++++++
 src/lib/small                 |   2 +-
 src/lib/swim/swim_io.h        |   2 +-
 src/lib/swim/swim_proto.h     |   2 +-
 src/lib/swim/swim_transport.h |   1 -
 src/lib/uuid/tt_uuid.c        |   2 +-
 src/lua/utf8.c                |   1 +
 src/trivia/util.h             |  53 ---------------
 28 files changed, 146 insertions(+), 72 deletions(-)
 create mode 100644 src/lib/core/tt_static.h

diff --git a/src/box/call.c b/src/box/call.c
index b9750c5f3..56da53fb3 100644
--- a/src/box/call.c
+++ b/src/box/call.c
@@ -41,6 +41,7 @@
 #include "iproto_constants.h"
 #include "rmean.h"
 #include "small/obuf.h"
+#include "tt_static.h"
 
 /**
  * Find a function by name and check "EXECUTE" permissions.
diff --git a/src/box/identifier.c b/src/box/identifier.c
index 252d53618..b1c56bdc3 100644
--- a/src/box/identifier.c
+++ b/src/box/identifier.c
@@ -32,7 +32,7 @@
 
 #include "say.h"
 #include "diag.h"
-
+#include "tt_static.h"
 #include <unicode/utf8.h>
 #include <unicode/uchar.h>
 
diff --git a/src/box/identifier.h b/src/box/identifier.h
index f34380d62..a0ed6c10e 100644
--- a/src/box/identifier.h
+++ b/src/box/identifier.h
@@ -30,7 +30,6 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "trivia/util.h"
 #include <stdbool.h>
 #include "error.h"
 
diff --git a/src/box/iproto.cc b/src/box/iproto.cc
index 10b6a6792..b9d2004f0 100644
--- a/src/box/iproto.cc
+++ b/src/box/iproto.cc
@@ -62,6 +62,7 @@
 #include "rmean.h"
 #include "execute.h"
 #include "errinj.h"
+#include "tt_static.h"
 
 enum {
 	IPROTO_SALT_SIZE = 32,
diff --git a/src/box/opt_def.c b/src/box/opt_def.c
index c78021440..e2820853b 100644
--- a/src/box/opt_def.c
+++ b/src/box/opt_def.c
@@ -35,6 +35,7 @@
 #include "small/region.h"
 #include "error.h"
 #include "diag.h"
+#include "tt_static.h"
 
 const char *opt_type_strs[] = {
 	/* [OPT_BOOL]	= */ "boolean",
diff --git a/src/box/relay.cc b/src/box/relay.cc
index e3d7f0ed1..906bf8efd 100644
--- a/src/box/relay.cc
+++ b/src/box/relay.cc
@@ -31,7 +31,7 @@
 #include "relay.h"
 
 #include "trivia/config.h"
-#include "trivia/util.h"
+#include "tt_static.h"
 #include "scoped_guard.h"
 #include "cbus.h"
 #include "cfg.h"
diff --git a/src/box/session.cc b/src/box/session.cc
index 70822e8fd..4bb13d031 100644
--- a/src/box/session.cc
+++ b/src/box/session.cc
@@ -35,6 +35,7 @@
 #include "trigger.h"
 #include "user.h"
 #include "error.h"
+#include "tt_static.h"
 
 const char *session_type_strs[] = {
 	"background",
diff --git a/src/box/space_def.c b/src/box/space_def.c
index d0864cc72..d825def75 100644
--- a/src/box/space_def.c
+++ b/src/box/space_def.c
@@ -34,6 +34,7 @@
 #include "error.h"
 #include "sql.h"
 #include "msgpuck.h"
+#include "tt_static.h"
 
 /**
  * Make checks from msgpack.
diff --git a/src/box/space_def.h b/src/box/space_def.h
index 52ff56764..c6639a8d8 100644
--- a/src/box/space_def.h
+++ b/src/box/space_def.h
@@ -30,9 +30,9 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "trivia/util.h"
 #include "tuple_dictionary.h"
 #include "schema_def.h"
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdbool.h>
 
diff --git a/src/box/sql/sqlLimit.h b/src/box/sql/sqlLimit.h
index 76e0d9c53..53dbe1505 100644
--- a/src/box/sql/sqlLimit.h
+++ b/src/box/sql/sqlLimit.h
@@ -35,7 +35,7 @@
  *
  * This file defines various limits of what sql can process.
  */
-#include "trivia/util.h"
+#include "tt_static.h"
 
 enum {
 	/*
diff --git a/src/box/tuple.h b/src/box/tuple.h
index eed8e1a34..a496bf6f0 100644
--- a/src/box/tuple.h
+++ b/src/box/tuple.h
@@ -35,6 +35,7 @@
 #include "diag.h"
 #include "error.h"
 #include "uuid/tt_uuid.h" /* tuple_field_uuid */
+#include "tt_static.h"
 #include "tuple_format.h"
 
 #if defined(__cplusplus)
diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c
index 804a678a1..9f742d900 100644
--- a/src/box/tuple_format.c
+++ b/src/box/tuple_format.c
@@ -33,6 +33,7 @@
 #include "json/json.h"
 #include "tuple_format.h"
 #include "coll_id_cache.h"
+#include "tt_static.h"
 
 #include "third_party/PMurHash.h"
 
diff --git a/src/box/user.cc b/src/box/user.cc
index 403d6d6c4..48bdf18ee 100644
--- a/src/box/user.cc
+++ b/src/box/user.cc
@@ -38,6 +38,7 @@
 #include "session.h"
 #include "scoped_guard.h"
 #include "sequence.h"
+#include "tt_static.h"
 
 struct universe universe;
 static struct user users[BOX_USER_MAX];
diff --git a/src/box/vclock.c b/src/box/vclock.c
index cea67017c..90ae27591 100644
--- a/src/box/vclock.c
+++ b/src/box/vclock.c
@@ -35,7 +35,7 @@
 #include <ctype.h>
 
 #include "diag.h"
-#include "trivia/util.h"
+#include "tt_static.h"
 
 int64_t
 vclock_follow(struct vclock *vclock, uint32_t replica_id, int64_t lsn)
diff --git a/src/box/vy_log.c b/src/box/vy_log.c
index be97cdbbe..de39b746f 100644
--- a/src/box/vy_log.c
+++ b/src/box/vy_log.c
@@ -57,7 +57,7 @@
 #include "replication.h" /* INSTANCE_UUID */
 #include "salad/stailq.h"
 #include "say.h"
-#include "trivia/util.h"
+#include "tt_static.h"
 #include "wal.h"
 #include "vclock.h"
 #include "xlog.h"
diff --git a/src/box/xrow.c b/src/box/xrow.c
index aaed84e38..fef4f2dff 100644
--- a/src/box/xrow.c
+++ b/src/box/xrow.c
@@ -37,7 +37,7 @@
 
 #include "fiber.h"
 #include "version.h"
-
+#include "tt_static.h"
 #include "error.h"
 #include "vclock.h"
 #include "scramble.h"
diff --git a/src/lib/coll/coll.c b/src/lib/coll/coll.c
index 495eb6d64..98e4d0e64 100644
--- a/src/lib/coll/coll.c
+++ b/src/lib/coll/coll.c
@@ -35,7 +35,7 @@
 #include "assoc.h"
 #include <unicode/ucol.h>
 #include <unicode/ucasemap.h>
-#include <trivia/config.h>
+#include "tt_static.h"
 
 struct UCaseMap *icu_ucase_default_map = NULL;
 
diff --git a/src/lib/core/fio.c b/src/lib/core/fio.c
index b79d3d058..4388b9a53 100644
--- a/src/lib/core/fio.c
+++ b/src/lib/core/fio.c
@@ -41,7 +41,7 @@
 #include <lib/bit/bit.h>
 
 #include <say.h>
-#include <trivia/util.h>
+#include "tt_static.h"
 
 const char *
 fio_filename(int fd)
diff --git a/src/lib/core/say.c b/src/lib/core/say.c
index 3b13b766a..24963cf82 100644
--- a/src/lib/core/say.c
+++ b/src/lib/core/say.c
@@ -31,6 +31,7 @@
 #include "say.h"
 #include "fiber.h"
 #include "errinj.h"
+#include "tt_static.h"
 
 #include <errno.h>
 #include <stdarg.h>
diff --git a/src/lib/core/sio.c b/src/lib/core/sio.c
index 3e1b7e784..64aae97bc 100644
--- a/src/lib/core/sio.c
+++ b/src/lib/core/sio.c
@@ -38,12 +38,12 @@
 #include <netinet/tcp.h> /* TCP_NODELAY */
 #include <arpa/inet.h>
 #include "say.h"
-#include "trivia/util.h"
+#include "tt_static.h"
 #include "exception.h"
 #include "uri/uri.h"
 #include "errinj.h"
 
-static_assert(TT_STATIC_BUF_LEN > NI_MAXHOST,
+static_assert(SMALL_STATIC_SIZE > NI_MAXHOST + NI_MAXSERV,
 	      "static buffer should fit host name");
 
 const char *
@@ -330,8 +330,9 @@ sio_strfaddr(const struct sockaddr *addr, socklen_t addrlen)
 					NI_NUMERICHOST | NI_NUMERICSERV) != 0)
 				return tt_sprintf("(host):(port)");
 
-			return tt_sprintf(addr->sa_family == AF_INET ?
-					  "%s:%s" : "[%s]:%s", host, serv);
+			return tt_snprintf(NI_MAXHOST + NI_MAXSERV,
+					   addr->sa_family == AF_INET ?
+					   "%s:%s" : "[%s]:%s", host, serv);
 		}
 	}
 	unreachable();
diff --git a/src/lib/core/tt_static.h b/src/lib/core/tt_static.h
new file mode 100644
index 000000000..5621c640c
--- /dev/null
+++ b/src/lib/core/tt_static.h
@@ -0,0 +1,118 @@
+#ifndef TARANTOOL_CORE_STATIC_H_INCLUDED
+#define TARANTOOL_CORE_STATIC_H_INCLUDED
+/*
+ * 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 "small/static.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#ifndef MIN
+#define UNDEF_MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+/** Can't be enum - used by preprocessor for static assertions. */
+#define TT_STATIC_BUF_LEN 1024
+
+/**
+ * Return a thread-local statically allocated temporary buffer of
+ * size @a TT_STATIC_BUF_LEN.
+ */
+static inline char *
+tt_static_buf(void)
+{
+	return static_alloc(TT_STATIC_BUF_LEN);
+}
+
+/**
+ * Return a null-terminated string for @a str of length @a len.
+ */
+static inline const char *
+tt_cstr(const char *str, size_t len)
+{
+	len = MIN(len, SMALL_STATIC_SIZE - 1);
+	char *buf = static_alloc(len + 1);
+	memcpy(buf, str, len);
+	buf[len] = '\0';
+	return buf;
+}
+
+/**
+ * Wrapper around vsnprintf() that prints the result to
+ * the static buffer.
+ */
+static inline const char *
+tt_vsnprintf(size_t size, const char *format, va_list ap)
+{
+	char *buf = static_reserve(size);
+	assert(buf != NULL);
+	int rc = vsnprintf(buf, size, format, ap);
+	if (rc >= 0) {
+		/* +1 for terminating zero. */
+		rc = MIN((int) size, rc + 1);
+		static_alloc(rc);
+	}
+	return buf;
+}
+
+/** @copydoc tt_vsnprintf() */
+static inline const char *
+tt_sprintf(const char *format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	const char *result = tt_vsnprintf(TT_STATIC_BUF_LEN, format, ap);
+	va_end(ap);
+	return result;
+}
+
+/**
+ * The same as tt_sprintf() but allows to specify more precise
+ * string limits.
+ */
+static inline const char *
+tt_snprintf(size_t size, const char *format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	const char *result = tt_vsnprintf(MIN(size, (size_t) SMALL_STATIC_SIZE),
+					  format, ap);
+	va_end(ap);
+	return result;
+}
+
+#ifdef UNDEF_MIN
+#undef MIN
+#endif
+
+#endif /* TARANTOOL_CORE_STATIC_H_INCLUDED */
diff --git a/src/lib/small b/src/lib/small
index cdf7d4a8e..50ba09107 160000
--- a/src/lib/small
+++ b/src/lib/small
@@ -1 +1 @@
-Subproject commit cdf7d4a8e24ae465298d0ddacaf1aaed1085281e
+Subproject commit 50ba091077c074c4eecc1ee63f53d2f4f245bd51
diff --git a/src/lib/swim/swim_io.h b/src/lib/swim/swim_io.h
index b17629ba9..42d94fc92 100644
--- a/src/lib/swim/swim_io.h
+++ b/src/lib/swim/swim_io.h
@@ -30,7 +30,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "trivia/util.h"
+#include "tt_static.h"
 #include "small/rlist.h"
 #include "salad/stailq.h"
 #include "swim_transport.h"
diff --git a/src/lib/swim/swim_proto.h b/src/lib/swim/swim_proto.h
index 81770c01c..beb9bb1fe 100644
--- a/src/lib/swim/swim_proto.h
+++ b/src/lib/swim/swim_proto.h
@@ -30,7 +30,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "trivia/util.h"
+#include "tt_static.h"
 #include "uuid/tt_uuid.h"
 #include <arpa/inet.h>
 #include <netinet/in.h>
diff --git a/src/lib/swim/swim_transport.h b/src/lib/swim/swim_transport.h
index 6f4370087..c4e48cdeb 100644
--- a/src/lib/swim/swim_transport.h
+++ b/src/lib/swim/swim_transport.h
@@ -30,7 +30,6 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "trivia/util.h"
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
diff --git a/src/lib/uuid/tt_uuid.c b/src/lib/uuid/tt_uuid.c
index 530aa31a1..1bd2e2cfe 100644
--- a/src/lib/uuid/tt_uuid.c
+++ b/src/lib/uuid/tt_uuid.c
@@ -33,7 +33,7 @@
 #include <msgpuck.h>
 #include <random.h>
 #include <trivia/config.h>
-#include <trivia/util.h>
+#include "tt_static.h"
 
 /* Zeroed by the linker. */
 const struct tt_uuid uuid_nil;
diff --git a/src/lua/utf8.c b/src/lua/utf8.c
index d829b57b4..9c678cad4 100644
--- a/src/lua/utf8.c
+++ b/src/lua/utf8.c
@@ -35,6 +35,7 @@
 #include "lua/utf8.h"
 #include "diag.h"
 #include "small/ibuf.h"
+#include "tt_static.h"
 
 extern struct ibuf *tarantool_lua_ibuf;
 
diff --git a/src/trivia/util.h b/src/trivia/util.h
index a3e84e6d5..1e01013db 100644
--- a/src/trivia/util.h
+++ b/src/trivia/util.h
@@ -479,59 +479,6 @@ int clock_gettime(uint32_t clock_id, struct timespec *tp);
 #define CLOCK_THREAD_CPUTIME_ID		3
 #endif
 
-#define TT_STATIC_BUF_LEN 1028
-
-/**
- * Return a thread-local statically allocated temporary buffer of size
- * \a TT_STATIC_BUF_LEN
- */
-static inline char *
-tt_static_buf(void)
-{
-	enum { TT_STATIC_BUFS = 4 };
-	static __thread char bufs[TT_STATIC_BUFS][TT_STATIC_BUF_LEN];
-	static __thread int bufno = TT_STATIC_BUFS - 1;
-
-	bufno = (bufno + 1) % TT_STATIC_BUFS;
-	return bufs[bufno];
-}
-
-/**
- * Return a null-terminated string for \a str of length \a len
- */
-static inline const char *
-tt_cstr(const char *str, size_t len)
-{
-	char *buf = tt_static_buf();
-	len = MIN(len, TT_STATIC_BUF_LEN - 1);
-	memcpy(buf, str, len);
-	buf[len] = '\0';
-	return buf;
-}
-
-/**
- * Wrapper around sprintf() that prints the result to
- * the static buffer returned by tt_static_buf().
- */
-static inline const char *
-tt_vsprintf(const char *format, va_list ap)
-{
-	char *buf = tt_static_buf();
-	vsnprintf(buf, TT_STATIC_BUF_LEN, format, ap);
-	return buf;
-}
-
-/** @copydoc tt_vsprintf() */
-static inline const char *
-tt_sprintf(const char *format, ...)
-{
-	va_list ap;
-	va_start(ap, format);
-	const char *result = tt_vsprintf(format, ap);
-	va_end(ap);
-	return result;
-}
-
 /**
  * Escape special characters in @a data to @a buf
  */
-- 
2.20.1 (Apple Git-117)

  reply	other threads:[~2019-04-28 16:56 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-28 16:56 [tarantool-patches] [PATCH 0/3] introduce static allocator Vladislav Shpilevoy
2019-04-28 16:56 ` Vladislav Shpilevoy [this message]
2019-04-28 16:56 ` [tarantool-patches] [PATCH 2/3] Use static_alloc() instead of 'static char[]' where possible Vladislav Shpilevoy
2019-04-28 16:56 ` [tarantool-patches] [PATCH 3/3] sio: optimize sio_strfaddr() for the most common case Vladislav Shpilevoy
2019-05-14  8:09   ` Vladimir Davydov
2019-04-29  4:14 ` [tarantool-patches] Re: [PATCH 0/3] introduce static allocator Konstantin Osipov
2019-04-29  8:35   ` Vladislav Shpilevoy
2019-05-13 22:57 ` 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=7a0ec60e4d19756f3a6ab1588b1b1dda860c1749.1556470563.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/3] small: introduce small/static' \
    /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