[master] fb19c2ce5 Refactor adding records to vsl buffers

Poul-Henning Kamp phk at FreeBSD.org
Tue Oct 25 17:17:05 UTC 2022


commit fb19c2ce5afbd05bdaab9f4a2862fcf6fa4d7a1b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Oct 25 17:16:23 2022 +0000

    Refactor adding records to vsl buffers

diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index 26e148e64..48ea0f9cc 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -110,6 +110,7 @@ vsl_sanity(const struct vsl_log *vsl)
 	AN(vsl->wlp);
 	AN(vsl->wlb);
 	AN(vsl->wle);
+	assert(vsl->wlp <= vsl->wle);
 }
 
 /*--------------------------------------------------------------------
@@ -329,72 +330,81 @@ VSL_Flush(struct vsl_log *vsl, int overflow)
 }
 
 /*--------------------------------------------------------------------
- * VSL-buffered-txt
+ * Buffered VSLs
  */
 
-void
-VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t)
+static char *
+vslb_get(struct vsl_log *vsl, enum VSL_tag_e tag, unsigned *length)
 {
-	unsigned l, mlen;
-	char *p;
+	unsigned mlen = cache_param->vsl_reclen;
+	char *retval;
 
 	vsl_sanity(vsl);
-	Tcheck(t);
-	if (vsl_tag_is_masked(tag))
-		return;
-	mlen = cache_param->vsl_reclen;
+	if (*length < mlen)
+		mlen = *length;
 
-	/* Truncate */
-	l = Tlen(t);
-	if (l > mlen - 1)
-		l = mlen - 1;
+	if (VSL_END(vsl->wlp, mlen) > vsl->wle)
+		VSL_Flush(vsl, 1);
 
-	assert(vsl->wlp <= vsl->wle);
+	retval = VSL_DATA(vsl->wlp);
 
-	/* Flush if necessary */
-	if (VSL_END(vsl->wlp, l + 1) > vsl->wle)
-		VSL_Flush(vsl, 1);
-	assert(VSL_END(vsl->wlp, l + 1) <= vsl->wle);
-	p = VSL_DATA(vsl->wlp);
-	memcpy(p, t.b, l);
-	p[l++] = '\0';		/* NUL-terminated */
-	vsl->wlp = vsl_hdr(tag, vsl->wlp, l, vsl->wid);
-	assert(vsl->wlp <= vsl->wle);
+	/* If it still doesn't fit, truncate */
+	if (VSL_END(vsl->wlp, mlen) > vsl->wle)
+		*length = mlen = ((char *)vsl->wle) - VSL_DATA(vsl->wlp);
+
+	vsl->wlp = vsl_hdr(tag, vsl->wlp, mlen, vsl->wid);
 	vsl->wlr++;
+	return (retval);
+}
+
+static void
+vslb_simple(struct vsl_log *vsl, enum VSL_tag_e tag,
+    unsigned length, const char *str)
+{
+	char *p;
+
+	if (length == 0)
+		length = strlen(str);
+	length += 1; // NUL
+	p = vslb_get(vsl, tag, &length);
+	memcpy(p, str, length - 1);
+	p[length - 1] = '\0';
 
 	if (DO_DEBUG(DBG_SYNCVSL))
 		VSL_Flush(vsl, 0);
 }
 
 /*--------------------------------------------------------------------
- * VSL-buffered-strands
+ * VSL-buffered-txt
  */
+
 void
-VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s)
+VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t)
 {
-	unsigned l, mlen;
 
-	vsl_sanity(vsl);
+	Tcheck(t);
 	if (vsl_tag_is_masked(tag))
 		return;
-	mlen = cache_param->vsl_reclen;
 
-	/* including NUL */
-	l = vmin_t(unsigned, strands_len(s) + 1, mlen);
+	vslb_simple(vsl, tag, Tlen(t), t.b);
+}
 
