| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | // Copyright 2011 Evan Shaw. All rights reserved. | 
					
						
							|  |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  | // license that can be found in the LICENSE-MMAP-GO file. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-17 17:10:51 +01:00
										 |  |  | //go:build darwin || dragonfly || freebsd || linux || (solaris && !illumos) || netbsd | 
					
						
							|  |  |  | // +build darwin dragonfly freebsd linux solaris,!illumos netbsd | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Modifications (c) 2017 The Memory Authors. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package memory // import "modernc.org/memory" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"syscall" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const pageSizeLog = 20 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	osPageMask = osPageSize - 1 | 
					
						
							|  |  |  | 	osPageSize = os.Getpagesize() | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func unmap(addr uintptr, size int) error { | 
					
						
							|  |  |  | 	_, _, errno := syscall.Syscall(syscall.SYS_MUNMAP, addr, uintptr(size), 0) | 
					
						
							|  |  |  | 	if errno != 0 { | 
					
						
							|  |  |  | 		return errno | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // pageSize aligned. | 
					
						
							|  |  |  | func mmap(size int) (uintptr, int, error) { | 
					
						
							|  |  |  | 	size = roundup(size, osPageSize) | 
					
						
							| 
									
										
										
										
											2024-04-17 17:10:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-24 12:26:22 +02:00
										 |  |  | 	// The actual mmap syscall varies by architecture. mmapSyscall provides same | 
					
						
							|  |  |  | 	// functionality as the unexported funtion syscall.mmap and is declared in | 
					
						
							|  |  |  | 	// mmap_*_*.go and mmap_fallback.go. To add support for a new architecture, | 
					
						
							|  |  |  | 	// check function mmap in src/syscall/syscall_*_*.go or | 
					
						
							|  |  |  | 	// src/syscall/zsyscall_*_*.go in Go's source code. | 
					
						
							|  |  |  | 	p, err := mmapSyscall(0, uintptr(size+pageSize), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_PRIVATE|syscall.MAP_ANON, -1, 0) | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return 0, 0, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-24 12:26:22 +02:00
										 |  |  | 	n := size + pageSize | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	if p&uintptr(osPageMask) != 0 { | 
					
						
							|  |  |  | 		panic("internal error") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mod := int(p) & pageMask | 
					
						
							|  |  |  | 	if mod != 0 { | 
					
						
							|  |  |  | 		m := pageSize - mod | 
					
						
							|  |  |  | 		if err := unmap(p, m); err != nil { | 
					
						
							|  |  |  | 			return 0, 0, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		n -= m | 
					
						
							|  |  |  | 		p += uintptr(m) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if p&uintptr(pageMask) != 0 { | 
					
						
							|  |  |  | 		panic("internal error") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if n-size != 0 { | 
					
						
							|  |  |  | 		if err := unmap(p+uintptr(size), n-size); err != nil { | 
					
						
							|  |  |  | 			return 0, 0, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p, size, nil | 
					
						
							|  |  |  | } |