Mailing List Archive

r84 - in trunk/varnish-cache: bin/varnishd include lib/libvcl
Author: phk
Date: 2006-03-30 09:05:10 +0200 (Thu, 30 Mar 2006)
New Revision: 84

Added:
trunk/varnish-cache/bin/varnishd/cache_pool.c
Modified:
trunk/varnish-cache/bin/varnishd/Makefile.am
trunk/varnish-cache/bin/varnishd/cache.h
trunk/varnish-cache/bin/varnishd/cache_acceptor.c
trunk/varnish-cache/bin/varnishd/cache_httpd.c
trunk/varnish-cache/bin/varnishd/cache_main.c
trunk/varnish-cache/bin/varnishd/cache_vcl.c
trunk/varnish-cache/bin/varnishd/varnishd.c
trunk/varnish-cache/include/vcl_lang.h
trunk/varnish-cache/lib/libvcl/vcl_compile.c
trunk/varnish-cache/lib/libvcl/vcl_fixed_token.c
trunk/varnish-cache/lib/libvcl/vcl_gen_fixed_token.tcl
trunk/varnish-cache/lib/libvcl/vcl_token_defs.h
Log:
Integrate the VCL code closer in the cache process: The passed
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.




Modified: trunk/varnish-cache/bin/varnishd/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishd/Makefile.am 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/Makefile.am 2006-03-30 07:05:10 UTC (rev 84)
@@ -8,6 +8,7 @@
cache_acceptor.c \
cache_httpd.c \
cache_main.c \
+ cache_pool.c \
cache_shmlog.c \
cache_vcl.c \
cli_event.c \

Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/cache.h 2006-03-30 07:05:10 UTC (rev 84)
@@ -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

Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_acceptor.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/cache_acceptor.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -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 @@
}
sp->hdr_e = p;
event_del(sp->rd_e);
- HttpdAnalyze(sp);
-
- /* XXX: for now, pass everything */
- sp->handling = HND_Pass;
+ DealWithSession(sp);
}

static void

Modified: trunk/varnish-cache/bin/varnishd/cache_httpd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_httpd.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/cache_httpd.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -9,6 +9,7 @@

#include "libvarnish.h"
#include "shmlog.h"
+#include "vcl_lang.h"
#include "cache.h"

void
@@ -20,23 +21,9 @@

/* 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 */

Modified: trunk/varnish-cache/bin/varnishd/cache_main.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_main.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/cache_main.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -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 @@
printf("Child starts\n");

VSL_Init();
+ CacheInitPool();

AZ(pthread_create(&vca_thread, NULL, vca_main, NULL));


Added: trunk/varnish-cache/bin/varnishd/cache_pool.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_pool.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/cache_pool.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -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));
+}

Modified: trunk/varnish-cache/bin/varnishd/cache_vcl.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vcl.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/cache_vcl.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -142,3 +142,13 @@
}
active_vcl = vcl;
}
+
+/*--------------------------------------------------------------------*/
+
+void
+VCL_pass(VCL_FARGS)
+{
+
+ sess->handling = HND_Pass;
+ sess->done++;
+}

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -68,8 +68,23 @@

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);

Modified: trunk/varnish-cache/include/vcl_lang.h
===================================================================
--- trunk/varnish-cache/include/vcl_lang.h 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/include/vcl_lang.h 2006-03-30 07:05:10 UTC (rev 84)
@@ -5,6 +5,7 @@
* XXX: *MUST* be rerun.
*/

+#include <sys/queue.h>

struct vcl_ref {
unsigned line;
@@ -18,19 +19,42 @@
unsigned mask;
};

-struct client {
- unsigned ip;
-};
+#define VCA_RXBUFSIZE 1024
+#define VCA_ADDRBUFSIZE 32

-struct req {
- char *req;
- char *useragent;
- struct {
- char *path;
- char *host;
- } url;
- double ttlfactor;
- struct backend *backend;
+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;
+
+ char done;
+
+ TAILQ_ENTRY(sess) list;
+
+ /* Various internal stuff */
+ struct event *rd_e;
+ struct sessmem *mem;
};

struct backend {
@@ -41,17 +65,9 @@
int down;
};

-struct obj {
- int exists;
- double ttl;
- unsigned result;
- unsigned size;
- unsigned usage;
-};
+#define VCL_FARGS struct sess *sess
+#define VCL_PASS_ARGS sess

-#define VCL_FARGS struct client *client, struct obj *obj, struct req *req, struct backend *backend
-#define VCL_PASS_ARGS client, obj, req, backend
-
void VCL_count(unsigned);
void VCL_no_cache();
void VCL_no_new_cache();
@@ -59,15 +75,18 @@
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;

Modified: trunk/varnish-cache/lib/libvcl/vcl_compile.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcl_compile.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/lib/libvcl/vcl_compile.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -818,6 +818,11 @@
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 @@
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:
@@ -1364,6 +1370,8 @@
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,
"\t.ref = VCL_ref,\n");

Modified: trunk/varnish-cache/lib/libvcl/vcl_fixed_token.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcl_fixed_token.c 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/lib/libvcl/vcl_fixed_token.c 2006-03-30 07:05:10 UTC (rev 84)
@@ -245,6 +245,11 @@
*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_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 @@
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 @@
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 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("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(" /* 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,17 +444,9 @@
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("#define VCL_FARGS struct sess *sess\n", f);
+ fputs("#define VCL_PASS_ARGS sess\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("\n", f);
fputs("void VCL_count(unsigned);\n", f);
fputs("void VCL_no_cache();\n", f);
fputs("void VCL_no_new_cache();\n", f);
@@ -434,15 +454,18 @@
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);

Modified: trunk/varnish-cache/lib/libvcl/vcl_gen_fixed_token.tcl
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcl_gen_fixed_token.tcl 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/lib/libvcl/vcl_gen_fixed_token.tcl 2006-03-30 07:05:10 UTC (rev 84)
@@ -13,6 +13,7 @@
backend

error
+ pass
fetch
call
no_cache

Modified: trunk/varnish-cache/lib/libvcl/vcl_token_defs.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcl_token_defs.h 2006-03-27 14:12:07 UTC (rev 83)
+++ trunk/varnish-cache/lib/libvcl/vcl_token_defs.h 2006-03-30 07:05:10 UTC (rev 84)
@@ -14,30 +14,31 @@
#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