On 2013-10-12 06:16:17 +0000, Rainer Schuetze <r.sagita...@gmx.de> said:

On 12.10.2013 04:16, inout wrote:
On Thursday, 10 October 2013 at 08:55:00 UTC, Robert Schadek
wrote:
I would imagine the counter to be manipulated with atomic_add_and_fetch
operations, so no locks are required.

On shared objects, yes. Local objects need no atomics at all.

Atomic increments/decrements are not good enough for shared references. See this example from later in the discussion:

Consider a global shared reference R that holds the last reference to an object O. One thread exchanges the reference with another reference P while another thread reads the reference into S.

shared(C) R = O;      ; refcnt of O is 1

in pseudo-assembly missing null-checks:

Thread1 (R = P)        Thread2 (S = R)

                        mov ecx,[R]
                        ; thread suspended
mov eax,[P]
inc [eax].refcnt
mov ebx,[R]
mov [R],eax
dec [ebx].refcnt      ; refcnt of O now 0
jnz done
call delete_ebx
                        ; thread resumed
                        inc [ecx].refcnt
done:

The increment on [ecx].refcnt modifies garbage.

I think you are mixing shared references with shared objects. Atomic increment/decrement will work fine for shared objects with unshared pointers to it. But if the pointer to the object is itself shared and available from two threads (as in your example) then you need to properly serialize reads and writes to that pointer (with a mutex or through other means).

Of course, then you fall into the problem that in D you are not able to set different attributes to an object and to its reference. (Hint: const(Object)ref)

--
Michel Fortin
michel.for...@michelf.ca
http://michelf.ca

Reply via email to