github.com/fiatjaf/generic-ristretto@v0.0.1/z/mremap_linux.go (about) 1 // +build !arm64 2 3 /* 4 * Copyright 2020 Dgraph Labs, Inc. and Contributors 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package z 20 21 import ( 22 "fmt" 23 "reflect" 24 "unsafe" 25 26 "golang.org/x/sys/unix" 27 ) 28 29 // mremap is a Linux-specific system call to remap pages in memory. This can be used in place of munmap + mmap. 30 func mremap(data []byte, size int) ([]byte, error) { 31 //nolint:lll 32 // taken from <https://github.com/torvalds/linux/blob/f8394f232b1eab649ce2df5c5f15b0e528c92091/include/uapi/linux/mman.h#L8> 33 const MREMAP_MAYMOVE = 0x1 34 35 header := (*reflect.SliceHeader)(unsafe.Pointer(&data)) 36 mmapAddr, mmapSize, errno := unix.Syscall6( 37 unix.SYS_MREMAP, 38 header.Data, 39 uintptr(header.Len), 40 uintptr(size), 41 uintptr(MREMAP_MAYMOVE), 42 0, 43 0, 44 ) 45 if errno != 0 { 46 return nil, errno 47 } 48 if mmapSize != uintptr(size) { 49 return nil, fmt.Errorf("mremap size mismatch: requested: %d got: %d", size, mmapSize) 50 } 51 52 header.Data = mmapAddr 53 header.Cap = size 54 header.Len = size 55 return data, nil 56 }