[master] 06cf60a02 Add VRT_priv_task_lookup()
Nils Goroll
nils.goroll at uplex.de
Mon Jan 11 16:04:02 UTC 2021
commit 06cf60a020a81e49d001ee42e4d85f16580f3fe0
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Tue Jan 5 12:47:20 2021 +0100
Add VRT_priv_task_lookup()
VRT_priv_task() inserts a priv_task if it does not exist.
In some cases, it is more efficient to only insert a priv_task under
certain conditions. These require an API function to only return a
priv_task if it exists. This is VRT_priv_task_lookup().
A TODO comment has been added for a sensible performance optimization,
avoiding one VRBT traversal for the VRT_priv_task() case. I would
address this after this suggestion got accepted, if so.
diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c
index 9987abe21..1685ec06e 100644
--- a/bin/varnishd/cache/cache_vrt_priv.c
+++ b/bin/varnishd/cache/cache_vrt_priv.c
@@ -116,19 +116,36 @@ vrt_priv_dyncmp(const struct vrt_priv *vp1, const struct vrt_priv *vp2)
VRBT_GENERATE_STATIC(vrt_privs, vrt_priv, entry, vrt_priv_dyncmp)
static struct vmod_priv *
-vrt_priv_dynamic(struct ws *ws, struct vrt_privs *privs, uintptr_t vmod_id)
+vrt_priv_dynamic_get(struct ws *ws, struct vrt_privs *privs, uintptr_t vmod_id)
{
struct vrt_priv *vp;
+
const struct vrt_priv needle = {.vmod_id = vmod_id};
+ vp = VRBT_FIND(vrt_privs, privs, &needle);
+ if (vp == NULL)
+ return (NULL);
+
+ CHECK_OBJ(vp, VRT_PRIV_MAGIC);
+ assert(vp->vmod_id == vmod_id);
+ return (vp->priv);
+}
+
+static struct vmod_priv *
+vrt_priv_dynamic(struct ws *ws, struct vrt_privs *privs, uintptr_t vmod_id)
+{
+ struct vrt_priv *vp;
+ static struct vmod_priv *r;
+
AN(vmod_id);
- vp = VRBT_FIND(vrt_privs, privs, &needle);
- if (vp) {
- CHECK_OBJ(vp, VRT_PRIV_MAGIC);
- assert(vp->vmod_id == vmod_id);
- return (vp->priv);
- }
+ /*
+ * TODO: for insert == 1, we can avoid the VRBT_FIND:
+ * call only VRT_INSERT and reset the ws if the element existed
+ */
+ r = vrt_priv_dynamic_get(ws, privs, vmod_id);
+ if (r)
+ return (r);
vp = WS_Alloc(ws, sizeof *vp);
if (vp == NULL)
@@ -162,6 +179,17 @@ vrt_priv_task_context(VRT_CTX)
return (cli_task_privs);
}
+struct vmod_priv *
+VRT_priv_task_get(VRT_CTX, const void *vmod_id)
+{
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+
+ return (vrt_priv_dynamic_get(
+ ctx->ws,
+ vrt_priv_task_context(ctx),
+ (uintptr_t)vmod_id));
+}
+
struct vmod_priv *
VRT_priv_task(VRT_CTX, const void *vmod_id)
{
diff --git a/bin/varnishtest/tests/m00000.vtc b/bin/varnishtest/tests/m00000.vtc
index 48fc749c0..49c9cc234 100644
--- a/bin/varnishtest/tests/m00000.vtc
+++ b/bin/varnishtest/tests/m00000.vtc
@@ -47,6 +47,7 @@ varnish v1 -vcl+backend {
}
sub priv_task {
+ debug.test_priv_task_get();
debug.test_priv_task("foo");
}
diff --git a/include/vrt.h b/include/vrt.h
index fe888060e..23de2361b 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -59,6 +59,7 @@
* struct vmod_priv free member replaced with methods
* VRT_CTX_Assert() added
* VRT_ban_string() signature changed
+ * VRT_priv_task_get() added
* 12.0 (2020-09-15)
* Added VRT_DirectorResolve()
* Added VCL_STRING VRT_BLOB_string(VRT_CTX, VCL_BLOB)
@@ -597,6 +598,7 @@ struct vmod_priv {
void VRT_priv_fini(const struct vmod_priv *p);
struct vmod_priv *VRT_priv_task(VRT_CTX, const void *vmod_id);
+struct vmod_priv *VRT_priv_task_get(VRT_CTX, const void *vmod_id);
struct vmod_priv *VRT_priv_top(VRT_CTX, const void *vmod_id);
/* Stevedore related functions */
diff --git a/vmod/vmod_debug.c b/vmod/vmod_debug.c
index 2288c4ff1..bb663ea94 100644
--- a/vmod/vmod_debug.c
+++ b/vmod/vmod_debug.c
@@ -243,6 +243,14 @@ xyzzy_test_priv_call(VRT_CTX, struct vmod_priv *priv)
}
}
+VCL_VOID v_matchproto_(td_debug_test_priv_task_get)
+xyzzy_test_priv_task_get(VRT_CTX)
+{
+
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ AZ(VRT_priv_task_get(ctx, NULL));
+}
+
static void
priv_task_free(void *ptr)
{
@@ -848,7 +856,7 @@ xyzzy_priv_perf(VRT_CTX, VCL_INT size, VCL_INT rounds)
t0 = VTIM_mono();
for (r = 0; r < rounds; r++) {
for (s = 1; s <= size; s++) {
- p = VRT_priv_task(ctx, (void *)(uintptr_t)s);
+ p = VRT_priv_task_get(ctx, (void *)(uintptr_t)s);
AN(p);
check += (uintptr_t)p->priv;
p->priv = (void *)(uintptr_t)(s * rounds + r);
@@ -1035,7 +1043,7 @@ xyzzy_get_ip(VRT_CTX)
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
- priv = VRT_priv_task(ctx, &store_ip_token);
+ priv = VRT_priv_task_get(ctx, &store_ip_token);
AN(priv);
AZ(priv->methods);
diff --git a/vmod/vmod_debug.vcc b/vmod/vmod_debug.vcc
index 4eee74547..fa81c8cf8 100644
--- a/vmod/vmod_debug.vcc
+++ b/vmod/vmod_debug.vcc
@@ -56,6 +56,10 @@ $Function VOID test_priv_vcl(PRIV_VCL)
Test function for VCL private pointers
+$Function VOID test_priv_task_get()
+
+Assert that the priv_task for the NULL pointer is NULL.
+
$Function STRING test_priv_task(PRIV_TASK, STRING s="")
Test function for TASK private pointers
More information about the varnish-commit
mailing list