<p>Neels Hofmeyr has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13061">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add osmo_string_ringbuffer and osmo_static_string() API<br><br>Change-Id: I48f8951de4d209d4cd3ca1aa9ce6137918913125<br>---<br>M include/osmocom/core/utils.h<br>M src/utils.c<br>M tests/utils/utils_test.c<br>M tests/utils/utils_test.ok<br>4 files changed, 639 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/61/13061/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h</span><br><span>index 16159d3..efc9bcc 100644</span><br><span>--- a/include/osmocom/core/utils.h</span><br><span>+++ b/include/osmocom/core/utils.h</span><br><span>@@ -230,4 +230,33 @@</span><br><span> #define OSMO_STRBUF_PRINTF(STRBUF, fmt, args...) \</span><br><span> OSMO_STRBUF_APPEND(STRBUF, snprintf, fmt, ##args)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! State for managing a ringbuffer of static strings. See osmo_static_string(). */</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_string_ringbuffer {</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Start of the usable memory. */</span><br><span style="color: hsl(120, 100%, 40%);">+ char *buf;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Size of the usable memory. */</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t buf_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Pointer to after the last used static string. */</span><br><span style="color: hsl(120, 100%, 40%);">+ char *next;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Most recent usages, for sanity checking. If not NULL, should point to an array of char*[recent_len]. */</span><br><span style="color: hsl(120, 100%, 40%);">+ char **recent;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Number of recent usages that is considered as still in use. */</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t recent_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *osmo_string_ringbuffer_get(struct osmo_string_ringbuffer *buf, size_t bufsize);</span><br><span style="color: hsl(120, 100%, 40%);">+size_t osmo_string_ringbuffer_avail(struct osmo_string_ringbuffer *buf);</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_string_ringbuffer_clear(struct osmo_string_ringbuffer *buf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+char *osmo_static_string(size_t bufsize);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Useful to pass osmo_static_string() and size arguments without repeating the size.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * printf("%s\n", osmo_hexdump_buf(OSMO_STATIC_STRING(my_data_len*2), my_data, my_data_len, NULL, false));</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define OSMO_STATIC_STRING(SIZE) osmo_static_string(SIZE), (SIZE)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct osmo_string_ringbuffer osmo_static_string_buf_default;</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct osmo_string_ringbuffer *osmo_static_string_buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! @} */</span><br><span>diff --git a/src/utils.c b/src/utils.c</span><br><span>index 2d5bcb0..12189b6 100644</span><br><span>--- a/src/utils.c</span><br><span>+++ b/src/utils.c</span><br><span>@@ -826,4 +826,160 @@</span><br><span> return (sum * 9) % 10 + '0';</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Return section from a string ringbuffer that is currently considered unused.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] buf osmo_string_ringbuffer instance.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] bufsize The amount of bytes that should be available, caller needs to include terminating nul.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns Pointer to string buffer, or NULL if there is not enough unused memory available in osmo_static_string_buf.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+char *osmo_string_ringbuffer_get(struct osmo_string_ringbuffer *buf, size_t bufsize)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *ret;</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!bufsize || !buf)</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bufsize > buf->buf_size)</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = buf->next;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret < buf->buf</span><br><span style="color: hsl(120, 100%, 40%);">+ || ret + bufsize > buf->buf + buf->buf_size)</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = buf->buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (buf->recent) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ret <= buf->recent[0]</span><br><span style="color: hsl(120, 100%, 40%);">+ && bufsize > buf->recent[0] - ret)</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Record used chunk in list of recent buffers */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < buf->recent_len; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!buf->recent[i])</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (i < buf->recent_len)</span><br><span style="color: hsl(120, 100%, 40%);">+ buf->recent[i] = ret;</span><br><span style="color: hsl(120, 100%, 40%);">+ else {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (buf->recent_len > 1)</span><br><span style="color: hsl(120, 100%, 40%);">+ memmove(&buf->recent[0], &buf->recent[1], (buf->recent_len - 1) *</span><br><span style="color: hsl(120, 100%, 40%);">+ sizeof(buf->recent[0]));</span><br><span style="color: hsl(120, 100%, 40%);">+ buf->recent[buf->recent_len - 1] = ret;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ buf->next = ret + bufsize;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Reset string ringbuffer to make all of its space available.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This can be useful to mark a buffer as unused, e.g. to recover from a full buffer, or before and after the caller</span><br><span style="color: hsl(120, 100%, 40%);">+ * would like to allocate an unusually large buffer. All previously allocated pointers gotten by</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo_string_ringbuffer_get() for this ring buffer must no longer be used. */</span><br><span style="color: hsl(120, 100%, 40%);">+void osmo_string_ringbuffer_clear(struct osmo_string_ringbuffer *buf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (buf->recent && buf->recent_len)</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(buf->recent, 0, buf->recent_len * sizeof(buf->recent[0]));</span><br><span style="color: hsl(120, 100%, 40%);">+ buf->next = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Return the largest amount of bytes that could be allocated at this point in time.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] buf osmo_string_ringbuffer instance.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns Size of largest continuous chunk of bytes available.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+size_t osmo_string_ringbuffer_avail(struct osmo_string_ringbuffer *buf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *pos = buf->next;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pos < buf->buf || pos > buf->buf + buf->buf_size)</span><br><span style="color: hsl(120, 100%, 40%);">+ pos = buf->buf;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (buf->recent && buf->recent[0]) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pos <= buf->recent[0])</span><br><span style="color: hsl(120, 100%, 40%);">+ return buf->recent[0] - pos;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return OSMO_MAX(buf->buf_size - (pos - buf->buf),</span><br><span style="color: hsl(120, 100%, 40%);">+ buf->recent[0] - buf->buf);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return buf->buf_size - (pos - buf->buf);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Re-use static string ring buffer not before five osmo_static_string() calls have occured. */</span><br><span style="color: hsl(120, 100%, 40%);">+static char *default_string_buf_recent[5] = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Currently, the largest requested size within libosmocore is 4100 bytes (msgb_hexdump()), allow for enough space so</span><br><span style="color: hsl(120, 100%, 40%);">+ * that it can be called any number of times in a row without hitting the recent[] check. To guarantee N untouched</span><br><span style="color: hsl(120, 100%, 40%);">+ * previous buffers, there has to be space for N+1 buffers. However, a fragmented offset may lead to needing N+2. */</span><br><span style="color: hsl(120, 100%, 40%);">+static char default_string_buf_storage[4100 * (ARRAY_SIZE(default_string_buf_recent) + 2)];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_string_ringbuffer osmo_static_string_buf_default = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .buf = default_string_buf_storage,</span><br><span style="color: hsl(120, 100%, 40%);">+ .buf_size = sizeof(default_string_buf_storage),</span><br><span style="color: hsl(120, 100%, 40%);">+ .recent = default_string_buf_recent,</span><br><span style="color: hsl(120, 100%, 40%);">+ .recent_len = ARRAY_SIZE(default_string_buf_recent),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_string_ringbuffer *osmo_static_string_buf = &osmo_static_string_buf_default;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Return a static string buffer that can hold the given string length plus an additional nul character, or abort the</span><br><span style="color: hsl(120, 100%, 40%);">+ * program if no buffer is available.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The idea is to provide distinct string buffers for various osmo_xxx_name() API implementations, so that the same</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo_xxx_name() function can be used multiple times in the same print format arguments.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Use osmo_static_string_buf, which can be redirected by the caller to a larger buffer, if required. By default,</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo_static_string_buf points at osmo_static_string_buf_default, so that no initialization is necessary by the</span><br><span style="color: hsl(120, 100%, 40%);">+ * caller.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * It is the responsibility of the caller to ensure that enough string buffer space is available. If insufficient space</span><br><span style="color: hsl(120, 100%, 40%);">+ * is detected, abort the program using OSMO_ASSERT(false).</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Insufficient space is detected by considering the last N allocations as still used. Depending on the amount of bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ * reserved each time, there can in practice be many more than N allocations without overlapping. If, for example,</span><br><span style="color: hsl(120, 100%, 40%);">+ * osmo_static_string_buf is configured to guarantee 5 allocations of 4100 bytes each without overlaps, that would also</span><br><span style="color: hsl(120, 100%, 40%);">+ * allow for 50 non-overlapping allocations of 410 bytes each. Hence this mechanism merely ensures basic sanity, so that</span><br><span style="color: hsl(120, 100%, 40%);">+ * the caller can at all times be sure that at least 5 concurrent allocations will succeed, and will receive a program</span><br><span style="color: hsl(120, 100%, 40%);">+ * error otherwise.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param bufsize The amount of bytes that should be available, caller needs to include terminating nul.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns Pointer to string buffer.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+char *osmo_static_string(size_t bufsize)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *ret = osmo_string_ringbuffer_get(osmo_static_string_buf, bufsize);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If we're going to assert because of no more static strings being available, print out a status to stderr</span><br><span style="color: hsl(120, 100%, 40%);">+ * first. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ret) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, "\n\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "*** Static ringbuffer full:\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " avail = %zu\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " requested %zu\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ " size = %zu\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_string_ringbuffer_avail(osmo_static_string_buf),</span><br><span style="color: hsl(120, 100%, 40%);">+ bufsize,</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_static_string_buf->buf_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PRINT_IDX(val, label_fmt, label_args...) \</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_static_string_buf->val >= osmo_static_string_buf->buf \</span><br><span style="color: hsl(120, 100%, 40%);">+ && osmo_static_string_buf->val <= (osmo_static_string_buf->buf + osmo_static_string_buf->buf_size)) \</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, " [%zu] " label_fmt "\n", \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_static_string_buf->val - osmo_static_string_buf->buf, ## label_args); \</span><br><span style="color: hsl(120, 100%, 40%);">+ else \</span><br><span style="color: hsl(120, 100%, 40%);">+ fprintf(stderr, " " label_fmt " out of bounds\n", ## label_args);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ PRINT_IDX(next, "next");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_static_string_buf->recent) {</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < osmo_static_string_buf->recent_len; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!osmo_static_string_buf->recent[i])</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ PRINT_IDX(recent[i], "recent[%d]", i);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#undef PRINT_IDX</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(ret);</span><br><span style="color: hsl(120, 100%, 40%);">+ return ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! @} */</span><br><span>diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c</span><br><span>index d592fe0..73589d6 100644</span><br><span>--- a/tests/utils/utils_test.c</span><br><span>+++ b/tests/utils/utils_test.c</span><br><span>@@ -1022,6 +1022,115 @@</span><br><span> printf("(need %d chars, had size=63) %s\n", rc, buf);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void string_ringbuf_test_print_pos(struct osmo_string_ringbuffer *b, char *pos, const char* label)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *marker = "^";</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pos < b->buf) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pos = b->buf;</span><br><span style="color: hsl(120, 100%, 40%);">+ marker = "<-";</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pos > b->buf + b->buf_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+ pos = b->buf + b->buf_size + 5;</span><br><span style="color: hsl(120, 100%, 40%);">+ marker = "->";</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < (pos - b->buf); i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" ");</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" " "%s%s\n", marker, label);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void string_ringbuf_test_get(struct osmo_string_ringbuffer *b, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *ret = osmo_string_ringbuffer_get(b, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ static char marker = 'a';</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("osmo_string_ringbuffer_get(%2zu) -> ", len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ret)</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("NULL");</span><br><span style="color: hsl(120, 100%, 40%);">+ else {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("buf[%zu]", ret - b->buf);</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < len; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ ret[i] = marker;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("buf = [");</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < b->buf_size; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("%c", b->buf[i]? : '_');</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("]\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_print_pos(b, b->next, "next");</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = b->recent_len-1; i >= 0; i--)</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_print_pos(b, b->recent[i], "recent");</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("avail = %zu\n", osmo_string_ringbuffer_avail(b));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ marker++;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (marker > 'z')</span><br><span style="color: hsl(120, 100%, 40%);">+ marker = 'a';</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void string_ringbuf_test()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char buf[23] = {};</span><br><span style="color: hsl(120, 100%, 40%);">+ char *recent[3] = {};</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_string_ringbuffer _b = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .buf = buf,</span><br><span style="color: hsl(120, 100%, 40%);">+ .buf_size = sizeof(buf),</span><br><span style="color: hsl(120, 100%, 40%);">+ .recent = recent,</span><br><span style="color: hsl(120, 100%, 40%);">+ .recent_len = ARRAY_SIZE(recent),</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_string_ringbuffer *b = &_b;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define CLEAR \</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(buf, 0, sizeof(buf)); \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_string_ringbuffer_clear(b);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n\n%s\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n*** Test continuous small buffers\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < 26; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, i&1? 5 : 3);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n*** Test exact use\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ CLEAR</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n*** Test deadlock\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ CLEAR</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 5);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 15);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 3);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n*** Test deadlock (2)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ CLEAR</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 23);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\n*** Test bounds checking: available size\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ CLEAR</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 30);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 10);</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\nTest bounds checking: invalid args\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test_get(b, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(osmo_string_ringbuffer_get(NULL, 10) == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span> static const struct log_info log_info = {};</span><br><span>@@ -1040,5 +1149,6 @@</span><br><span> osmo_sockaddr_to_str_and_uint_test();</span><br><span> osmo_str_tolowupper_test();</span><br><span> strbuf_test();</span><br><span style="color: hsl(120, 100%, 40%);">+ string_ringbuf_test();</span><br><span> return 0;</span><br><span> }</span><br><span>diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok</span><br><span>index 1215ddd..48574cb 100644</span><br><span>--- a/tests/utils/utils_test.ok</span><br><span>+++ b/tests/utils/utils_test.ok</span><br><span>@@ -342,3 +342,347 @@</span><br><span> (need 134 chars)</span><br><span> T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off!</span><br><span> (need 134 chars, had size=63) T minus 10 9 8 7 6 5 4 3 2 1 ... Lift off! -- T minus 10 9 8 7</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+string_ringbuf_test</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*** Test continuous small buffers</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaa____________________]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 20</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[3]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaabbbbb_______________]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 15</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[8]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaabbbbbccc____________]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 12</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[11]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaabbbbbcccddddd_______]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 7</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[16]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaabbbbbcccdddddeee____]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [fffffbbbcccdddddeee____]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 6</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[5]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [fffffgggcccdddddeee____]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[8]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [fffffggghhhhhdddeee____]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 10</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[13]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [fffffggghhhhhiiieee____]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 7</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[16]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [fffffggghhhhhiiijjjjj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [kkkffggghhhhhiiijjjjj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 10</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[3]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [kkklllllhhhhhiiijjjjj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[8]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [kkklllllmmmhhiiijjjjj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 12</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[11]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [kkklllllmmmnnnnnjjjjj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 7</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[16]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [kkklllllmmmnnnnnooojj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [ppppplllmmmnnnnnooojj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 6</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[5]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [pppppqqqmmmnnnnnooojj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[8]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [pppppqqqrrrrrnnnooojj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 10</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[13]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [pppppqqqrrrrrsssooojj__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 7</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[16]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [pppppqqqrrrrrsssttttt__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [uuuppqqqrrrrrsssttttt__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 10</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[3]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [uuuvvvvvrrrrrsssttttt__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[8]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [uuuvvvvvwwwrrsssttttt__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 12</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[11]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [uuuvvvvvwwwxxxxxttttt__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 7</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[16]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [uuuvvvvvwwwxxxxxyyytt__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 8</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [zzzzzvvvwwwxxxxxyyytt__]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 6</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*** Test exact use</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaaaa__________________]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 18</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[5]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaaaabbbbb_____________]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 13</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get(10) -> buf[10]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaaaabbbbbcccccccccc___]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 3</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[20]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [aaaaabbbbbccccccccccddd]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 5</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [eeeeebbbbbccccccccccddd]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 5</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[5]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [eeeeefffffccccccccccddd]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 10</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get(10) -> buf[10]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [eeeeefffffggggggggggddd]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 3</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[20]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [eeeeefffffgggggggggghhh]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 5</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*** Test deadlock</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 5) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [iiiii__________________]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 18</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get(15) -> buf[5]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [iiiiijjjjjjjjjjjjjjj___]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 3</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 3) -> buf[20]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [iiiiijjjjjjjjjjjjjjjkkk]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 1) -> NULL</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [iiiiijjjjjjjjjjjjjjjkkk]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 1) -> NULL</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [iiiiijjjjjjjjjjjjjjjkkk]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*** Test deadlock (2)</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get(23) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [nnnnnnnnnnnnnnnnnnnnnnn]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 1) -> NULL</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [nnnnnnnnnnnnnnnnnnnnnnn]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 1) -> NULL</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [nnnnnnnnnnnnnnnnnnnnnnn]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*** Test bounds checking: available size</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get(30) -> NULL</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [_______________________]</span><br><span style="color: hsl(120, 100%, 40%);">+ <-next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 23</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get(10) -> buf[0]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [rrrrrrrrrr_____________]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 13</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get(10) -> buf[10]</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [rrrrrrrrrrssssssssss___]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 3</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 4) -> NULL</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [rrrrrrrrrrssssssssss___]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Test bounds checking: invalid args</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_string_ringbuffer_get( 0) -> NULL</span><br><span style="color: hsl(120, 100%, 40%);">+buf = [rrrrrrrrrrssssssssss___]</span><br><span style="color: hsl(120, 100%, 40%);">+ ^next</span><br><span style="color: hsl(120, 100%, 40%);">+ <-recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+ ^recent</span><br><span style="color: hsl(120, 100%, 40%);">+avail = 3</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13061">change 13061</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13061"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I48f8951de4d209d4cd3ca1aa9ce6137918913125 </div>
<div style="display:none"> Gerrit-Change-Number: 13061 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>