vbp_task(struct worker *wrk, void *priv)
{
	struct vbp_target *vt;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	CAST_OBJ_NOTNULL(vt, priv, VBP_TARGET_MAGIC);

	AN(vt->running);
	AN(vt->req);
	assert(vt->req_len > 0);

	vbp_start_poke(vt);
	vbp_poke(vt);
	vbp_has_poked(vt);
	VBP_Update_Backend(vt);

	Lck_Lock(&vbp_mtx);
	if (vt->running < 0) {
		assert(vt->heap_idx == BINHEAP_NOIDX);
		vbp_delete(vt);
	} else {
		vt->running = 0;
		if (vt->heap_idx != BINHEAP_NOIDX) {
			vt->due = VTIM_real() + vt->interval;
			binheap_delete(vbp_heap, vt->heap_idx);
			binheap_insert(vbp_heap, vt);
		}
	}
	Lck_Unlock(&vbp_mtx);
}
vbp_thread(struct worker *wrk, void *priv)
{
	vtim_real now, nxt;
	struct vbp_target *vt;

	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
	AZ(priv);
	Lck_Lock(&vbp_mtx);
	while (1) {
		now = VTIM_real();
		vt = binheap_root(vbp_heap);
		if (vt == NULL) {
			nxt = 8.192 + now;
			(void)Lck_CondWait(&vbp_cond, &vbp_mtx, nxt);
		} else if (vt->due > now) {
			nxt = vt->due;
			vt = NULL;
			(void)Lck_CondWait(&vbp_cond, &vbp_mtx, nxt);
		} else {
			binheap_delete(vbp_heap, vt->heap_idx);
			vt->due = now + vt->interval;
			if (!vt->running) {
				vt->running = 1;
				vt->task.func = vbp_task;
				vt->task.priv = vt;
				if (Pool_Task_Any(&vt->task, TASK_QUEUE_REQ))
					vt->running = 0;
			}
			binheap_insert(vbp_heap, vt);
		}
	}
	NEEDLESS(Lck_Unlock(&vbp_mtx));
	NEEDLESS(return NULL);
}
void
EXP_Rearm(const struct object *o)
{
	struct objcore *oc;

	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
	oc = o->objcore;
	if (oc == NULL)
		return;
	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
	Lck_Lock(&exp_mtx);
	/*
	 * The hang-man might have this object of the binheap while
	 * tending to a timer.  If so, we do not muck with it here.
	 */
	if (oc->timer_idx != BINHEAP_NOIDX && update_object_when(o)) {
		/*
		 * XXX: this could possibly be optimized by shuffling
		 * XXX: up or down, but that leaves some very nasty
		 * XXX: corner cases, such as shuffling all the way
		 * XXX: down the left half, then back up the right half.
		 */
		assert(oc->timer_idx != BINHEAP_NOIDX);
		binheap_delete(exp_heap, oc->timer_idx);
		assert(oc->timer_idx == BINHEAP_NOIDX);
		binheap_insert(exp_heap, oc);
		assert(oc->timer_idx != BINHEAP_NOIDX);
	}
	Lck_Unlock(&exp_mtx);
	if (o->smp_object != NULL)
		SMP_TTLchanged(o);
}
示例#4
0
int
Wait_HeapDelete(const struct waiter *w, const struct waited *wp)
{
	CHECK_OBJ_NOTNULL(w, WAITER_MAGIC);
	CHECK_OBJ_NOTNULL(wp, WAITED_MAGIC);
	if (wp->idx == BINHEAP_NOIDX)
		return (0);
	binheap_delete(w->heap, wp->idx);
	return (1);
}
static void *
exp_timer(struct sess *sp, void *priv)
{
	struct objcore *oc;
	struct object *o;
	double t;
	struct objcore_head *lru;

	(void)priv;
	AZ(sleep(10));		/* XXX: Takes time for VCL to arrive */
	VCL_Get(&sp->vcl);
	t = TIM_real();
	while (1) {
		Lck_Lock(&exp_mtx);
		oc = binheap_root(exp_heap);
		CHECK_OBJ_ORNULL(oc, OBJCORE_MAGIC);
		if (oc == NULL || oc->timer_when > t) { /* XXX: > or >= ? */
			Lck_Unlock(&exp_mtx);
			WSL_Flush(sp->wrk, 0);
			WRK_SumStat(sp->wrk);
			AZ(sleep(1));
			VCL_Refresh(&sp->vcl);
			t = TIM_real();
			continue;
		}

		o = oc->obj;
		CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
		CHECK_OBJ_NOTNULL(o->objhead, OBJHEAD_MAGIC);
		assert(oc->flags & OC_F_ONLRU);
		assert(oc->timer_idx != BINHEAP_NOIDX);
		binheap_delete(exp_heap, oc->timer_idx);
		assert(oc->timer_idx == BINHEAP_NOIDX);
		lru = STV_lru(o->objstore);
		AN(lru);
		VTAILQ_REMOVE(lru, o->objcore, lru_list);
		oc->flags &= ~OC_F_ONLRU;

		{	/* Sanity checking */
			struct objcore *oc2 = binheap_root(exp_heap);
			if (oc2 != NULL) {
				assert(oc2->timer_idx != BINHEAP_NOIDX);
				assert(oc2->timer_when >= oc->timer_when);
			}
		}

		VSL_stats->n_expired++;
		Lck_Unlock(&exp_mtx);
		WSL(sp->wrk, SLT_ExpKill, 0, "%u %d",
		    o->xid, (int)(o->ttl - t));
		HSH_Deref(sp->wrk, &o);
	}
}
示例#6
0
static void
exp_inbox(struct exp_priv *ep, struct objcore *oc, unsigned flags)
{

	CHECK_OBJ_NOTNULL(ep, EXP_PRIV_MAGIC);
	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
	assert(oc->refcnt > 0);

	VSLb(&ep->vsl, SLT_ExpKill, "EXP_Inbox flg=%x p=%p e=%.9f f=0x%x",
	    flags, oc, oc->timer_when, oc->flags);

	if (flags & OC_EF_REMOVE) {
		if (!(flags & OC_EF_INSERT)) {
			assert(oc->timer_idx != BINHEAP_NOIDX);
			binheap_delete(ep->heap, oc->timer_idx);
		}
		assert(oc->timer_idx == BINHEAP_NOIDX);
		assert(oc->refcnt > 0);
		AZ(oc->exp_flags);
		ObjSendEvent(ep->wrk, oc, OEV_EXPIRE);
		(void)HSH_DerefObjCore(ep->wrk, &oc, 0);
		return;
	}

	if (flags & OC_EF_MOVE) {
		oc->timer_when = EXP_WHEN(oc);
		ObjSendEvent(ep->wrk, oc, OEV_TTLCHG);
	}

	VSLb(&ep->vsl, SLT_ExpKill, "EXP_When p=%p e=%.9f f=0x%x", oc,
	    oc->timer_when, flags);

	/*
	 * XXX: There are some pathological cases here, were we
	 * XXX: insert or move an expired object, only to find out
	 * XXX: the next moment and rip them out again.
	 */

	if (flags & OC_EF_INSERT) {
		assert(oc->timer_idx == BINHEAP_NOIDX);
		binheap_insert(exphdl->heap, oc);
		assert(oc->timer_idx != BINHEAP_NOIDX);
	} else if (flags & OC_EF_MOVE) {
		assert(oc->timer_idx != BINHEAP_NOIDX);
		binheap_reorder(exphdl->heap, oc->timer_idx);
		assert(oc->timer_idx != BINHEAP_NOIDX);
	} else {
		WRONG("Objcore state wrong in inbox");
	}
}
示例#7
0
static double
exp_expire(struct exp_priv *ep, double now)
{
	struct objcore *oc;

	CHECK_OBJ_NOTNULL(ep, EXP_PRIV_MAGIC);

	oc = binheap_root(ep->heap);
	if (oc == NULL)
		return (now + 355./113.);
	VSLb(&ep->vsl, SLT_ExpKill, "EXP_expire p=%p e=%.9f f=0x%x", oc,
	    oc->timer_when - now, oc->flags);

	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);

	/* Ready ? */
	if (oc->timer_when > now)
		return (oc->timer_when);

	VSC_C_main->n_expired++;

	Lck_Lock(&ep->mtx);
	if (oc->exp_flags & OC_EF_POSTED) {
		oc->exp_flags |= OC_EF_REMOVE;
		oc = NULL;
	} else {
		oc->exp_flags &= ~OC_EF_REFD;
	}
	Lck_Unlock(&ep->mtx);
	if (oc != NULL) {
		if (!(oc->flags & OC_F_DYING))
			HSH_Kill(oc);

		/* Remove from binheap */
		assert(oc->timer_idx != BINHEAP_NOIDX);
		binheap_delete(ep->heap, oc->timer_idx);
		assert(oc->timer_idx == BINHEAP_NOIDX);

		CHECK_OBJ_NOTNULL(oc->objhead, OBJHEAD_MAGIC);
		VSLb(&ep->vsl, SLT_ExpKill, "EXP_Expired x=%u t=%.0f",
		    ObjGetXID(ep->wrk, oc), EXP_Ttl(NULL, oc) - now);
		ObjSendEvent(ep->wrk, oc, OEV_EXPIRE);
		(void)HSH_DerefObjCore(ep->wrk, &oc, 0);
	}
	return (0);
}
void
VBP_Control(const struct backend *be, int enable)
{
	struct vbp_target *vt;

	CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
	vt = be->probe;
	CHECK_OBJ_NOTNULL(vt, VBP_TARGET_MAGIC);

	vbp_reset(vt);
	VBP_Update_Backend(vt);

	Lck_Lock(&vbp_mtx);
	if (enable) {
		assert(vt->heap_idx == BINHEAP_NOIDX);
		vt->due = VTIM_real();
		binheap_insert(vbp_heap, vt);
		AZ(pthread_cond_signal(&vbp_cond));
	} else {
		assert(vt->heap_idx != BINHEAP_NOIDX);
		binheap_delete(vbp_heap, vt->heap_idx);
	}
	Lck_Unlock(&vbp_mtx);
}
示例#9
0
int main(int argc, char *argv[])
{
    binheap_t h;
    int32_t a[1024];
    int32_t i, j, r;
    int32_t parent, child;
    binheap_node_t *nodes[1024];
    
    for (i = 0; i < 1024; i++) {
        a[i] = 1024 - i;
    }
    
    binheap_init(&h, compare_int, NULL);
    for (i = 0; i < 1024; i++) {
        binheap_insert(&h, a + i);
    }
    
    for (i = 0; i < 1024; i++) {
        parent = (i - 1) / 2;
        child = (2 * i) + 1;
        if (!i) {
            if (*(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                printf("Error follows:\n");
            }
            printf("%4d:      %4d %4d %4d\n",
                   h.array[i]->index,
                   *(int *) h.array[i]->datum,
                   *(int *) h.array[child]->datum,
                   *(int *) h.array[child + 1]->datum);
        } else if (i < (h.size - 1) / 2) {
            if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum ||
                *(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                printf("Error follows:\n");
            }
            printf("%4d: %4d %4d %4d %4d\n",
                   h.array[i]->index,
                   *(int *) h.array[parent]->datum,
                   *(int *) h.array[i]->datum,
                   *(int *) h.array[child]->datum,
                   *(int *) h.array[child + 1]->datum);
        } else {
            if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum) {
                printf("Error follows:\n");
            }
            printf("%4d: %4d %4d\n",
                   h.array[i]->index,
                   *(int *) h.array[parent]->datum,
                   *(int *) h.array[i]->datum);
        }
    }
    
    binheap_delete(&h);
    
    binheap_init_from_array(&h, a, sizeof (*a), 1024, compare_int, NULL);
    
    for (i = 0; i < 1024; i++) {
        parent = (i - 1) / 2;
        child = (2 * i) + 1;
        if (!i) {
            if (*(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                printf("Error follows:\n");
            }
            printf("%4d:      %4d %4d %4d\n",
                   h.array[i]->index,
                   *(int *) h.array[i]->datum,
                   *(int *) h.array[child]->datum,
                   *(int *) h.array[child + 1]->datum);
        } else if (i < (h.size - 1) / 2) {
            if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum ||
                *(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                printf("Error follows:\n");
            }
            printf("%4d: %4d %4d %4d %4d\n",
                   h.array[i]->index,
                   *(int *) h.array[parent]->datum,
                   *(int *) h.array[i]->datum,
                   *(int *) h.array[child]->datum,
                   *(int *) h.array[child + 1]->datum);
        } else {
            if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum) {
                printf("Error follows:\n");
            }
            printf("%4d: %4d %4d\n",
                   h.array[i]->index,
                   *(int *) h.array[parent]->datum,
                   *(int *) h.array[i]->datum);
        }
    }
    
    while (!binheap_is_empty(&h)) {
        binheap_remove_min(&h);
        
        for (i = 0; i < h.size; i++) {
            parent = (i - 1) / 2;
            child = (2 * i) + 1;
            if (h.size == 1) {
                printf("%4d:      %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[i]->datum);
            } else if (!i) {
                if (*(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                    *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                    printf("Error follows:\n");
                }
                printf("%4d:      %4d %4d %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[i]->datum,
                       *(int *) h.array[child]->datum,
                       *(int *) h.array[child + 1]->datum);
            } else if (i < (h.size - 1) / 2) {
                if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum ||
                    *(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                    *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                    printf("Error follows:\n");
                }
                printf("%4d: %4d %4d %4d %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[parent]->datum,
                       *(int *) h.array[i]->datum,
                       *(int *) h.array[child]->datum,
                       *(int *) h.array[child + 1]->datum);
            } else {
                if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum) {
                    printf("Error follows:\n");
                }
                printf("%4d: %4d %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[parent]->datum,
                       *(int *) h.array[i]->datum);
            }
        }
    }
    
    binheap_delete(&h);
    
    binheap_init(&h, compare_int, NULL);
    for (i = 0; i < 1024; i++) {
        nodes[i] = binheap_insert(&h, a + i);
    }
    
    for (i = 0; i < 1024; i++) {
        printf("%d\n", *(int *) nodes[i]->datum);
    }
    
    for (j = 0; j < 1; j++) {
        r = 1020;
        a[r] = 0;
        binheap_decrease_key(&h, nodes[r]);
        for (i = 0; i < h.size; i++) {
            parent = (i - 1) / 2;
            child = (2 * i) + 1;
            if (h.size == 1) {
                printf("%4d:      %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[i]->datum);
            } else if (!i) {
                if (*(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                    *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                    printf("Error follows:\n");
                }
                printf("%4d:      %4d %4d %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[i]->datum,
                       *(int *) h.array[child]->datum,
                       *(int *) h.array[child + 1]->datum);
            } else if (i < (h.size - 1) / 2) {
                if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum ||
                    *(int *) h.array[i]->datum > *(int *) h.array[child]->datum ||
                    *(int *) h.array[i]->datum > *(int *) h.array[child + 1]->datum) {
                    printf("Error follows:\n");
                }
                printf("%4d: %4d %4d %4d %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[parent]->datum,
                       *(int *) h.array[i]->datum,
                       *(int *) h.array[child]->datum,
                       *(int *) h.array[child + 1]->datum);
            } else {
                if (*(int *) h.array[i]->datum < *(int *) h.array[parent]->datum) {
                    printf("Error follows:\n");
                }
                printf("%4d: %4d %4d\n",
                       h.array[i]->index,
                       *(int *) h.array[parent]->datum,
                       *(int *) h.array[i]->datum);
            }
        }
    }
    
    binheap_delete(&h);
    
    return 0;
}