char *f; /* (F)ree pointer */
char *r; /* (R)eserved length */
char *e; /* (E)nd of buffer */
+ int overflow; /* workspace overflowed */
};
/*--------------------------------------------------------------------
int HSH_Compare(const struct sess *sp, const struct objhead *o);
void HSH_Copy(const struct sess *sp, const struct objhead *o);
struct object *HSH_Lookup(struct sess *sp);
-void HSH_Unbusy(struct object *o);
+void HSH_Unbusy(struct sess *sp);
void HSH_Ref(struct object *o);
void HSH_Deref(struct object *o);
void HSH_Init(void);
char *WS_Alloc(struct ws *ws, unsigned bytes);
char *WS_Dup(struct ws *ws, const char *);
char *WS_Snapshot(struct ws *ws);
+unsigned WS_Used(struct ws *ws);
/* rfc2616.c */
int RFC2616_cache_policy(const struct sess *sp, const struct http *hp);
case VCL_RET_RESTART:
sp->obj->ttl = 0;
sp->obj->cacheable = 0;
- HSH_Unbusy(sp->obj);
+ HSH_Unbusy(sp);
HSH_Deref(sp->obj);
sp->obj = NULL;
if (sp->handling == VCL_RET_ERROR)
if (sp->obj->objhead != NULL) {
VRY_Create(sp);
EXP_Insert(sp->obj, sp->wrk->used);
- HSH_Unbusy(sp->obj);
+ HSH_Unbusy(sp);
}
sp->wrk->acct.fetch++;
sp->step = STP_DELIVER;
VCL_miss_method(sp);
if (sp->handling == VCL_RET_ERROR) {
sp->obj->cacheable = 0;
- HSH_Unbusy(sp->obj);
+ HSH_Unbusy(sp);
HSH_Deref(sp->obj);
sp->obj = NULL;
VBE_free_bereq(sp->bereq);
}
if (sp->handling == VCL_RET_PASS) {
sp->obj->cacheable = 0;
- HSH_Unbusy(sp->obj);
+ HSH_Unbusy(sp);
HSH_Deref(sp->obj);
sp->obj = NULL;
sp->step = STP_PASS;
}
void
-HSH_Unbusy(struct object *o)
+HSH_Unbusy(struct sess *sp)
{
+ struct object *o;
struct objhead *oh;
struct object *parent;
+ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ o = sp->obj;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
assert(o->busy);
assert(o->refcnt > 0);
+ if (o->ws_o->overflow)
+ VSL_stats->n_objoverflow++;
+ if (params->diag_bitmap & 0x40)
+ WSP(sp, SLT_Debug,
+ "Object workspace used %u", WS_Used(o->ws_o));
+
oh = o->objhead;
if (oh != NULL) {
CHECK_OBJ(oh, OBJHEAD_MAGIC);
if (r != 0)
return;
+ if (params->diag_bitmap & 0x40)
+ VSL(SLT_Debug, 0,
+ "Object workspace max used %u", WS_Used(o->ws_o));
+
if (o->vary != NULL)
free(o->vary);
WS_Assert(ws);
assert(ws->r == NULL);
- if (ws->f + bytes > ws->e)
+ if (ws->f + bytes > ws->e) {
+ ws->overflow++;
return(NULL);
+ }
r = ws->f;
ws->f += bytes;
WS_DEBUG("WS_Alloc(%p, %u) = %p", ws, bytes, r);
return (p);
}
+unsigned
+WS_Used(struct ws *ws)
+{
+
+ WS_Assert(ws);
+ return(ws->f - ws->s);
+}
+
char *
WS_Snapshot(struct ws *ws)
{
" 0x00000008 - mutex logging.\n"
" 0x00000010 - mutex contests.\n"
" 0x00000020 - waiting list.\n"
+ " 0x00000040 - object workspace.\n"
"Use 0x notation and do the bitor in your head :-)\n",
0,
"0", "bitmap" },
MAC_STAT(n_objsendfile, uint64_t, 'a', "Objects sent with sendfile")
MAC_STAT(n_objwrite, uint64_t, 'a', "Objects sent with write")
+MAC_STAT(n_objoverflow, uint64_t, 'a', "Objects overflowing workspace")
MAC_STAT(s_sess, uint64_t, 'a', "Total Sessions")
MAC_STAT(s_req, uint64_t, 'a', "Total Requests")