Opened 5 years ago

Closed 5 years ago

#877 closed enhancement (fixed)

Use atomic in double checked locking pattern

Reported by: Peter Owned by: Peter
Priority: major Milestone: yat 0.15
Component: random Version: trunk
Keywords: Cc:

Description

related to ticket #876

As discussed in this paper by Alexandrescu and Meyers the line

instance_ = new RNG;

is usually compiled to

  1. allocation of new RNG
  2. Construction of new RNG
  3. Assignment of instance

in which case everything is fine; however, the compiler might change the order of (2) and (3) in which case all kinds of ugly things might happen. Most seriously the if (instance_) statement returns true, i.e., a second thread might return instance_ which is not dereferencable.

This should be quite rare because RNG constructor throws on failure.

The solution is to turn member variable instance_ atomic either using boost::atomic (introduced in boost v1.53) or std::atomic (introduced in c++11).

One idea is to turn use atomic only when atomic is available with something like (not tested):

#if YAT_HAVE_STD_ATOMIC
std::atomic<RNG*> instance_;
#elif YAT_HAVE_BOOST_ATOMIC
boost::atomic<RNG*> instance_;
#else
RNG* instance_;
#endif

which then would require appropriate configure tests to set #defines YAT_HAVE_* macros.

Change History (3)

comment:1 Changed 5 years ago by Peter

Milestone: yat 0.x+yat 0.15

comment:2 Changed 5 years ago by Peter

Owner: changed from Jari Häkkinen to Peter
Status: newassigned

comment:3 Changed 5 years ago by Peter

Resolution: fixed
Status: assignedclosed

(In [3591]) fixes #877

Generalize YAT_CXX_RVALUE into YAT_CXX_TRY_CXX11 and use that to implement new macro YAT_CXX_ATOMIC. Use this macro in configure.ac and use std::atomic<> conditoionally in RNG singleton.

Note: See TracTickets for help on using tickets.