r4965 - trunk/varnish-cache/bin/varnishd

phk at varnish-cache.org phk at varnish-cache.org
Wed Jun 16 14:47:08 CEST 2010


Author: phk
Date: 2010-06-16 14:47:07 +0200 (Wed, 16 Jun 2010)
New Revision: 4965

Modified:
   trunk/varnish-cache/bin/varnishd/cache_panic.c
   trunk/varnish-cache/bin/varnishd/cache_shmlog.c
   trunk/varnish-cache/bin/varnishd/common.h
   trunk/varnish-cache/bin/varnishd/mgt_child.c
   trunk/varnish-cache/bin/varnishd/mgt_shmem.c
   trunk/varnish-cache/bin/varnishd/varnishd.c
   trunk/varnish-cache/bin/varnishd/vsm.c
Log:
Add mark/clean facility to VSM, so that all dynamic allocations gets
Freeed (cooled) on child start.



Modified: trunk/varnish-cache/bin/varnishd/cache_panic.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_panic.c	2010-06-16 12:25:46 UTC (rev 4964)
+++ trunk/varnish-cache/bin/varnishd/cache_panic.c	2010-06-16 12:47:07 UTC (rev 4965)
@@ -341,18 +341,18 @@
 	vsb_bcat(vsp, "", 1);	/* NUL termination */
 
 	if (params->diag_bitmap & 0x4000)
-		(void)fputs(loghead->panicstr, stderr);
+		(void)fputs(vsm_head->panicstr, stderr);
 
 #ifdef HAVE_ABORT2
 	if (params->diag_bitmap & 0x8000) {
 		void *arg[1];
 		char *p;
 
-		for (p = loghead->panicstr; *p; p++)
+		for (p = vsm_head->panicstr; *p; p++)
 			if (*p == '\n')
 				*p = ' ';
-		arg[0] = loghead->panicstr;
-		abort2(loghead->panicstr, 1, arg);
+		arg[0] = vsm_head->panicstr;
+		abort2(vsm_head->panicstr, 1, arg);
 	}
 #endif
 	if (params->diag_bitmap & 0x1000)
@@ -369,6 +369,6 @@
 
 	vas_fail = pan_ic;
 	vsp = &vsps;
-	AN(vsb_new(vsp, loghead->panicstr, sizeof loghead->panicstr,
+	AN(vsb_new(vsp, vsm_head->panicstr, sizeof vsm_head->panicstr,
 	    VSB_FIXEDLEN));
 }

Modified: trunk/varnish-cache/bin/varnishd/cache_shmlog.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_shmlog.c	2010-06-16 12:25:46 UTC (rev 4964)
+++ trunk/varnish-cache/bin/varnishd/cache_shmlog.c	2010-06-16 12:47:07 UTC (rev 4965)
@@ -43,7 +43,7 @@
 static pthread_mutex_t vsl_mtx;
 
 static uint32_t			*vsl_start;
-static uint32_t			*vsl_end;
+static const uint32_t		*vsl_end;
 static uint32_t			*vsl_ptr;
 
 static inline uint32_t
@@ -276,6 +276,8 @@
 
 	AZ(pthread_mutex_init(&vsl_mtx, NULL));
 
+	VSM_Clean();
+
 	VSM_ITER(vsc)
 		if (!strcmp(vsc->class, VSL_CLASS))
 			break;
@@ -285,8 +287,8 @@
 	vsl_ptr = vsl_start + 1;
 
 	vsl_wrap();
-	loghead->starttime = (intmax_t)TIM_real();
-	loghead->panicstr[0] = '\0';
+	vsm_head->starttime = (intmax_t)TIM_real();
+	vsm_head->panicstr[0] = '\0';
 	memset(VSL_stats, 0, sizeof *VSL_stats);
-	loghead->child_pid = getpid();
+	vsm_head->child_pid = getpid();
 }

Modified: trunk/varnish-cache/bin/varnishd/common.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/common.h	2010-06-16 12:25:46 UTC (rev 4964)
+++ trunk/varnish-cache/bin/varnishd/common.h	2010-06-16 12:47:07 UTC (rev 4965)
@@ -71,12 +71,22 @@
 
 /* vsm.c */
 extern struct vsm_head		*vsm_head;
