For PR540:
authorReid Spencer <rspencer@reidspencer.com>
Tue, 12 Jul 2005 15:37:43 +0000 (15:37 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Tue, 12 Jul 2005 15:37:43 +0000 (15:37 +0000)
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

include/llvm/System/Mutex.h [new file with mode: 0644]
lib/System/Mutex.cpp [new file with mode: 0644]
lib/System/Unix/Mutex.inc [new file with mode: 0644]
lib/System/Win32/Mutex.inc [new file with mode: 0644]

diff --git a/include/llvm/System/Mutex.h b/include/llvm/System/Mutex.h
new file mode 100644 (file)
index 0000000..16e898c
--- /dev/null
@@ -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
diff --git a/lib/System/Mutex.cpp b/lib/System/Mutex.cpp
new file mode 100644 (file)
index 0000000..2a15197
--- /dev/null
@@ -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
diff --git a/lib/System/Unix/Mutex.inc b/lib/System/Unix/Mutex.inc
new file mode 100644 (file)
index 0000000..fa218db
--- /dev/null
@@ -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 )
+{
+}
+
+}
diff --git a/lib/System/Win32/Mutex.inc b/lib/System/Win32/Mutex.inc
new file mode 100644 (file)
index 0000000..d6acb23
--- /dev/null
@@ -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 )
+{
+}
+
+}