Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

atomic shared pointer #12

Closed
P-p-H-d opened this issue Aug 19, 2017 · 1 comment
Closed

atomic shared pointer #12

P-p-H-d opened this issue Aug 19, 2017 · 1 comment
Labels
enhancement MOVED Moved to ISSUES.org

Comments

@P-p-H-d
Copy link
Owner

P-p-H-d commented Aug 19, 2017

Extension to the SHARED_PTR API :

  • New type atomic_shared_ptr
  • name_init_atomic_set (&atomic_shared_ptr, shared_ptr);
  • name_init_set_atomic (shared_ptr, &atomic_shared_ptr);
  • name_init_atomic_set_atomic (&atomic_shared_ptr, &atomic_shared_ptr);
  • name_atomic_set (&atomic_shared_ptr, shared_ptr);
  • name_set_atomic (shared_ptr, &atomic_shared_ptr);
  • name_atomic_set_atomic (&atomic_shared_ptr, &atomic_shared_ptr);
  • name_atomic_clear

No _ref or direct _init: we need to init first a normal shared_ptr then the atomic (TBC)

_atomic_set

It can be implemented by incrementing the non atomic shared pointer reference, then performs a compare_and_swap to the data of the atomic shared pointer, finally decrement and dec/free the swapped previous data of the atomic .

_set_atomic

It needs to perform the following atomic operation : <read the pointer, deref pointer and increment the pointed value> I don't known how to do it properly.

See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4162.pdf

@P-p-H-d
Copy link
Owner Author

P-p-H-d commented Aug 21, 2017

Proposition for _set_atomic we store temporary NULL to the atomic_ptr struct to request an exclusive access to the data (this looks like a lock and other operations need to handle NULL) :

void shared_ptr_set_atomic(ptr a, atomic_ptr *ptr)
{
  // Get exclusive access to the data
  p = atomic_load(ptr);
  do {
    if (p == NULL) {
      // TODO: exponential backoff
      p = atomic_load(ptr);
      continue;
    }
  } while (!atomic_compare_exchange_weak(ptr, &p, NULL));
  // p has exclusive access to the pointer
  p->data->cpt ++;
  a->data = p->data;
  atomic_exchange (ptr, p);
}

This prevents using NULL which obliges atomic shared pointer to point to a created object...

Other alternative solution is to use the bit 0 to mark the pointer as being updated, preventing other from using it (TBC only clear):

void shared_ptr_set_atomic(ptr a, atomic_ptr *ptr)
{
  // Get exclusive access to the data
  p = atomic_load(ptr);
  do {
    if ( (p&1) != 0) {
      // TODO: exponential backoff
      p = atomic_load(ptr);
      continue;
    }
  } while (!atomic_compare_exchange_weak(ptr, &p, p|1));
 // Exclusive access (kind of lock).
  p->data->cpt ++;
  a->data = p->data;
  atomic_set (ptr, p);
}

Other implementation seems to have it hard to be lock-free: cf. llvm-mirror/libcxx@5fec82d

@P-p-H-d P-p-H-d added the MOVED Moved to ISSUES.org label Jul 20, 2018
@P-p-H-d P-p-H-d closed this as completed Jul 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement MOVED Moved to ISSUES.org
Projects
None yet
Development

No branches or pull requests

1 participant