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  }