Skip to content
Ken Raffenetti edited this page Aug 24, 2018 · 1 revision

What is OPA?

OPA (or sometimes OpenPA or Open Portable Atomics) is an open source library intended to provide a consistent C API for performing atomic operations on a variety of platforms. The main goal of the project is to enable the portable usage of atomic operations in concurrent software. Developers of client software can worry about implementing and improving their concurrent algorithms instead of fiddling with inline assembly syntax and learning new assembly dialects in order improve or maintain application portability.

See the Overview page for more info on the design goals, source layout, and usage of OPA.

Under what license is OPA available?

OPA is licensed under a very permissive MIT-style license. No attribution is required and it is not viral like the GPL.

Why should I use this instead of writing my own assembly by hand?

Code that uses OPA will never beat hand written and tuned code for size and performance, so if you are a strong assembly programmer and absolutely can't spare a processor cycle or two in some circumstances then you probably should not use OPA. However with that said, OPA is designed to have low overhead and is intended for use in performance sensitive code. OPA is great for several concurrent programming scenarios:

  • You don't know assembly language very well or don't know it on a particular platform that you want to target.
  • You need a non-GPL encumbered reference implementation for atomic assembly instructions on some platform that OPA already supports.
  • Your software needs to be portable to many different platforms (where platform is a particular processor architecture plus compiler version) and you don't have the time, wherewithal, and/or knowledge to implement the necessary assembly routines for said platforms.
  • You want to experiment with a new or existing concurrent algorithm using atomic operations but don't want to be distracted by writing assembly.

Also OPA has a substantive unit test suite that is still undergoing expansion and improvement. Most roll-your-own assembly libraries lack adequate testing.

Why should I use this instead of libatomic_ops?

(libatomic_ops info can be found here)

Well, for starters you can get the latest version of OPA without extracting it from the Boehm-Demers-Weiser garbage collector, not that that is an overly onerous hurdle.

At the time that we started working on OPA the libatomic_ops project looked like it was no longer under active development. At this point libatomic_ops appears to be in good shape and cover most of the same ground as OPA and quite a bit more in some areas. It is a more complex implementation with a much larger API because of the combination of atomic operations with memory barriers. That approach provides a better opportunity to emit an ideal sequence of assembly instructions, particularly when memory barriers are involved.

One of the lock-free algorithms used in MPICH2 (from which OPA was originally derived) requires a compare-and-swap operation that returns the read value, regardless of the success or failure of the swap. libatomic_ops does not appear to provide such an operation. Similarly, MPICH2 also requires a swap operation, which isn't provided by libatomic_ops. So if you need either of these operations, you might be better off with OPA instead.

OPA's type abstraction is currently always a struct type to help catch programming mistakes from incorrectly aligning data, incorrectly manipulating volatile variables, and passing non-volatile variables to atomic operation functions. We feel that this is a better approach in terms of usability and programming safety, two aspects that often suffer when dealing with atomic operations.

OPA's testing appears to be more substantial and detailed than that of libatomic_ops.

All in all, the libatomic_ops developers appear to have done some very nice work that should serve the needs of many software projects. We (the OPA developers) have made certain design decisions that are more suited for other projects. Please use whatever library makes the most sense for your project.

Why should I use this instead of libsync?

(libsync can be found here)

libsync doesn't appear to be as portable as OPA. It also has an URCU implementation which is currently out of scope for OPA.

Why should I use this instead of GCC atomic intrinsics?

(GCC atomic intrinsics info can be found here)

They aren't overly portable because they are only available in gcc-4.1 and later. Most other compilers haven't implemented them and there are still plenty of pre-4.1 gcc compilers out there. For example Mac OS X 10.5 currently ships with gcc-4.0.1 by default. Also all of the operations include a full memory barrier as part of the operation which can be expensive on non-Intel platforms.

What are the memory barrier semantics associated with the OPA_foo_bar primitive?

They are undefined. For simplicity of API and implementation OPA keeps the atomic operations separate from the memory barriers. This can lead to superfluous memory barriers on some platforms where the operations have ordering properties.

Where are the load-store, store-load, acquire, release, etc. memory barriers?

They don't currently exist. We only provide load-load, store-store, and full memory barriers at this time. This shortcoming should be rectified in a future release. Please contact us if you need them sooner rather than later for some reason.

Does OPA provide mutexes or reader-writer locks?

No. The operating system scheduling policies play a big factor in the implementation of these sorts of mechanisms, which puts them out of scope for OPA right now. Also it is unlikely that we would be able to develop any substantially faster implementations of these traditional concurrency controls than is present in most system threading libraries such as pthreads.

Does OPA work on platform XYZ?

Please see the README for a current list of supported platforms. At the time of this writing OPA supports GCC inline assembly for x86, x86_64, ia64, PPC 440, and MIPS 5K processors. Several compilers with GCC-compatible-ish front-ends are also supported on the same architectures, such as icc, PGI, and IBM's xlc. GCC atomic intrinsics are supported as a target, so most GCC 4.1+ installations should be supported. Sun's atomic operations library on Solaris is supported. Windows NT intrinsics in MS Visual Studio are supported.

Two special pseudo-platforms are supported as well. One is a pthreads mutex-based emulation for the primitives. This is a low performance implementation but it is good for testing and just making OPA client code run on an otherwise unsupported platform. The other pseudo-platform is the "unsafe" implementation which is intended for meta-testing and providing an efficient single-threaded implementation in non-concurrent code without jumping through any special conditional compilation hoops.

How do I build OPA on Windows?

Very carefully.

In all seriousness though, without a Cygwin installation there isn't any build system currently in place for Windows. You can basically "build" it by copying the src directory over to the installation directory and fill in the right values for opa_config.h. That would be pretty simple except the opa_config.h isn't a normal config.h, it's created by AX_PREFIX_CONFIG_H. Please mail the list if you need help with this or if you wish to contribute a proper build system.