]> err.no Git - varnish/commitdiff
Integrate the VCL code closer in the cache process: The passed
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 30 Mar 2006 07:05:10 +0000 (07:05 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Thu, 30 Mar 2006 07:05:10 +0000 (07:05 +0000)
argument will be the session structure.

Add the pool of worker threads (cache_pool).  With a unitary nature
of the VCL code, the HTTP parsing can be postponed to the worker thread.

This actually helps us with CPU cache locality as it will reduce the
amount of memory allocated on one CPU but freed on another.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@84 d4fa192b-c00b-0410-8231-f00ffab90ce4

13 files changed:
varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_acceptor.c
varnish-cache/bin/varnishd/cache_httpd.c
varnish-cache/bin/varnishd/cache_main.c
varnish-cache/bin/varnishd/cache_pool.c [new file with mode: 0644]
varnish-cache/bin/varnishd/cache_vcl.c
varnish-cache/bin/varnishd/varnishd.c
varnish-cache/include/vcl_lang.h
varnish-cache/lib/libvcl/vcl_compile.c
varnish-cache/lib/libvcl/vcl_fixed_token.c
varnish-cache/lib/libvcl/vcl_gen_fixed_token.tcl
varnish-cache/lib/libvcl/vcl_token_defs.h

index 72654aed843bf63d052dccde93e4d31be01fa65d..a822cc26ce8459b1d5a727bccf5751fc845070cf 100644 (file)
@@ -8,6 +8,7 @@ varnishd_SOURCES = \
        cache_acceptor.c \
        cache_httpd.c \
        cache_main.c \
+       cache_pool.c \
        cache_shmlog.c \
        cache_vcl.c \
        cli_event.c \
index cdf878d0e3b80e3fa750b05df7858c8f37d1ebc4..cb530c7297ba4b7e26242c844d6bfa45986f09fd 100644 (file)
@@ -2,46 +2,16 @@
  * $Id$
  */
 
-#define VCA_RXBUFSIZE          1024
-#define VCA_ADDRBUFSIZE                32
-
-struct sess {
-       int             fd;
-
-       /* formatted ascii client address */
-       char            addr[VCA_ADDRBUFSIZE];
-
-       /* Receive buffer for HTTP header */
-       char            rcv[VCA_RXBUFSIZE + 1];
-       unsigned        rcv_len;
-
-       /* HTTP request info, points into rcv */
-       const char      *req_b;
-       const char      *req_e;
-       const char      *url_b;
-       const char      *url_e;
-       const char      *proto_b;
-       const char      *proto_e;
-       const char      *hdr_b;
-       const char      *hdr_e;
-
-       enum {
-               HND_Unclass,
-               HND_Handle,
-               HND_Pass
-       }               handling;
-
-       /* Various internal stuff */
-       struct event    *rd_e;
-       struct sessmem  *mem;
-};
-
 /* cache_acceptor.c */
 void *vca_main(void *arg);
 
 /* cache_httpd.c */
 void HttpdAnalyze(struct sess *sp);
 
+/* cache_pool.c */
+void CacheInitPool(void);
+void DealWithSession(struct sess *sp);
+
 /* cache_shmlog.c */
 void VSL_Init(void);
 #ifdef SHMLOGHEAD_MAGIC
index ae46f4f6163e066e6893dab25188bd2c05492ed7..5a66371d7b5f7ebde442d9fd6dbd96c80cbc91e9 100644 (file)
@@ -17,6 +17,7 @@
 #include <event.h>
 
 #include "libvarnish.h"
+#include "vcl_lang.h"
 #include "heritage.h"
 #include "shmlog.h"
 #include "cache.h"
@@ -65,10 +66,7 @@ http_read_f(int fd, short event, void *arg)
        }
        sp->hdr_e = p;
        event_del(sp->rd_e);
-       HttpdAnalyze(sp);
-
-       /* XXX: for now, pass everything */
-       sp->handling = HND_Pass;
+       DealWithSession(sp);
 }
 
 static void
index 576f25bb3e942598bf21174381ecf45948efed2f..1ed4f7eb1eb9a3ee021cc79eab0f2f285378e877 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "libvarnish.h"
 #include "shmlog.h"
+#include "vcl_lang.h"
 #include "cache.h"
 
 void
@@ -20,23 +21,9 @@ HttpdAnalyze(struct sess *sp)
 
        /* First, isolate and possibly identify request type */
        p = sp->req_b = sp->rcv;
