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