Squashed 'third_party/ntcore_2016/' content from commit d8de5e4

Change-Id: Id4839f41b6a620d8bae58dcf1710016671cc4992
git-subtree-dir: third_party/ntcore_2016
git-subtree-split: d8de5e4f19e612e7102172c0dbf152ce82d3d63a
diff --git a/src/support/ConcurrentQueue.h b/src/support/ConcurrentQueue.h
new file mode 100644
index 0000000..fa99477
--- /dev/null
+++ b/src/support/ConcurrentQueue.h
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2013 Juan Palacios juan.palacios.puyana@gmail.com
+// Subject to the BSD 2-Clause License
+// - see < http://opensource.org/licenses/BSD-2-Clause>
+//
+
+#ifndef NT_SUPPORT_CONCURRENT_QUEUE_H_
+#define NT_SUPPORT_CONCURRENT_QUEUE_H_
+
+#include <queue>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+
+template <typename T>
+class ConcurrentQueue {
+ public:
+  bool empty() const {
+    std::unique_lock<std::mutex> mlock(mutex_);
+    return queue_.empty();
+  }
+
+  typename std::queue<T>::size_type size() const {
+    std::unique_lock<std::mutex> mlock(mutex_);
+    return queue_.size();
+  }
+
+  T pop() {
+    std::unique_lock<std::mutex> mlock(mutex_);
+    while (queue_.empty()) {
+      cond_.wait(mlock);
+    }
+    auto item = std::move(queue_.front());
+    queue_.pop();
+    return item;
+  }
+
+  void pop(T& item) {
+    std::unique_lock<std::mutex> mlock(mutex_);
+    while (queue_.empty()) {
+      cond_.wait(mlock);
+    }
+    item = queue_.front();
+    queue_.pop();
+  }
+
+  void push(const T& item) {
+    std::unique_lock<std::mutex> mlock(mutex_);
+    queue_.push(item);
+    mlock.unlock();
+    cond_.notify_one();
+  }
+
+  void push(T&& item) {
+    std::unique_lock<std::mutex> mlock(mutex_);
+    queue_.push(std::forward<T>(item));
+    mlock.unlock();
+    cond_.notify_one();
+  }
+
+  template <typename... Args>
+  void emplace(Args&&... args) {
+    std::unique_lock<std::mutex> mlock(mutex_);
+    queue_.emplace(std::forward<Args>(args)...);
+    mlock.unlock();
+    cond_.notify_one();
+  }
+
+  ConcurrentQueue() = default;
+  ConcurrentQueue(const ConcurrentQueue&) = delete;
+  ConcurrentQueue& operator=(const ConcurrentQueue&) = delete;
+
+ private:
+  std::queue<T> queue_;
+  mutable std::mutex mutex_;
+  std::condition_variable cond_;
+};
+
+#endif  // NT_SUPPORT_CONCURRENT_QUEUE_H_
diff --git a/src/support/timestamp.cpp b/src/support/timestamp.cpp
new file mode 100644
index 0000000..6dd4387
--- /dev/null
+++ b/src/support/timestamp.cpp
@@ -0,0 +1,89 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2015. 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 the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+#include "timestamp.h"
+
+#ifdef _WIN32
+#include <cassert>
+#include <exception>
+#include <windows.h>
+#else
+#include <chrono>
+#endif
+
+// offset in microseconds
+static unsigned long long zerotime() {
+#ifdef _WIN32
+  FILETIME ft;
+  unsigned long long tmpres = 0;
+  // 100-nanosecond intervals since January 1, 1601 (UTC)
+  // which means 0.1 us
+  GetSystemTimeAsFileTime(&ft);
+  tmpres |= ft.dwHighDateTime;
+  tmpres <<= 32;
+  tmpres |= ft.dwLowDateTime;
+  // January 1st, 1970 - January 1st, 1601 UTC ~ 369 years
+  // or 116444736000000000 us
+  static const unsigned long long deltaepoch = 116444736000000000ull;
+  tmpres -= deltaepoch;
+  return tmpres;
+#else
+  // 100-ns intervals
+  using namespace std::chrono;
+  return duration_cast<nanoseconds>(
+    high_resolution_clock::now().time_since_epoch()).count() / 100u;
+#endif
+}
+
+static unsigned long long timestamp() {
+#ifdef _WIN32
+  LARGE_INTEGER li;
+  QueryPerformanceCounter(&li);
+  // there is an imprecision with the initial value,
+  // but what matters is that timestamps are monotonic and consistent
+  return static_cast<unsigned long long>(li.QuadPart);
+#else
+  // 100-ns intervals
+  using namespace std::chrono;
+  return duration_cast<nanoseconds>(
+    steady_clock::now().time_since_epoch()).count() / 100u;
+#endif
+}
+
+#ifdef _WIN32
+static unsigned long long update_frequency() {
+  LARGE_INTEGER li;
+  if (!QueryPerformanceFrequency(&li) || !li.QuadPart) {
+    // log something
+    std::terminate();
+  }
+  return static_cast<unsigned long long>(li.QuadPart);
+}
+#endif
+
+static const unsigned long long zerotime_val = zerotime();
+static const unsigned long long offset_val = timestamp();
+#ifdef _WIN32
+static const unsigned long long frequency_val = update_frequency();
+#endif
+
+unsigned long long nt::Now() {
+#ifdef _WIN32
+  assert(offset_val > 0u);
+  assert(frequency_val > 0u);
+  unsigned long long delta = timestamp() - offset_val;
+  // because the frequency is in update per seconds, we have to multiply the
+  // delta by 10,000,000
+  unsigned long long delta_in_us = delta * 10000000ull / frequency_val;
+  return delta_in_us + zerotime_val;
+#else
+  return zerotime_val + timestamp() - offset_val;
+#endif
+}
+
+unsigned long long NT_Now() {
+  return nt::Now();
+}
diff --git a/src/support/timestamp.h b/src/support/timestamp.h
new file mode 100644
index 0000000..215aa88
--- /dev/null
+++ b/src/support/timestamp.h
@@ -0,0 +1,28 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2015. 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 the root directory of */
+/* the project.                                                               */
+/*----------------------------------------------------------------------------*/
+#ifndef NT_SUPPORT_TIMESTAMP_H_
+#define NT_SUPPORT_TIMESTAMP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned long long NT_Now(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+namespace nt {
+
+unsigned long long Now();
+
+}  // namespace nt
+#endif
+
+#endif  // NT_SUPPORT_TIMESTAMP_H_