-       if (p[0] == 'G' && p[1] == 'E' && p[2] == 'T' && p[3] == ' ') {
-               p = sp->req_e = p + 4;
-               sp->handling = HND_Handle;
-       } else if (p[0] == 'H' && p[1] == 'E' && p[2] == 'A' && p[3] == 'D'
-           && p[4] == ' ') {
-               p = sp->req_e = p + 5;
-               sp->handling = HND_Handle;
-       } else {
-               /*
-                * We don't bother to identify the rest, we won't handle
-                * them in any case
-                */
-               for (q = p; isalpha(*q); q++)
-                       ;
-               p = sp->req_e = q;
-               sp->handling = HND_Pass;
-       }
+       for (q = p; isalpha(*q); q++)
+               ;
+       p = sp->req_e = q;
        VSLR(SLT_Request, sp->fd, sp->req_b, sp->req_e);
 
        /* Next find the URI */
index 3b8d88cae29122c33a04b1bc24464301d4bc3539..98e571264e9515813f85cf6d071057265ffc56c6 100644 (file)
@@ -18,6 +18,7 @@
 #include "libvarnish.h"
 #include "heritage.h"
 #include "shmlog.h"
+#include "vcl_lang.h"
 #include "cache.h"
 #include "cli_event.h"
 
@@ -100,6 +101,7 @@ child_main(void)
        printf("Child starts\n");
 
        VSL_Init();
+       CacheInitPool();
 
        AZ(pthread_create(&vca_thread, NULL, vca_main, NULL));
 
diff --git a/varnish-cache/bin/varnishd/cache_pool.c b/varnish-cache/bin/varnishd/cache_pool.c
new file mode 100644 (file)
index 0000000..769435d
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <pthread.h>
+
+#include "libvarnish.h"
+#include "vcl_lang.h"
+#include "cache.h"
+
+static TAILQ_HEAD(, sess) shd = TAILQ_HEAD_INITIALIZER(shd);
+
+static pthread_mutex_t shdmtx;
+static pthread_cond_t  shdcnd;
+
+static void *
+CacheWorker(void *priv __unused)
+{
+       struct sess *sp;
+
+       while (1) {
+               AZ(pthread_mutex_lock(&shdmtx));
+               while (1) {
+                       sp = TAILQ_FIRST(&shd);
+                       if (sp != NULL)
+                               break;
+                       AZ(pthread_cond_wait(&shdcnd, &shdmtx));
+               }
+               TAILQ_REMOVE(&shd, sp, list);
+               AZ(pthread_mutex_unlock(&shdmtx));
+
+               HttpdAnalyze(sp);
+
+               /*
+                * XXX send session to acceptor for reuse/disposal
+                */
+       }
+}
+
+void
+DealWithSession(struct sess *sp)
+{
+       AZ(pthread_mutex_lock(&shdmtx));
+       TAILQ_INSERT_TAIL(&shd, sp, list);
+       AZ(pthread_mutex_unlock(&shdmtx));
+       AZ(pthread_cond_signal(&shdcnd));
+}
+
+void
+CacheInitPool(void)
+{
+       pthread_t tp;
+
+       AZ(pthread_mutex_init(&shdmtx, NULL));
+       AZ(pthread_cond_init(&shdcnd, NULL));
+
+       AZ(pthread_create(&tp, NULL, CacheWorker, NULL));
+       AZ(pthread_detach(tp));
+}
index 3c22982415890c6190ac0f66124452c9c12c25dc..e69c8e797c1c3482bbf7b3ad96d177a247908482 100644 (file)
@@ -142,3 +142,13 @@ cli_func_config_use(struct cli *cli, char **av, void *priv)
        }
        active_vcl = vcl;
 }
+
+/*--------------------------------------------------------------------*/
+
+void
+VCL_pass(VCL_FARGS)
+{
+
+       sess->handling = HND_Pass;
+       sess->done++;
+}
index 747648c6593e27f7b6651556d5ef783c3d5b7219..6266f63878c8dccfe215be41ad9b9920bb4134ab 100644 (file)
@@ -68,8 +68,23 @@ vcl_default(const char *bflag)
 
        buf = NULL;
        asprintf(&buf,
-          "backend default { set backend.ip = %s; }",
-           bflag);
+           "backend default { set backend.ip = %s; }\n"
+           "sub main {\n"
+           "    pass;\n"
+#if 0
+           "    if (req.request != \"GET\" && req.request != \"HEAD\") {\n"
+           "        pass;\n"
+           "    }\n"
+           "    lookup;\n"
+           "    if (!obj.valid) {\n"
+           "        fetch;\n"
+           "        if (obj.cacheable) {\n"
+           "            insert;\n"
+           "        }\n"
+           "    }\n"
+#endif
+           "}\n"
+           "", bflag);
        assert(buf != NULL);
        sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
        assert(sb != NULL);
