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