Squashed 'third_party/allwpilib_2017/' content from commit 35ac87d

Change-Id: I7bb6f5556c30d3f5a092e68de0be9c710c60c9f4
git-subtree-dir: third_party/allwpilib_2017
git-subtree-split: 35ac87d6ff8b7f061c4f18c9ea316e5dccd4888a
diff --git a/wpilibc/sim/include/Notifier.h b/wpilibc/sim/include/Notifier.h
new file mode 100644
index 0000000..2e9f88f
--- /dev/null
+++ b/wpilibc/sim/include/Notifier.h
@@ -0,0 +1,76 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2008-2017. 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.                                                               */
+/*----------------------------------------------------------------------------*/
+
+#pragma once
+
+#include <atomic>
+#include <functional>
+#include <list>
+#include <thread>
+#include <utility>
+
+#include "ErrorBase.h"
+#include "HAL/cpp/priority_mutex.h"
+
+namespace frc {
+
+typedef std::function<void()> TimerEventHandler;
+
+class Notifier : public ErrorBase {
+ public:
+  explicit Notifier(TimerEventHandler handler);
+
+  template <typename Callable, typename Arg, typename... Args>
+  Notifier(Callable&& f, Arg&& arg, Args&&... args)
+      : Notifier(std::bind(std::forward<Callable>(f), std::forward<Arg>(arg),
+                           std::forward<Args>(args)...)) {}
+  virtual ~Notifier();
+
+  Notifier(const Notifier&) = delete;
+  Notifier& operator=(const Notifier&) = delete;
+
+  void StartSingle(double delay);
+  void StartPeriodic(double period);
+  void Stop();
+
+ private:
+  static std::list<Notifier*> timerQueue;
+  static priority_recursive_mutex queueMutex;
+  static priority_mutex halMutex;
+  static void* m_notifier;
+  static std::atomic<int> refcount;
+
+  // Process the timer queue on a timer event
+  static void ProcessQueue(int mask, void* params);
+
+  // Update the FPGA alarm since the queue has changed
+  static void UpdateAlarm();
+
+  // Insert the Notifier in the timer queue
+  void InsertInQueue(bool reschedule);
+
+  // Delete this Notifier from the timer queue
+  void DeleteFromQueue();
+
+  // Address of the handler
+  TimerEventHandler m_handler;
+  // The relative time (either periodic or single)
+  double m_period = 0;
+  // Absolute expiration time for the current event
+  double m_expirationTime = 0;
+  // True if this is a periodic event
+  bool m_periodic = false;
+  // Indicates if this entry is queued
+  bool m_queued = false;
+  // Held by interrupt manager task while handler call is in progress
+  priority_mutex m_handlerMutex;
+  static std::thread m_task;
+  static std::atomic<bool> m_stopped;
+  static void Run();
+};
+
+}  // namespace frc