-extern void			*vsm_end;
+extern const struct vsm_chunk	*vsm_end;
 
 void *VSM_Alloc(unsigned size, const char *class, const char *type,
     const char *ident);
+void VSM_Free(const void *ptr);
+void VSM_Clean(void);
 
+
 struct vsm_chunk *vsm_iter_0(void);
 void vsm_iter_n(struct vsm_chunk **pp);
 
 #define VSM_ITER(vd) for ((vd) = vsm_iter_0(); (vd) != NULL; vsm_iter_n(&vd))
+
+/* These classes are opaque to other programs, so we define the here */
+#define VSM_CLASS_FREE	"Free"
+#define VSM_CLASS_COOL	"Cool"
+#define VSM_CLASS_PARAM	"Params"
+#define VSM_CLASS_MARK	"MgrCld"
+#define VSM_COOL_TIME	5

Modified: trunk/varnish-cache/bin/varnishd/mgt_child.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_child.c	2010-06-16 12:25:46 UTC (rev 4964)
+++ trunk/varnish-cache/bin/varnishd/mgt_child.c	2010-06-16 12:47:07 UTC (rev 4965)
@@ -461,10 +461,10 @@
 mgt_report_panic(pid_t r)
 {
 
-	if (loghead->panicstr[0] == '\0')
+	if (vsm_head->panicstr[0] == '\0')
 		return;
 	REPORT(LOG_ERR, "Child (%jd) Panic message: %s",
-	    (intmax_t)r, loghead->panicstr);
+	    (intmax_t)r, vsm_head->panicstr);
 }
 
 /*--------------------------------------------------------------------*/

Modified: trunk/varnish-cache/bin/varnishd/mgt_shmem.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_shmem.c	2010-06-16 12:25:46 UTC (rev 4964)
+++ trunk/varnish-cache/bin/varnishd/mgt_shmem.c	2010-06-16 12:47:07 UTC (rev 4965)
@@ -114,7 +114,6 @@
 #endif
 
 struct vsc_main	*VSL_stats;
-struct vsm_head	*loghead;
 
 static int vsl_fd = -1;
 
@@ -272,29 +271,28 @@
 	(void)close(i);
 	vsl_buildnew(VSM_FILENAME, size, fill);
 
-	loghead = (void *)mmap(NULL, size,
+	vsm_head = (void *)mmap(NULL, size,
 	    PROT_READ|PROT_WRITE,
 	    MAP_HASSEMAPHORE | MAP_NOSYNC | MAP_SHARED,
 	    vsl_fd, 0);
-	loghead->master_pid = getpid();
-	xxxassert(loghead != MAP_FAILED);
-	(void)mlock((void*)loghead, size);
+	vsm_head->master_pid = getpid();
+	xxxassert(vsm_head != MAP_FAILED);
+	(void)mlock((void*)vsm_head, size);
 
-	memset(&loghead->head, 0, sizeof loghead->head);
-	loghead->head.magic = VSM_CHUNK_MAGIC;
-	loghead->head.len =
-	    (uint8_t*)(loghead) + size - (uint8_t*)&loghead->head;
-	bprintf(loghead->head.class, "%s", "Free");
+	memset(&vsm_head->head, 0, sizeof vsm_head->head);
+	vsm_head->head.magic = VSM_CHUNK_MAGIC;
+	vsm_head->head.len =
+	    (uint8_t*)(vsm_head) + size - (uint8_t*)&vsm_head->head;
+	bprintf(vsm_head->head.class, "%s", VSM_CLASS_FREE);
 	VWMB();
 
-	vsm_head = loghead;
-	vsm_end = (uint8_t*)loghead + size;
+	vsm_end = (void*)((uint8_t*)vsm_head + size);
 
 	VSL_stats = VSM_Alloc(sizeof *VSL_stats,
 	    VSC_CLASS, VSC_TYPE_MAIN, "");
 	AN(VSL_stats);
 
-	pp = VSM_Alloc(sizeof *pp, "Params", "", "");
+	pp = VSM_Alloc(sizeof *pp, VSM_CLASS_PARAM, "", "");
 	AN(pp);
 	*pp = *params;
 	params = pp;
@@ -311,8 +309,8 @@
 	VWMB();
 
 	do
-		loghead->alloc_seq = random();
-	while (loghead->alloc_seq == 0);
+		vsm_head->alloc_seq = random();
+	while (vsm_head->alloc_seq == 0);
 
 }
 
