/////////////////////////////////////////////////////////////////////////////// // memory-bundle.cc - simple memory allocator /////////////////////////////////////////////////////////////////////////////// import "base/types" import "base/numbers" import "base/memory-allocator" typedef bytes = [] byte /////////////////////////////////////////////////////////////////////////////// // Memory Bundle /////////////////////////////////////////////////////////////////////////////// public struct memory bundle private chunk base: bytes private chunk free: bytes private chunk size: size private total: size end public equ size (bundle: memory bundle) = total (bundle) //----------------------------------------------------------------------------- // Macros & Constants //----------------------------------------------------------------------------- private struct bundle head next: bytes size: size end equ head size = sizeof(local bundle head) equ chunk size = (16*1024) equ alignment = sizeof(bundle head) // base limit // +------+------+----------------------------+ // | next | size | | // +------+------+----------------------------+ // // next is a pointer on the next // size is the size of the chunk equ next (base:bytes) = next ((base-head size): bundle head) equ size (base:bytes) = size ((base-head size): bundle head) //----------------------------------------------------------------------------- // Allocate a new chunk //----------------------------------------------------------------------------- func new chunk (bundle: memory bundle, size: size) def old base = chunk base (bundle) chunk base (bundle) = allocate memory (size+head size):bytes + head size chunk free (bundle) = chunk base (bundle) + size next(chunk base (bundle)) = old base size(chunk base (bundle)) = size end //----------------------------------------------------------------------------- // allocate a new memory block //----------------------------------------------------------------------------- public func allocate (bundle: memory bundle, s: size) // align size on next round value def size = s size += alignment-1 size &= ~(alignment-1) // stats total (bundle) += size chunk free (bundle) -= size if chunk free (bundle) >= chunk base (bundle) return chunk free (bundle) end new chunk (bundle, max (size, chunk size)) chunk free (bundle) -= size return chunk free (bundle) end //----------------------------------------------------------------------------- // initialize //----------------------------------------------------------------------------- public func bundle(size: size, return bundle: memory bundle) chunk base (bundle) = nil chunk size (bundle) = size new chunk (bundle, size) total (bundle) = 0 end //----------------------------------------------------------------------------- // release //----------------------------------------------------------------------------- public func release (bundle: memory bundle) def base = chunk base (bundle) while not nil (base) def next = next (base) free memory (base - head size) base = next end end