You have to signal a condition variable while the mutex is locked [1].
If you signal without a lock on the mutex you run into a race
condition called the lost wakeup. There's a note in [2] that I always
remember reading talking about people commonly getting this wrong due
to some old documentation being incorrect. Sadly I can never remember
which way is right so I always have to look it up again.
[1] https://computing.llnl.gov/tutorials/pthreads/#ConVarSignal
[2] http://www.amazon.com/Multithreaded-Programming-PThreads-Bil-Lewis/dp/0136807291
Actually, I think that's not correct -- you must ALWAYS hold a mutex
when signaling a CV or else you risk missing signals.
There is someone wrong on the Internet and I must correct it! ;)
(http://xkcd.com/386/)
D.
You have to signal a condition variable while the mutex is locked [1].
If you signal without a lock on the mutex you run into a race
#define snprintf _snprintf
#define close _close
#define fread_unlocked _fread_nolock
I moved them around because port.h isn't the right place for them.
I'm curious, how did you use Interlocked operations? Would you care
sharing your implementation?
-Edouard
2011/6/20 kurak <kur...@gmail.com>
Although the pointer operation is atomic, you have no guarantee the
compiler will generate only one instruction for your code.
Example:
void * a = ...;
void * b = ...;
if (a != b)
a = b;
will probably generate something along the lines of
mov eax, [a]
cmp [b], eax
jz next
; welcome to race condition world, we hope you will enjoy your stay
mov [b], eax
next:
On the other hand
volatile void * a = ...;
volatile void * b = ... ;
will probably generate the right assembly
mov eax, [b]
lock cmpxchg [a], eax
jz next
mov [b], eax
next:
Am I missing something?
-Edouard
LevelDB: version 1.2
Keys: 16 bytes each
Values: 100 bytes each (50 bytes after compression)
Entries: 1000000
RawSize: 110.6 MB (estimated)
FileSize: 62.9 MB (estimated)
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq : 5.018 micros/op; 22.0 MB/s
fillsync : 5.300 micros/op; 20.9 MB/s (10000 ops)
fillrandom : 6.442 micros/op; 17.2 MB/s
overwrite : 6.605 micros/op; 16.7 MB/s
readrandom : 16.933 micros/op;
readrandom : 16.727 micros/op;
readseq : 0.382 micros/op; 289.7 MB/s
readreverse : 0.671 micros/op; 164.8 MB/s
compact : 1172064.000 micros/op;
readrandom : 9.463 micros/op;
readseq : 0.315 micros/op; 350.8 MB/s
readreverse : 0.544 micros/op; 203.4 MB/s
fill100K : 1119.551 micros/op; 85.2 MB/s (1000 ops)
crc32c : 5.547 micros/op; 704.2 MB/s (4K per op)
snappycomp : 0.000 micros/op; (snappy failure)
snappyuncomp : 0.000 micros/op; (snappy failure)
acquireload : 0.840 micros/op; (each op is 1000 loads)
As far as I can tell this code does the following
void * temp = rep_;
rep_ = v;
return temp;
I don' think that's the intent.
I think you want to do
InterlockedExchangePointer(&v, rep_);
-Edouard
Linux :
LevelDB: version 1.2
Date: Tue Jun 21 13:13:28 2011
CPU: 4 * Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
CPUCache: 4096 KB
Keys: 16 bytes each
Values: 100 bytes each (50 bytes after compression)
Entries: 1000000
RawSize: 110.6 MB (estimated)
FileSize: 62.9 MB (estimated)
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq : 7.847 micros/op; 14.1 MB/s
fillsync : 8.171 micros/op; 13.5 MB/s (10000 ops)
fillrandom : 10.326 micros/op; 10.7 MB/s
overwrite : 14.657 micros/op; 7.5 MB/s
readrandom : 34.661 micros/op;
readrandom : 33.236 micros/op;
readseq : 1.144 micros/op; 96.7 MB/s
readreverse : 3.484 micros/op; 31.8 MB/s
compact : 3091813.000 micros/op;
readrandom : 18.797 micros/op;
readseq : 0.938 micros/op; 117.9 MB/s
readreverse : 3.029 micros/op; 36.5 MB/s
fill100K : 963.255 micros/op; 99.0 MB/s (1000 ops)
crc32c : 4.506 micros/op; 866.9 MB/s (4K per op)
snappycomp : 3.000 micros/op; (snappy failure)
snappyuncomp : 7.000 micros/op; (snappy failure)
acquireload : 5.857 micros/op; (each op is 1000 loads)
FreeBSD:
LevelDB: version 1.2
Keys: 16 bytes each
Values: 100 bytes each (50 bytes after compression)
Entries: 1000000
RawSize: 110.6 MB (estimated)
FileSize: 62.9 MB (estimated)
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq : 7.060 micros/op; 15.7 MB/s
fillsync : 7.085 micros/op; 15.6 MB/s (10000 ops)
fillrandom : 10.303 micros/op; 10.7 MB/s
overwrite : 12.296 micros/op; 9.0 MB/s
readrandom : 50.320 micros/op;
readrandom : 49.764 micros/op;
readseq : 1.036 micros/op; 106.8 MB/s
readreverse : 1.634 micros/op; 67.7 MB/s
compact : 1638005.000 micros/op;
readrandom : 14.949 micros/op;
readseq : 0.514 micros/op; 215.4 MB/s
readreverse : 0.908 micros/op; 121.9 MB/s
fill100K : 3467.195 micros/op; 27.5 MB/s (1000 ops)
crc32c : 4.891 micros/op; 798.6 MB/s (4K per op)
snappycomp : 4.000 micros/op; (snappy failure)
snappyuncomp : 12.000 micros/op; (snappy failure)
acquireload : 6.261 micros/op; (each op is 1000 loads)
Which failure(s) do you have?
> BTW. I've just noticed, that corruption tests are failing. Does any
> one else have this problem?
On r33 corruption this test now fails.
-Edouard
Which binary are you looking for? Our program based on LevelDB (which
is freely available on our website) or the compiled leveldb
libraries/unit tests?
Keep in mind that compiled libraries will require you to use the exact
same compiler and C++ libraries to be useable.
Regards.
-Edouard