c748be2017-07-25Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
d476592013-06-12Arne Goedeke #ifndef BLOCK_ALLOCATOR_H #define BLOCK_ALLOCATOR_H #include "global.h" #include "pike_error.h" #include "pike_memory.h" struct ba_layout { unsigned INT32 offset; unsigned INT32 block_size; unsigned INT32 blocks;
aa432a2013-08-01Arne Goedeke  unsigned INT32 alignment; unsigned INT32 doffset;
d476592013-06-12Arne Goedeke };
aa432a2013-08-01Arne Goedeke #define BA_LAYOUT_INIT(block_size, blocks, alignment) { 0, (block_size), (blocks), (alignment), 0 }
d476592013-06-12Arne Goedeke  struct ba_page_header { struct ba_block_header * first; unsigned INT32 used;
ceae362013-10-09Arne Goedeke  unsigned INT32 flags;
d476592013-06-12Arne Goedeke }; struct ba_page { struct ba_page_header h; }; struct block_allocator { struct ba_layout l;
1138422013-11-01Arne Goedeke  unsigned char size, last_free, alloc;
d476592013-06-12Arne Goedeke  /* * This places an upper limit on the number of blocks * and should be adjusted as needed. * * the formula is as follows: * (initial_size << 24) - initial_size * for example for short pike strings this means that at most * 192 GB of short pike strings with shift width 0 can be allocated. */ struct ba_page * pages[24]; };
ceae362013-10-09Arne Goedeke struct ba_iterator { void * cur; void * end; struct ba_layout l; }; typedef void (*ba_walk_callback)(struct ba_iterator *,void*); PMOD_EXPORT void ba_walk(struct block_allocator * a, ba_walk_callback cb, void * data);
01b9212016-01-12Per Hedbor static inline int PIKE_UNUSED_ATTRIBUTE ba_it_step(struct ba_iterator * it) {
ceae362013-10-09Arne Goedeke  it->cur = (char*)it->cur + it->l.block_size; return (char*)it->cur < (char*)it->end; }
01b9212016-01-12Per Hedbor static inline void PIKE_UNUSED_ATTRIBUTE * ba_it_val(struct ba_iterator * it) {
ceae362013-10-09Arne Goedeke  return it->cur; }
aa432a2013-08-01Arne Goedeke #define BA_INIT_ALIGNED(block_size, blocks, alignment) { \ BA_LAYOUT_INIT(block_size, blocks, alignment), \
7dc1bb2013-10-31Arne Goedeke  0, 0, 0, \
aa432a2013-08-01Arne Goedeke  { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, \ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL } \
d476592013-06-12Arne Goedeke }
aa432a2013-08-01Arne Goedeke #define BA_INIT(block_size, blocks) BA_INIT_ALIGNED(block_size, blocks, 0)
d476592013-06-12Arne Goedeke #define BA_INIT_PAGES(block_size, pages) BA_INIT(block_size, ((pages) * PIKE_MALLOC_PAGE_SIZE)/(block_size))
aa432a2013-08-01Arne Goedeke PMOD_EXPORT void ba_init_aligned(struct block_allocator * a, unsigned INT32 block_size, unsigned INT32 blocks, unsigned INT32 alignment);
d476592013-06-12Arne Goedeke ATTRIBUTE((malloc)) PMOD_EXPORT void * ba_alloc(struct block_allocator * a); PMOD_EXPORT void ba_free(struct block_allocator * a, void * ptr); PMOD_EXPORT void ba_destroy(struct block_allocator * a);
3036092013-10-09Arne Goedeke PMOD_EXPORT void ba_free_all(struct block_allocator * a);
d476592013-06-12Arne Goedeke PMOD_EXPORT size_t ba_count(const struct block_allocator * a); PMOD_EXPORT void ba_count_all(const struct block_allocator * a, size_t * num, size_t * size);
aa432a2013-08-01Arne Goedeke 
01b9212016-01-12Per Hedbor static inline void PIKE_UNUSED_ATTRIBUTE ba_init(struct block_allocator * a, unsigned INT32 block_size, unsigned INT32 blocks) {
aa432a2013-08-01Arne Goedeke  ba_init_aligned(a, block_size, blocks, 0); }
d476592013-06-12Arne Goedeke #endif