As every programmer worth his salt knows, synchronization primitives form the very building blocks of multithreaded programming. Without them, the world as we know it would cease to exist and chaos would reign free and unchecked.
All joking aside, synchronization objects such as mutexes and semaphores are essential to safe multithreading and are found on just about any platform under the sun. Mutexes and semaphores alike have one purpose: to keep different threads from messing around with bits and bytes at the same time another thread is, keeping your code free of segfaults and memory access violations alike. But that’s about where the similarities between the synchronization primitives on different platforms end.
POSIX-compliant operating systems with pthreads offer additional really neat synchronization primitives not found on Windows, such as condition variables and read-write locks (the latter is now available on Windows Vista+). And Windows programmers have at their disposal automatic and manual reset events, which make designing certain types of multithreaded software incredibly easy, abstracting away much of the hard-core synchronization logic that lies beneath the hood.
We’ve decided to open source two libraries we’ve found useful in transitioning from Windows development to Linux and from Linux development to Windows. The first (and most important) is an implementation of WIN32 manual/auto-reset events for Linux. While there’s nothing WIN32 events can do that POSIX condition variables can’t, the differences between the syntax and usage semantics of both has resulted in entirely different programming paradigms on the different platforms, making it hard for some developers to port code from one platform to the other or even write code from scratch on the platform they’re unfamiliar with.
Enter pevents. pevents is a C++ library (easily portable to C) for *nix platforms that provides an implementation of WIN32 events on Linux, giving developers access to the CreateEvent, SetEvent, ResetEvent, and WaitForSingleObject functions that make them feel warm and fuzzy inside. More importantly and unlike all the other efforts at porting WIN32 events to *nix in the past, pevents also has support for the all-important WaitForMultipleObjects. WFMO is an important concept in multithreaded programming on Windows, and allows a developer to wait in the kernel until one or more events has fired (or, alternatively, until they have all fired) with a single line of code, resulting in high-performance synchronization waits.
While *nix zealots have long maintained that WaitForMultipleObjects encourages bad programming practices, the fact remains that it can be a powerful tool in the arsenal of a good developer… and any claims that WaitForMultipleObjects is inherently flawed as it leads to the loss of events are outright incorrect statements that only those unfamiliar with correct multithreaded programming on Windows would say. With pevents, Windows developers can feel right at home on Linux/*nix with access to WIN32 events in both manual and auto-reset flavors (MSDN explanation for the uninitiated) with both WaitForSingleObject and WaitForMultipleObjects functions.
On the other hand, *nix developers have long had at their fingertips powerful and lightweight locks adapted for the readers-writers problem (Wikipedia overview). ReadWrite locks (pthread_rwlock_t) are powerful objects that can drastically improve multithreaded performance by allowing unlimited simultaneous read-only access to shared variables while only limiting access to one thread at a time for writing purposes. Microsoft has realized the importance of this over time, and with Windows Vista now has support for read-write locks in the kernel (SRW Locks).
However, as very few developers today are free to target only Vista and above, we have written RWLocks for Windows, a library which provides access to three different flavors of read-write locks, with advanced features not found in either pthread_rwlock_t on POSIX and SRW Locks on Vista such as support for cross-process synchronization, reentrance support, and writer -> reader declination.
Both these libraries are released under the terms of the MIT license and hosted on github. These libraries were developed from the ground-up to be as minimalistic, lightweight and fast as possible (though WFMO requires a bit more overhead and can be disabled at compile-time for better performance). Fork, use, and contribute your changes back. Enjoy!
Please note that these are on-going projects still undergoing development and maintenance. WFMO support in particular is in BETA and can be #define’d out if it’s not required.
Find anything wrong? Drop us an email at firstname.lastname@example.org, comment below, or fork the code at github.