Is incr/decr atomic in multithread mode?

dormando dormando at rydia.net
Mon Feb 25 16:34:47 UTC 2008


Steve Chu wrote:
> On Mon, Feb 25, 2008 at 4:28 PM, dormando <dormando at rydia.net> wrote:
>> Steve Chu wrote:
>>  > On Mon, Feb 25, 2008 at 2:51 PM, dormando <dormando at rydia.net> wrote:
>>  >> I think this is fine?
>>  >>
>>  >>  Since the operations are independently atomic, it's perfectly valid for
>>  >>  two threads to incr the same value.
>>  >>
>>  >
>>  > But for client api, they seems NOT atomic, because when Thread A just
>>  > has 'item_get' done but before 'add_delta', Thread B can still do
>>  > item_get.
>>  >
>>  > X-> set "foo" 1
>>  > A-> item_get "foo"
>>  > B-> item_get "foo"
>>  > A-> add_delta "foo" by 1
>>  > B-> add_delta "foo" by 1
>>  >
>>  > then A and B both hold value 2, which one should be stored?
>>  >
>>  > And the exact value we need is 3, right? I am not quit sure, correct
>>  > me if i am wrong:)
>>
>>  The result gets copied into the thread-local 'temp' buffer, then copied
>>  into that connection (implicitly atomic)'s output buffer.
>>
>>  So actually I read the code wrong the first time. This _should_ do the
>>  right thing:
>>
>>  We have threads (A, B, X):
>>
>>  X -> set 'foo' 1
>>
>>  A -> process_arithmetic_command()
>>  note thread local storage (char temp[])
>>  B -> same.
>>
>>  A -> it = item_get(key, nkey)
>>  (atomically increments the refcount for that item, returns a reference
>>  to it)
>>  B -> same, same time.
>>  (same)
>>
>>  A -> out_string(c, add_delta(it, incr, delta, temp));
>>  add_delta runs atomically, copies the result of the addition into the
>>  thread local 'temp' buffer and _returns the 'temp' buffer_ (which
>>  contains 2)
>>  B -> out_string(c, add_delta(it, incr, delta, temp));
>>  Gets serialized behind A, and its 'temp' then holds a value one higher
>>  than A's (containing 3)
> 
> Here I am confused. Every thread has a local var 'temp' and here
> 'temp' should hold 2.  'temp' is independent, and doesn't share
> between threads. So thread B should overwrite the value in the
> slabber. Am I right?

Yes, it does. Just like it would if the increments happened at 
completely different times. Since the result of the addition is copied 
into the connection's write buffer atomically, this doesn't upset the 
balance of the universe.

Or are you talking about something else?

-Dormando



More information about the memcached mailing list