#include #include #include #define PAGE_SIZE (1<<12) struct slab { int x[7]; }; typedef long kmem_bufctl_t; #define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) static size_t slab_mgmt_size(size_t nr_objs, size_t align) { return ALIGN(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t), align); } int estimate (int size, int align, int *leftover, int *hold1, int * hold2, int *num, int order) { int nr_objs; int slab_size = PAGE_SIZE << order; int nr1; int nr2; int mgmt_size; int nr_while; int nr_if; int ret = 0; nr_objs = (slab_size - sizeof(struct slab)) / (size + sizeof(kmem_bufctl_t)); nr1 = nr_objs; /* * Now take the padding into account and increase the * number of objects/slab until it doesn't fit * anymore. */ nr_if = nr_objs; if (slab_mgmt_size(nr_objs, align) + nr_objs*size <= slab_size) nr_if++; if (slab_mgmt_size(nr_objs, align) + nr_objs*size <= slab_size) nr_objs++; if (nr_if != nr_objs) ret = 1; nr2 = nr_objs; /* * Reduce it by one which the maximum number of objects that * fit in the slab. */ if (nr_objs > 0) nr_objs--; mgmt_size = slab_mgmt_size(nr_objs, align); *num = nr_objs; *leftover = slab_size - nr_objs*size - mgmt_size; *hold1 = nr1; *hold2 = nr2; return ret; } int main (int argc, char **argv) { int i; int x; int leftover; int hold1; int hold2; int num; int order; for (order=0; order <= 1; order++) { for (i=8; i < (PAGE_SIZE >> 1); i++) { for (x=4; x < i; x++) { if (estimate(i, x, &leftover, &hold1, &hold2, &num, order)) printf("%8d%8d%8d%8d%8d%8d%8d%8d\n", i, x, leftover, hold1, hold2, num, hold1-num, hold2-num); } } } return 0; }