Is incr/decr atomic in multithread mode?

Paul van den Bogaard Paul.Vandenbogaard at Sun.COM
Mon Feb 25 12:02:35 UTC 2008


if there are too many mutex calls these can become scalability  
issues. Solaris 10 has some atomic routines that could be helpfull.
See http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/ 
common/sys/atomic.h

for the routines.

Of course if multiple operations are needed that need the protection  
of a mutex than a atomic operation is no alternative, besides a CPU  
consuming polling device. And sometimes these come in handy too.

--Paul


On 25-feb-2008, at 10:53, 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?
>
>>  A -> runs out_string(c, temp), with 'temp' having the atomically
>>  incremented value.
>>  A -> inside out_string, copy's the contents of the original 'temp'
>>  buffer into the connection's local write buffer, then sets the
>>  connection into write mode (which will flush its buffer before doing
>>  further processing). Then returns.
>>  A -> returns to the state machine, 'temp' goes to the wolves, etc.
>>  A -> sends value '2' to its client.
>>
>>  B -> Same thing. Client should receive a '3'.
>>
>>  Apologies to the original patch author and the list for the  
>> confusion :)
>>  I had mentally confused "normal" responses and "get" responses,  
>> which
>>  operate differently.
>>
>>  -Dormando
>>
>>
>>
>>>>  It's possible that with two threads (A, B):
>>>>
>>>>  X -> set "foo" 1
>>>>  A -> incr "foo" by 1
>>>>  B -> incr "foo" by 1
>>>>
>>>>  A -> returns 3
>>>>  B -> returns 3
>>>>
>>>>  The only guarantee the slabber makes for returning values, is  
>>>> that they
>>>>  won't get deleted before being transferred through the network.
>>>>
>>>>  Could be wrong, but that's my impression from checking the  
>>>> sources.
>>>>
>>>>  -Dormando
>>>>
>>>>
>>>>
>>>>  Steve Chu wrote:
>>>>> In 'process_arithmetic_command' function:
>>>>> We first do item_get from slabs and then do add_delta to incr/ 
>>>>> decr the value.
>>>>>
>>>>> My question is:
>>>>> Is this atomic in multithread mode? Item_get is atomic and so is
>>>>> add_delta because they are protected by mutex. But the entire two
>>>>> operations seems NOT atomic. Two threads can both do item_get with
>>>>> same key, then both incr it, and write back.
>>>>>
>>>>> Anybody can tell me whether it is a bug or not?
>>>>>
>>>>> Regards,
>>>>>
>>>>> Steve Chu
>>>>
>>>>
>>>
>>
>>
>
>
>
> -- 
> Steve Chu
> http://stvchu.org

------------------------------------------------------------------------ 
---------------------
Paul van den Bogaard                                
Paul.vandenBogaard at sun.com
ISV-E  -- ISV Engineering, Opensource Engineering group

Sun Microsystems, Inc                              phone:        +31  
334 515 918
Saturnus 1                                                  
extentsion: x (70)15918
3824 ME Amersfoort                                 mobile:       +31  
651 913 354
The Netherlands                                         
fax:            +31 334 515 001



More information about the memcached mailing list