Squashed 'third_party/allwpilib_2016/' content from commit 7f61816

Change-Id: If9d9245880859cdf580f5d7f77045135d0521ce7
git-subtree-dir: third_party/allwpilib_2016
git-subtree-split: 7f618166ed253a24629934fcf89c3decb0528a3b
diff --git a/hal/include/HAL/cpp/Resource.hpp b/hal/include/HAL/cpp/Resource.hpp
new file mode 100644
index 0000000..ae31996
--- /dev/null
+++ b/hal/include/HAL/cpp/Resource.hpp
@@ -0,0 +1,46 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008. All Rights Reserved.							  */
+/* Open Source Software - may be modified and shared by FRC teams. The code   */
+/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib.  */
+/*----------------------------------------------------------------------------*/
+#pragma once
+
+#include "../Errors.hpp"
+#include "HAL/cpp/priority_mutex.h"
+#include <stdint.h>
+
+#include <vector>
+
+// TODO: Replace this with something appropriate to avoid conflicts with
+// wpilibC++ Resource class (which performs an essentially identical function).
+namespace hal {
+
+/**
+ * The Resource class is a convenient way to track allocated resources.
+ * It tracks them as indicies in the range [0 .. elements - 1].
+ * E.g. the library uses this to track hardware channel allocation.
+ *
+ * The Resource class does not allocate the hardware channels or other
+ * resources; it just tracks which indices were marked in use by
+ * Allocate and not yet freed by Free.
+ */
+class Resource
+{
+public:
+	Resource(const Resource&) = delete;
+	Resource& operator=(const Resource&) = delete;
+	explicit Resource(uint32_t size);
+	virtual ~Resource() = default;
+	static void CreateResourceObject(Resource **r, uint32_t elements);
+	uint32_t Allocate(const char *resourceDesc);
+	uint32_t Allocate(uint32_t index, const char *resourceDesc);
+	void Free(uint32_t index);
+
+private:
+	std::vector<bool> m_isAllocated;
+	priority_recursive_mutex m_allocateLock;
+
+	static priority_recursive_mutex m_createLock;
+};
+
+}  // namespace hal
diff --git a/hal/include/HAL/cpp/Semaphore.hpp b/hal/include/HAL/cpp/Semaphore.hpp
new file mode 100644
index 0000000..6a6374b
--- /dev/null
+++ b/hal/include/HAL/cpp/Semaphore.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <cstdint>
+#include <condition_variable>
+
+#include "HAL/cpp/priority_mutex.h"
+
+class Semaphore {
+ public:
+  explicit Semaphore(uint32_t count = 0);
+  Semaphore(Semaphore&&);
+  Semaphore& operator=(Semaphore&&);
+
+  void give();
+  void take();
+
+  // @return true if semaphore was locked successfully. false if not.
+  bool tryTake();
+
+  static const int32_t kNoWait = 0;
+  static const int32_t kWaitForever = -1;
+
+  static const uint32_t kEmpty = 0;
+  static const uint32_t kFull = 1;
+
+ private:
+  priority_mutex m_mutex;
+  std::condition_variable_any m_condition;
+  uint32_t m_count = 0;
+};
diff --git a/hal/include/HAL/cpp/priority_condition_variable.h b/hal/include/HAL/cpp/priority_condition_variable.h
new file mode 100644
index 0000000..e8ab9e5
--- /dev/null
+++ b/hal/include/HAL/cpp/priority_condition_variable.h
@@ -0,0 +1,117 @@
+#pragma once
+
+/* std::condition_variable provides the native_handle() method to return its
+ * underlying pthread_cond_t*. WPILib uses this to interface with the FRC
+ * network communication library. Since WPILib uses a custom mutex class and
+ * not std::mutex, std::condition_variable_any must be used instead.
+ * std::condition_variable_any doesn't expose its internal handle, so this
+ * class provides the same interface and implementation in addition to a
+ * native_handle() method.
+ */
+
+#include <condition_variable>
+#include <memory>
+#include "priority_mutex.h"
+
+class priority_condition_variable {
+  typedef std::chrono::system_clock clock_t;
+
+ public:
+  typedef std::condition_variable::native_handle_type native_handle_type;
+
+  priority_condition_variable() : m_mutex(std::make_shared<std::mutex>()) {}
+  ~priority_condition_variable() = default;
+
+  priority_condition_variable(const priority_condition_variable&) = delete;
+  priority_condition_variable& operator=(const priority_condition_variable&) = delete;
+
+  void notify_one() noexcept {
+    std::lock_guard<std::mutex> lock(*m_mutex);
+    m_cond.notify_one();
+  }
+
+  void notify_all() noexcept {
+    std::lock_guard<std::mutex> lock(*m_mutex);
+    m_cond.notify_all();
+  }
+
+  template<typename Lock>
+  void wait(Lock& _lock) {
+    std::shared_ptr<std::mutex> _mutex = m_mutex;
+    std::unique_lock<std::mutex> my_lock(*_mutex);
+    Unlock<Lock> unlock(_lock);
+
+    // *mutex must be unlocked before re-locking _lock so move
+    // ownership of *_mutex lock to an object with shorter lifetime.
+    std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
+    m_cond.wait(my_lock2);
+  }
+
+  template<typename Lock, typename Predicate>
+  void wait(Lock& lock, Predicate p) {
+    while (!p()) { wait(lock); }
+  }
+
+  template<typename Lock, typename Clock, typename Duration>
+  std::cv_status wait_until(Lock& _lock,
+        const std::chrono::time_point<Clock, Duration>& atime) {
+    std::shared_ptr<std::mutex> _mutex = m_mutex;
+    std::unique_lock<std::mutex> my_lock(*_mutex);
+    Unlock<Lock> unlock(_lock);
+
+    // *_mutex must be unlocked before re-locking _lock so move
+    // ownership of *_mutex lock to an object with shorter lifetime.
+    std::unique_lock<std::mutex> my_lock2(std::move(my_lock));
+    return m_cond.wait_until(my_lock2, atime);
+  }
+
+  template<typename Lock, typename Clock, typename Duration, typename Predicate>
+  bool wait_until(Lock& lock,
+      const std::chrono::time_point<Clock, Duration>& atime, Predicate p) {
+    while (!p()) {
+      if (wait_until(lock, atime) == std::cv_status::timeout) {
+        return p();
+      }
+    }
+    return true;
+  }
+
+  template<typename Lock, typename Rep, typename Period>
+  std::cv_status wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& rtime) {
+    return wait_until(lock, clock_t::now() + rtime);
+  }
+
+  template<typename Lock, typename Rep, typename Period, typename Predicate>
+  bool wait_for(Lock& lock, const std::chrono::duration<Rep, Period>& rtime,
+      Predicate p) {
+    return wait_until(lock, clock_t::now() + rtime, std::move(p));
+  }
+
+  native_handle_type native_handle() {
+    return m_cond.native_handle();
+  }
+
+ private:
+  std::condition_variable m_cond;
+  std::shared_ptr<std::mutex> m_mutex;
+
+  // scoped unlock - unlocks in ctor, re-locks in dtor
+  template<typename Lock>
+  struct Unlock {
+    explicit Unlock(Lock& lk) : m_lock(lk) { lk.unlock(); }
+
+    ~Unlock() /*noexcept(false)*/ {
+      if (std::uncaught_exception()) {
+        try { m_lock.lock(); } catch(...) {}
+      }
+      else {
+        m_lock.lock();
+      }
+    }
+
+    Unlock(const Unlock&) = delete;
+    Unlock& operator=(const Unlock&) = delete;
+
+    Lock& m_lock;
+  };
+};
diff --git a/hal/include/HAL/cpp/priority_mutex.h b/hal/include/HAL/cpp/priority_mutex.h
new file mode 100644
index 0000000..16e88f6
--- /dev/null
+++ b/hal/include/HAL/cpp/priority_mutex.h
@@ -0,0 +1,76 @@
+#pragma once
+
+// Allows usage with std::lock_guard without including <mutex> separately
+#include <mutex>
+
+#ifdef FRC_SIMULATOR
+// We do not want to use pthreads if in the simulator; however, in the
+// simulator, we do not care about priority inversion.
+typedef std::mutex priority_mutex;
+typedef std::recursive_mutex priority_recursive_mutex;
+#else // Covers rest of file.
+
+#include <pthread.h>
+
+class priority_recursive_mutex {
+ public:
+  typedef pthread_mutex_t *native_handle_type;
+
+  constexpr priority_recursive_mutex() noexcept = default;
+  priority_recursive_mutex(const priority_recursive_mutex &) = delete;
+  priority_recursive_mutex &operator=(const priority_recursive_mutex &) = delete;
+
+  // Lock the mutex, blocking until it's available.
+  void lock();
+
+  // Unlock the mutex.
+  void unlock();
+
+  // Tries to lock the mutex.
+  bool try_lock() noexcept;
+
+  pthread_mutex_t *native_handle();
+
+ private:
+  // Do the equivalent of setting PTHREAD_PRIO_INHERIT and
+  // PTHREAD_MUTEX_RECURSIVE_NP.
+#if __WORDSIZE == 64
+  pthread_mutex_t m_mutex = {
+      {0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, 0, {0, 0}}};
+#else
+  pthread_mutex_t m_mutex = {
+      {0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {0}}};
+#endif
+};
+
+class priority_mutex {
+ public:
+  typedef pthread_mutex_t *native_handle_type;
+
+  constexpr priority_mutex() noexcept = default;
+  priority_mutex(const priority_mutex &) = delete;
+  priority_mutex &operator=(const priority_mutex &) = delete;
+
+  // Lock the mutex, blocking until it's available.
+  void lock();
+
+  // Unlock the mutex.
+  void unlock();
+
+  // Tries to lock the mutex.
+  bool try_lock() noexcept;
+
+  pthread_mutex_t *native_handle();
+
+ private:
+  // Do the equivalent of setting PTHREAD_PRIO_INHERIT.
+#if __WORDSIZE == 64
+  pthread_mutex_t m_mutex = {
+      {0, 0, 0, 0, 0x20, 0, 0, {0, 0}}};
+#else
+  pthread_mutex_t m_mutex = {
+      {0, 0, 0, 0x20, 0, {0}}};
+#endif
+};
+
+#endif  // FRC_SIMULATOR