@@ -320,5 +318,5 @@
 mgt_SHM_Pid(void)
 {
 
-	loghead->master_pid = getpid();
+	vsm_head->master_pid = getpid();
 }

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2010-06-16 12:25:46 UTC (rev 4964)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2010-06-16 12:47:07 UTC (rev 4965)
@@ -631,6 +631,8 @@
 	if (T_arg != NULL)
 		mgt_cli_telnet(T_arg);
 
+	VSM_Alloc(0, VSM_CLASS_MARK, "", "");
+
 	MGT_Run();
 
 	if (pfh != NULL)

Modified: trunk/varnish-cache/bin/varnishd/vsm.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/vsm.c	2010-06-16 12:25:46 UTC (rev 4964)
+++ trunk/varnish-cache/bin/varnishd/vsm.c	2010-06-16 12:47:07 UTC (rev 4965)
@@ -45,8 +45,31 @@
 #include "vmb.h"
 
 struct vsm_head		*vsm_head;
-void			*vsm_end;
+const struct vsm_chunk	*vsm_end;
 
+static unsigned
+vsm_mark(void)
+{
+	unsigned seq;
+
+	seq = vsm_head->alloc_seq;
+	vsm_head->alloc_seq = 0;
+	VWMB();
+	return (seq);
+}
+
+static void
+vsm_release(unsigned seq)
+{
+
+	if (seq == 0)
+		return;
+	VWMB();
+	do
+		vsm_head->alloc_seq = ++seq;
+	while (vsm_head->alloc_seq == 0);
+}
+
 /*--------------------------------------------------------------------*/
 
 struct vsm_chunk *
@@ -65,7 +88,7 @@
 	CHECK_OBJ_NOTNULL(vsm_head, VSM_HEAD_MAGIC);
 	CHECK_OBJ_NOTNULL(*pp, VSM_CHUNK_MAGIC);
 	*pp = VSM_NEXT(*pp);
