From de39877efb0a9b445bd973d4231cf8f19416d053 Mon Sep 17 00:00:00 2001 From: Thad House Date: Tue, 20 Oct 2015 10:37:04 -0700 Subject: [PATCH] artf4153 Adds HAL structure memory management In the current HAL, once the port structures were created, there was no way to free the structures. The way the C++ libraries were written this wasn't a problem, since it grabbed a copy of each and stored them in an array on bootup. However java does not do this, and grabs new ports every time an object is created. This causes memory leaks if an object is ever disposed in java. The same thing looks to be happening in python, and C# does it too currently, but that would change if this gets merged. Adds java memory management fixes Adds memory management to AnalogInput and Analog Output C++ SolenoidPorts and Digital Ports are all hold static arrays with their port pointers (although solenoid overwrites them if a new solenoid on the same module is created), however analog always grabbed new pointers. I would fix the solenoid one, but I don't know what the ideal way to do it would be. Silently ignores free(null) calls by checking passed parameter is non-null. Change-Id: Id32993b57b53f896e46e55c97541d3bd90b52648 --- hal/include/HAL/Analog.hpp | 2 ++ hal/include/HAL/Digital.hpp | 1 + hal/include/HAL/HAL.hpp | 1 + hal/include/HAL/Solenoid.hpp | 1 + hal/lib/Athena/Analog.cpp | 17 +++++++++++++ hal/lib/Athena/Digital.cpp | 19 +++++++++------ hal/lib/Athena/HALAthena.cpp | 6 +++++ hal/lib/Athena/Solenoid.cpp | 5 ++++ wpilibc/Athena/src/AnalogInput.cpp | 5 +++- wpilibc/Athena/src/AnalogOutput.cpp | 5 +++- wpilibj/src/athena/cpp/lib/AnalogJNI.cpp | 24 +++++++++++++++++++ wpilibj/src/athena/cpp/lib/DIOJNI.cpp | 13 ++++++++++ wpilibj/src/athena/cpp/lib/JNIWrapper.cpp | 15 ++++++++++++ wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp | 14 +++++++++++ .../edu/wpi/first/wpilibj/AnalogInput.java | 2 ++ .../edu/wpi/first/wpilibj/AnalogOutput.java | 2 ++ .../edu/wpi/first/wpilibj/DigitalSource.java | 2 ++ .../edu/wpi/first/wpilibj/DoubleSolenoid.java | 1 + .../java/edu/wpi/first/wpilibj/PWM.java | 3 +++ .../java/edu/wpi/first/wpilibj/Relay.java | 2 ++ .../java/edu/wpi/first/wpilibj/Solenoid.java | 3 +++ .../edu/wpi/first/wpilibj/SolenoidBase.java | 11 +++++++++ .../edu/wpi/first/wpilibj/hal/AnalogJNI.java | 4 ++++ .../edu/wpi/first/wpilibj/hal/DIOJNI.java | 2 ++ .../edu/wpi/first/wpilibj/hal/JNIWrapper.java | 2 ++ .../wpi/first/wpilibj/hal/SolenoidJNI.java | 2 ++ 26 files changed, 155 insertions(+), 9 deletions(-) diff --git a/hal/include/HAL/Analog.hpp b/hal/include/HAL/Analog.hpp index 17523683aa..2aa5e43ede 100644 --- a/hal/include/HAL/Analog.hpp +++ b/hal/include/HAL/Analog.hpp @@ -14,12 +14,14 @@ extern "C" { // Analog output functions void* initializeAnalogOutputPort(void* port_pointer, int32_t *status); + void freeAnalogOutputPort(void* analog_port_pointer); void setAnalogOutput(void* analog_port_pointer, double voltage, int32_t *status); double getAnalogOutput(void* analog_port_pointer, int32_t *status); bool checkAnalogOutputChannel(uint32_t pin); // Analog input functions void* initializeAnalogInputPort(void* port_pointer, int32_t *status); + void freeAnalogInputPort(void* analog_port_pointer); bool checkAnalogModule(uint8_t module); bool checkAnalogInputChannel(uint32_t pin); diff --git a/hal/include/HAL/Digital.hpp b/hal/include/HAL/Digital.hpp index 2ef512df80..25eb91be2a 100644 --- a/hal/include/HAL/Digital.hpp +++ b/hal/include/HAL/Digital.hpp @@ -16,6 +16,7 @@ priority_recursive_mutex& spiGetSemaphore(uint8_t port); extern "C" { void* initializeDigitalPort(void* port_pointer, int32_t *status); + void freeDigitalPort(void* digital_port_pointer); bool checkPWMChannel(void* digital_port_pointer); bool checkRelayChannel(void* digital_port_pointer); diff --git a/hal/include/HAL/HAL.hpp b/hal/include/HAL/HAL.hpp index df87d96d93..3ef56504ff 100644 --- a/hal/include/HAL/HAL.hpp +++ b/hal/include/HAL/HAL.hpp @@ -211,6 +211,7 @@ extern "C" void* getPort(uint8_t pin); void* getPortWithModule(uint8_t module, uint8_t pin); + void freePort(void* port); const char* getHALErrorMessage(int32_t code); uint16_t getFPGAVersion(int32_t *status); diff --git a/hal/include/HAL/Solenoid.hpp b/hal/include/HAL/Solenoid.hpp index df06a33b77..f5bb9cf69c 100644 --- a/hal/include/HAL/Solenoid.hpp +++ b/hal/include/HAL/Solenoid.hpp @@ -5,6 +5,7 @@ extern "C" { void* initializeSolenoidPort(void* port_pointer, int32_t *status); + void freeSolenoidPort(void* solenoid_port_pointer); bool checkSolenoidModule(uint8_t module); bool getSolenoid(void* solenoid_port_pointer, int32_t *status); diff --git a/hal/lib/Athena/Analog.cpp b/hal/lib/Athena/Analog.cpp index 9c644f91c3..5a45178736 100644 --- a/hal/lib/Athena/Analog.cpp +++ b/hal/lib/Athena/Analog.cpp @@ -71,6 +71,13 @@ void* initializeAnalogInputPort(void* port_pointer, int32_t *status) { return analog_port; } +void freeAnalogInputPort(void* analog_port_pointer) { + AnalogPort* port = (AnalogPort*) analog_port_pointer; + if (!port) return; + delete port->accumulator; + delete port; +} + /** * Initialize the analog output port using the given port object. */ @@ -81,9 +88,17 @@ void* initializeAnalogOutputPort(void* port_pointer, int32_t *status) { // Initialize port structure AnalogPort* analog_port = new AnalogPort(); analog_port->port = *port; + analog_port->accumulator = NULL; return analog_port; } +void freeAnalogOutputPort(void* analog_port_pointer) { + AnalogPort* port = (AnalogPort*) analog_port_pointer; + if (!port) return; + delete port->accumulator; + delete port; +} + /** * Check that the analog module number is valid. @@ -594,8 +609,10 @@ void* initializeAnalogTrigger(void* port_pointer, uint32_t *index, int32_t *stat void cleanAnalogTrigger(void* analog_trigger_pointer, int32_t *status) { AnalogTrigger* trigger = (AnalogTrigger*) analog_trigger_pointer; + if (!trigger) return; triggers->Free(trigger->index); delete trigger->trigger; + freeAnalogInputPort(trigger->port); delete trigger; } diff --git a/hal/lib/Athena/Digital.cpp b/hal/lib/Athena/Digital.cpp index add1202a3f..801a6a3287 100644 --- a/hal/lib/Athena/Digital.cpp +++ b/hal/lib/Athena/Digital.cpp @@ -150,6 +150,11 @@ void* initializeDigitalPort(void* port_pointer, int32_t *status) { return digital_port; } +void freeDigitalPort(void* digital_port_pointer) { + DigitalPort* port = (DigitalPort*) digital_port_pointer; + delete port; +} + bool checkPWMChannel(void* digital_port_pointer) { DigitalPort* port = (DigitalPort*) digital_port_pointer; return port->port.pin < kPwmPins; @@ -487,6 +492,7 @@ bool allocatePWMChannel(void* digital_port_pointer, int32_t *status) { void freePWMChannel(void* digital_port_pointer, int32_t *status) { DigitalPort* port = (DigitalPort*) digital_port_pointer; + if (!port) return; if (!verifyPWMChannel(port, status)) { return; } PWMChannels->Free(port->port.pin); @@ -505,6 +511,7 @@ void freePWMChannel(void* digital_port_pointer, int32_t *status) { */ void freeDIO(void* digital_port_pointer, int32_t *status) { DigitalPort* port = (DigitalPort*) digital_port_pointer; + if (!port) return; DIOChannels->Free(port->port.pin); } @@ -666,13 +673,10 @@ void* initializeCounter(Mode mode, uint32_t *index, int32_t *status) { } void freeCounter(void* counter_pointer, int32_t *status) { - if (counter_pointer != NULL) { - Counter* counter = (Counter*) counter_pointer; - delete counter->counter; - counters->Free(counter->index); - } else { - *status = NULL_PARAMETER; - } + Counter* counter = (Counter*) counter_pointer; + if (!counter) return; + delete counter->counter; + counters->Free(counter->index); } void setCounterAverageSize(void* counter_pointer, int32_t size, int32_t *status) { @@ -1004,6 +1008,7 @@ void* initializeEncoder(uint8_t port_a_module, uint32_t port_a_pin, bool port_a_ void freeEncoder(void* encoder_pointer, int32_t *status) { Encoder* encoder = (Encoder*) encoder_pointer; + if (!encoder) return; quadEncoders->Free(encoder->index); delete encoder->encoder; } diff --git a/hal/lib/Athena/HALAthena.cpp b/hal/lib/Athena/HALAthena.cpp index e6463fbf83..378cb3db8e 100644 --- a/hal/lib/Athena/HALAthena.cpp +++ b/hal/lib/Athena/HALAthena.cpp @@ -41,6 +41,12 @@ void* getPortWithModule(uint8_t module, uint8_t pin) return port; } +void freePort(void* port_pointer) +{ + Port* port = (Port*) port_pointer; + delete port; +} + const char* getHALErrorMessage(int32_t code) { switch(code) { diff --git a/hal/lib/Athena/Solenoid.cpp b/hal/lib/Athena/Solenoid.cpp index 876045024b..49be9b1e09 100644 --- a/hal/lib/Athena/Solenoid.cpp +++ b/hal/lib/Athena/Solenoid.cpp @@ -33,6 +33,11 @@ void* initializeSolenoidPort(void *port_pointer, int32_t *status) { return solenoid_port; } +void freeSolenoidPort(void* solenoid_port_pointer) { + solenoid_port_t* port = (solenoid_port_t*) solenoid_port_pointer; + delete port; +} + bool checkSolenoidModule(uint8_t module) { return module < NUM_MODULE_NUMBERS; } diff --git a/wpilibc/Athena/src/AnalogInput.cpp b/wpilibc/Athena/src/AnalogInput.cpp index 34d5564f09..540c84ef5b 100644 --- a/wpilibc/Athena/src/AnalogInput.cpp +++ b/wpilibc/Athena/src/AnalogInput.cpp @@ -55,7 +55,10 @@ AnalogInput::AnalogInput(uint32_t channel) { /** * Channel destructor. */ -AnalogInput::~AnalogInput() { inputs->Free(m_channel); } +AnalogInput::~AnalogInput() { + freeAnalogInputPort(m_port); + inputs->Free(m_channel); +} /** * Get a sample straight from this channel. diff --git a/wpilibc/Athena/src/AnalogOutput.cpp b/wpilibc/Athena/src/AnalogOutput.cpp index 6b8b0c04d9..4905e824a0 100644 --- a/wpilibc/Athena/src/AnalogOutput.cpp +++ b/wpilibc/Athena/src/AnalogOutput.cpp @@ -50,7 +50,10 @@ AnalogOutput::AnalogOutput(uint32_t channel) { /** * Destructor. Frees analog output resource */ -AnalogOutput::~AnalogOutput() { outputs->Free(m_channel); } +AnalogOutput::~AnalogOutput() { + freeAnalogOutputPort(m_port); + outputs->Free(m_channel); +} /** * Set the value of the analog output diff --git a/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp b/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp index 04bc6367dd..8a20b7f95e 100644 --- a/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/AnalogJNI.cpp @@ -33,6 +33,18 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_initializeAnalo return (jlong)analog; } +/* + * Class: edu_wpi_first_wpilibj_hal_AnalogJNI + * Method: freeAnalogInputPort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_freeAnalogInputPort + (JNIEnv * env, jclass, jlong id) +{ + ANALOGJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeAnalogInputPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_AnalogJNI * Method: initializeAnalogOutputPort @@ -50,6 +62,18 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_initializeAnalo return (jlong)analog; } +/* + * Class: edu_wpi_first_wpilibj_hal_AnalogJNI + * Method: freeAnalogOutputPort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_AnalogJNI_freeAnalogOutputPort + (JNIEnv * env, jclass, jlong id) +{ + ANALOGJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeAnalogOutputPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_AnalogJNI * Method: checkAnalogModule diff --git a/wpilibj/src/athena/cpp/lib/DIOJNI.cpp b/wpilibj/src/athena/cpp/lib/DIOJNI.cpp index a79b5a85a7..ff06f36d34 100644 --- a/wpilibj/src/athena/cpp/lib/DIOJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/DIOJNI.cpp @@ -34,6 +34,19 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_initializeDigitalP return (jlong)dio; } +/* +* Class: edu_wpi_first_wpilibj_hal_DIOJNI +* Method: freeDigitalPort +* Signature: (J)V; +*/ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_DIOJNI_freeDigitalPort +(JNIEnv * env, jclass, jlong id) +{ + DIOJNI_LOG(logDEBUG) << "Calling DIOJNI freeDigitalPort"; + DIOJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeDigitalPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_DIOJNI * Method: allocateDIO diff --git a/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp b/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp index f8d0e95e61..fb9dd4465f 100644 --- a/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp +++ b/wpilibj/src/athena/cpp/lib/JNIWrapper.cpp @@ -40,4 +40,19 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_JNIWrapper_getPort return (jlong)port; } +/* + * Class: edu_wpi_first_wpilibj_hal_JNIWrapper + * Method: freePort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_JNIWrapper_freePort + (JNIEnv * env, jclass, jlong id) +{ + //FILE_LOG(logDEBUG) << "Calling JNIWrapper getPortWithModlue"; + //FILE_LOG(logDEBUG) << "Module = " << (jint)module; + //FILE_LOG(logDEBUG) << "Pin = " << (jint)pin; + freePort((void*)id); + //FILE_LOG(logDEBUG) << "Port Ptr = " << port; +} + } // extern "C" diff --git a/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp b/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp index 861a3ce5b1..d2b03bea1d 100644 --- a/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp +++ b/wpilibj/src/athena/cpp/lib/SolenoidJNI.cpp @@ -41,6 +41,20 @@ JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_SolenoidJNI_initializeSol return (jlong)solenoid_port_pointer; } +/* + * Class: edu_wpi_first_wpilibj_hal_SolenoidJNI + * Method: freeSolenoidPort + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_SolenoidJNI_freeSolenoidPort + (JNIEnv *env, jclass, jlong id) +{ + SOLENOIDJNI_LOG(logDEBUG) << "Calling SolenoidJNI initializeSolenoidPort"; + + SOLENOIDJNI_LOG(logDEBUG) << "Port Ptr = " << (void*)id; + freeSolenoidPort((void*)id); +} + /* * Class: edu_wpi_first_wpilibj_hal_SolenoidJNI * Method: getPortWithModule diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java index a2873f4007..008790d186 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogInput.java @@ -77,6 +77,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend * Channel destructor. */ public void free() { + AnalogJNI.freeAnalogInputPort(m_port); + m_port = 0; channels.free(m_channel); m_channel = 0; m_accumulatorOffset = 0; diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java index 5a66357885..f04c10fa94 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/AnalogOutput.java @@ -52,6 +52,8 @@ public class AnalogOutput extends SensorBase implements LiveWindowSendable { * Channel destructor. */ public void free() { + AnalogJNI.freeAnalogOutputPort(m_port); + m_port = 0; channels.free(m_channel); m_channel = 0; } diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java index 160486fdd9..e5a98bb3e3 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DigitalSource.java @@ -47,6 +47,8 @@ public abstract class DigitalSource extends InterruptableSensorBase { public void free() { channels.free(m_channel); DIOJNI.freeDIO(m_port); + DIOJNI.freeDigitalPort(m_port); + m_port = 0; m_channel = 0; } diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java index c5045e7523..9d9cc49bc2 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/DoubleSolenoid.java @@ -100,6 +100,7 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable { public synchronized void free() { m_allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel); m_allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel); + super.free(); } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java index 899e633130..24d933b86d 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/PWM.java @@ -140,9 +140,12 @@ public class PWM extends SensorBase implements LiveWindowSendable { * Free the resource associated with the PWM channel and set the value to 0. */ public void free() { + if (m_port == 0) return; PWMJNI.setPWM(m_port, (short) 0); PWMJNI.freePWMChannel(m_port); PWMJNI.freeDIO(m_port); + DIOJNI.freeDigitalPort(m_port); + m_port = 0; } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java index 8284bf49c4..d8084125d0 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Relay.java @@ -178,6 +178,8 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable RelayJNI.setRelayReverse(m_port, false); DIOJNI.freeDIO(m_port); + DIOJNI.freeDigitalPort(m_port); + m_port = 0; } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java index 10533eadd1..a3610da940 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/Solenoid.java @@ -77,6 +77,9 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable { */ public synchronized void free() { m_allocated.free(m_moduleNumber * kSolenoidChannels + m_channel); + SolenoidJNI.freeSolenoidPort(m_solenoid_port); + m_solenoid_port = 0; + super.free(); } /** diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java index 53168a9d15..b4129552dc 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/SolenoidBase.java @@ -34,6 +34,17 @@ public abstract class SolenoidBase extends SensorBase { } } + /** + * Free the resources associated with by the solenoid base. + */ + @Override + public void free() { + for (int i = 0; i < m_ports.length; i++) { + SolenoidJNI.freeSolenoidPort(m_ports[i]); + m_ports[i] = 0; + } + } + /** * Set the value of a solenoid. * diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java index a90e592494..d8bec8bf45 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/AnalogJNI.java @@ -34,8 +34,12 @@ public class AnalogJNI extends JNIWrapper { public static native long initializeAnalogInputPort(long port_pointer); + public static native void freeAnalogInputPort(long port_pointer); + public static native long initializeAnalogOutputPort(long port_pointer); + public static native void freeAnalogOutputPort(long port_pointer); + public static native boolean checkAnalogModule(byte module); public static native boolean checkAnalogInputChannel(int pin); diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java index d6ac993676..4ebeb25a6f 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/DIOJNI.java @@ -3,6 +3,8 @@ package edu.wpi.first.wpilibj.hal; public class DIOJNI extends JNIWrapper { public static native long initializeDigitalPort(long port_pointer); + public static native void freeDigitalPort(long port_pointer); + public static native boolean allocateDIO(long digital_port_pointer, boolean input); public static native void freeDIO(long digital_port_pointer); diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java index 5b9d3e89ee..a07a5e1819 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/JNIWrapper.java @@ -51,4 +51,6 @@ public class JNIWrapper { public static native long getPortWithModule(byte module, byte pin); public static native long getPort(byte pin); + + public static native void freePort(long port_pointer); } diff --git a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java index 857ac11c59..bf187f2eec 100644 --- a/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java +++ b/wpilibj/src/athena/java/edu/wpi/first/wpilibj/hal/SolenoidJNI.java @@ -3,6 +3,8 @@ package edu.wpi.first.wpilibj.hal; public class SolenoidJNI extends JNIWrapper { public static native long initializeSolenoidPort(long portPointer); + public static native void freeSolenoidPort(long port_pointer); + public static native long getPortWithModule(byte module, byte channel); public static native void setSolenoid(long port, boolean on);