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  }