-	assert(vsl->wlp <= vsl->wle);
+/*--------------------------------------------------------------------
+ * VSL-buffered-strands
+ */
+void
+VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s)
+{
+	unsigned l;
+	char *p;
 
-	/* Flush if necessary */
-	if (VSL_END(vsl->wlp, l) > vsl->wle)
-		VSL_Flush(vsl, 1);
-	assert(VSL_END(vsl->wlp, l) <= vsl->wle);
+	if (vsl_tag_is_masked(tag))
+		return;
 
-	mlen = strands_cat(VSL_DATA(vsl->wlp), l, s);
-	assert(l == mlen);
+	l = strands_len(s) + 1;
+	p = vslb_get(vsl, tag, &l);
 
-	vsl->wlp = vsl_hdr(tag, vsl->wlp, l, vsl->wid);
-	assert(vsl->wlp <= vsl->wle);
-	vsl->wlr++;
+	(void)strands_cat(p, l, s);
 
 	if (DO_DEBUG(DBG_SYNCVSL))
 		VSL_Flush(vsl, 0);
@@ -407,14 +417,10 @@ VSLbs(struct vsl_log *vsl, enum VSL_tag_e tag, const struct strands *s)
 void
 VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap)
 {
-	char *p;
-	const char *u, *f;
-	unsigned n, mlen;
-	txt t;
+	char *p, *p1;
+	unsigned n = 0, mlen;
 	va_list ap2;
-	int first;
 
-	vsl_sanity(vsl);
 	AN(fmt);
 	if (vsl_tag_is_masked(tag))
 		return;
@@ -422,63 +428,43 @@ VSLbv(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, va_list ap)
 	/*
 	 * If there are no printf-expansions, don't waste time expanding them
 	 */
-	f = NULL;
-	for (u = fmt; *u != '\0'; u++)
-		if (*u == '%')
-			f = u;
-	if (f == NULL) {
-		t.b = TRUST_ME(fmt);
-		t.e = TRUST_ME(u);
-		VSLbt(vsl, tag, t);
+	if (strchr(fmt, '%') == NULL) {
+		vslb_simple(vsl, tag, 0, fmt);
 		return;
 	}
 
+	/*
+	 * If the format is trivial, deal with it directly
+	 */
 	if (!strcmp(fmt, "%s")) {
-		p = va_arg(ap, char *);
-		t.b = p;
-		t.e = strchr(p, '\0');
-		VSLbt(vsl, tag, t);
+		p1 = va_arg(ap, char *);
+		vslb_simple(vsl, tag, 0, p1);
 		return;
 	}
 
-	assert(vsl->wlp <= vsl->wle);
+	vsl_sanity(vsl);
 
-	/* Flush if we can't fit any bytes */
-	if (vsl->wle - vsl->wlp <= VSL_OVERHEAD)
-		VSL_Flush(vsl, 1);
+	mlen = (char *)vsl->wle - VSL_DATA(vsl->wlp);
 
-	/* Do the vsnprintf formatting in one or two stages. If the first
-	   stage shows that we overflowed, and the available space to work
-	   with was less than vsl_reclen, flush and do the formatting
-	   again. */
-	first = 1;
-	while (1) {
-		assert(vsl->wle - vsl->wlp > VSL_OVERHEAD);
-		mlen = VSL_BYTES((vsl->wle - vsl->wlp) - VSL_OVERHEAD);
-		if (mlen > cache_param->vsl_reclen)
-			mlen = cache_param->vsl_reclen;
-		assert(mlen > 0);
-		assert(VSL_END(vsl->wlp, mlen) <= vsl->wle);
+	// First attempt, only if any space at all
+	if (mlen > 0) {
 		p = VSL_DATA(vsl->wlp);
 		va_copy(ap2, ap);
 		n = vsnprintf(p, mlen, fmt, ap2);
 		va_end(ap2);
-
-		if (first && n >= mlen && mlen < cache_param->vsl_reclen) {
-			first = 0;
-			VSL_Flush(vsl, 1);
-			continue;
-		}
-
-		break;
 	}
 
-	if (n > mlen - 1)
-		n = mlen - 1;	/* we truncate long fields */
-	p[n++] = '\0';		/* NUL-terminated */
-	vsl->wlp = vsl_hdr(tag, vsl->wlp, n, vsl->wid);
-	assert(vsl->wlp <= vsl->wle);
-	vsl->wlr++;
+	// Second attempt after a flush
+	if (mlen == 0 || n + 1 > mlen) {
+		// Second attempt after a flush
+		VSL_Flush(vsl, 1);
+		mlen = (char *)vsl->wle - VSL_DATA(vsl->wlp);
+		p = VSL_DATA(vsl->wlp);
+		n = vsnprintf(p, mlen, fmt, ap);
+	}
+	if (n + 1 < mlen)
+		mlen = n + 1;
+	(void)vslb_get(vsl, tag, &mlen);
 
 	if (DO_DEBUG(DBG_SYNCVSL))
 		VSL_Flush(vsl, 0);


More information about the varnish-commit mailing list