diff --git a/hal/include/HAL/HAL.h b/hal/include/HAL/HAL.h index f314fd9cf2..a0b319cdb5 100644 --- a/hal/include/HAL/HAL.h +++ b/hal/include/HAL/HAL.h @@ -31,7 +31,6 @@ #include "Power.h" #include "Relay.h" #include "SPI.h" -#include "Semaphore.h" #include "SerialPort.h" #include "Solenoid.h" #include "Task.h" @@ -135,7 +134,7 @@ int HAL_SetJoystickOutputs(uint8_t joystickNum, uint32_t outputs, uint16_t leftRumble, uint16_t rightRumble); float HAL_GetMatchTime(int32_t* status); -void HAL_SetNewDataSem(MULTIWAIT_ID sem); +void HAL_WaitForDSData(); bool HAL_GetSystemActive(int32_t* status); bool HAL_GetBrownedOut(int32_t* status); diff --git a/hal/include/HAL/Semaphore.h b/hal/include/HAL/Semaphore.h deleted file mode 100644 index b54e73a7cf..0000000000 --- a/hal/include/HAL/Semaphore.h +++ /dev/null @@ -1,28 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2016. 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 "cpp/priority_condition_variable.h" -#include "cpp/priority_mutex.h" - -typedef priority_mutex* MUTEX_ID; -typedef priority_condition_variable* MULTIWAIT_ID; -typedef priority_condition_variable::native_handle_type NATIVE_MULTIWAIT_ID; - -extern "C" { -MUTEX_ID HAL_InitializeMutexNormal(); -void HAL_DeleteMutex(MUTEX_ID sem); -void HAL_TakeMutex(MUTEX_ID sem); -bool HAL_TryTakeMutex(MUTEX_ID sem); -void HAL_GiveMutex(MUTEX_ID sem); - -MULTIWAIT_ID HAL_InitializeMultiWait(); -void HAL_DeleteMultiWait(MULTIWAIT_ID sem); -void HAL_TakeMultiWait(MULTIWAIT_ID sem, MUTEX_ID m); -void HAL_GiveMultiWait(MULTIWAIT_ID sem); -} diff --git a/hal/lib/athena/HALAthena.cpp b/hal/lib/athena/HALAthena.cpp index 769f7c2074..9ef101cdce 100644 --- a/hal/lib/athena/HALAthena.cpp +++ b/hal/lib/athena/HALAthena.cpp @@ -23,6 +23,8 @@ #include "FRC_NetworkCommunication/FRCComm.h" #include "FRC_NetworkCommunication/LoadOut.h" #include "HAL/Errors.h" +#include "HAL/cpp/priority_condition_variable.h" +#include "HAL/cpp/priority_mutex.h" #include "ctre/ctre.h" #include "handles/HandlesInternal.h" #include "visa/visa.h" @@ -36,6 +38,9 @@ static uint32_t timeEpoch = 0; static uint32_t prevFPGATime = 0; static HAL_NotifierHandle rolloverNotifier = 0; +static priority_condition_variable newDSDataAvailableCond; +static priority_mutex newDSDataAvailableMutex; + using namespace hal; extern "C" { @@ -284,6 +289,9 @@ bool HAL_GetBrownedOut(int32_t* status) { static void HALCleanupAtExit() { global = nullptr; watchdog = nullptr; + + // Unregister our new data condition variable. + setNewDataSem(nullptr); } static void timerRollover(uint64_t currentTime, void*) { @@ -293,6 +301,14 @@ static void timerRollover(uint64_t currentTime, void*) { &status); } +/** + * Waits for the newest DS packet to arrive. Note that this is a blocking call. + */ +void HAL_WaitForDSData() { + std::unique_lock lock(newDSDataAvailableMutex); + newDSDataAvailableCond.wait(lock); +} + /** * Call this to start up HAL. This is required for robot programs. */ @@ -360,6 +376,9 @@ int HAL_Initialize(int mode) { fs << pid << std::endl; fs.close(); + // Set our DS new data condition variable. + setNewDataSem(newDSDataAvailableCond.native_handle()); + return 1; } diff --git a/hal/lib/athena/Semaphore.cpp b/hal/lib/athena/Semaphore.cpp deleted file mode 100644 index 30c3f33ac1..0000000000 --- a/hal/lib/athena/Semaphore.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2016. 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 "HAL/Semaphore.h" - -#include "Log.h" - -// set the logging level -TLogLevel semaphoreLogLevel = logDEBUG; - -#define SEMAPHORE_LOG(level) \ - if (level > semaphoreLogLevel) \ - ; \ - else \ - Log().Get(level) - -extern "C" { - -MUTEX_ID HAL_InitializeMutexNormal() { return new priority_mutex; } - -void HAL_DeleteMutex(MUTEX_ID sem) { delete sem; } - -/** - * Lock the mutex, blocking until it's available. - */ -void HAL_TakeMutex(MUTEX_ID mutex) { mutex->lock(); } - -/** - * Attempt to lock the mutex. - * @return true if succeeded in locking the mutex, false otherwise. - */ -bool HAL_TryTakeMutex(MUTEX_ID mutex) { return mutex->try_lock(); } - -/** - * Unlock the mutex. - * @return 0 for success, -1 for error. If -1, the error will be in errno. - */ -void HAL_GiveMutex(MUTEX_ID mutex) { mutex->unlock(); } - -MULTIWAIT_ID HAL_InitializeMultiWait() { - return new priority_condition_variable; -} - -void HAL_DeleteMultiWait(MULTIWAIT_ID cond) { delete cond; } - -void HAL_TakeMultiWait(MULTIWAIT_ID cond, MUTEX_ID m) { - std::unique_lock lock(*m); - cond->wait(lock); -} - -void HAL_GiveMultiWait(MULTIWAIT_ID cond) { cond->notify_all(); } - -} // extern "C" diff --git a/hal/lib/shared/HAL.cpp b/hal/lib/shared/HAL.cpp index d1a702d89a..2d009e7293 100644 --- a/hal/lib/shared/HAL.cpp +++ b/hal/lib/shared/HAL.cpp @@ -7,6 +7,7 @@ #include "HAL/HAL.h" +#include #include #include "FRC_NetworkCommunication/FRCComm.h" @@ -24,10 +25,6 @@ int HAL_GetControlWord(HAL_ControlWord* controlWord) { reinterpret_cast(controlWord)); } -void HAL_SetNewDataSem(MULTIWAIT_ID sem) { - setNewDataSem(sem->native_handle()); -} - HAL_AllianceStationID HAL_GetAllianceStation(int32_t* status) { HAL_AllianceStationID allianceStation; *status = FRC_NetworkCommunication_getAllianceStation( diff --git a/wpilibc/athena/include/DriverStation.h b/wpilibc/athena/include/DriverStation.h index e1dc5cc783..0ed6487759 100644 --- a/wpilibc/athena/include/DriverStation.h +++ b/wpilibc/athena/include/DriverStation.h @@ -114,8 +114,6 @@ class DriverStation : public SensorBase, public RobotStateInterface { Task m_task; std::atomic m_isRunning{false}; mutable Semaphore m_newControlData{Semaphore::kEmpty}; - mutable priority_condition_variable m_packetDataAvailableCond; - priority_mutex m_packetDataAvailableMutex; bool m_updatedControlLoopData = false; std::condition_variable_any m_waitForDataCond; priority_mutex m_waitForDataMutex; diff --git a/wpilibc/athena/src/DriverStation.cpp b/wpilibc/athena/src/DriverStation.cpp index 9b8d134f11..5642b7c591 100644 --- a/wpilibc/athena/src/DriverStation.cpp +++ b/wpilibc/athena/src/DriverStation.cpp @@ -54,9 +54,6 @@ DriverStation::DriverStation() { m_joystickDescriptorCache[i].type = -1; m_joystickDescriptorCache[i].name[0] = '\0'; } - // Register that semaphore with the network communications task. - // It will signal when new packet data is available. - HAL_SetNewDataSem(&m_packetDataAvailableCond); m_task = Task("DriverStation", &DriverStation::Run, this); } @@ -64,19 +61,13 @@ DriverStation::DriverStation() { DriverStation::~DriverStation() { m_isRunning = false; m_task.join(); - - // Unregister our semaphore. - HAL_SetNewDataSem(nullptr); } void DriverStation::Run() { m_isRunning = true; int period = 0; while (m_isRunning) { - { - std::unique_lock lock(m_packetDataAvailableMutex); - m_packetDataAvailableCond.wait(lock); - } + HAL_WaitForDSData(); GetData(); { std::lock_guard lock(m_waitForDataMutex); diff --git a/wpilibj/src/athena/cpp/lib/HAL.cpp b/wpilibj/src/athena/cpp/lib/HAL.cpp index 73a4fd20a2..15bfe0ec61 100644 --- a/wpilibj/src/athena/cpp/lib/HAL.cpp +++ b/wpilibj/src/athena/cpp/lib/HAL.cpp @@ -274,14 +274,12 @@ Java_edu_wpi_first_wpilibj_hal_HAL_getJoystickAxisType(JNIEnv*, jclass, /* * Class: edu_wpi_first_wpilibj_hal_HAL - * Method: HALSetNewDataSem - * Signature: (J)V + * Method: HAL_waitForDSData + * Signature: ()V */ JNIEXPORT void JNICALL -Java_edu_wpi_first_wpilibj_hal_HAL_setNewDataSem(JNIEnv* env, jclass, - jlong id) { - NETCOMM_LOG(logDEBUG) << "Mutex Ptr = " << (void *)id; - HAL_SetNewDataSem((MULTIWAIT_ID)id); +Java_edu_wpi_first_wpilibj_hal_HAL_waitForDSData(JNIEnv* env, jclass) { + HAL_WaitForDSData(); } /* diff --git a/wpilibj/src/athena/cpp/lib/HALUtil.cpp b/wpilibj/src/athena/cpp/lib/HALUtil.cpp index b03a65fe42..02350aeb86 100644 --- a/wpilibj/src/athena/cpp/lib/HALUtil.cpp +++ b/wpilibj/src/athena/cpp/lib/HALUtil.cpp @@ -372,80 +372,6 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { jvm = nullptr; } -/* - * Class: edu_wpi_first_wpilibj_hal_HALUtil - * Method: initializeMutex - * Signature: (I)J - */ -JNIEXPORT jlong JNICALL -Java_edu_wpi_first_wpilibj_hal_HALUtil_initializeMutexNormal( - JNIEnv *env, jclass) { - HALUTIL_LOG(logDEBUG) << "Calling HALUtil initializeMutex"; - MUTEX_ID mutex = HAL_InitializeMutexNormal(); - HALUTIL_LOG(logDEBUG) << "Mutex Ptr = " << mutex; - return (jlong)mutex; -} - -/* - * Class: edu_wpi_first_wpilibj_hal_HALUtil - * Method: deleteMutex - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_HALUtil_deleteMutex( - JNIEnv *env, jclass, jlong id) { - HALUTIL_LOG(logDEBUG) << "Calling HALUtil deleteMutex"; - HALUTIL_LOG(logDEBUG) << "Mutex Ptr = " << (MUTEX_ID)id; - HAL_DeleteMutex((MUTEX_ID)id); -} - -/* - * Class: edu_wpi_first_wpilibj_hal_HALUtil - * Method: takeMutex - * Signature: (JI)V - */ -JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_HALUtil_takeMutex( - JNIEnv *env, jclass, jlong id) { - // HALUTIL_LOG(logDEBUG) << "Calling HALUtil takeMutex"; - // HALUTIL_LOG(logDEBUG) << "Mutex Ptr = " << (MUTEX_ID)id; - HAL_TakeMutex((MUTEX_ID)id); -} - -/* - * Class: edu_wpi_first_wpilibj_hal_HALUtil - * Method: initializeMultiWait - * Signature: ()J - */ -JNIEXPORT jlong JNICALL -Java_edu_wpi_first_wpilibj_hal_HALUtil_initializeMultiWait( - JNIEnv *env, jclass) { - HALUTIL_LOG(logDEBUG) << "Calling HALUtil initializeMultiWait"; - MULTIWAIT_ID multiWait = HAL_InitializeMultiWait(); - HALUTIL_LOG(logDEBUG) << "MultiWait Ptr = " << multiWait; - return (jlong)multiWait; -} - -/* - * Class: edu_wpi_first_wpilibj_hal_HALUtil - * Method: deleteMultiWait - * Signature: (J)V - */ -JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_HALUtil_deleteMultiWait( - JNIEnv *env, jclass, jlong id) { - HALUTIL_LOG(logDEBUG) << "Calling HALUtil deleteMultiWait"; - HALUTIL_LOG(logDEBUG) << "MultiWait Ptr = " << (MULTIWAIT_ID)id; - HAL_DeleteMultiWait((MULTIWAIT_ID)id); -} - -/* - * Class: edu_wpi_first_wpilibj_hal_HALUtil - * Method: takeMultiWait - * Signature: (JJ)V - */ -JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_HALUtil_takeMultiWait( - JNIEnv *env, jclass, jlong multiWaitId, jlong mutexId) { - HAL_TakeMultiWait((MULTIWAIT_ID)multiWaitId, (MUTEX_ID)mutexId); -} - /* * Class: edu_wpi_first_wpilibj_hal_HALUtil * Method: getFPGAVersion diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DriverStation.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DriverStation.java index 089a3d24e7..4118a72537 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DriverStation.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DriverStation.java @@ -100,8 +100,6 @@ public class DriverStation implements RobotState.Interface { private boolean m_userInTest = false; private boolean m_updatedControlLoopData; private boolean m_newControlData; - private final long m_packetDataAvailableMutex; - private final long m_packetDataAvailableSem; /** * Gets an instance of the DriverStation @@ -132,10 +130,6 @@ public class DriverStation implements RobotState.Interface { m_joystickPOVsCache[i] = new HALJoystickPOVs(HAL.kMaxJoystickPOVs); } - m_packetDataAvailableMutex = HALUtil.initializeMutexNormal(); - m_packetDataAvailableSem = HALUtil.initializeMultiWait(); - HAL.setNewDataSem(m_packetDataAvailableSem); - m_thread = new Thread(new DriverStationTask(this), "FRCDriverStation"); m_thread.setPriority((Thread.NORM_PRIORITY + Thread.MAX_PRIORITY) / 2); @@ -155,7 +149,7 @@ public class DriverStation implements RobotState.Interface { private void task() { int safetyCounter = 0; while (m_threadKeepAlive) { - HALUtil.takeMultiWait(m_packetDataAvailableSem, m_packetDataAvailableMutex); + HAL.waitForDSData(); getData(); synchronized (m_dataSem) { m_updatedControlLoopData = true; diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HAL.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HAL.java index 4ae19e763f..0c944b227d 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HAL.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HAL.java @@ -16,7 +16,7 @@ import edu.wpi.first.wpilibj.hal.JNIWrapper; */ @SuppressWarnings({"AbbreviationAsWordInName", "MethodName"}) public class HAL extends JNIWrapper { - public static native void setNewDataSem(long mutexId); + public static native void waitForDSData(); public static native int initialize(int mode); diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HALUtil.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HALUtil.java index 1e7ff0518d..96e60e4e4e 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HALUtil.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/HALUtil.java @@ -18,24 +18,6 @@ public class HALUtil extends JNIWrapper { public static final int NO_AVAILABLE_RESOURCES = -104; public static final int PARAMETER_OUT_OF_RANGE = -1028; - // public static final int SEMAPHORE_WAIT_FOREVER = -1; - // public static final int SEMAPHORE_Q_PRIORITY = 0x01; - - public static native long initializeMutexNormal(); - - public static native void deleteMutex(long sem); - - public static native void takeMutex(long sem); - - // public static native long initializeSemaphore(int initialValue); - // public static native void deleteSemaphore(long sem); - // public static native byte takeSemaphore(long sem, int timeout); - public static native long initializeMultiWait(); - - public static native void deleteMultiWait(long sem); - - public static native void takeMultiWait(long sem, long ms); - public static native short getFPGAVersion(); public static native int getFPGARevision();