[master] 10590c1 Go over the generation of VSL records with some spit & polish
Poul-Henning Kamp
phk at varnish-cache.org
Mon Nov 19 22:42:20 CET 2012
commit 10590c104c9cc2a03dc5e502f56bee162323d810
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Nov 19 21:41:49 2012 +0000
Go over the generation of VSL records with some spit & polish
diff --git a/bin/varnishd/cache/cache_shmlog.c b/bin/varnishd/cache/cache_shmlog.c
index 228dde8..e7ae53e 100644
--- a/bin/varnishd/cache/cache_shmlog.c
+++ b/bin/varnishd/cache/cache_shmlog.c
@@ -50,6 +50,10 @@ static uint32_t *vsl_ptr;
struct VSC_C_main *VSC_C_main;
+/*--------------------------------------------------------------------
+ * Check if the VSL_tag is masked by parameter bitmap
+ */
+
static inline int
vsl_tag_is_masked(enum VSL_tag_e tag)
{
@@ -62,28 +66,27 @@ vsl_tag_is_masked(enum VSL_tag_e tag)
return (*bm & b);
}
-static inline uint32_t
-vsl_w0(uint32_t type, uint32_t length)
-{
-
- assert(length < 0x10000);
- return (((type & 0xff) << 24) | length);
-}
-
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Lay down a header fields, and return pointer to the next record
+ */
-static inline void
+static inline uint32_t *
vsl_hdr(enum VSL_tag_e tag, uint32_t *p, unsigned len, uint32_t vxid)
{
assert(((uintptr_t)p & 0x3) == 0);
+ assert(tag > SLT_Bogus);
+ assert(tag < SLT_Reserved);
+ AZ(len & ~VSL_LENMASK);
p[1] = vxid;
- VMB();
- p[0] = vsl_w0(tag, len);
+ p[0] = ((((unsigned)tag & 0xff) << 24) | len);
+ return (VSL_END(p, len));
}
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Wrap the VSL buffer
+ */
static void
vsl_wrap(void)
@@ -140,8 +143,7 @@ vsl_get(unsigned len, unsigned records, unsigned flushes)
}
/*--------------------------------------------------------------------
- * This variant copies a byte-range directly to the log, without
- * taking the detour over sprintf()
+ * Stick a finished record into VSL.
*/
static void
@@ -159,10 +161,22 @@ vslr(enum VSL_tag_e tag, uint32_t vxid, const char *b, unsigned len)
p = vsl_get(len, 1, 0);
memcpy(p + 2, b, len);
- vsl_hdr(tag, p, len, vxid);
+
+ /*
+ * vsl_hdr() writes p[1] again, but we want to make sure it
+ * has hit memory because we work on the live buffer here.
+ */
+ p[1] = vxid;
+ VWMB();
+ (void)vsl_hdr(tag, p, len, vxid);
}
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Add a unbuffered record to VSL
+ *
+ * NB: This variant should be used sparingly and only for low volume
+ * NB: since it significantly adds to the mutex load on the VSL.
+ */
void
VSL(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, ...)
@@ -171,20 +185,21 @@ VSL(enum VSL_tag_e tag, uint32_t vxid, const char *fmt, ...)
unsigned n, mlen = cache_param->shm_reclen;
char buf[mlen];
+ AN(fmt);
if (vsl_tag_is_masked(tag))
return;
- AN(fmt);
- va_start(ap, fmt);
+
if (strchr(fmt, '%') == NULL) {
vslr(tag, vxid, fmt, strlen(fmt));
} else {
+ va_start(ap, fmt);
n = vsnprintf(buf, mlen, fmt, ap);
+ va_end(ap);
if (n > mlen)
n = mlen;
vslr(tag, vxid, buf, n);
}
- va_end(ap);
}
/*--------------------------------------------------------------------*/
@@ -210,24 +225,24 @@ VSL_Flush(struct vsl_log *vsl, int overflow)
vsl->wlr = 0;
}
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * VSL-buffered-txt
+ */
-static void
-wslr(struct vsl_log *vsl, enum VSL_tag_e tag, int id, txt t)
+void
+VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t)
{
unsigned l, mlen;
Tcheck(t);
- if (id == -1)
- id = vsl->wid;
+ if (vsl_tag_is_masked(tag))
+ return;
mlen = cache_param->shm_reclen;
/* Truncate */
l = Tlen(t);
- if (l > mlen) {
+ if (l > mlen)
l = mlen;
- t.e = t.b + l;
- }
assert(vsl->wlp < vsl->wle);
@@ -236,51 +251,10 @@ wslr(struct vsl_log *vsl, enum VSL_tag_e tag, int id, txt t)
VSL_Flush(vsl, 1);
assert(VSL_END(vsl->wlp, l) < vsl->wle);
memcpy(VSL_DATA(vsl->wlp), t.b, l);
- vsl_hdr(tag, vsl->wlp, l, id);
- vsl->wlp = VSL_END(vsl->wlp, l);
+ vsl->wlp = vsl_hdr(tag, vsl->wlp, l, vsl->wid);
assert(vsl->wlp < vsl->wle);
vsl->wlr++;
- if (DO_DEBUG(DBG_SYNCVSL))
- VSL_Flush(vsl, 0);
-}
-/*--------------------------------------------------------------------*/
-
-static void
-wsl(struct vsl_log *, enum VSL_tag_e tag, int id, const char *fmt, va_list ap)
- __printflike(4, 0);
-
-static void
-wsl(struct vsl_log *vsl, enum VSL_tag_e tag, int id, const char *fmt,
- va_list ap)
-{
- char *p;
- unsigned n, mlen;
- txt t;
-
- AN(fmt);
- mlen = cache_param->shm_reclen;
-
- if (strchr(fmt, '%') == NULL) {
- t.b = TRUST_ME(fmt);
- t.e = strchr(t.b, '\0');
- wslr(vsl, tag, id, t);
- } else {
- assert(vsl->wlp < vsl->wle);
-
- /* Wrap if we cannot fit a full size record */
- if (VSL_END(vsl->wlp, mlen) >= vsl->wle)
- VSL_Flush(vsl, 1);
-
- p = VSL_DATA(vsl->wlp);
- n = vsnprintf(p, mlen, fmt, ap);
- if (n > mlen)
- n = mlen; /* we truncate long fields */
- vsl_hdr(tag, vsl->wlp, n, id);
- vsl->wlp = VSL_END(vsl->wlp, n);
- assert(vsl->wlp < vsl->wle);
- vsl->wlr++;
- }
if (DO_DEBUG(DBG_SYNCVSL))
VSL_Flush(vsl, 0);
}
@@ -292,32 +266,55 @@ wsl(struct vsl_log *vsl, enum VSL_tag_e tag, int id, const char *fmt,
void
VSLb(struct vsl_log *vsl, enum VSL_tag_e tag, const char *fmt, ...)
{
+ char *p;
+ const char *u, *f;
+ unsigned n, mlen;
va_list ap;
+ txt t;
AN(fmt);
if (vsl_tag_is_masked(tag))
return;
+
+ /*
+ * 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);
+ return;
+ }
+
+ mlen = cache_param->shm_reclen;
+
+ /* Wrap if we cannot fit a full size record */
+ if (VSL_END(vsl->wlp, mlen) >= vsl->wle)
+ VSL_Flush(vsl, 1);
+
+ p = VSL_DATA(vsl->wlp);
va_start(ap, fmt);
- wsl(vsl, tag, vsl->wid, fmt, ap);
+ n = vsnprintf(p, mlen, fmt, ap);
va_end(ap);
+ if (n > mlen)
+ n = mlen; /* we truncate long fields */
+ vsl->wlp = vsl_hdr(tag, vsl->wlp, n, vsl->wid);
+ assert(vsl->wlp < vsl->wle);
+ vsl->wlr++;
+
+ if (DO_DEBUG(DBG_SYNCVSL))
+ VSL_Flush(vsl, 0);
}
/*--------------------------------------------------------------------
- * VSL-buffered-txt
+ * Allocate a VSL buffer
*/
void
-VSLbt(struct vsl_log *vsl, enum VSL_tag_e tag, txt t)
-{
-
- if (vsl_tag_is_masked(tag))
- return;
- wslr(vsl, tag, -1, t);
-}
-
-/*--------------------------------------------------------------------*/
-
-void
VSL_Setup(struct vsl_log *vsl, void *ptr, size_t len)
{
diff --git a/include/vapi/vsl_int.h b/include/vapi/vsl_int.h
index 6f192e9..24f2037 100644
--- a/include/vapi/vsl_int.h
+++ b/include/vapi/vsl_int.h
@@ -46,18 +46,22 @@
*
* Each logrecord consist of:
* [n] = ((type & 0xff) << 24) | (length & 0xffff)
- * [n + 1] = identifier
+ * [n + 1] = ((marker & 0x03) << 30) | (identifier & 0x3fffffff)
* [n + 2] ... [m] = content
+ *
+ * Notice that the constants in these macros cannot be changed without
+ * changing corresponding magic numbers in varnishd/cache/cache_shmlog.c
*/
#define VSL_CLIENTMARKER (1U<<30)
#define VSL_BACKENDMARKER (1U<<31)
#define VSL_IDENTMASK (~(3U<<30))
+#define VSL_LENMASK 0xffff
#define VSL_WORDS(len) (((len) + 3) / 4)
#define VSL_END(ptr, len) ((ptr) + 2 + VSL_WORDS(len))
#define VSL_NEXT(ptr) VSL_END(ptr, VSL_LEN(ptr))
-#define VSL_LEN(ptr) ((ptr)[0] & 0xffff)
+#define VSL_LEN(ptr) ((ptr)[0] & VSL_LENMASK)
#define VSL_TAG(ptr) ((ptr)[0] >> 24)
#define VSL_ID(ptr) (((ptr)[1]) & VSL_IDENTMASK)
#define VSL_CLIENT(ptr) (((ptr)[1]) & VSL_CLIENTMARKER)
More information about the varnish-commit
mailing list