1
0
Fork 0

removed spinlocks and TRI_WINDOWS_VISTA_LOCKS

This commit is contained in:
Jan Steemann 2016-01-25 17:54:09 +01:00
parent 301749e48f
commit 5dc0a429b2
20 changed files with 8 additions and 1084 deletions

View File

@ -27,12 +27,10 @@
#define ARANGOD_HTTP_SERVER_HTTP_SERVER_H 1
#include "Basics/Mutex.h"
#include "Basics/SpinLock.h"
#include "HttpServer/HttpHandler.h"
#include "Rest/ConnectionInfo.h"
#include "Scheduler/TaskManager.h"
namespace arangodb {
namespace rest {

View File

@ -28,8 +28,6 @@
#include "Basics/Common.h"
#include "Scheduler/Scheduler.h"
#include "Basics/Mutex.h"
#include "Basics/SpinLock.h"
namespace arangodb {
namespace rest {

View File

@ -26,7 +26,6 @@
#include "Basics/logging.h"
#include "Basics/MutexLocker.h"
#include "Basics/SpinLocker.h"
#include "velocypack/Value.h"
#include "velocypack/Builder.h"
#include "velocypack/velocypack-aliases.h"
@ -41,11 +40,7 @@
using namespace arangodb::basics;
using namespace arangodb::rest;
#ifdef TRI_USE_SPIN_LOCK_SCHEDULER_THREAD
#define SCHEDULER_LOCKER(a) SPIN_LOCKER(a)
#else
#define SCHEDULER_LOCKER(a) MUTEX_LOCKER(a)
#endif
SchedulerThread::SchedulerThread(Scheduler* scheduler, EventLoop loop,
bool defaultLoop)

View File

@ -30,21 +30,16 @@
#include <boost/lockfree/queue.hpp>
#include "Basics/Mutex.h"
#include "Basics/SpinLock.h"
#include "Basics/Thread.h"
#include "Scheduler/Task.h"
#include "Scheduler/TaskManager.h"
#include <deque>
// #define TRI_USE_SPIN_LOCK_SCHEDULER_THREAD 1
namespace arangodb {
namespace rest {
class Scheduler;
/////////////////////////////////////////////////////////////////////////////
/// @brief job scheduler thread
/////////////////////////////////////////////////////////////////////////////
@ -54,14 +49,10 @@ class SchedulerThread : public basics::Thread, private TaskManager {
SchedulerThread(SchedulerThread const&);
SchedulerThread& operator=(SchedulerThread const&);
public:
SchedulerThread(Scheduler*, EventLoop, bool defaultLoop);
~SchedulerThread();
public:
//////////////////////////////////////////////////////////////////////////////
@ -111,9 +102,7 @@ class SchedulerThread : public basics::Thread, private TaskManager {
void run();
void addStatus(arangodb::velocypack::Builder* b);
private:
//////////////////////////////////////////////////////////////////////////////
@ -174,11 +163,7 @@ class SchedulerThread : public basics::Thread, private TaskManager {
/// @brief queue lock
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_USE_SPIN_LOCK_SCHEDULER_THREAD
arangodb::basics::SpinLock _queueLock;
#else
arangodb::basics::Mutex _queueLock;
#endif
//////////////////////////////////////////////////////////////////////////////
/// @brief work queue

View File

@ -42,8 +42,6 @@
#include "Basics/memory-map.h"
#include "Basics/MutexLocker.h"
#include "Basics/random.h"
#include "Basics/SpinLock.h"
#include "Basics/SpinLocker.h"
#include "Basics/tri-strings.h"
#include "Cluster/ServerState.h"
#include "Utils/CursorRepository.h"

View File

@ -190,15 +190,11 @@ static inline void TRI_MemoryPrefetch(void* p) {}
#define TRI_CHAR_LENGTH_PAIR(value) (value), strlen(value)
////////////////////////////////////////////////////////////////////////////////
/// @brief fake spinlocks
/// spin locks seem to have issues when used under Valgrind
/// we thus mimic spinlocks using ordinary mutexes when in maintainer mode
/// @brief asserts
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_ENABLE_MAINTAINER_MODE
#define TRI_FAKE_SPIN_LOCKS 1
#ifndef TRI_ASSERT
#define TRI_ASSERT(expr) \
{ \
@ -218,8 +214,6 @@ static inline void TRI_MemoryPrefetch(void* p) {}
#else
#undef TRI_FAKE_SPIN_LOCKS
#ifndef TRI_ASSERT
#define TRI_ASSERT(expr) \
do { \

View File

@ -1,55 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
////////////////////////////////////////////////////////////////////////////////
#include "SpinLock.h"
using namespace arangodb::basics;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a spinlock
////////////////////////////////////////////////////////////////////////////////
SpinLock::SpinLock() : _lock() { TRI_InitSpin(&_lock); }
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes the lock
////////////////////////////////////////////////////////////////////////////////
SpinLock::~SpinLock() { TRI_DestroySpin(&_lock); }
////////////////////////////////////////////////////////////////////////////////
/// @brief acquires the lock
////////////////////////////////////////////////////////////////////////////////
void SpinLock::lock() { TRI_LockSpin(&_lock); }
////////////////////////////////////////////////////////////////////////////////
/// @brief releases the lock
////////////////////////////////////////////////////////////////////////////////
void SpinLock::unlock() { TRI_UnlockSpin(&_lock); }

View File

@ -1,85 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
////////////////////////////////////////////////////////////////////////////////
#ifndef LIB_BASICS_SPIN_LOCK_H
#define LIB_BASICS_SPIN_LOCK_H 1
#include "Basics/Common.h"
#include "Basics/locks.h"
namespace arangodb {
namespace basics {
////////////////////////////////////////////////////////////////////////////////
/// @brief spinlock
////////////////////////////////////////////////////////////////////////////////
class SpinLock {
private:
SpinLock(SpinLock const&) = delete;
SpinLock& operator=(SpinLock const&) = delete;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructs a spinlock
//////////////////////////////////////////////////////////////////////////////
SpinLock();
//////////////////////////////////////////////////////////////////////////////
/// @brief deletes the spinlock
//////////////////////////////////////////////////////////////////////////////
~SpinLock();
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief acquires the lock
//////////////////////////////////////////////////////////////////////////////
void lock();
//////////////////////////////////////////////////////////////////////////////
/// @brief releases the lock
//////////////////////////////////////////////////////////////////////////////
void unlock();
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief spinlock variable
//////////////////////////////////////////////////////////////////////////////
TRI_spin_t _lock;
};
}
}
#endif

View File

@ -1,75 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
////////////////////////////////////////////////////////////////////////////////
#include "SpinLocker.h"
#ifdef TRI_SHOW_LOCK_TIME
#include "Basics/logging.h"
#endif
using namespace arangodb::basics;
////////////////////////////////////////////////////////////////////////////////
/// @brief aquires a lock
///
/// The constructor aquires a lock, the destructor releases the lock.
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_SHOW_LOCK_TIME
////////////////////////////////////////////////////////////////////////////////
/// @brief aquires a lock
///
/// The constructor aquires a lock, the destructor releases the lock.
////////////////////////////////////////////////////////////////////////////////
SpinLocker::SpinLocker(SpinLock* lock, char const* file, int line)
: _lock(lock), _file(file), _line(line) {
double t = TRI_microtime();
_lock->lock();
_time = TRI_microtime() - t;
}
#else
SpinLocker::SpinLocker(SpinLock* lock) : _lock(lock) { _lock->lock(); }
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief releases the lock
////////////////////////////////////////////////////////////////////////////////
SpinLocker::~SpinLocker() {
_lock->unlock();
#ifdef TRI_SHOW_LOCK_TIME
if (_time > TRI_SHOW_LOCK_THRESHOLD) {
LOG_WARNING("SpinLocker %s:%d took %f s", _file, _line, _time);
}
#endif
}

View File

@ -1,129 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
////////////////////////////////////////////////////////////////////////////////
#ifndef LIB_BASICS_SPIN_LOCKER_H
#define LIB_BASICS_SPIN_LOCKER_H 1
#include "Basics/Common.h"
#include "Basics/SpinLock.h"
////////////////////////////////////////////////////////////////////////////////
/// @brief construct locker with file and line information
///
/// Ones needs to use macros twice to get a unique variable based on the line
/// number.
////////////////////////////////////////////////////////////////////////////////
#define SPIN_LOCKER_VAR_A(a) _spin_lock_variable_##a
#define SPIN_LOCKER_VAR_B(a) SPIN_LOCKER_VAR_A(a)
#ifdef TRI_SHOW_LOCK_TIME
#define SPIN_LOCKER(b) \
arangodb::basics::SpinLocker SPIN_LOCKER_VAR_B(__LINE__)(&b, __FILE__, \
__LINE__)
#else
#define SPIN_LOCKER(b) \
arangodb::basics::SpinLocker SPIN_LOCKER_VAR_B(__LINE__)(&b)
#endif
namespace arangodb {
namespace basics {
////////////////////////////////////////////////////////////////////////////////
/// @brief spin locker
///
/// A SpinLocker locks a spinlock during its lifetime und unlocks the spinlock
/// when it is destroyed.
////////////////////////////////////////////////////////////////////////////////
class SpinLocker {
SpinLocker(SpinLocker const&);
SpinLocker& operator=(SpinLocker const&);
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief aquires a lock
///
/// The constructor aquires a lock, the destructors releases the lock.
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_SHOW_LOCK_TIME
SpinLocker(SpinLock*, char const* file, int line);
#else
explicit SpinLocker(SpinLock*);
#endif
//////////////////////////////////////////////////////////////////////////////
/// @brief releases the lock
//////////////////////////////////////////////////////////////////////////////
~SpinLocker();
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief the mutex
//////////////////////////////////////////////////////////////////////////////
SpinLock* _lock;
#ifdef TRI_SHOW_LOCK_TIME
//////////////////////////////////////////////////////////////////////////////
/// @brief file
//////////////////////////////////////////////////////////////////////////////
char const* _file;
//////////////////////////////////////////////////////////////////////////////
/// @brief line number
//////////////////////////////////////////////////////////////////////////////
int _line;
//////////////////////////////////////////////////////////////////////////////
/// @brief lock time
//////////////////////////////////////////////////////////////////////////////
double _time;
#endif
};
}
}
#endif

View File

@ -1,67 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#include "locks.h"
#ifdef TRI_HAVE_MACOS_SPIN
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifndef TRI_FAKE_SPIN_LOCKS
void TRI_InitSpin(TRI_spin_t* spinLock) { *spinLock = 0; }
#else
void locks_macos_cpp_MusntBeEmpty(void) {}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifndef TRI_FAKE_SPIN_LOCKS
void TRI_DestroySpin(TRI_spin_t* spinLock) {}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief locks spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifndef TRI_FAKE_SPIN_LOCKS
void TRI_LockSpin(TRI_spin_t* spinLock) { OSSpinLockLock(spinLock); }
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief unlocks spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifndef TRI_FAKE_SPIN_LOCKS
void TRI_UnlockSpin(TRI_spin_t* spinLock) { OSSpinLockUnlock(spinLock); }
#endif
#endif

View File

@ -1,54 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#ifndef LIB_BASICS_LOCKS_MACOS_H
#define LIB_BASICS_LOCKS_MACOS_H 1
#include "Basics/Common.h"
#ifdef TRI_HAVE_MACOS_SPIN
#include <libkern/OSAtomic.h>
////////////////////////////////////////////////////////////////////////////////
/// @brief spin-lock type
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_FAKE_SPIN_LOCKS
#ifndef TRI_spin_t
#define TRI_spin_t pthread_mutex_t
#endif
#else
#define TRI_spin_t OSSpinLock
#endif
#endif
#endif

View File

@ -99,59 +99,6 @@ void TRI_UnlockMutex(TRI_mutex_t* mutex) {
}
}
#ifndef TRI_FAKE_SPIN_LOCKS
#ifdef TRI_HAVE_POSIX_SPIN
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new spin-lock
////////////////////////////////////////////////////////////////////////////////
void TRI_InitSpin(TRI_spin_t* spinLock) { pthread_spin_init(spinLock, 0); }
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a spin-lock
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroySpin(TRI_spin_t* spinLock) { pthread_spin_destroy(spinLock); }
////////////////////////////////////////////////////////////////////////////////
/// @brief locks spin-lock
////////////////////////////////////////////////////////////////////////////////
void TRI_LockSpin(TRI_spin_t* spinLock) {
int rc = pthread_spin_lock(spinLock);
if (rc != 0) {
if (rc == EDEADLK) {
LOG_ERROR("spinlock deadlock detected");
}
#ifdef TRI_ENABLE_MAINTAINER_MODE
TRI_ASSERT(false);
#endif
LOG_FATAL_AND_EXIT("could not lock the spin-lock: %s", strerror(rc));
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief unlocks spin-lock
////////////////////////////////////////////////////////////////////////////////
void TRI_UnlockSpin(TRI_spin_t* spinLock) {
int rc = pthread_spin_unlock(spinLock);
if (rc != 0) {
#ifdef TRI_ENABLE_MAINTAINER_MODE
TRI_ASSERT(false);
#endif
LOG_FATAL_AND_EXIT("could not release the spin-lock: %s", strerror(rc));
}
}
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new read-write lock
////////////////////////////////////////////////////////////////////////////////

View File

@ -28,29 +28,12 @@
#ifdef TRI_HAVE_POSIX_THREADS
////////////////////////////////////////////////////////////////////////////////
/// @brief mutex type
////////////////////////////////////////////////////////////////////////////////
#define TRI_mutex_t pthread_mutex_t
////////////////////////////////////////////////////////////////////////////////
/// @brief spin-lock type
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_FAKE_SPIN_LOCKS
#define TRI_spin_t pthread_mutex_t
#else
#ifdef TRI_HAVE_POSIX_SPIN
#define TRI_spin_t pthread_spinlock_t
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief read-write-lock type
////////////////////////////////////////////////////////////////////////////////
@ -70,4 +53,3 @@ typedef struct TRI_condition_s {
#endif

View File

@ -22,26 +22,15 @@
////////////////////////////////////////////////////////////////////////////////
#include "locks.h"
#include "Basics/logging.h"
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new mutex
////////////////////////////////////////////////////////////////////////////////
int TRI_InitMutex(TRI_mutex_t* mutex) {
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
#if TRI_WINDOWS_VISTA_LOCKS
mutex->_mutex = CreateMutex(nullptr, FALSE, nullptr);
if (mutex->_mutex == nullptr) {
LOG_FATAL_AND_EXIT("cannot create the mutex");
}
#else
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
InitializeSRWLock(&mutex->_mutex);
#endif
return TRI_ERROR_NO_ERROR;
}
@ -50,59 +39,17 @@ int TRI_InitMutex(TRI_mutex_t* mutex) {
////////////////////////////////////////////////////////////////////////////////
int TRI_DestroyMutex(TRI_mutex_t* mutex) {
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
#if TRI_WINDOWS_VISTA_LOCKS
if (CloseHandle(mutex->_mutex) == 0) {
DWORD result = GetLastError();
LOG_FATAL_AND_EXIT(
"locks-win32.c:TRI_DestroyMutex:could not destroy the mutex -->%d",
result);
}
#else
#endif
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief locks mutex
////////////////////////////////////////////////////////////////////////////////
void TRI_LockMutex(TRI_mutex_t* mutex) {
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
#if TRI_WINDOWS_VISTA_LOCKS
DWORD result = WaitForSingleObject(mutex->_mutex, INFINITE);
switch (result) {
case WAIT_ABANDONED: {
LOG_FATAL_AND_EXIT(
"locks-win32.c:TRI_LockMutex:could not lock the condition --> "
"WAIT_ABANDONED");
}
case WAIT_OBJECT_0: {
// everything ok
break;
}
case WAIT_TIMEOUT: {
LOG_FATAL_AND_EXIT(
"locks-win32.c:TRI_LockMutex:could not lock the condition --> "
"WAIT_TIMEOUT");
}
case WAIT_FAILED: {
result = GetLastError();
LOG_FATAL_AND_EXIT(
"locks-win32.c:TRI_LockMutex:could not lock the condition --> "
"WAIT_FAILED - reason -->%d",
result);
}
}
#else
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
AcquireSRWLockExclusive(&mutex->_mutex);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -110,136 +57,16 @@ void TRI_LockMutex(TRI_mutex_t* mutex) {
////////////////////////////////////////////////////////////////////////////////
void TRI_UnlockMutex(TRI_mutex_t* mutex) {
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
#if TRI_WINDOWS_VISTA_LOCKS
BOOL ok = ReleaseMutex(mutex->_mutex);
if (!ok) {
LOG_FATAL_AND_EXIT("could not unlock the mutex");
}
#else
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
ReleaseSRWLockExclusive(&mutex->_mutex);
#endif
}
#ifndef TRI_FAKE_SPIN_LOCKS
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new spin
////////////////////////////////////////////////////////////////////////////////
void TRI_InitSpin(TRI_spin_t* spin) { InitializeCriticalSection(spin); }
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a spin
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroySpin(TRI_spin_t* spin) { DeleteCriticalSection(spin); }
////////////////////////////////////////////////////////////////////////////////
/// @brief locks spin
////////////////////////////////////////////////////////////////////////////////
void TRI_LockSpin(TRI_spin_t* spin) { EnterCriticalSection(spin); }
////////////////////////////////////////////////////////////////////////////////
/// @brief unlocks spin
////////////////////////////////////////////////////////////////////////////////
void TRI_UnlockSpin(TRI_spin_t* spin) { LeaveCriticalSection(spin); }
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief increments readers
////////////////////////////////////////////////////////////////////////////////
#if TRI_WINDOWS_VISTA_LOCKS
static void IncrementReaders(TRI_read_write_lock_t* lock) {
// ...........................................................................
// increment the number of readers we have on the read_write lock
// ...........................................................................
lock->_readers++;
// ...........................................................................
// Since the number of readers must be positive, set the readers event to
// non-signalled so that any write event will have to wait.
// ...........................................................................
ResetEvent(lock->_readersEvent);
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief decrements readers
////////////////////////////////////////////////////////////////////////////////
#if TRI_WINDOWS_VISTA_LOCKS
static void DecrementReaders(TRI_read_write_lock_t* lock) {
// ...........................................................................
// reduce the number of readers using the read_write lock by 1
// ...........................................................................
lock->_readers--;
// ...........................................................................
// When the number of readers is 0, set the event to signalled which allows
// a writer to use the read_write lock.
// ...........................................................................
if (lock->_readers == 0) {
SetEvent(lock->_readersEvent);
} else if (lock->_readers < 0) {
LOG_FATAL_AND_EXIT("reader count is negative");
}
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new read-write lock
////////////////////////////////////////////////////////////////////////////////
void TRI_InitReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
// ...........................................................................
// set the number of readers reading on the read_write lock to 0
// ...........................................................................
lock->_readers = 0;
// ...........................................................................
// Signaled: writer has no access
// Non-Signaled: writer has access, block readers
// Creates an event which allows a thread to wait on it (perhaps should use
// a mutux rather than an event here). The writer event is set to signalled
// when CreateEvent is called with these parameters.
// ...........................................................................
lock->_writerEvent = CreateEvent(0, TRUE, TRUE, 0);
// ...........................................................................
// Signaled: no readers
// Non-Signaled: some readers have access, block writer
// Same as the writer event above except this is the reader event
// ...........................................................................
lock->_readersEvent = CreateEvent(0, TRUE, TRUE, 0);
// ...........................................................................
// Creates critical sections for writer and readers.
// Waits for ownership of the specified critical section object.
// The function returns when the calling thread is granted ownership.
// ...........................................................................
InitializeCriticalSection(&lock->_lockWriter);
InitializeCriticalSection(&lock->_lockReaders);
#else
InitializeSRWLock(&lock->_lock);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -247,39 +74,14 @@ void TRI_InitReadWriteLock(TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
DeleteCriticalSection(&lock->_lockWriter);
DeleteCriticalSection(&lock->_lockReaders);
CloseHandle(lock->_writerEvent);
CloseHandle(lock->_readersEvent);
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to read lock a read-write lock
////////////////////////////////////////////////////////////////////////////////
bool TRI_TryReadLockReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
WaitForSingleObject(lock->_writerEvent, 10); // 10 millis timeout
EnterCriticalSection(&lock->_lockReaders);
IncrementReaders(lock);
LeaveCriticalSection(&lock->_lockReaders);
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
EnterCriticalSection(&lock->_lockReaders);
DecrementReaders(lock);
LeaveCriticalSection(&lock->_lockReaders);
return false;
}
return true;
#else
return (TryAcquireSRWLockShared(&lock->_lock) != 0);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -287,43 +89,7 @@ bool TRI_TryReadLockReadWriteLock(TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_ReadLockReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
while (true) {
// ........................................................................
// Waits for a writer to finish if there is one. This function only
// returns when the writer event is in a signalled state
// ........................................................................
WaitForSingleObject(lock->_writerEvent, INFINITE);
// .........................................................................
// This thread will wait here until this resource becomes excusively
// available
// .........................................................................
EnterCriticalSection(&lock->_lockReaders);
IncrementReaders(lock);
// .........................................................................
// allows some other thread to use this resource
// .........................................................................
LeaveCriticalSection(&lock->_lockReaders);
// it could have happened that the writer event is no longer in a signalled
// state. Between leaving the crtical section and here a writer sneaked in.
//
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
EnterCriticalSection(&lock->_lockReaders);
DecrementReaders(lock);
LeaveCriticalSection(&lock->_lockReaders);
} else {
break;
}
}
#else
AcquireSRWLockShared(&lock->_lock);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -331,41 +97,7 @@ void TRI_ReadLockReadWriteLock(TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_ReadUnlockReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
EnterCriticalSection(&lock->_lockReaders);
/* this is wrong since it is possible for the write locker to block this event
// a write lock eists
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
LOG_FATAL_AND_EXIT("write lock, but trying to unlock read");
}
// at least one reader exists
else if (0 < lock->_readers) {
DecrementReaders(lock);
}
// ups, no writer and no reader
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("no reader and no writer, but trying to unlock");
}
-*/
if (0 < lock->_readers) {
DecrementReaders(lock);
}
// oops no reader
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("no reader, but trying to unlock read lock");
}
LeaveCriticalSection(&lock->_lockReaders);
#else
ReleaseSRWLockShared(&lock->_lock);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -373,58 +105,7 @@ void TRI_ReadUnlockReadWriteLock(TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
bool TRI_TryWriteLockReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
BOOL result;
// ...........................................................................
// Here we use TryEnterCriticalSection instead of EnterCriticalSection
// There could already be a write lock - which will actuall block from this
// point on.
// ...........................................................................
result = TryEnterCriticalSection(&lock->_lockWriter);
if (result == 0) {
// appears some other writer is writing
return false;
}
// ...........................................................................
// Wait until the lock->_writerEvent is in a 'signalled' state
// This might fail because a reader is just about to read
// ...........................................................................
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
LeaveCriticalSection(&lock->_lockWriter);
return false;
}
// ...........................................................................
// Set _writeEvent as nonsignalled -- this will block other read/write
// lockers
// ...........................................................................
ResetEvent(lock->_writerEvent);
// ...........................................................................
// If there are ANY read locks outstanding, leave
// ...........................................................................
if (WaitForSingleObject(lock->_readersEvent, 0) != WAIT_OBJECT_0) {
LeaveCriticalSection(&lock->_lockWriter);
SetEvent(lock->_writerEvent);
return false;
}
// ...........................................................................
// Allow other threads to access this function
// ...........................................................................
LeaveCriticalSection(&lock->_lockWriter);
return true;
#else
return (TryAcquireSRWLockExclusive(&lock->_lock) != 0);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -432,42 +113,7 @@ bool TRI_TryWriteLockReadWriteLock(TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_WriteLockReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
// ...........................................................................
// Lock so no other thread can access this
// EnterCriticalSection(&lock->_lockWriter) will block this thread until
// it has been released by the other thread.
// ...........................................................................
EnterCriticalSection(&lock->_lockWriter);
// ...........................................................................
// Wait until the lock->_writerEvent is in a 'signalled' state
// ...........................................................................
WaitForSingleObject(lock->_writerEvent, INFINITE);
// ...........................................................................
// Set _writeEvent as nonsignalled -- this will block other read/write
// lockers
// ...........................................................................
ResetEvent(lock->_writerEvent);
// ...........................................................................
// If there are ANY read locks outstanding, then wait until these are cleared
// ...........................................................................
WaitForSingleObject(lock->_readersEvent, INFINITE);
// ...........................................................................
// Allow other threads to access this function
// ...........................................................................
LeaveCriticalSection(&lock->_lockWriter);
#else
AcquireSRWLockExclusive(&lock->_lock);
#endif
}
////////////////////////////////////////////////////////////////////////////////
@ -475,57 +121,9 @@ void TRI_WriteLockReadWriteLock(TRI_read_write_lock_t* lock) {
////////////////////////////////////////////////////////////////////////////////
void TRI_WriteUnlockReadWriteLock(TRI_read_write_lock_t* lock) {
#if TRI_WINDOWS_VISTA_LOCKS
// ...........................................................................
// Write lock this _lockReader so no other threads can access this
// This will block this thread until it is released by the other thread
// We do not need to lock the _lockWriter SINCE the TRI_WriteLockReadWriteLock
// function above will lock (due to the ResetEvent(lock->_writerEvent); )
// ...........................................................................
EnterCriticalSection(&lock->_lockReaders);
// ...........................................................................
// In the function TRI_WriteLockReadWriteLock we set the _writerEvent to
// 'nonsignalled'. So if a write lock exists clear it by setting it to
// 'signalled'
// ...........................................................................
if (WaitForSingleObject(lock->_writerEvent, 0) != WAIT_OBJECT_0) {
SetEvent(lock->_writerEvent);
}
// ...........................................................................
// Oops at least one reader exists - something terrible happened.
// ...........................................................................
else if (0 < lock->_readers) {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("read lock, but trying to unlock write");
}
// ...........................................................................
// Oops we are trying to unlock a write lock, but there isn't one! Something
// terrible happend.
// ...........................................................................
else {
LeaveCriticalSection(&lock->_lockReaders);
LOG_FATAL_AND_EXIT("no reader and no writer, but trying to unlock");
}
// ...........................................................................
// Allow read locks to be applied now.
// ...........................................................................
LeaveCriticalSection(&lock->_lockReaders);
#else
ReleaseSRWLockExclusive(&lock->_lock);
#endif
}
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new condition variable
////////////////////////////////////////////////////////////////////////////////
@ -543,7 +141,6 @@ void TRI_DestroyCondition(TRI_condition_t* cond) {
DeleteCriticalSection(&cond->_lockWaiters);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief signals a condition variable
///
@ -586,8 +183,6 @@ bool TRI_TimedWaitCondition(TRI_condition_t* cond, uint64_t delay) {
// The POSIX threads function pthread_cond_timedwait accepts microseconds
// while the Windows function accepts milliseconds
// ...........................................................................
DWORD res;
delay = delay / 1000;
if (SleepConditionVariableCS(&cond->_conditionVariable, &cond->_lockWaiters,
@ -595,7 +190,8 @@ bool TRI_TimedWaitCondition(TRI_condition_t* cond, uint64_t delay) {
return true;
}
res = GetLastError();
DWORD res = GetLastError();
if (res == ERROR_TIMEOUT) {
return false;
}
@ -687,4 +283,3 @@ bool TRI_ComparePointer(void* volatile* theValue, void* oldValue) {
#endif

View File

@ -28,52 +28,21 @@
#ifdef TRI_HAVE_WIN32_THREADS
////////////////////////////////////////////////////////////////////////////////
/// @brief mutex type
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_mutex_s {
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
#if TRI_WINDOWS_VISTA_LOCKS
HANDLE _mutex;
#else
// as of VS2013, exclusive SRWLocks tend to be faster than native mutexes
SRWLOCK _mutex;
#endif
} TRI_mutex_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief spin-lock type
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_FAKE_SPIN_LOCKS
#define TRI_spin_t TRI_mutex_t
#define TRI_InitSpin TRI_InitMutex
#define TRI_DestroySpin TRI_DestroyMutex
#define TRI_LockSpin TRI_LockMutex
#define TRI_UnlockSpin TRI_UnlockMutex
#else
#define TRI_spin_t CRITICAL_SECTION
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief read-write-lock type
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_read_write_lock_s {
#if TRI_WINDOWS_VISTA_LOCKS
HANDLE _writerEvent;
HANDLE _readersEvent;
int _readers;
CRITICAL_SECTION _lockWriter;
CRITICAL_SECTION _lockReaders;
#else
SRWLOCK _lock;
#endif
} TRI_read_write_lock_t;
////////////////////////////////////////////////////////////////////////////////

View File

@ -26,24 +26,14 @@
#include "Basics/Common.h"
#ifdef TRI_HAVE_POSIX_THREADS
#include "Basics/locks-posix.h"
#endif
#ifdef TRI_HAVE_WIN32_THREADS
#include "Basics/locks-win32.h"
#endif
#ifdef TRI_HAVE_MACOS_SPIN
#include "Basics/locks-macos.h"
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new mutex
///
@ -65,7 +55,6 @@ int TRI_InitMutex(TRI_mutex_t*);
int TRI_DestroyMutex(TRI_mutex_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief locks mutex
////////////////////////////////////////////////////////////////////////////////
@ -78,51 +67,6 @@ void TRI_LockMutex(TRI_mutex_t*);
void TRI_UnlockMutex(TRI_mutex_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_FAKE_SPIN_LOCKS
#define TRI_InitSpin TRI_InitMutex
#else
void TRI_InitSpin(TRI_spin_t* spin);
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief destroyes a spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_FAKE_SPIN_LOCKS
#define TRI_DestroySpin TRI_DestroyMutex
#else
void TRI_DestroySpin(TRI_spin_t* spin);
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief locks spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_FAKE_SPIN_LOCKS
#define TRI_LockSpin TRI_LockMutex
#else
void TRI_LockSpin(TRI_spin_t* spin);
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief unlocks spin-lock
////////////////////////////////////////////////////////////////////////////////
#ifdef TRI_FAKE_SPIN_LOCKS
#define TRI_UnlockSpin TRI_UnlockMutex
#else
void TRI_UnlockSpin(TRI_spin_t* spin);
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new read-write lock
///
@ -150,7 +94,6 @@ void TRI_InitReadWriteLock(TRI_read_write_lock_t* lock);
void TRI_DestroyReadWriteLock(TRI_read_write_lock_t* lock);
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to read lock read-write lock
////////////////////////////////////////////////////////////////////////////////
@ -187,8 +130,6 @@ void TRI_WriteLockReadWriteLock(TRI_read_write_lock_t* lock);
void TRI_WriteUnlockReadWriteLock(TRI_read_write_lock_t* lock);
////////////////////////////////////////////////////////////////////////////////
/// @brief initializes a new condition variable
////////////////////////////////////////////////////////////////////////////////
@ -201,7 +142,6 @@ void TRI_InitCondition(TRI_condition_t* cond);
void TRI_DestroyCondition(TRI_condition_t* cond);
////////////////////////////////////////////////////////////////////////////////
/// @brief signals a condition variable
///

View File

@ -113,7 +113,6 @@
#define TRI_HAVE_MACOS_MEM_STATS 1
#define TRI_HAVE_LINUX_SOCKETS 1
#define TRI_HAVE_MACH 1
#define TRI_HAVE_MACOS_SPIN 1
#define TRI_HAVE_POSIX_THREADS 1
#define TRI_HAVE_POSIX_MMAP 1
#define TRI_HAVE_POSIX_PWD_GRP 1
@ -291,7 +290,6 @@
#define TRI_HAVE_LINUX_PROC 1
#define TRI_HAVE_LINUX_SOCKETS 1
#define TRI_HAVE_POSIX_SPIN 1
#define TRI_HAVE_POSIX_THREADS 1
#define TRI_HAVE_POSIX_MMAP 1
#define TRI_HAVE_POSIX_PWD_GRP 1
@ -457,7 +455,6 @@
#define TRI_HAVE_SC_PHYS_PAGES 1
#define TRI_HAVE_LINUX_PROC 1
#define TRI_HAVE_LINUX_SOCKETS 1
#define TRI_HAVE_POSIX_SPIN 1
#define TRI_HAVE_POSIX_THREADS 1
#define TRI_HAVE_POSIX_MMAP 1
#define TRI_HAVE_POSIX_PWD_GRP 1

View File

@ -14,10 +14,6 @@ include_directories(.)
### @brief LIB_ARANGO
################################################################################
if (APPLE)
SET(LIB_ARANGO_APPLE Basics/locks-macos.cpp)
endif ()
if (MSVC)
SET(LIB_ARANGO_MSVC
Basics/locks-win32.cpp
@ -116,8 +112,6 @@ add_library(
Basics/ReadWriteLock.cpp
Basics/ReadWriteLockCPP11.cpp
Basics/socket-utils.cpp
Basics/SpinLock.cpp
Basics/SpinLocker.cpp
Basics/ssl-helper.cpp
Basics/StringBuffer.cpp
Basics/StringUtils.cpp

View File

@ -36,7 +36,6 @@ lib_libarango_a_SOURCES = \
lib/Basics/json.cpp \
lib/Basics/JsonHelper.cpp \
lib/Basics/levenshtein.cpp \
lib/Basics/locks-macos.cpp \
lib/Basics/locks-posix.cpp \
lib/Basics/logging.cpp \
lib/Basics/memory-map-posix.cpp \
@ -54,8 +53,6 @@ lib_libarango_a_SOURCES = \
lib/Basics/ReadWriteLock.cpp \
lib/Basics/ReadWriteLockCPP11.cpp \
lib/Basics/socket-utils.cpp \
lib/Basics/SpinLock.cpp \
lib/Basics/SpinLocker.cpp \
lib/Basics/ssl-helper.cpp \
lib/Basics/StringBuffer.cpp \
lib/Basics/StringUtils.cpp \