Commit ce8d05a7 authored by Kenton Varda's avatar Kenton Varda

Use Win32 synchronization APIs on Cygwin.

They are more efficient, and self-contained enough not to create trouble.

Also, Cygwin's pthread_rwlock implementation appears buggy. I am seeing it allow double locks from time to time.
parent 3d2a505f
......@@ -120,7 +120,7 @@ TEST(Mutex, MutexGuarded) {
EXPECT_EQ(321u, *value.lockExclusive());
#if !_WIN32 // Not checked on win32.
#if !_WIN32 && !__CYGWIN__ // Not checked on win32.
EXPECT_DEBUG_ANY_THROW(value.getAlreadyLockedExclusive());
EXPECT_DEBUG_ANY_THROW(value.getAlreadyLockedShared());
#endif
......
......@@ -19,7 +19,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if _WIN32
#if _WIN32 || __CYGWIN__
#define WIN32_LEAN_AND_MEAN 1 // lolz
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
......@@ -28,7 +28,7 @@
#include "mutex.h"
#include "debug.h"
#if !_WIN32
#if !_WIN32 && !__CYGWIN__
#include <time.h>
#include <errno.h>
#endif
......@@ -50,7 +50,7 @@
#define FUTEX_WAKE_PRIVATE FUTEX_WAKE
#endif
#elif _WIN32
#elif _WIN32 || __CYGWIN__
#include <windows.h>
#endif
......@@ -95,7 +95,7 @@ bool Mutex::checkPredicate(Waiter& waiter) {
return result;
}
#if !_WIN32
#if !_WIN32 && !__CYGWIN__
namespace {
TimePoint toTimePoint(struct timespec ts) {
......@@ -422,7 +422,7 @@ void Once::reset() {
}
}
#elif _WIN32
#elif _WIN32 || __CYGWIN__
// =======================================================================================
// Win32 implementation
......
......@@ -33,8 +33,14 @@
#define KJ_USE_FUTEX 1
#endif
#if !KJ_USE_FUTEX && !_WIN32
// On Linux we use futex. On other platforms we wrap pthreads.
#if !KJ_USE_FUTEX && !_WIN32 && !__CYGWIN__
// We fall back to pthreads when we don't have a better platform-specific primitive. pthreads
// mutexes are bloated, though, so we like to avoid them. Hence on Linux we use futex(), and on
// Windows we use SRW locks and friends. On Cygwin we prefer the Win32 primitives both because they
// are more efficient and because I ran into problems with Cygwin's implementation of RW locks
// seeming to allow multiple threads to lock the same mutex (but I didn't investigate very
// closely).
//
// TODO(someday): Write efficient low-level locking primitives for other platforms.
#include <pthread.h>
#endif
......@@ -101,7 +107,7 @@ private:
static constexpr uint EXCLUSIVE_REQUESTED = 1u << 30;
static constexpr uint SHARED_COUNT_MASK = EXCLUSIVE_REQUESTED - 1;
#elif _WIN32
#elif _WIN32 || __CYGWIN__
uintptr_t srwLock; // Actually an SRWLOCK, but don't want to #include <windows.h> in header.
#else
......@@ -116,7 +122,7 @@ private:
#if KJ_USE_FUTEX
uint futex;
bool hasTimeout;
#elif _WIN32
#elif _WIN32 || __CYGWIN__
uintptr_t condvar;
// Actually CONDITION_VARIABLE, but don't want to #include <windows.h> in header.
#else
......@@ -135,7 +141,7 @@ private:
inline void addWaiter(Waiter& waiter);
inline void removeWaiter(Waiter& waiter);
bool checkPredicate(Waiter& waiter);
#if _WIN32
#if _WIN32 || __CYGWIN__
void wakeReadyWaiter(Waiter* waiterToSkip);
#endif
};
......@@ -160,7 +166,7 @@ public:
void runOnce(Initializer& init);
#if _WIN32 // TODO(perf): Can we make this inline on win32 somehow?
#if _WIN32 || __CYGWIN__ // TODO(perf): Can we make this inline on win32 somehow?
bool isInitialized() noexcept;
#else
......@@ -190,7 +196,7 @@ private:
INITIALIZED
};
#elif _WIN32
#elif _WIN32 || __CYGWIN__
uintptr_t initOnce; // Actually an INIT_ONCE, but don't want to #include <windows.h> in header.
#else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment