<p>This is <a href="http://en.wikipedia.org/wiki/Double-checked_locking" rel="nofollow">double-checked locking</a>, which is</p>

<blockquote>
  <p>...a software design pattern used to reduce the overhead of acquiring a lock by first testing the locking criterion [...] without actually acquiring the lock.</p>
</blockquote>

<p>This pattern can be fraught with issues; even folks who otherwise know what they're doing can be bitten by subtle issues.  See, for example, <a href="http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf" rel="nofollow">C++ and the Perils of Double-Checked Locking</a> by Scott Meyers and Andrei Alexandrescu.</p>

<p>The particular use case you cite looks fairly innocuous, though.</p>

CC BY-SA 3.0
2014-12-12T00:02:06.047Z
2014-12-12T00:02:06.047Z
Chuck Batson
<p>From the v0.9.3 miner.cpp source (<a href="https://github.com/bitcoin/bitcoin/blob/v0.9.3/src/miner.cpp#L598-L604" rel="nofollow">https://github.com/bitcoin/bitcoin/blob/v0.9.3/src/miner.cpp#L598-L604</a>):</p>

<pre><code>if (GetTimeMillis() - nHPSTimerStart &gt; 4000)
{
    static CCriticalSection cs;
    {
        LOCK(cs);
        if (GetTimeMillis() - nHPSTimerStart &gt; 4000)
        {
        ....
</code></pre>

<p>Why is the same if statement "<code>if (GetTimeMillis() - nHPSTimerStart &gt; 4000)</code>" executed twice? GetTimeMillis() can only go up, so it seems like if the first one is true, then the second statement can only ever evaluate to true as well, and is useless. I'm assuming this is not entirely correct, though, and am also assuming it has something to do with the <code>CCriticalSelection</code>, but would like to understand the nature of it better.</p>

<p>Thanks!</p>

CC BY-SA 3.0
2014-12-04T22:01:47.817Z
I agree, I think that's a copy-paste bug. Maybe you should ask `#bitcoin-dev` to double-check.
Nick ODell
CC BY-SA 3.0
2014-12-05T00:31:44.843Z
Can any other thread modify `nHPSTimerStart`?
Greg Hewgill
CC BY-SA 3.0
2014-12-05T00:45:46.497Z
Yes, I think so. There could be quite a few threads working on the mining.
morsecoder
CC BY-SA 3.0
2014-12-05T13:13:06.233Z
I have used something similar before. The first `if` checks if we should bother to do the potentially expensive lock. If yes, then we lock and now that `nHPSTimerStart` is guaranteed not to change we can safely execute the `if` again.
Floris
CC BY-SA 3.0
2014-12-11T00:17:22.880Z
Thanks, Floris, that seems reasonable. If you post as an answer, I could mark it as such.
morsecoder
<mining-technical-details><bitcoin-core-development>
Why does the bitcoin mining code have the same if statement twice?
morsecoder
# Why does the bitcoin mining code have the same if statement twice?

(Asked by: username_0 on 2014-12-04)

From the v0.9.3 miner.cpp source (https://github.com/bitcoin/bitcoin/blob/v0.9.3/src/miner.cpp#L598-L604):
if (GetTimeMillis() - nHPSTimerStart > 4000)
{
    static CCriticalSection cs;
    {
        LOCK(cs);
        if (GetTimeMillis() - nHPSTimerStart > 4000)
        {
        ....

Why is the same if statement "if (GetTimeMillis() - nHPSTimerStart > 4000)" executed twice? GetTimeMillis() can only go up, so it seems like if the first one is true, then the second statement can only ever evaluate to true as well, and is useless. I'm assuming this is not entirely correct, though, and am also assuming it has something to do with the CCriticalSelection, but would like to understand the nature of it better.
Thanks!

**Tags:** mining-technical-details, bitcoin-core-development

> **Comments:**
> **username_1**: I agree, I think that's a copy-paste bug. Maybe you should ask `#bitcoin-dev` to double-check.  
> **username_2**: Can any other thread modify `nHPSTimerStart`?  
> **username_0**: Yes, I think so. There could be quite a few threads working on the mining.  
> **username_3**: I have used something similar before. The first `if` checks if we should bother to do the potentially expensive lock. If yes, then we lock and now that `nHPSTimerStart` is guaranteed not to change we can safely execute the `if` again.  
> **username_0**: Thanks, username_3, that seems reasonable. If you post as an answer, I could mark it as such.  

---

## 1 answers

### Answer by username_4 on 2014-12-12. Score: 3 | Accepted answer

This is [double-checked locking](http://en.wikipedia.org/wiki/Double-checked_locking), which is

> ...a software design pattern used to reduce the overhead of acquiring a lock by first testing the locking criterion [...] without actually acquiring the lock.

This pattern can be fraught with issues; even folks who otherwise know what they're doing can be bitten by subtle issues. See, for example, [C++ and the Perils of Double-Checked Locking](http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf) by Scott Meyers and Andrei Alexandrescu.

The particular use case you cite looks fairly innocuous, though.


---

