aboutsummaryrefslogtreecommitdiff
path: root/weed
diff options
context:
space:
mode:
authorj.laycock <joseph.laycock@4sightimaging.com>2019-09-10 16:18:51 +0100
committerj.laycock <joseph.laycock@4sightimaging.com>2019-09-10 16:18:51 +0100
commit9c9dff7386acdd1002849c855ea1b3e160e7a177 (patch)
tree3ab4b03dad1a78b31c792bf545b686d8e6b0bcde /weed
parentd757ed2fe3049289ad662e7edb2293b79f5343fa (diff)
downloadseaweedfs-9c9dff7386acdd1002849c855ea1b3e160e7a177.tar.xz
seaweedfs-9c9dff7386acdd1002849c855ea1b3e160e7a177.zip
Virtual lock memory pages and Set Process Working set size to hint to windows harder not to write pages to disk as much, add finalize function, minor renaming
Diffstat (limited to 'weed')
-rw-r--r--weed/storage/memory_map/memory_map_windows.go103
1 files changed, 79 insertions, 24 deletions
diff --git a/weed/storage/memory_map/memory_map_windows.go b/weed/storage/memory_map/memory_map_windows.go
index 58ebcea22..fd11a688a 100644
--- a/weed/storage/memory_map/memory_map_windows.go
+++ b/weed/storage/memory_map/memory_map_windows.go
@@ -5,6 +5,7 @@ package memory_map
import (
"os"
"reflect"
+ "runtime"
"syscall"
"unsafe"
@@ -33,32 +34,41 @@ type DWORD = uint32
type WORD = uint16
var (
- procGetSystemInfo = syscall.NewLazyDLL("kernel32.dll").NewProc("GetSystemInfo")
+ modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+ procGetSystemInfo = modkernel32.NewProc("GetSystemInfo")
+ procGetProcessWorkingSetSize = modkernel32.NewProc("GetProcessWorkingSetSize")
+ procSetProcessWorkingSetSize = modkernel32.NewProc("SetProcessWorkingSetSize")
)
-var system_info, err = getSystemInfo()
+var currentProcess, _ = windows.GetCurrentProcess()
+var currentMinWorkingSet uint64 = 0
+var currentMaxWorkingSet uint64 = 0
+var _ = getProcessWorkingSetSize(uintptr(currentProcess), &currentMinWorkingSet, &currentMaxWorkingSet)
-var chunk_size = uint64(system_info.dwAllocationGranularity) * 256
+var systemInfo, _ = getSystemInfo()
+var chunkSize = uint64(systemInfo.dwAllocationGranularity) * 256
-func (mMap *MemoryMap) CreateMemoryMap(file *os.File, maxlength uint64) {
+func (mMap *MemoryMap) CreateMemoryMap(file *os.File, maxLength uint64) {
- chunks := (maxlength / chunk_size)
- if chunks*chunk_size < maxlength {
+ chunks := (maxLength / chunkSize)
+ if chunks*chunkSize < maxLength {
chunks = chunks + 1
}
- alignedMaxLength := chunks * chunk_size
+ alignedMaxLength := chunks * chunkSize
- maxlength_high := uint32(alignedMaxLength >> 32)
- maxlength_low := uint32(alignedMaxLength & 0xFFFFFFFF)
- file_memory_map_handle, err := windows.CreateFileMapping(windows.Handle(file.Fd()), nil, windows.PAGE_READWRITE, maxlength_high, maxlength_low, nil)
+ maxLength_high := uint32(alignedMaxLength >> 32)
+ maxLength_low := uint32(alignedMaxLength & 0xFFFFFFFF)
+ file_memory_map_handle, err := windows.CreateFileMapping(windows.Handle(file.Fd()), nil, windows.PAGE_READWRITE, maxLength_high, maxLength_low, nil)
if err == nil {
mMap.File = file
mMap.file_memory_map_handle = uintptr(file_memory_map_handle)
- mMap.write_map_views = make([]MemoryBuffer, 0, alignedMaxLength/chunk_size)
+ mMap.write_map_views = make([]MemoryBuffer, 0, alignedMaxLength/chunkSize)
mMap.max_length = alignedMaxLength
mMap.End_of_file = -1
+ runtime.SetFinalizer(mMap, mMap.DeleteFileAndMemoryMap)
}
}
@@ -84,7 +94,7 @@ func min(x, y uint64) uint64 {
func (mMap *MemoryMap) WriteMemory(offset uint64, length uint64, data []byte) {
for {
- if ((offset+length)/chunk_size)+1 > uint64(len(mMap.write_map_views)) {
+ if ((offset+length)/chunkSize)+1 > uint64(len(mMap.write_map_views)) {
allocateChunk(mMap)
} else {
break
@@ -92,19 +102,19 @@ func (mMap *MemoryMap) WriteMemory(offset uint64, length uint64, data []byte) {
}
remaining_length := length
- slice_index := offset / chunk_size
- slice_offset := offset - (slice_index * chunk_size)
- data_offset := uint64(0)
+ sliceIndex := offset / chunkSize
+ sliceOffset := offset - (sliceIndex * chunkSize)
+ dataOffset := uint64(0)
for {
- write_end := min((remaining_length + slice_offset), chunk_size)
- copy(mMap.write_map_views[slice_index].Buffer[slice_offset:write_end], data[data_offset:])
- remaining_length -= (write_end - slice_offset)
- data_offset += (write_end - slice_offset)
+ writeEnd := min((remaining_length + sliceOffset), chunkSize)
+ copy(mMap.write_map_views[sliceIndex].Buffer[sliceOffset:writeEnd], data[dataOffset:])
+ remaining_length -= (writeEnd - sliceOffset)
+ dataOffset += (writeEnd - sliceOffset)
if remaining_length > 0 {
- slice_index += 1
- slice_offset = 0
+ sliceIndex += 1
+ sliceOffset = 0
} else {
break
}
@@ -120,8 +130,15 @@ func (mMap *MemoryMap) ReadMemory(offset uint64, length uint64) (MemoryBuffer, e
}
func (mBuffer *MemoryBuffer) ReleaseMemory() {
+
+ currentMinWorkingSet = currentMinWorkingSet - mBuffer.aligned_length
+ currentMaxWorkingSet = currentMaxWorkingSet - mBuffer.aligned_length
+
+ windows.VirtualUnlock(mBuffer.aligned_ptr, uintptr(mBuffer.aligned_length))
windows.UnmapViewOfFile(mBuffer.aligned_ptr)
+ var _ = setProcessWorkingSetSize(uintptr(currentProcess), uintptr(currentMinWorkingSet), uintptr(currentMaxWorkingSet))
+
mBuffer.ptr = 0
mBuffer.aligned_ptr = 0
mBuffer.length = 0
@@ -131,11 +148,12 @@ func (mBuffer *MemoryBuffer) ReleaseMemory() {
func allocateChunk(mMap *MemoryMap) {
- start := uint64(len(mMap.write_map_views)) * chunk_size
- mBuffer, err := allocate(windows.Handle(mMap.file_memory_map_handle), start, chunk_size, true)
+ start := uint64(len(mMap.write_map_views)) * chunkSize
+ mBuffer, err := allocate(windows.Handle(mMap.file_memory_map_handle), start, chunkSize, true)
if err == nil {
mMap.write_map_views = append(mMap.write_map_views, mBuffer)
+ windows.VirtualLock(mBuffer.aligned_ptr, uintptr(mBuffer.aligned_length))
}
}
@@ -143,7 +161,7 @@ func allocate(hMapFile windows.Handle, offset uint64, length uint64, write bool)
mBuffer := MemoryBuffer{}
- dwSysGran := system_info.dwAllocationGranularity
+ dwSysGran := systemInfo.dwAllocationGranularity
start := (offset / uint64(dwSysGran)) * uint64(dwSysGran)
diff := offset - start
@@ -158,6 +176,11 @@ func allocate(hMapFile windows.Handle, offset uint64, length uint64, write bool)
access = windows.FILE_MAP_WRITE
}
+ currentMinWorkingSet = currentMinWorkingSet + aligned_length
+ currentMaxWorkingSet = currentMaxWorkingSet + aligned_length
+
+ var _ = setProcessWorkingSetSize(uintptr(currentProcess), uintptr(currentMinWorkingSet), uintptr(currentMaxWorkingSet))
+
addr_ptr, errno := windows.MapViewOfFile(hMapFile,
uint32(access), // read/write permission
offset_high,
@@ -227,3 +250,35 @@ func getSystemInfo() (_SYSTEM_INFO, error) {
}
return si, nil
}
+
+// BOOL GetProcessWorkingSetSize(
+// HANDLE hProcess,
+// PSIZE_T lpMinimumWorkingSetSize,
+// PSIZE_T lpMaximumWorkingSetSize
+// );
+
+func getProcessWorkingSetSize(process uintptr, dwMinWorkingSet *uint64, dwMaxWorkingSet *uint64) error {
+ r1, _, err := syscall.Syscall(procGetProcessWorkingSetSize.Addr(), 3, process, uintptr(unsafe.Pointer(dwMinWorkingSet)), uintptr(unsafe.Pointer(dwMaxWorkingSet)))
+ if r1 == 0 {
+ if err != syscall.Errno(0) {
+ return err
+ }
+ }
+ return nil
+}
+
+// BOOL SetProcessWorkingSetSize(
+// HANDLE hProcess,
+// SIZE_T dwMinimumWorkingSetSize,
+// SIZE_T dwMaximumWorkingSetSize
+// );
+
+func setProcessWorkingSetSize(process uintptr, dwMinWorkingSet uintptr, dwMaxWorkingSet uintptr) error {
+ r1, _, err := syscall.Syscall(procSetProcessWorkingSetSize.Addr(), 3, process, (dwMinWorkingSet), (dwMaxWorkingSet))
+ if r1 == 0 {
+ if err != syscall.Errno(0) {
+ return err
+ }
+ }
+ return nil
+}