-	if ((void*)(*pp) >= vsm_end) {
+	if (*pp >= vsm_end) {
 		*pp = NULL;
 		return;
 	}
@@ -74,6 +97,63 @@
 
 /*--------------------------------------------------------------------*/
 
+static void
+vsm_cleanup(void)
+{
+	unsigned now = (unsigned)TIM_mono();
+	struct vsm_chunk *sha, *sha2;
+	unsigned seq;
+
+	CHECK_OBJ_NOTNULL(vsm_head, VSM_HEAD_MAGIC);
+	VSM_ITER(sha) {
+		if (strcmp(sha->class, VSM_CLASS_COOL))
+			continue;
+		if (sha->state + VSM_COOL_TIME < now)
+			break;
+	}
+	if (sha == NULL)
+		return;
+	seq = vsm_mark();
+	/* First pass, free, and collaps with next if applicable */
+	VSM_ITER(sha) {
+		if (strcmp(sha->class, VSM_CLASS_COOL))
+			continue;
+		if (sha->state + VSM_COOL_TIME >= now)
+			continue;
+
+		bprintf(sha->class, "%s", VSM_CLASS_FREE);
+		bprintf(sha->type, "%s", "");
+		bprintf(sha->ident, "%s", "");
+		sha2 = VSM_NEXT(sha);
+		assert(sha2 <= vsm_end);
+		if (sha2 == vsm_end)
+			break;
+		CHECK_OBJ_NOTNULL(sha2, VSM_CHUNK_MAGIC);
+		if (!strcmp(sha2->class, VSM_CLASS_FREE)) {
+			sha->len += sha2->len;
+			memset(sha2, 0, sizeof *sha2);
+		}
+		sha->state = 0;
+	}
+	/* Second pass, collaps with prev if applicable */
+	VSM_ITER(sha) {
+		if (strcmp(sha->class, VSM_CLASS_FREE))
+			continue;
+		sha2 = VSM_NEXT(sha);
+		assert(sha2 <= vsm_end);
+		if (sha2 == vsm_end)
+			break;
+		CHECK_OBJ_NOTNULL(sha2, VSM_CHUNK_MAGIC);
+		if (!strcmp(sha2->class, VSM_CLASS_FREE)) {
+			sha->len += sha2->len;
+			memset(sha2, 0, sizeof *sha2);
+		}
+	}
+	vsm_release(seq);
+}
+
+/*--------------------------------------------------------------------*/
+
 void *
 VSM_Alloc(unsigned size, const char *class, const char *type, const char *ident)
 {
@@ -82,6 +162,8 @@
 
 	CHECK_OBJ_NOTNULL(vsm_head, VSM_HEAD_MAGIC);
 
+	vsm_cleanup();
+
 	/* Round up to pointersize */
 	size += sizeof(void *) - 1;
 	size &= ~(sizeof(void *) - 1);
@@ -91,35 +173,77 @@
 	VSM_ITER(sha) {
 		CHECK_OBJ_NOTNULL(sha, VSM_CHUNK_MAGIC);
 
-		if (strcmp(sha->class, "Free"))
+		if (strcmp(sha->class, VSM_CLASS_FREE))
 			continue;
 
-		xxxassert(size <= sha->len);
+		if (size > sha->len)
+			continue;
 
-		sha2 = (void*)((uintptr_t)sha + size);
+			/* Mark as inconsistent while we write string fields */
+		seq = vsm_mark();
 
-		/* Mark as inconsistent while we write string fields */
-		seq = vsm_head->alloc_seq;
-		vsm_head->alloc_seq = 0;
-		VWMB();
+		if (size < sha->len) {
+			sha2 = (void*)((uintptr_t)sha + size);
 
-		memset(sha2, 0, sizeof *sha2);
-		sha2->magic = VSM_CHUNK_MAGIC;
-		sha2->len = sha->len - size;
-		bprintf(sha2->class, "%s", "Free");
+			memset(sha2, 0, sizeof *sha2);
+			sha2->magic = VSM_CHUNK_MAGIC;
+			sha2->len = sha->len - size;
+			bprintf(sha2->class, "%s", VSM_CLASS_FREE);
+			sha->len = size;
+		}
 
-		sha->len = size;
 		bprintf(sha->class, "%s", class);
 		bprintf(sha->type, "%s", type);
 		bprintf(sha->ident, "%s", ident);
 
-		VWMB();
-		if (seq != 0)
-			do
-				loghead->alloc_seq = ++seq;
-			while (loghead->alloc_seq == 0);
-
+		vsm_release(seq);
 		return (VSM_PTR(sha));
 	}
 	return (NULL);
 }
+
+/*--------------------------------------------------------------------*/
+
+void
+VSM_Free(const void *ptr)
+{
+	struct vsm_chunk *sha;
+	unsigned seq;
+
+	CHECK_OBJ_NOTNULL(vsm_head, VSM_HEAD_MAGIC);
+	VSM_ITER(sha)
+		if (VSM_PTR(sha) == ptr)
+			break;
+	AN(sha);
+	seq = vsm_mark();
+	bprintf(sha->class, "%s", VSM_CLASS_COOL);
+	sha->state = (unsigned)TIM_mono();
+	vsm_release(seq);
+}
+
+/*--------------------------------------------------------------------
+ * Free all allocations after the mark (ie: allocated by child).
+ */
+
+void
+VSM_Clean(void)
+{
+	struct vsm_chunk *sha;
+	unsigned f, seq;
+
+	CHECK_OBJ_NOTNULL(vsm_head, VSM_HEAD_MAGIC);
+	f = 0;
+	seq = vsm_mark();
+	VSM_ITER(sha) {
+		if (f == 0 && !strcmp(sha->class, VSM_CLASS_MARK)) {
+			f = 1;
+			continue;
+		}
+		if (f == 0)
+			continue;
+		if (strcmp(sha->class, VSM_CLASS_FREE) &&
+		    strcmp(sha->class, VSM_CLASS_COOL))
+			VSM_Free(VSM_PTR(sha));
+	}
+	vsm_release(seq);
+}




More information about the varnish-commit mailing list