Portable c++ atomic swap (Windows - GNU/Linux - MacOSX) - c++

Is there free a portable (Windows, GNU/Linux & MacOSX) library providing a lock-free atomic swap function?
If not, how would it be implemented for each of these platforms? (x86 with VC++ or g++)
Thanks

There's a lock-free library pending review in boost. Also if you dig into source of boost smart pointers library you will find atomic ops inlined for multiple platforms. Another one - Intel Threading Building Blocks has implementation of atomic<> template.

Depends what you want to swap. In assembler for x86 you might be able to get a "nearly" atomic xor swap, otherwise I'd go with some solution that uses locking, which will differ on Win32/{Linux,Darwin}.
If you are looking for a library, have a look at APR (Apache Portable Runtime) - http://apr.apache.org/

Boost has a set of macros for facilitating lock-free operations in a portable way.

Related

Linux threads for dummies. Can some one explain the difference between multi-thread libraries in linux?

New to linux and c++.
I wante to create an application that only needs to run on linux (ubuntuz) and i need to use basic read-write locks.
I saw that there are a few libraries that give "concurrency capabilities".
e.g. to use mutexes, there are at least 3 options:
pthread_mutex_lock (pthread.h)
boost::mutex
std::mutex (mutex)
could someone explain the differences between the various approaches?
pthreads is a C-API and is available on all posix conformant systems (pthreads stands for Posix THREADS).
boost::mutex is a C++-only API that depends on the "boost"-library (you cannot use it in C-code; you add a dependency on "boost")
lots of features from boost will eventually end up in the C++ standard library, e.g. threading; with C++11 you have std::mutex, but you will need a compiler recent enough to support that recent addition. e.g. if you want your application to be backportable to older distributions you might want to avoid it.
std::mutex is part of the standard library. Every C++ compiler/library vendor is free to implement it in any way they like. A library implementation for Posix will more likely than not just use pthreads under the hood, while for instance a Windows library would use the Windows API primitives.
If you can, use std::mutex, but if you don't have C++11 support yet, write your own SBRM classes that wrap the pthread mutex and locking primitives, or use Boost if that's feasible (e.g. if your project already uses Boost anyway). It'll all come down to the same thing anyway.

Interlocked ops vs XXX::atomic on Win32

What are the advantages and disadvantages of using Interlocked winapi functions instead of any library provides atomic operations on Win32 platform?
Portability is not an issue.
If portability is not a concern then you're basically down to deciding whom you trust more to get this right. A library is generally designed to provide portability. It otherwise has a tough time competing with an OS provided implementation that's been battle-hardened for over 15 years.
Check this thread to see an example of how the obvious implementation is not in fact the best.
The Interlocked winapi functions work on old processors even when there is no CPU support for locked operations. 386 and maybe 486, not really a issue today unless you still support Win9x and older NT.
It would likely depend up on the specific atomic library in question.
A good library with a specific back-end would likely end up with the same implementation of a couple of ASM instructions to issue an x86 lock instruction and do their work. And assuming the library itself is portable, subsequently make your code portable.
A naive atomic implementation might do something heavier like use a mutex to protect a normal variable. I don't know of any that do - just making the point for argument.
As such, given your stated non-portability requirements, using the Win32 functions should be fine. Alternately, go ahead with an Atomic version, but perhaps look at the actual implementation.

Is there any cross-platform threading library in C++?

I'm looking for some easy to use cross-platform threading library written in C++.
What's your opinion on boost::thread or Pthreads?
Does Pthreads run only on POSIX compliant systems?
What about the threading support in the Qt library?
Boost.Thread is the draft for the coming standard threading library of the C++ language. Knowing that, I prefer to use it as it provide some strong guarantees (because it becomes standard).
Update: Now that we have the standard threading libraries, some more precisions. Some boost constructs, like boost::shared_mutex, have not been standardised (but might be later). However the standard library exploit the move semantic better. Good to know before choosing a library. Also, using C++11 threading library requires a compiler that provides it. It's not the case for all compilers today.
Update:
Now [Nov2012] most of the Standard compilers provide C++11 threading library. VS2012, GCC4.8 and Clang3.1 have support for threads and synchronization primitives and atomic operations.
For complete implementation you can also use just thread by Anthony Williams. It is C++11 compliant library supported on Windows/Mac and Linux.
Links for status of C++11 features with various compilers:
GCC 4.8 - http://gcc.gnu.org/gcc-4.8/cxx0x_status.html
Clang3.1 - http://clang.llvm.org/cxx_status.html
VS2012 - http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx
There is a threading library coming with C++11. It's built upon the boost threading library. Unfortunately, I seem to remember that there are non-trivial differences between Boost.Threads and what C++11 comes with. Still, if you plan to switch to the C++ standard threading library, I believe Boost.Threads is the closest you can get to now.
I suppose that, under the hood, these libraries will use Pthreads on POSIX systems and whatever native threading support is available elsewhere.
Disclaimer: I haven't worked with either of the two.
Pthreads are running only on POSIX systems. QThread from Qt is a way to go. It is available on platforms: Linux, Mac OS X, Windows, Embedded Linux, Windows CE, Symbian, Maemo.
Also have a look at OpenMP, it's a set of (somewhat standard) pragmas specifications that is supported by most major compilers. The good of OpenMP is that it's simple and that your code can be easily compiled in both single and multi-threaded versions.
Just a simple example:
std::vector<double> a, b;
...
double sum = 0.0;
...
#pragma omp parallel for reduction(+:sum)
for (i=0; i < n; i++)
sum = sum + (a[i] * b[i]);
It's obviously possible to do also more complex things.
I am surprised that nobody mentioned the Intel TBB library (linked to an another answer of mine). Also, a task-based implementation should be preferred over a thread-based.
Qt has pretty good thread support. If you just need to create a thread and run some code in it, QThread is all you need. There are many other high-level classes that can help you with thread pools or even abstract the concurrent execution (the QtConcurrent framework).
List the concerning platforms. If you're only using say, Linux/Mac/Windows, then boost::thread will likely do you fine until C++0x (harhar) provides std::thread.
I have used pthreads for code that work on multiple platforms. To get around the Windows lack of pthreads, I have used the following open source library with great success: POSIX Threads for Windows
wxWidgets has thread classes, and as wxWidgets is platform independent, it might just be the best thing for u.
Boost.Threads is built on top of PThreads on UNIX systems and Win32 Threads on Windows.
The boost library is syntactically simple and all of the hairy business of properly interfacing C++ code with C libraries is taken care of behind the scenes. If you're not very comfortable with C++, however, PThreads might seem more straight-forward with its simple C API.
Qt Threads is also a good library, but because I use several other boost libraries, I'll compile and link against Boost no matter what. I might not always link against Qt. And, well, I just don't want to remember how to use two different libraries.
SDL is simple, cross-platform and has threading support.
Pthread is part of Posix, but not every posix systems will have threads. pthreads is most portable.
What platforms will you support?

