c++ - Compare some atomic exchange other -
what need today atomic operations rather tricky , i'd help. in nutshell, perform following operation atomically:
/* begin of atomicity */ if (--counter == 0) { widget* widget = nullptr; swap(some_widget, widget); /* end of atomicity */ // use local 'widget' here } /* end of atomicity */ i aware of c++11 atomics , intrinsics. previous code pseudo , intended show happen atomically. know 1 solution make counter have "transition" state (example 0xffffffff) , change value moving transition first , new value: analogous spinlock. idea on how efficiently (i.e. no spinlocks, no mutexes, , possibly no waits)?
thank much.
assuming c++11, want atomic fetch_and_add, work results.
for example:
std::atomic<int> counter = 20; if (counter.fetch_sub(1) == 1) /* return value old value */ { widget* widget = nullptr; swap(some_widget, widget); } if counter used across threads, need ensure compiler , hardware not mess memory ordering. default ordering std::atomic<>.fetch_sub() std::memory_order_seq_cst fine, if want win on e.g. arm64, can reduce std::memory_order_acquire.
to make swap operation fit in above scheme, need lock. interestingly, fits "double checked lock" pattern, frowned upon rather useful here - operations not suffer lock, when counts, it's there. here's how:
std::atomic<int> counter = 20; std::mutex counterlock; std::atomic<widget*> some_widget; ... if (counter.load(std::memory_order_acquire) > 5) /* first check whether we're "close enough" */ { /* lock when needed */ std::lock_guard<std::mutex> templock(counterlock); /* free lock whenever exit scope */ if (counter.fetch_sub(1) == 1) /* return value old value */ { widget* oldwidgetpr = some_widget.exchange(nullptr, std::memory_ordering_release); /* whatever need oldwidgetptr */ } } else counter.fetch_sub(1);
Comments
Post a Comment