/*--------------------------------------------------------------------*/
static void
-phk(struct smf *sp)
+phk(struct smf_sc *sc, struct smf *sp)
{
struct smf *sp2;
+ size_t b;
+
+ CHECK_OBJ_NOTNULL(sp, SMF_MAGIC);
+ return;
+ assert(sp->size > 0);
sp2 = TAILQ_NEXT(sp, order);
if (sp2 != NULL) {
+ CHECK_OBJ(sp2, SMF_MAGIC);
assert(sp2->offset > sp->offset);
assert(sp2->ptr > sp->ptr);
}
sp2 = TAILQ_PREV(sp, smfhead, order);
if (sp2 != NULL) {
+ CHECK_OBJ(sp2, SMF_MAGIC);
assert(sp2->offset < sp->offset);
assert(sp2->ptr < sp->ptr);
}
+ if (sp->flist != NULL) {
+ b = sp->size / sc->pagesize;
+ if (b >= NBUCKET)
+ b = NBUCKET - 1;
+ assert(sp->flist == &sc->free[b]);
+ }
}
/*--------------------------------------------------------------------
static void
insfree(struct smf_sc *sc, struct smf *sp)
{
- unsigned b, n;
+ size_t b;
struct smf *sp2;
+ size_t ns;
- phk(sp);
+ phk(sc, sp);
assert(sp->alloc == 0);
assert(sp->flist == NULL);
b = sp->size / sc->pagesize;
VSL_stats->n_smf_frag++;
}
sp->flist = &sc->free[b];
- n = 0;
+ ns = b * sc->pagesize;
TAILQ_FOREACH(sp2, sp->flist, status) {
+ phk(sc, sp2);
+ assert(sp2->size >= ns);
assert(sp2->alloc == 0);
assert(sp2->flist == sp->flist);
- if (sp->offset < sp2->offset) {
- TAILQ_INSERT_BEFORE(sp2, sp, status);
+ if (sp->offset < sp2->offset)
break;
- }
- n++;
}
if (sp2 == NULL)
TAILQ_INSERT_TAIL(sp->flist, sp, status);
+ else
+ TAILQ_INSERT_BEFORE(sp2, sp, status);
+ phk(sc, sp);
}
static void
remfree(struct smf_sc *sc, struct smf *sp)
{
- unsigned b;
+ size_t b;
- phk(sp);
+ phk(sc, sp);
assert(sp->alloc == 0);
assert(sp->flist != NULL);
b = sp->size / sc->pagesize;
assert(sp->flist == &sc->free[b]);
TAILQ_REMOVE(sp->flist, sp, status);
sp->flist = NULL;
+ phk(sc, sp);
}
/*--------------------------------------------------------------------
alloc_smf(struct smf_sc *sc, size_t bytes)
{
struct smf *sp, *sp2;
- unsigned b;
- int n;
+ size_t b;
+ assert(!(bytes % sc->pagesize));
b = bytes / sc->pagesize;
if (b >= NBUCKET)
b = NBUCKET - 1;
- n = 0;
- for (sp = NULL; sp == NULL && b < NBUCKET; b++) {
+ for (sp = NULL; b < NBUCKET - 1; b++) {
sp = TAILQ_FIRST(&sc->free[b]);
- n++;
+ if (sp != NULL)
+ break;
+ }
+ if (sp == NULL) {
+ TAILQ_FOREACH(sp, &sc->free[NBUCKET -1], status)
+ if (sp->size >= bytes)
+ break;
}
if (sp == NULL)
return (sp);
+ phk(sc, sp);
+ assert(sp->size >= bytes);
remfree(sc, sp);
+ phk(sc, sp);
if (sp->size == bytes) {
sp->alloc = 1;
TAILQ_INSERT_TAIL(&sc->used, sp, status);
sp2->size = bytes;
sp2->alloc = 1;
+ phk(sc, sp);
TAILQ_INSERT_BEFORE(sp, sp2, order);
+ phk(sc, sp);
+ phk(sc, sp2);
TAILQ_INSERT_TAIL(&sc->used, sp2, status);
insfree(sc, sp);
- phk(sp);
- phk(sp2);
+ phk(sc, sp);
+ phk(sc, sp2);
return (sp2);
}
CHECK_OBJ_NOTNULL(sp, SMF_MAGIC);
assert(sp->alloc != 0);
+ assert(sp->size > 0);
+ assert(!(sp->size % sc->pagesize));
TAILQ_REMOVE(&sc->used, sp, status);
sp->alloc = 0;
- phk(sp);
+ phk(sc, sp);
sp2 = TAILQ_NEXT(sp, order);
+ if (sp2 != NULL)
+ phk(sc, sp2);
if (sp2 != NULL &&
sp2->alloc == 0 &&
(sp2->ptr == sp->ptr + sp->size) &&
remfree(sc, sp2);
free(sp2);
VSL_stats->n_smf--;
+ phk(sc, sp);
}
sp2 = TAILQ_PREV(sp, smfhead, order);
+ if (sp2 != NULL)
+ phk(sc, sp2);
if (sp2 != NULL &&
sp2->alloc == 0 &&
(sp->ptr == sp2->ptr + sp2->size) &&
free(sp);
VSL_stats->n_smf--;
sp = sp2;
+ phk(sc, sp);
}
insfree(sc, sp);
struct smf *sp2;
struct smf_sc *sc = sp->sc;
- phk(sp);
+ phk(sc, sp);
assert(sp->alloc != 0);
assert(bytes > 0);
+ assert(bytes < sp->size);
+ assert(!(bytes % sc->pagesize));
+ assert(!(sp->size % sc->pagesize));
CHECK_OBJ_NOTNULL(sp, SMF_MAGIC);
sp2 = malloc(sizeof *sp2);
XXXAN(sp2);
sp->size = bytes;
sp2->ptr += bytes;
sp2->offset += bytes;
- TAILQ_INSERT_TAIL(&sc->used, sp2, status);
TAILQ_INSERT_AFTER(&sc->order, sp, sp2, order);
+ TAILQ_INSERT_TAIL(&sc->used, sp2, status);
free_smf(sp2);
}
sp->alloc = 1;
TAILQ_FOREACH(sp2, &sc->order, order) {
+ phk(sc, sp2);
if (sp->ptr < sp2->ptr) {
TAILQ_INSERT_BEFORE(sp2, sp, order);
break;
struct smf *smf;
struct smf_sc *sc = st->priv;
+ assert(size > 0);
size += (sc->pagesize - 1);
size &= ~(sc->pagesize - 1);
LOCK(&sc->mtx);
struct smf_sc *sc;
CHECK_OBJ_NOTNULL(s, STORAGE_MAGIC);
- if (size == 0) {
- /* XXX: this should not happen */
- return;
- }
+ assert(size > 0);
assert(size <= s->space);
xxxassert(size > 0); /* XXX: seen */
CAST_OBJ_NOTNULL(smf, s->priv, SMF_MAGIC);