Memory barriers in userspace? (Linux, x86-64)

It is easy to set memory barriers on the kernel side: the macros mb, wmb, rmb, etc. are always in place thanks to the Linux kernel headers.
How to accomplish this on the user side?
You are looking for the full memory barrier atomic builtins of gcc.
Please note the detail on the reference i gave here says,
The [following] builtins are intended to be compatible with those described in the Intel Itanium Processor-specific Application Binary Interface, section 7.4. As such, they depart from the normal GCC practice of using the “__builtin_” prefix, and further that they are overloaded such that they work on multiple types.
Posix defines a number of functions as acting as memory barriers. Memory locations must not be concurrently accessed; to prevent this, use synchronization - and that synchronization will also work as a barrier.
Use libatomic_ops. http://www.hpl.hp.com/research/linux/atomic_ops/
It's not compiler-specific, and less buggy than the GCC stuff. It's not a giganto-library that provides tons of functionality you don't care about. It just provides atomic operations. Also, it's portable to different CPU architectures.
Linux x64 means you can use the Intel memory barrier instructions.
You might wrap them in macros similar to those in the Linux headers, if
those macros aren't appropriate or accessible to your code
__sync_synchronize() in GCC 4.4+
The Intel Memory Ordering White Paper, a section from Volume 3A of Intel 64 and IA-32 manual http://developer.intel.com/Assets/PDF/manual/253668.pdf
The Qprof profiling library (nothing to do with Qt) also includes in its source code a library of atomic operations, including memory barriers. They work on many compilers and architectures. I'm using it on a project of mine.
http://www.hpl.hp.com/research/linux/qprof/download.php4
The include/arch/qatomic_*.h headers of a recent Qt distribution include (LGPL) code for a lot of architectures and all kinds of memory barriers (acquire, release, both).
Simply borrowing barriers defined for Linux kernel, just add those macros to your header file: http://lxr.linux.no/#linux+v3.6.5/arch/x86/include/asm/barrier.h#L21 . And of course, give Linux developers credit in your source code.

Interlocked equivalent on Linux

In a C++ Linux app, what is the simplest way to get the functionality that the Interlocked functions on Win32 provide? Specifically, a lightweight way to atomically increment or add 32 or 64 bit integers?
Just few notes to clarify the issue which has nothing to do with Linux.
RWM (read-modify-write) operations and those that do not execute in a single-step need the hardware-support to execute atomically; among them increments and decrements, fetch_and_add, etc.
For some architecture (including I386, AMD_64 and IA64) gcc has a built-in support for atomic memory access, therefore no external libray is required. Here you can read some information about the API.
Intel's open-source ThreadBuildingBlocks has a template, Atomic, that offers the same functionality as .NET's Interlocked class.
Unlike gcc's Atomic built-ins, it's cross platform and doesn't depend on a particular compiler. As Nemanja Trifunovic correctly points out above, it does depend on the compare-and-swap CPU instruction provided by x86 and Itanium chips. I guess you wouldn't expect anything else from an Intel library : )
Strictly speaking, Linux cannot offer atomic "interlocked" functions like ones in Win32, simply because these functions require hardware support, and Linux runs on some platforms that don't offer that support. Having said that, if you can constrain yourself to Intel x86/x64, take a look at the implementation of reference counting in Boost shared pointers library.
The atomic functions from the Apache Portable Runtime are really close to the Win32 InterlockedXXX functions.
You can insert some assembly code in your source, to use x68 interlocked instructions directly.
You should use a lock xadd operation.
See for instance this.
The fairly common glib library that's used in GTK and QT programming as well as standalone offers a variety of atomic operations. See http://library.gnome.org/devel/glib/2.16/glib-Atomic-Operations.html for a list. There are g_atomic functions for most of the operations that Interlocked supports on Win32, and on platforms where the hardware directly supports these, they are inlined as the needed assembly code.
Upon further review, this looks promising. Yay stack overflow.