For PR540:

Add a Mutex class for thread synchronization in a platform-independent way.
The current implementation only supports pthreads. Win32 use of Critical
Sections will be added later. The design permits other threading models to
be used if (and only if) pthreads is not available.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22403 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2005-07-12 15:37:43 +00:00
parent 22177fe580
commit b2164e5cb5
4 changed files with 315 additions and 0 deletions

View File

@ -0,0 +1,82 @@
//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the llvm::sys::Mutex class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SYSTEM_MUTEX_H
#define LLVM_SYSTEM_MUTEX_H
namespace llvm
{
namespace sys
{
/// @brief Platform agnostic Mutex class.
class Mutex
{
/// @name Constructors
/// @{
public:
/// Initializes the lock but doesn't acquire it. if \p recursive is set
/// to false, the lock will not be recursive which makes it cheaper but
/// also more likely to deadlock (same thread can't acquire more than
/// once).
/// @brief Default Constructor.
Mutex ( bool recursive = true );
/// Releases and removes the lock
/// @brief Destructor
~Mutex ( void );
/// @}
/// @name Methods
/// @{
public:
/// Attempts to unconditionally acquire the lock. If the lock is held by
/// another thread, this method will wait until it can acquire the lock.
/// @returns false if any kind of error occurs, true otherwise.
/// @brief Unconditionally acquire the lock.
bool acquire();
/// Attempts to release the lock. If the lock is held by the current
/// thread, the lock is released allowing other threads to acquire the
/// lock.
/// @returns false if any kind of error occurs, true otherwise.
/// @brief Unconditionally release the lock.
bool release(void);
/// Attempts to acquire the lock without blocking. If the lock is not
/// available, this function returns false quickly (without blocking). If
/// the lock is available, it is acquired.
/// @returns false if any kind of error occurs or the lock is not
/// available, true otherwise.
/// @brief Try to acquire the lock.
bool tryacquire();
//@}
/// @name Platform Dependent Data
/// @{
private:
void* data_; ///< We don't know what the data will be
/// @}
/// @name Do Not Implement
/// @{
private:
Mutex(const Mutex & original);
void operator=(const Mutex &);
/// @}
};
}
}
#endif

141
lib/System/Mutex.cpp Normal file
View File

@ -0,0 +1,141 @@
//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the llvm::sys::Mutex class.
//
//===----------------------------------------------------------------------===//
#include "llvm/System/Mutex.h"
#include "llvm/Config/config.h"
namespace llvm {
using namespace sys;
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//=== independent code.
//===----------------------------------------------------------------------===//
#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
#include <cassert>
#include <pthread.h>
#include <stdlib.h>
// This variable is useful for situations where the pthread library has been
// compiled with weak linkage for its interface symbols. This allows the
// threading support to be turned off by simply not linking against -lpthread.
// In that situation, the value of pthread_mutex_init will be 0 and
// consequently pthread_enabled will be false. In such situations, all the
// pthread operations become no-ops and the functions all return false. If
// pthread_mutex_init does have an address, then mutex support is enabled.
// Note: all LLVM tools will link against -lpthread if its available since it
// is configured into the LIBS variable.
// Note: this line of code generates a warning if pthread_mutex_init is not
// declared with weak linkage. Its safe to ignore the warning.
static const bool pthread_enabled = static_cast<bool>(pthread_mutex_init);
// Construct a Mutex using pthread calls
Mutex::Mutex( bool recursive)
: data_(0)
{
if (pthread_enabled)
{
// Declare the pthread_mutex data structures
pthread_mutex_t* mutex =
static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
pthread_mutexattr_t attr;
// Initialize the mutex attributes
int errorcode = pthread_mutexattr_init(&attr);
assert(errorcode == 0);
// Initialize the mutex as a recursive mutex, if requested, or normal
// otherwise.
int kind = ( recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
errorcode = pthread_mutexattr_settype(&attr, kind);
assert(errorcode == 0);
// Make it a process local mutex
errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
// Initialize the mutex
errorcode = pthread_mutex_init(mutex, &attr);
assert(errorcode == 0);
// Destroy the attributes
errorcode = pthread_mutexattr_destroy(&attr);
assert(errorcode == 0);
// Assign the data member
data_ = mutex;
}
}
// Destruct a Mutex
Mutex::~Mutex()
{
if (pthread_enabled)
{
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
assert(mutex != 0);
int errorcode = pthread_mutex_destroy(mutex);
assert(mutex != 0);
}
}
bool
Mutex::acquire()
{
if (pthread_enabled)
{
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
assert(mutex != 0);
int errorcode = pthread_mutex_lock(mutex);
return errorcode == 0;
}
return false;
}
bool
Mutex::release()
{
if (pthread_enabled)
{
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
assert(mutex != 0);
int errorcode = pthread_mutex_unlock(mutex);
return errorcode == 0;
}
return false;
}
bool
Mutex::tryacquire()
{
if (pthread_enabled)
{
pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
assert(mutex != 0);
int errorcode = pthread_mutex_trylock(mutex);
return errorcode == 0;
}
return false;
}
}
#elif defined(LLVM_ON_UNIX)
#include "Unix/Mutex.inc"
#elif defined( LLVM_ON_WIN32)
#include "Win32/Mutex.inc"
#else
#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
#endif

46
lib/System/Unix/Mutex.inc Normal file
View File

@ -0,0 +1,46 @@
//===- llvm/System/Unix/Mutex.inc - Unix Mutex Implementation ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific (non-pthread) Mutex class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
namespace llvm
{
using namespace sys;
Mutex::Mutex( bool recursive)
{
}
Mutex::~Mutex()
{
}
bool
Mutex::acquire()
{
}
bool
Mutex::release()
{
}
bool
Mutex::tryacquire( void )
{
}
}

View File

@ -0,0 +1,46 @@
//===- llvm/System/Win32/Mutex.inc - Win32 Mutex Implementation -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Reid Spencer and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Win32 specific (non-pthread) Mutex class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic Win32 code that
//=== is guaranteed to work on *all* Win32 variants.
//===----------------------------------------------------------------------===//
namespace llvm
{
using namespace sys;
Mutex::Mutex( bool recursive)
{
}
Mutex::~Mutex()
{
}
bool
Mutex::acquire()
{
}
bool
Mutex::release()
{
}
bool
Mutex::tryacquire( void )
{
}
}