Implements locking in C++ DriverStation, and adds double buffering to DS Thread (#25)

Currently, about 5ms of every 20ms loop the DS thread would hold
the mutex, while grabbing data. During this time, and call to grab
joystick data would be blocked. This change grabs the joystick data
to a cache, and then grabs the mutex and moves the data references
around. This is much more efficient then the old code, and gives
teams more of their teleop loop time back for use.

Another major change this does is use preallocated arrays when entering
the JNI. Previously every JNI DS call would allocate an entire new array.
With a GC'd language where those arrays go on the heap, thats a problem,
and creates tons of garbage. That garbage is no longer created anymore,
as all arrays and byte buffers sent to JNI in the DS are preallocated.

In addition, GetJoystickName was always returning joystick 0 data, which
this fixes.
This commit is contained in:
Thad House
2016-05-21 00:41:15 -07:00
committed by Peter Johnson
parent 0965d60a71
commit a4f0c4fbe0
5 changed files with 274 additions and 131 deletions

View File

@@ -9,6 +9,7 @@
#include <atomic>
#include <condition_variable>
#include <memory>
#include "HAL/HAL.hpp"
#include "HAL/cpp/Semaphore.hpp"
#include "HAL/cpp/priority_condition_variable.h"
@@ -100,10 +101,17 @@ class DriverStation : public SensorBase, public RobotStateInterface {
void ReportJoystickUnpluggedWarning(std::string message);
void Run();
HALJoystickAxes m_joystickAxes[kJoystickPorts];
HALJoystickPOVs m_joystickPOVs[kJoystickPorts];
HALJoystickButtons m_joystickButtons[kJoystickPorts];
HALJoystickDescriptor m_joystickDescriptor[kJoystickPorts];
std::unique_ptr<HALJoystickAxes[]> m_joystickAxes;
std::unique_ptr<HALJoystickPOVs[]> m_joystickPOVs;
std::unique_ptr<HALJoystickButtons[]> m_joystickButtons;
std::unique_ptr<HALJoystickDescriptor[]> m_joystickDescriptor;
// Cached Data
std::unique_ptr<HALJoystickAxes[]> m_joystickAxesCache;
std::unique_ptr<HALJoystickPOVs[]> m_joystickPOVsCache;
std::unique_ptr<HALJoystickButtons[]> m_joystickButtonsCache;
std::unique_ptr<HALJoystickDescriptor[]> m_joystickDescriptorCache;
Task m_task;
std::atomic<bool> m_isRunning{false};
mutable Semaphore m_newControlData{Semaphore::kEmpty};
@@ -111,6 +119,7 @@ class DriverStation : public SensorBase, public RobotStateInterface {
priority_mutex m_packetDataAvailableMutex;
std::condition_variable_any m_waitForDataCond;
priority_mutex m_waitForDataMutex;
mutable priority_mutex m_joystickDataMutex;
bool m_userInDisabled = false;
bool m_userInAutonomous = false;
bool m_userInTeleop = false;