index 4e74e47429cf05a804e21db2a54f75fcd1fddfc5..3d40068822584b7196aabf0fdc7b1cd02cbd6f2d 100644 (file)
@@ -5,6 +5,7 @@
  * XXX: *MUST* be rerun.
  */
 
+#include <sys/queue.h>
 
 struct vcl_ref {
        unsigned        line;
@@ -18,19 +19,42 @@ struct vcl_acl {
        unsigned        mask;
 };
 
-struct client {
-       unsigned        ip;
-};
+#define VCA_RXBUFSIZE          1024
+#define VCA_ADDRBUFSIZE                32
+
+struct sess {
+       int                     fd;
+
+       /* formatted ascii client address */
+       char                    addr[VCA_ADDRBUFSIZE];
+
+       /* Receive buffer for HTTP header */
+       char                    rcv[VCA_RXBUFSIZE + 1];
+       unsigned                rcv_len;
+
+       /* HTTP request info, points into rcv */
+       const char              *req_b;
+       const char              *req_e;
+       const char              *url_b;
+       const char              *url_e;
+       const char              *proto_b;
+       const char              *proto_e;
+       const char              *hdr_b;
+       const char              *hdr_e;
 
-struct req {
-       char            *req;
-       char            *useragent;
-       struct {
-               char            *path;
-               char            *host;
-       }               url;
-       double          ttlfactor;
-       struct backend  *backend;
+       enum {
+               HND_Unclass,
+               HND_Handle,
+               HND_Pass
+       }                       handling;
+
+       char                    done;
+
+       TAILQ_ENTRY(sess)       list;
+
+       /* Various internal stuff */
+       struct event            *rd_e;
+       struct sessmem          *mem;
 };
 
 struct backend {
@@ -41,16 +65,8 @@ struct backend {
        int             down;
 };
 
-struct obj {
-       int             exists;
-       double          ttl;
-       unsigned        result;
-       unsigned        size;
-       unsigned        usage;
-};
-
-#define VCL_FARGS      struct client *client, struct obj *obj, struct req *req, struct backend *backend
-#define VCL_PASS_ARGS  client, obj, req, backend
+#define VCL_FARGS      struct sess *sess
+#define VCL_PASS_ARGS  sess
 
 void VCL_count(unsigned);
 void VCL_no_cache();
@@ -59,15 +75,18 @@ int ip_match(unsigned, struct vcl_acl *);
 int string_match(const char *, const char *);
 int VCL_rewrite(const char *, const char *);
 int VCL_error(unsigned, const char *);
+void VCL_pass(VCL_FARGS);
 int VCL_fetch(void);
 int VCL_switch_config(const char *);
 
 typedef void vcl_init_f(void);
+typedef void vcl_func_f(VCL_FARGS);
 
 struct VCL_conf {
        unsigned        magic;
 #define VCL_CONF_MAGIC 0x7406c509      /* from /dev/random */
        vcl_init_f      *init_func;
+       vcl_func_f      *main_func;
        struct backend  *default_backend;
        struct vcl_ref  *ref;
        unsigned        nref;
index 1ea9838814a01a108698b07efb3bc335c4617f5b..eeb31b33482625dfc526500d03bc07db51055223 100644 (file)
@@ -818,6 +818,11 @@ Action(struct tokenlist *tl)
                I(tl);
                sbuf_printf(tl->fc, "return;\n");
                return;
+       case T_PASS:
+               I(tl);
+               sbuf_printf(tl->fc, "VCL_pass(VCL_PASS_ARGS);\n");
+               sbuf_printf(tl->fc, "return;\n");
+               return;
        case T_FETCH:
                I(tl);
                sbuf_printf(tl->fc, "VCL_fetch();\n");
@@ -849,7 +854,8 @@ Action(struct tokenlist *tl)
                sbuf_printf(tl->fc, "VCL_function_%*.*s(VCL_PASS_ARGS);\n",
                    tl->t->e - tl->t->b,
                    tl->t->e - tl->t->b, tl->t->b);
-               /* XXX: check if function finished request */
+               I(tl); sbuf_printf(tl->fc, "if (sess->done)\n");
+               I(tl); sbuf_printf(tl->fc, "\treturn;\n");
                NextToken(tl);
                return;
        case T_REWRITE:
@@ -1363,6 +1369,8 @@ EmitStruct(struct tokenlist *tl)
            "\t.magic = VCL_CONF_MAGIC,\n");
        sbuf_printf(tl->fc,
            "\t.init_func = VCL_Init,\n");
+       sbuf_printf(tl->fc,
+           "\t.main_func = VCL_function_main,\n");
        sbuf_printf(tl->fc,
            "\t.default_backend = &VCL_backend_default,\n");
        sbuf_printf(tl->fc,
index 548e0028c2315fb8995829d024cb7788cce5eee4..3f2f4bbdd70dece94fdb4322df4e5a01e3e29018 100644 (file)
@@ -245,6 +245,11 @@ vcl_fixed_token(const char *p, const char **q)
                        *q = p + 4;
                        return (T_PROC);
                }
+               if (p[0] == 'p' && p[1] == 'a' && p[2] == 's' && 
+                   p[3] == 's' && !isvar(p[4])) {
+                       *q = p + 4;
+                       return (T_PASS);
+               }
                return (0);
        case 'r':
                if (p[0] == 'r' && p[1] == 'e' && p[2] == 'w' && 
@@ -360,6 +365,7 @@ vcl_init_tnames(void)
        vcl_tnames[T_NEQ] = "!=";
        vcl_tnames[T_NO_CACHE] = "no_cache";
        vcl_tnames[T_NO_NEW_CACHE] = "no_new_cache";
+       vcl_tnames[T_PASS] = "pass";
        vcl_tnames[T_PROC] = "proc";
        vcl_tnames[T_REWRITE] = "rewrite";
        vcl_tnames[T_SET] = "set";
@@ -380,6 +386,7 @@ vcl_output_lang_h(FILE *f)
        fputs(" * XXX: *MUST* be rerun.\n", f);
        fputs(" */\n", f);
        fputs("\n", f);
+       fputs("#include <sys/queue.h>\n", f);
        fputs("\n", f);
        fputs("struct vcl_ref {\n", f);
        fputs(" unsigned        line;\n", f);
@@ -393,19 +400,40 @@ vcl_output_lang_h(FILE *f)
        fputs(" unsigned        mask;\n", f);
        fputs("};\n", f);
        fputs("\n", f);
-       fputs("struct client {\n", f);
-       fputs(" unsigned        ip;\n", f);
-       fputs("};\n", f);
+       fputs("#define VCA_RXBUFSIZE            1024\n", f);
+       fputs("#define VCA_ADDRBUFSIZE          32\n", f);
+       fputs("\n", f);
+       fputs("struct sess {\n", f);
+       fputs(" int             fd;\n", f);
+       fputs("\n", f);
+       fputs(" /* formatted ascii client address */\n", f);
+       fputs(" char            addr[VCA_ADDRBUFSIZE];\n", f);
        fputs("\n", f);
-       fputs("struct req {\n", f);
-       fputs(" char            *req;\n", f);
-       fputs(" char            *useragent;\n", f);
-       fputs(" struct {\n", f);
-       fputs("         char            *path;\n", f);
-       fputs("         char            *host;\n", f);
-       fputs(" }               url;\n", f);
-       fputs(" double          ttlfactor;\n", f);
-       fputs(" struct backend  *backend;\n", f);
+       fputs(" /* Receive buffer for HTTP header */\n", f);
+       fputs(" char            rcv[VCA_RXBUFSIZE + 1];\n", f);
+       fputs(" unsigned        rcv_len;\n", f);
+       fputs("\n", f);
+       fputs(" /* HTTP request info, points into rcv */\n", f);
+       fputs(" const char      *req_b;\n", f);
+       fputs(" const char      *req_e;\n", f);
+       fputs(" const char      *url_b;\n", f);
+       fputs(" const char      *url_e;\n", f);
+       fputs(" const char      *proto_b;\n", f);
+       fputs(" const char      *proto_e;\n", f);
+       fputs(" const char      *hdr_b;\n", f);
+       fputs(" const char      *hdr_e;\n", f);
+       fputs("\n", f);
+       fputs(" enum {\n", f);
+       fputs("         HND_Unclass,\n", f);
+       fputs("         HND_Handle,\n", f);
+       fputs("         HND_Pass\n", f);
+       fputs(" }               handling;\n", f);
+       fputs("\n", f);
+       fputs(" char            done;\n", f);
+       fputs("\n", f);
+       fputs(" /* Various internal stuff */\n", f);
+       fputs(" struct event    *rd_e;\n", f);
+       fputs(" struct sessmem  *mem;\n", f);
        fputs("};\n", f);
        fputs("\n", f);
        fputs("struct backend {\n", f);
@@ -416,16 +444,8 @@ vcl_output_lang_h(FILE *f)
        fputs(" int             down;\n", f);
        fputs("};\n", f);
        fputs("\n", f);
-       fputs("struct obj {\n", f);
-       fputs(" int             exists;\n", f);
-       fputs(" double          ttl;\n", f);
-       fputs(" unsigned        result;\n", f);
-       fputs(" unsigned        size;\n", f);
-       fputs(" unsigned        usage;\n", f);
-       fputs("};\n", f);
-       fputs("\n", f);
-       fputs("#define VCL_FARGS        struct client *client, struct obj *obj, struct req *req, struct backend *backend\n", f);
-       fputs("#define VCL_PASS_ARGS    client, obj, req, backend\n", f);
+       fputs("#define VCL_FARGS        struct sess *sess\n", f);
+       fputs("#define VCL_PASS_ARGS    sess\n", f);
        fputs("\n", f);
        fputs("void VCL_count(unsigned);\n", f);
        fputs("void VCL_no_cache();\n", f);
@@ -434,15 +454,18 @@ vcl_output_lang_h(FILE *f)
        fputs("int string_match(const char *, const char *);\n", f);
        fputs("int VCL_rewrite(const char *, const char *);\n", f);
        fputs("int VCL_error(unsigned, const char *);\n", f);
+       fputs("void VCL_pass(VCL_FARGS);\n", f);
        fputs("int VCL_fetch(void);\n", f);
        fputs("int VCL_switch_config(const char *);\n", f);
        fputs("\n", f);
        fputs("typedef void vcl_init_f(void);\n", f);
+       fputs("typedef void vcl_func_f(VCL_FARGS);\n", f);
        fputs("\n", f);
        fputs("struct VCL_conf {\n", f);
        fputs(" unsigned        magic;\n", f);
        fputs("#define VCL_CONF_MAGIC   0x7406c509      /* from /dev/random */\n", f);
        fputs(" vcl_init_f      *init_func;\n", f);
+       fputs(" vcl_func_f      *main_func;\n", f);
        fputs(" struct backend  *default_backend;\n", f);
        fputs(" struct vcl_ref  *ref;\n", f);
        fputs(" unsigned        nref;\n", f);
index 60fbf0f58038211356398910c09f53967cd6073c..4a06af594759c9a29f9aa26fcdaf46ae8c3649b3 100755 (executable)
@@ -13,6 +13,7 @@ set keywords {
        backend
 
        error
+       pass
        fetch
        call
        no_cache
index 29655dc9dd58360c266816a59b27ab65513b2a7e..760f921fae3502048e9a8bfe7a239be9e099c026 100644 (file)
 #define T_ACL 135
 #define T_BACKEND 136
 #define T_ERROR 137
-#define T_FETCH 138
-#define T_CALL 139
-#define T_NO_CACHE 140
-#define T_NO_NEW_CACHE 141
-#define T_SET 142
-#define T_REWRITE 143
-#define T_FINISH 144
-#define T_SWITCH_CONFIG 145
-#define T_INC 146
-#define T_DEC 147
-#define T_CAND 148
-#define T_COR 149
-#define T_LEQ 150
-#define T_EQ 151
-#define T_NEQ 152
-#define T_GEQ 153
-#define T_SHR 154
-#define T_SHL 155
-#define T_INCR 156
-#define T_DECR 157
-#define T_MUL 158
-#define T_DIV 159
-#define ID 160
-#define VAR 161
-#define CNUM 162
-#define CSTR 163
-#define EOI 164
+#define T_PASS 138
+#define T_FETCH 139
+#define T_CALL 140
+#define T_NO_CACHE 141
+#define T_NO_NEW_CACHE 142
+#define T_SET 143
+#define T_REWRITE 144
+#define T_FINISH 145
+#define T_SWITCH_CONFIG 146
+#define T_INC 147
+#define T_DEC 148
+#define T_CAND 149
+#define T_COR 150
+#define T_LEQ 151
+#define T_EQ 152
+#define T_NEQ 153
+#define T_GEQ 154
+#define T_SHR 155
+#define T_SHL 156
+#define T_INCR 157
+#define T_DECR 158
+#define T_MUL 159
+#define T_DIV 160
+#define ID 161
+#define VAR 162
+#define CNUM 163
+#define CSTR 164
+#define EOI 165