Skip to content

Commit 8e67fe7

Browse files
committed
worker: remove contention on worker.currentMu by maintaining a snapshot of pending data.
1 parent 329ac18 commit 8e67fe7

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

miner/worker.go

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ type worker struct {
117117
currentMu sync.Mutex
118118
current *Work
119119

120+
snapshotMu sync.RWMutex
121+
snapshotBlock *types.Block
122+
snapshotState *state.StateDB
123+
120124
uncleMu sync.Mutex
121125
possibleUncles map[common.Hash]*types.Block
122126

@@ -171,32 +175,28 @@ func (self *worker) setExtra(extra []byte) {
171175
}
172176

173177
func (self *worker) pending() (*types.Block, *state.StateDB) {
174-
self.currentMu.Lock()
175-
defer self.currentMu.Unlock()
176-
177178
if atomic.LoadInt32(&self.mining) == 0 {
178-
return types.NewBlock(
179-
self.current.header,
180-
self.current.txs,
181-
nil,
182-
self.current.receipts,
183-
), self.current.state.Copy()
179+
// return a snapshot to avoid contention on currentMu mutex
180+
self.snapshotMu.RLock()
181+
defer self.snapshotMu.RUnlock()
182+
return self.snapshotBlock, self.snapshotState.Copy()
184183
}
185-
return self.current.Block, self.current.state.Copy()
186-
}
187184

188-
func (self *worker) pendingBlock() *types.Block {
189185
self.currentMu.Lock()
190186
defer self.currentMu.Unlock()
187+
return self.current.Block, self.current.state.Copy()
188+
}
191189

190+
func (self *worker) pendingBlock() *types.Block {
192191
if atomic.LoadInt32(&self.mining) == 0 {
193-
return types.NewBlock(
194-
self.current.header,
195-
self.current.txs,
196-
nil,
197-
self.current.receipts,
198-
)
192+
// return a snapshot to avoid contention on currentMu mutex
193+
self.snapshotMu.RLock()
194+
defer self.snapshotMu.RUnlock()
195+
return self.snapshotBlock
199196
}
197+
198+
self.currentMu.Lock()
199+
defer self.currentMu.Unlock()
200200
return self.current.Block
201201
}
202202

@@ -268,6 +268,7 @@ func (self *worker) update() {
268268
txset := types.NewTransactionsByPriceAndNonce(self.current.signer, txs)
269269

270270
self.current.commitTransactions(self.mux, txset, self.chain, self.coinbase)
271+
self.updateSnapshot()
271272
self.currentMu.Unlock()
272273
} else {
273274
// If we're mining, but nothing is being processed, wake on new transactions
@@ -489,6 +490,7 @@ func (self *worker) commitNewWork() {
489490
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
490491
}
491492
self.push(work)
493+
self.updateSnapshot()
492494
}
493495

494496
func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
@@ -506,6 +508,19 @@ func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
506508
return nil
507509
}
508510

511+
func (self *worker) updateSnapshot() {
512+
self.snapshotMu.Lock()
513+
defer self.snapshotMu.Unlock()
514+
515+
self.snapshotBlock = types.NewBlock(
516+
self.current.header,
517+
self.current.txs,
518+
nil,
519+
self.current.receipts,
520+
)
521+
self.snapshotState = self.current.state.Copy()
522+
}
523+
509524
func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsByPriceAndNonce, bc *core.BlockChain, coinbase common.Address) {
510525
gp := new(core.GasPool).AddGas(env.header.GasLimit)
511526

0 commit comments

Comments
 (0)