diff options
| author | Ed Schouten <ed@FreeBSD.org> | 2009-06-22 08:08:12 +0000 |
|---|---|---|
| committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-22 08:08:12 +0000 |
| commit | b2f21fb044b6b5c52cff6227f9f79ca4ed42b18f (patch) | |
| tree | 86c1bc482baa6c81fc70b8d715153bfa93377186 /include/llvm/System | |
| parent | 600c6fa13de5c407dc36dbb0ab73807868741ae0 (diff) | |
Notes
Diffstat (limited to 'include/llvm/System')
| -rw-r--r-- | include/llvm/System/Atomic.h | 2 | ||||
| -rw-r--r-- | include/llvm/System/Mutex.h | 80 | ||||
| -rw-r--r-- | include/llvm/System/Path.h | 5 | ||||
| -rw-r--r-- | include/llvm/System/RWMutex.h | 175 | ||||
| -rw-r--r-- | include/llvm/System/Threading.h | 45 |
5 files changed, 300 insertions, 7 deletions
diff --git a/include/llvm/System/Atomic.h b/include/llvm/System/Atomic.h index cb9277cc35ec8..adbb975298e81 100644 --- a/include/llvm/System/Atomic.h +++ b/include/llvm/System/Atomic.h @@ -24,6 +24,8 @@ namespace llvm { cas_flag CompareAndSwap(volatile cas_flag* ptr, cas_flag new_value, cas_flag old_value); + cas_flag AtomicIncrement(volatile cas_flag* ptr); + cas_flag AtomicDecrement(volatile cas_flag* ptr); } } diff --git a/include/llvm/System/Mutex.h b/include/llvm/System/Mutex.h index 4f3849341aa1f..d2c457dbc91c6 100644 --- a/include/llvm/System/Mutex.h +++ b/include/llvm/System/Mutex.h @@ -14,12 +14,15 @@ #ifndef LLVM_SYSTEM_MUTEX_H #define LLVM_SYSTEM_MUTEX_H +#include "llvm/System/Threading.h" +#include <cassert> + namespace llvm { namespace sys { /// @brief Platform agnostic Mutex class. - class Mutex + class MutexImpl { /// @name Constructors /// @{ @@ -30,11 +33,11 @@ namespace llvm /// also more likely to deadlock (same thread can't acquire more than /// once). /// @brief Default Constructor. - explicit Mutex(bool recursive = true); + explicit MutexImpl(bool recursive = true); /// Releases and removes the lock /// @brief Destructor - ~Mutex(); + ~MutexImpl(); /// @} /// @name Methods @@ -66,18 +69,81 @@ namespace llvm /// @name Platform Dependent Data /// @{ private: -#ifdef ENABLE_THREADS void* data_; ///< We don't know what the data will be -#endif /// @} /// @name Do Not Implement /// @{ private: - Mutex(const Mutex & original); - void operator=(const Mutex &); + MutexImpl(const MutexImpl & original); + void operator=(const MutexImpl &); /// @} }; + + + /// SmartMutex - A mutex with a compile time constant parameter that + /// indicates whether this mutex should become a no-op when we're not + /// running in multithreaded mode. + template<bool mt_only> + class SmartMutex : public MutexImpl { + unsigned acquired; + bool recursive; + public: + explicit SmartMutex(bool rec = true) : + MutexImpl(rec), acquired(0), recursive(rec) { } + + bool acquire() { + if (!mt_only || llvm_is_multithreaded()) + return MutexImpl::acquire(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert((recursive || acquired == 0) && "Lock already acquired!!"); + ++acquired; + return true; + } + + bool release() { + if (!mt_only || llvm_is_multithreaded()) + return MutexImpl::release(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert(((recursive && acquired) || (acquired == 1)) && + "Lock not acquired before release!"); + --acquired; + return true; + } + + bool tryacquire() { + if (!mt_only || llvm_is_multithreaded()) + return MutexImpl::tryacquire(); + return true; + } + + private: + SmartMutex(const SmartMutex<mt_only> & original); + void operator=(const SmartMutex<mt_only> &); + }; + + /// Mutex - A standard, always enforced mutex. + typedef SmartMutex<false> Mutex; + + template<bool mt_only> + class SmartScopedLock { + SmartMutex<mt_only>* mtx; + + public: + SmartScopedLock(SmartMutex<mt_only>* m) : mtx(m) { + mtx->acquire(); + } + + ~SmartScopedLock() { + mtx->release(); + } + }; + + typedef SmartScopedLock<false> ScopedLock; } } diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h index de2f173ae4175..05be2212758b4 100644 --- a/include/llvm/System/Path.h +++ b/include/llvm/System/Path.h @@ -309,6 +309,11 @@ namespace sys { /// @brief Determine if the path is absolute. bool isAbsolute() const; + /// This function determines if the path name is absolute, as opposed to + /// relative. + /// @brief Determine if the path is absolute. + static bool isAbsolute(const char *NameStart, unsigned NameLen); + /// This function opens the file associated with the path name provided by /// the Path object and reads its magic number. If the magic number at the /// start of the file matches \p magic, true is returned. In all other diff --git a/include/llvm/System/RWMutex.h b/include/llvm/System/RWMutex.h new file mode 100644 index 0000000000000..e577d457afb51 --- /dev/null +++ b/include/llvm/System/RWMutex.h @@ -0,0 +1,175 @@ +//===- RWMutex.h - Reader/Writer Mutual Exclusion Lock ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the llvm::sys::RWMutex class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYSTEM_RWMUTEX_H +#define LLVM_SYSTEM_RWMUTEX_H + +#include "llvm/System/Threading.h" +#include <cassert> + +namespace llvm +{ + namespace sys + { + /// @brief Platform agnostic RWMutex class. + class RWMutexImpl + { + /// @name Constructors + /// @{ + public: + + /// Initializes the lock but doesn't acquire it. + /// @brief Default Constructor. + explicit RWMutexImpl(); + + /// Releases and removes the lock + /// @brief Destructor + ~RWMutexImpl(); + + /// @} + /// @name Methods + /// @{ + public: + + /// Attempts to unconditionally acquire the lock in reader mode. If the + /// lock is held by a writer, 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 in reader mode. + bool reader_acquire(); + + /// Attempts to release the lock in reader mode. + /// @returns false if any kind of error occurs, true otherwise. + /// @brief Unconditionally release the lock in reader mode. + bool reader_release(); + + /// Attempts to unconditionally acquire the lock in reader mode. If the + /// lock is held by any readers, 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 in writer mode. + bool writer_acquire(); + + /// Attempts to release the lock in writer mode. + /// @returns false if any kind of error occurs, true otherwise. + /// @brief Unconditionally release the lock in write mode. + bool writer_release(); + + //@} + /// @name Platform Dependent Data + /// @{ + private: + void* data_; ///< We don't know what the data will be + + /// @} + /// @name Do Not Implement + /// @{ + private: + RWMutexImpl(const RWMutexImpl & original); + void operator=(const RWMutexImpl &); + /// @} + }; + + /// SmartMutex - An R/W mutex with a compile time constant parameter that + /// indicates whether this mutex should become a no-op when we're not + /// running in multithreaded mode. + template<bool mt_only> + class SmartRWMutex : public RWMutexImpl { + unsigned readers, writers; + public: + explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { } + + bool reader_acquire() { + if (!mt_only || llvm_is_multithreaded()) + return RWMutexImpl::reader_acquire(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + ++readers; + return true; + } + + bool reader_release() { + if (!mt_only || llvm_is_multithreaded()) + return RWMutexImpl::reader_release(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert(readers > 0 && "Reader lock not acquired before release!"); + --readers; + return true; + } + + bool writer_acquire() { + if (!mt_only || llvm_is_multithreaded()) + return RWMutexImpl::writer_acquire(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert(writers == 0 && "Writer lock already acquired!"); + ++writers; + return true; + } + + bool writer_release() { + if (!mt_only || llvm_is_multithreaded()) + return RWMutexImpl::writer_release(); + + // Single-threaded debugging code. This would be racy in multithreaded + // mode, but provides not sanity checks in single threaded mode. + assert(writers == 1 && "Writer lock not acquired before release!"); + --writers; + return true; + } + + private: + SmartRWMutex(const SmartRWMutex<mt_only> & original); + void operator=(const SmartRWMutex<mt_only> &); + }; + typedef SmartRWMutex<false> RWMutex; + + /// ScopedReader - RAII acquisition of a reader lock + template<bool mt_only> + struct SmartScopedReader { + SmartRWMutex<mt_only>* mutex; + + explicit SmartScopedReader(SmartRWMutex<mt_only>* m) { + mutex = m; + mutex->reader_acquire(); + } + + ~SmartScopedReader() { + mutex->reader_release(); + } + }; + typedef SmartScopedReader<false> ScopedReader; + + /// ScopedWriter - RAII acquisition of a writer lock + template<bool mt_only> + struct SmartScopedWriter { + SmartRWMutex<mt_only>* mutex; + + explicit SmartScopedWriter(SmartRWMutex<mt_only>* m) { + mutex = m; + mutex->writer_acquire(); + } + + ~SmartScopedWriter() { + mutex->writer_release(); + } + }; + typedef SmartScopedWriter<false> ScopedWriter; + } +} + +#endif diff --git a/include/llvm/System/Threading.h b/include/llvm/System/Threading.h new file mode 100644 index 0000000000000..42d2f89bcb825 --- /dev/null +++ b/include/llvm/System/Threading.h @@ -0,0 +1,45 @@ +//===-- llvm/System/Threading.h - Control multithreading mode --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// TThis file defines llvm_start_multithreaded() and friends. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SYSTEM_THREADING_H +#define LLVM_SYSTEM_THREADING_H + +namespace llvm { + /// llvm_start_multithreaded - Allocate and initialize structures needed to + /// make LLVM safe for multithreading. The return value indicates whether + /// multithreaded initialization succeeded. LLVM will still be operational + /// on "failed" return, and will still be safe for hosting threading + /// applications in the JIT, but will not be safe for concurrent calls to the + /// LLVM APIs. + /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS. + bool llvm_start_multithreaded(); + + /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM + /// safe for multithreading. + /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS. + void llvm_stop_multithreaded(); + + /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe + /// mode or not. + bool llvm_is_multithreaded(); + + /// acquire_global_lock - Acquire the global lock. This is a no-op if called + /// before llvm_start_multithreaded(). + void llvm_acquire_global_lock(); + + /// release_global_lock - Release the global lock. This is a no-op if called + /// before llvm_start_multithreaded(). + void llvm_release_global_lock(); +} + +#endif |
