Line data Source code
1 : #include <stdlib.h> 2 : 3 : #include <crater/sla.h> 4 : 5 5 : bool cr8r_sla_init(cr8r_sla *self, uint64_t elem_size, uint64_t cap){ 6 5 : if(!cap || elem_size < sizeof(void*)){ 7 : return 0; 8 : } 9 5 : self->elem_size = elem_size; 10 5 : char (*slab)[elem_size] = malloc(cap*elem_size);//start the allocator with one block of length cap 11 5 : if(!slab){ 12 : return 0; 13 5 : }else if(!(self->slabs = malloc(1*sizeof(void*)))){//put slab in an array 14 0 : free(slab); 15 0 : return 0; 16 : } 17 5 : self->slab_cap = cap; 18 5 : self->first_elem = self->slabs[0] = slab; 19 5 : self->slabs_len = 1; 20 94731 : for(uint64_t i = 0; i + 1 < cap; ++i){//fill the stack with the pointers 21 94726 : *(void**)(slab + i) = slab + i + 1; 22 : } 23 5 : *(void**)(slab + cap - 1) = NULL; 24 5 : return 1; 25 : } 26 : 27 5 : void cr8r_sla_delete(cr8r_sla *self){ 28 16 : for(uint64_t i = 0; i < self->slabs_len; ++i){ 29 11 : free(self->slabs[i]); 30 : } 31 5 : free(self->slabs); 32 5 : *self = (cr8r_sla){}; 33 5 : } 34 : 35 177912800 : void *cr8r_sla_alloc(cr8r_sla *self){ 36 177912800 : if(!self->first_elem){ 37 6 : uint64_t slab_cap = self->slab_cap << 1; 38 6 : char (*slab)[self->elem_size] = malloc(slab_cap*self->elem_size); 39 6 : void **slabs; 40 6 : if(!slab){ 41 : return NULL; 42 6 : }else if(!(slabs = realloc(self->slabs, (self->slabs_len + 1)*sizeof(void*)))){ 43 0 : free(slab); 44 0 : return NULL; 45 : } 46 6 : self->first_elem = slabs[self->slabs_len++] = (void*)slab; 47 6 : self->slabs = slabs; 48 12600 : for(uint64_t i = 0; i + 1 < slab_cap; ++i){ 49 12594 : *(void**)(slab + i) = slab + i + 1; 50 : } 51 6 : *(void**)(slab + slab_cap - 1) = NULL; 52 6 : self->slab_cap = slab_cap; 53 : } 54 177912800 : void *ret = self->first_elem; 55 177912800 : self->first_elem = *(void**)self->first_elem; 56 177912800 : return ret; 57 : } 58 : 59 177821201 : void cr8r_sla_free(cr8r_sla *self, void *p){ 60 177821201 : *(void**)p = self->first_elem; 61 177821201 : self->first_elem = p; 62 177821201 : } 63 :