gitlab.com/jokerrs1/Sia@v1.3.2/modules/miner/cpuminer.go (about) 1 package miner 2 3 import ( 4 "time" 5 6 "github.com/NebulousLabs/Sia/build" 7 ) 8 9 // threadedMine starts a gothread that does CPU mining. threadedMine is the 10 // only function that should be setting the mining flag to true. 11 func (m *Miner) threadedMine() { 12 if err := m.tg.Add(); err != nil { 13 return 14 } 15 defer m.tg.Done() 16 17 // There should not be another thread mining, and mining should be enabled. 18 m.mu.Lock() 19 if m.mining || !m.miningOn { 20 m.mu.Unlock() 21 return 22 } 23 m.mining = true 24 m.mu.Unlock() 25 26 // Solve blocks repeatedly, keeping track of how fast hashing is 27 // occurring. 28 cycleStart := time.Now() 29 for { 30 m.mu.Lock() 31 32 // Kill the thread if 'Stop' has been called. 33 select { 34 case <-m.tg.StopChan(): 35 m.miningOn = false 36 m.mining = false 37 m.mu.Unlock() 38 return 39 default: 40 } 41 42 // Kill the thread if mining has been turned off. 43 if !m.miningOn { 44 m.mining = false 45 m.mu.Unlock() 46 return 47 } 48 49 // Prepare the work and release the miner lock. 50 bfw := m.blockForWork() 51 target := m.persist.Target 52 m.mu.Unlock() 53 54 // Solve the block. 55 b, solved := solveBlock(bfw, target) 56 if solved { 57 err := m.managedSubmitBlock(b) 58 if err != nil { 59 m.log.Println("ERROR: An error occurred while cpu mining:", err) 60 } 61 } 62 63 // Update the hashrate. If the block was solved, the full set of 64 // iterations was not completed, so the hashrate should not be updated. 65 m.mu.Lock() 66 if !solved { 67 nanosecondsElapsed := 1 + time.Since(cycleStart).Nanoseconds() // Add 1 to prevent divide by zero errors. 68 cycleStart = time.Now() // Reset the cycle counter as soon as the previous value is measured. 69 m.hashRate = 1e9 * solveAttempts / nanosecondsElapsed 70 } 71 m.mu.Unlock() 72 } 73 } 74 75 // CPUHashrate returns an estimated cpu hashrate. 76 func (m *Miner) CPUHashrate() int { 77 if err := m.tg.Add(); err != nil { 78 build.Critical(err) 79 } 80 defer m.tg.Done() 81 82 m.mu.Lock() 83 defer m.mu.Unlock() 84 return int(m.hashRate) 85 } 86 87 // CPUMining indicates whether the cpu miner is running. 88 func (m *Miner) CPUMining() bool { 89 if err := m.tg.Add(); err != nil { 90 build.Critical(err) 91 } 92 defer m.tg.Done() 93 94 m.mu.Lock() 95 defer m.mu.Unlock() 96 return m.miningOn 97 } 98 99 // StartCPUMining will start a single threaded cpu miner. If the miner is 100 // already running, nothing will happen. 101 func (m *Miner) StartCPUMining() { 102 if err := m.tg.Add(); err != nil { 103 build.Critical(err) 104 } 105 defer m.tg.Done() 106 107 m.mu.Lock() 108 defer m.mu.Unlock() 109 m.miningOn = true 110 go m.threadedMine() 111 } 112 113 // StopCPUMining will stop the cpu miner. If the cpu miner is already stopped, 114 // nothing will happen. 115 func (m *Miner) StopCPUMining() { 116 if err := m.tg.Add(); err != nil { 117 build.Critical(err) 118 } 119 defer m.tg.Done() 120 121 m.mu.Lock() 122 defer m.mu.Unlock() 123 m.hashRate = 0 124 m.miningOn = false 125 }