void sl_free(void *);
void sl_delete(slab *);
-/* A whole stonehenge of slabs */
-
-typedef struct stonehenge stonehenge;
-typedef struct sth_block {
- void *block;
- bool large;
-} sth_block;
-
-stonehenge *sth_new(pool *);
-sth_block sth_alloc(stonehenge *, uint size);
-sth_block sth_allocz(stonehenge *, uint size);
-void sth_free(sth_block);
-void sth_delete(stonehenge *);
-
/*
* Low-level memory allocation functions, please don't use
* outside resource manager and possibly sysdep code.
return NULL;
}
-static const uint stonehenge_sizes[] = { 56, 112, 168, 288, 448, 800, 1344 };
-
-struct stonehenge {
- pool *p;
- slab *s[ARRAY_SIZE(stonehenge_sizes)];
-};
-
-sth_block
-sth_alloc(stonehenge *sth, uint size)
-{
- for (uint i=0; i<ARRAY_SIZE(stonehenge_sizes); i++)
- if (size <= stonehenge_sizes[i])
- {
- if (!sth->s[i])
- sth->s[i] = sl_new(sth->p, stonehenge_sizes[i]);
-
- return (sth_block) { .block = sl_alloc(sth->s[i]), };
- }
-
- return (sth_block) {
- .block = mb_alloc(sth->p, size),
- .large = 1,
- };
-}
-
-sth_block
-sth_allocz(stonehenge *sth, uint size)
-{
- sth_block b = sth_alloc(sth, size);
- bzero(b.block, size);
- return b;
-}
-
-void
-sth_free(sth_block b)
-{
- if (b.large)
- mb_free(b.block);
- else
- sl_free(b.block);
-}
-
-stonehenge *
-sth_new(pool *pp)
-{
- stonehenge tmps = {
- .p = rp_new(pp, pp->domain, "Stonehenge"),
- };
-
- stonehenge *s = sth_alloc(&tmps, sizeof(stonehenge)).block;
- *s = tmps;
- return s;
-}
-
-void sth_delete(stonehenge *s)
-{
- pool *p = s->p;
- sth_free((sth_block) { s });
- rp_free(p);
-}
-
-
#endif
pool *rta_pool;
-static stonehenge *ea_sth;
+/* Assuming page size of 4096, these are magic values for slab allocation */
+static const uint ea_slab_sizes[] = { 56, 112, 168, 288, 448, 800, 1344 };
+static slab *ea_slab[ARRAY_SIZE(ea_slab_sizes)];
static slab *rte_src_slab;
return rr;
}
+ struct ea_storage *r = NULL;
uint elen = ea_list_size(o);
uint sz = elen + sizeof(struct ea_storage);
- sth_block b = sth_alloc(ea_sth, sz);
+ for (uint i=0; i<ARRAY_SIZE(ea_slab_sizes); i++)
+ if (sz <= ea_slab_sizes[i])
+ {
+ r = sl_alloc(ea_slab[i]);
+ break;
+ }
- struct ea_storage *r = b.block;
+ int huge = r ? 0 : EALF_HUGE;;
+ if (huge)
+ r = mb_alloc(rta_pool, sz);
ea_list_copy(r->l, o, elen);
ea_list_ref(r->l);
- if (b.large)
- r->l->flags |= EALF_HUGE;
-
+ r->l->flags |= huge;
r->l->stored = oid;
r->hash_key = h;
atomic_store_explicit(&r->uc, 1, memory_order_release);
/* And now we can free the object, finally */
ea_list_unref(r->l);
- sth_free((sth_block) { r, !!(r->l->flags & EALF_HUGE) });
+ if (r->l->flags & EALF_HUGE)
+ mb_free(r);
+ else
+ sl_free(r);
RTA_UNLOCK;
}
RTA_LOCK;
rta_pool = rp_new(&root_pool, attrs_domain.attrs, "Attributes");
- ea_sth = sth_new(rta_pool);
+ for (uint i=0; i<ARRAY_SIZE(ea_slab_sizes); i++)
+ ea_slab[i] = sl_new(rta_pool, ea_slab_sizes[i]);
+
SPINHASH_INIT(rta_hash_table, RTAH, rta_pool, &global_work_list);
rte_src_init();
uint size = sizeof(struct bgp_bucket) + ea_size;
/* Allocate the bucket */
- sth_block blk = sth_alloc(c->sth, size);
- b = blk.block;
+ b = mb_alloc(c->pool, size);
*b = (struct bgp_bucket) { };
init_list(&b->prefixes);
b->hash = hash;
/* Copy the ea_list */
ea_list_copy(b->eattrs, new, ea_size);
- if (blk.large)
- b->eattrs->flags |= EALF_HUGE;
/* Insert the bucket to bucket hash */
HASH_INSERT2(c->bucket_hash, RBH, c->pool, b);
bgp_free_bucket(struct bgp_ptx_private *c, struct bgp_bucket *b)
{
HASH_REMOVE2(c->bucket_hash, RBH, c->pool, b);
- sth_free((sth_block) { b, !!(b->eattrs->flags & EALF_HUGE) });
+ mb_free(b);
}
int
bpp->lock = dom;
bpp->pool = p;
- bpp->sth = sth_new(p);
bpp->c = c;
bgp_init_bucket_table(bpp);
HASH_WALK_END;
HASH_FREE(c->bucket_hash);
- sth_delete(c->sth);
+ sl_delete(c->bucket_slab);
+ c->bucket_slab = NULL;
rp_free(c->pool);
struct { BGP_PTX_PUBLIC; };
struct bgp_ptx_private **locked_at;
- pool *pool; /* Pool for infrequent long-term blocks */
- stonehenge *sth; /* Bucket allocator */
+ pool *pool; /* Resource pool for TX related allocations */
HASH(struct bgp_bucket) bucket_hash; /* Hash table of route buckets */
struct bgp_bucket *withdraw_bucket; /* Withdrawn routes */
HASH(struct bgp_prefix) prefix_hash; /* Hash table of pending prefices */
slab *prefix_slab; /* Slab holding prefix nodes */
+ slab *bucket_slab; /* Slab holding buckets to send */
char bmp; /* This is a fake ptx for BMP encoding */
};