Boost logo

Boost :

Subject: [boost] [thread] A few submissions
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2010-07-04 13:15:43


Hi,

I would like to propose the following components for inclusion into
Boost.Thread:

1. Once-blocks. This is a flavor of the "once" concept. One can define a
block of code that should be executed only once, like that:

   void foo()
   {
     BOOST_LOG_ONCE_BLOCK()
     {
       puts("Hello, world once!");
     }
   }

The code within the block can access names (e.g. variables) as if it was
a usual code block.

Why not call_once:

* The once-code is defined in-place, which greatly simplifies usage in
many cases. One of the main goals of the "once" concept is the dynamic
initialization, which involves the variables being initialized. With
once-blocks there is no need bind these variables into a functor.
Once-blocks are also easier to be used within a macro.
* The resulting code is much shorter since the thread synchronization
code is separated from the once-code. call_once is instantiated with
each once-functor, although the synchronization code is the same.
* The once-flag is smaller on Windows. In fact, unlike call_once, the
behavior on Windows is equivalent to POSIX.
* It has ticket #4225 fixed.

If this component is accepted, I would also like to port call_once to
once-blocks.

Source code:

<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/boost/log/utility/once_block.hpp>
<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/libs/log/src/once_block.cpp>

2. Lightweight read/write mutex. Basically, I want a portable analogue
for pthread_rwlock_t, with minimum dependencies, code size and memory
footprint. Naturally, it is compatible with Boost.Thread locks.

Why not shared_mutex:

* shared_mutex.hpp depends on a lot of other headers. It brings in a
great deal of Boost.DateTime, although I don't need the timed methods at
all.
* It offers more than I ever use. I don't need upgradeability.
* It is larger than pthread_rwlock_t on POSIX systems (on Linux x64 it's
192 bytes vs 56). On Windows NT 6 it can be implemented through SRWLOCK,
which is of size of one pointer.
* I remember there were reports that shared_mutex is slower than
pthread_rwlock_t. But I haven't done testing, so I won't press it.

Source code:

<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/boost/log/detail/light_rw_mutex.hpp>
<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/libs/log/src/light_rw_mutex.cpp>

3. Lightweight thread-local storage for small POD values. Allows to
store POD values of size up to sizeof(void*) with least possible
overhead, memory and performance-vise.

   thread_specific< int > tls;

Why not thread_specific_ptr:

* thread_specific_ptr performance depends on the total number of ptrs
within the application as it involves an additional lookup among them on
access. thread_local does nothing more than abstracting away the native
API for TLS, so it provides better performance.
* thread_specific_ptr requires to dynamically allocate memory even for
tiniest things, like bool or int. This is inconvenient and awkward,
especially when memory and exception safety matters.

<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/boost/log/detail/thread_specific.hpp>
<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/libs/log/src/thread_specific.cpp>

A few notes up-front. There are extensions in some compilers for TLS
support. It offers even better performance and easier to use. Also,
C++0x will bring this feature into the language. But:
* It is known to have problems with dynamically-loaded modules.
* It is not portable. Even when C++0x it out, not all compilers will
support it right away.
* thread_specific does not require the variable to have a static storage
duration.

4. shared_lock_guard. A light analogue to shared_lock, which allows to
generate a more efficient code. Ticket #3567.

Source code:

<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/boost/log/detail/locks.hpp>

As a part of this addition I would like to improve segregation of
boost/thread/locks.hpp by extracting every component within it into a
separate header in a new "locks" directory.

5. The strictest_lock metafunction. Given the list of lock types, it
selects the one that offers the strictest concurrency guarantees (i.e.
shared lock is stricter than no lock at all, exclusive lock is stricter
than shared lock). This metafunction can be useful in generic code,
where the final lock type must be deduced.

Source code:

<http://boost-log.svn.sourceforge.net/viewvc/boost-log/trunk/boost-log/boost/log/utility/strictest_lock.hpp>

I understand that some of these tools might seem specific to my case,
but I think they could be useful in general. If any of these tools is
accepted into Boost.Thread, the code is not set in stone - namings and
implementation details can be changed, if needed. I can do the code
transition, write docs and a few tests, if needed. Just let me know if
either of these is of interest and whether I am allowed to do so.

PS: If you want SVN access to all these things, it is available on the
SourceForge:

<http://sourceforge.net/scm/?type=svn&group_id=199644>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk