github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/cmd/dero-miner/thread_windows.go (about) 1 package main 2 3 import "runtime" 4 import "sync/atomic" 5 import "syscall" 6 import "unsafe" 7 import "math/bits" 8 9 var libkernel32 uintptr 10 var setThreadAffinityMask uintptr 11 12 func doLoadLibrary(name string) uintptr { 13 lib, _ := syscall.LoadLibrary(name) 14 return uintptr(lib) 15 } 16 17 func doGetProcAddress(lib uintptr, name string) uintptr { 18 addr, _ := syscall.GetProcAddress(syscall.Handle(lib), name) 19 return uintptr(addr) 20 } 21 22 func syscall3(trap, nargs, a1, a2, a3 uintptr) uintptr { 23 ret, _, _ := syscall.Syscall(trap, nargs, a1, a2, a3) 24 return ret 25 } 26 27 func init() { 28 libkernel32 = doLoadLibrary("kernel32.dll") 29 setThreadAffinityMask = doGetProcAddress(libkernel32, "SetThreadAffinityMask") 30 } 31 32 var processor int32 33 34 // currently we suppport upto 64 cores 35 func SetThreadAffinityMask(hThread syscall.Handle, dwThreadAffinityMask uint) *uint32 { 36 ret1 := syscall3(setThreadAffinityMask, 2, 37 uintptr(hThread), 38 uintptr(dwThreadAffinityMask), 39 0) 40 return (*uint32)(unsafe.Pointer(ret1)) 41 } 42 43 // CurrentThread returns the handle for the current thread. 44 // It is a pseudo handle that does not need to be closed. 45 func CurrentThread() syscall.Handle { return syscall.Handle(^uintptr(2 - 1)) } 46 47 // sets thread affinity to avoid cache collision and thread migration 48 func threadaffinity() { 49 lock_on_cpu := atomic.AddInt32(&processor, 1) 50 if lock_on_cpu >= int32(runtime.GOMAXPROCS(0)) { // threads are more than cpu, we do not know what to do 51 return 52 } 53 54 if lock_on_cpu >= bits.UintSize { 55 return 56 } 57 var cpuset uint 58 cpuset = 1 << uint(avoidHT(int(lock_on_cpu))) 59 SetThreadAffinityMask(CurrentThread(), cpuset) 60 } 61 62 func avoidHT(i int) int { 63 count := runtime.GOMAXPROCS(0) 64 if i < count/2 { 65 return i * 2 66 } else { 67 return (i-count/2)*2 + 1 68 } 69 }