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
This commit is contained in:
Thad House
2015-10-20 10:37:04 -07:00
committed by Peter Johnson
parent e162e4d1c0
commit de39877efb
26 changed files with 155 additions and 9 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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();
}
/**

View File

@@ -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;
}
/**

View File

@@ -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;
}
/**

View File

@@ -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();
}
/**

View File

@@ -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.
*

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);