Source file 
src/runtime/mfixalloc.go
     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  
     9  package runtime
    10  
    11  import (
    12  	"internal/runtime/sys"
    13  	"unsafe"
    14  )
    15  
    16  
    17  
    18  
    19  
    20  
    21  
    22  
    23  
    24  
    25  
    26  
    27  
    28  
    29  
    30  
    31  type fixalloc struct {
    32  	size   uintptr
    33  	first  func(arg, p unsafe.Pointer) 
    34  	arg    unsafe.Pointer
    35  	list   *mlink
    36  	chunk  uintptr 
    37  	nchunk uint32  
    38  	nalloc uint32  
    39  	inuse  uintptr 
    40  	stat   *sysMemStat
    41  	zero   bool 
    42  }
    43  
    44  
    45  
    46  
    47  
    48  
    49  type mlink struct {
    50  	_    sys.NotInHeap
    51  	next *mlink
    52  }
    53  
    54  
    55  
    56  func (f *fixalloc) init(size uintptr, first func(arg, p unsafe.Pointer), arg unsafe.Pointer, stat *sysMemStat) {
    57  	if size > _FixAllocChunk {
    58  		throw("runtime: fixalloc size too large")
    59  	}
    60  	size = max(size, unsafe.Sizeof(mlink{}))
    61  
    62  	f.size = size
    63  	f.first = first
    64  	f.arg = arg
    65  	f.list = nil
    66  	f.chunk = 0
    67  	f.nchunk = 0
    68  	f.nalloc = uint32(_FixAllocChunk / size * size) 
    69  	f.inuse = 0
    70  	f.stat = stat
    71  	f.zero = true
    72  }
    73  
    74  func (f *fixalloc) alloc() unsafe.Pointer {
    75  	if f.size == 0 {
    76  		print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n")
    77  		throw("runtime: internal error")
    78  	}
    79  
    80  	if f.list != nil {
    81  		v := unsafe.Pointer(f.list)
    82  		f.list = f.list.next
    83  		f.inuse += f.size
    84  		if f.zero {
    85  			memclrNoHeapPointers(v, f.size)
    86  		}
    87  		return v
    88  	}
    89  	if uintptr(f.nchunk) < f.size {
    90  		f.chunk = uintptr(persistentalloc(uintptr(f.nalloc), 0, f.stat))
    91  		f.nchunk = f.nalloc
    92  	}
    93  
    94  	v := unsafe.Pointer(f.chunk)
    95  	if f.first != nil {
    96  		f.first(f.arg, v)
    97  	}
    98  	f.chunk = f.chunk + f.size
    99  	f.nchunk -= uint32(f.size)
   100  	f.inuse += f.size
   101  	return v
   102  }
   103  
   104  func (f *fixalloc) free(p unsafe.Pointer) {
   105  	f.inuse -= f.size
   106  	v := (*mlink)(p)
   107  	v.next = f.list
   108  	f.list = v
   109  }
   110  
View as plain text