| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // Fixed-size object allocator. Returned memory is not zeroed. |
| // |
| // See malloc.h for overview. |
| |
| #include "runtime.h" |
| #include "arch.h" |
| #include "malloc.h" |
| |
| // Initialize f to allocate objects of the given size, |
| // using the allocator to obtain chunks of memory. |
| void |
| runtime_FixAlloc_Init(FixAlloc *f, uintptr size, void (*first)(void*, byte*), void *arg, uint64 *stat) |
| { |
| f->size = size; |
| f->first = first; |
| f->arg = arg; |
| f->list = nil; |
| f->chunk = nil; |
| f->nchunk = 0; |
| f->inuse = 0; |
| f->stat = stat; |
| } |
| |
| void* |
| runtime_FixAlloc_Alloc(FixAlloc *f) |
| { |
| void *v; |
| |
| if(f->size == 0) { |
| runtime_printf("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n"); |
| runtime_throw("runtime: internal error"); |
| } |
| |
| if(f->list) { |
| v = f->list; |
| f->list = *(void**)f->list; |
| f->inuse += f->size; |
| return v; |
| } |
| if(f->nchunk < f->size) { |
| f->chunk = runtime_persistentalloc(FixAllocChunk, 0, f->stat); |
| f->nchunk = FixAllocChunk; |
| } |
| v = f->chunk; |
| if(f->first) |
| f->first(f->arg, v); |
| f->chunk += f->size; |
| f->nchunk -= f->size; |
| f->inuse += f->size; |
| return v; |
| } |
| |
| void |
| runtime_FixAlloc_Free(FixAlloc *f, void *p) |
| { |
| f->inuse -= f->size; |
| *(void**)p = f->list; |
| f->list = p; |
| } |
| |