aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Support/Process.h63
-rw-r--r--lib/Support/Process.cpp22
-rw-r--r--lib/Support/Unix/Process.inc6
-rw-r--r--lib/Support/Windows/Process.inc6
-rw-r--r--unittests/Support/CMakeLists.txt1
-rw-r--r--unittests/Support/ProcessTest.cpp33
6 files changed, 130 insertions, 1 deletions
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index 2113f62..080634c 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -25,11 +25,74 @@
#ifndef LLVM_SYSTEM_PROCESS_H
#define LLVM_SYSTEM_PROCESS_H
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TimeValue.h"
namespace llvm {
namespace sys {
+class self_process;
+
+/// \brief Generic base class which exposes information about an operating
+/// system process.
+///
+/// This base class is the core interface behind any OS process. It exposes
+/// methods to query for generic information about a particular process.
+///
+/// Subclasses implement this interface based on the mechanisms available, and
+/// can optionally expose more interfaces unique to certain process kinds.
+class process {
+protected:
+ /// \brief Only specific subclasses of process objects can be destroyed.
+ virtual ~process();
+
+public:
+ /// \brief Operating system specific type to identify a process.
+ ///
+ /// Note that the windows one is defined to 'void *' as this is the
+ /// documented type for HANDLE on windows, and we don't want to pull in the
+ /// Windows headers here.
+#if defined(LLVM_ON_UNIX)
+ typedef pid_t id_type;
+#elif defined(LLVM_ON_WIN32)
+ typedef void *id_type; // Must match the type of HANDLE.
+#else
+#error Unsupported operating system.
+#endif
+
+ /// \brief Get the operating system specific identifier for this process.
+ virtual id_type get_id() = 0;
+
+
+ /// \name Static factory routines for processes.
+ /// @{
+
+ /// \brief Get the process object for the current process.
+ static self_process *get_self();
+
+ /// @}
+
+};
+
+/// \brief The specific class representing the current process.
+///
+/// The current process can both specialize the implementation of the routines
+/// and can expose certain information not available for other OS processes.
+class self_process : public process {
+ friend class process;
+
+ /// \brief Private destructor, as users shouldn't create objects of this
+ /// type.
+ virtual ~self_process();
+
+public:
+ virtual id_type get_id();
+
+private:
+};
+
+
/// \brief A collection of legacy interfaces for querying information about the
/// current executing process.
class Process {
diff --git a/lib/Support/Process.cpp b/lib/Support/Process.cpp
index 88ca7c3..8d1b648 100644
--- a/lib/Support/Process.cpp
+++ b/lib/Support/Process.cpp
@@ -11,8 +11,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Process.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/ErrorHandling.h"
namespace llvm {
using namespace sys;
@@ -22,6 +23,25 @@ using namespace sys;
//=== independent code.
//===----------------------------------------------------------------------===//
+// Empty virtual destructor to anchor the vtable for the process class.
+process::~process() {}
+
+self_process *process::get_self() {
+ // Use a function local static for thread safe initialization and allocate it
+ // as a raw pointer to ensure it is never destroyed.
+ static self_process *SP = new self_process();
+
+ return SP;
+}
+
+// The destructor for the self_process subclass must never actually be
+// executed. There should be at most one instance of this class, and that
+// instance should live until the process terminates to avoid the potential for
+// racy accesses during shutdown.
+self_process::~self_process() {
+ llvm_unreachable("This destructor must never be executed!");
+}
+
}
// Include the platform-specific parts of this class.
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index 5204147..dedc443 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -44,6 +44,12 @@
using namespace llvm;
using namespace sys;
+
+process::id_type self_process::get_id() {
+ return getpid();
+}
+
+
unsigned
Process::GetPageSize()
{
diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc
index 89dbf23..fc24cea 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -38,6 +38,12 @@
namespace llvm {
using namespace sys;
+
+process::id_type self_process::get_id() {
+ return GetCurrentProcess();
+}
+
+
// This function retrieves the page size using GetSystemInfo and is present
// solely so it can be called once in Process::GetPageSize to initialize the
// static variable PageSize.
diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt
index f6a5949..c9a330d 100644
--- a/unittests/Support/CMakeLists.txt
+++ b/unittests/Support/CMakeLists.txt
@@ -20,6 +20,7 @@ add_llvm_unittest(SupportTests
MemoryBufferTest.cpp
MemoryTest.cpp
Path.cpp
+ ProcessTest.cpp
RegexTest.cpp
SwapByteOrderTest.cpp
TimeValue.cpp
diff --git a/unittests/Support/ProcessTest.cpp b/unittests/Support/ProcessTest.cpp
new file mode 100644
index 0000000..d4c4b54
--- /dev/null
+++ b/unittests/Support/ProcessTest.cpp
@@ -0,0 +1,33 @@
+//===- unittest/Support/ProcessTest.cpp -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Process.h"
+#include "gtest/gtest.h"
+
+#ifdef LLVM_ON_WIN32
+#include "windows.h"
+#endif
+
+namespace {
+
+using namespace llvm;
+using namespace sys;
+
+TEST(ProcessTest, SelfProcess) {
+ EXPECT_TRUE(process::get_self());
+ EXPECT_EQ(process::get_self(), process::get_self());
+
+#if defined(LLVM_ON_UNIX)
+ EXPECT_EQ(getpid(), process::get_self()->get_id());
+#elif defined(LLVM_ON_WIN32)
+ EXPECT_EQ(GetCurrentProcess(), process::get_self()->get_id());
+#endif
+}
+
+} // end anonymous namespace