Skip to content

Commit

Permalink
Merge pull request #630 from WildernessLabs/thread-pool-cleanup
Browse files Browse the repository at this point in the history
Remove unnecessary Task.Run calls and async decorations
  • Loading branch information
adrianstevens authored Apr 24, 2023
2 parents 31604b6 + c964273 commit e87fad2
Show file tree
Hide file tree
Showing 54 changed files with 958 additions and 1,272 deletions.
39 changes: 25 additions & 14 deletions Source/Meadow.Foundation.Core/Communications/I2cPeripheral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ public class I2cPeripheral : II2cPeripheral
/// </summary>
protected Memory<byte> ReadBuffer { get; }

/// <summary>
/// Initializes a new instance of the I2cPeripheral class
/// </summary>
/// <param name="bus">The II2cBus used for communication with the peripheral</param>
/// <param name="peripheralAddress">The address of the peripheral on the I2C bus</param>
/// <param name="readBufferSize">The size of the buffer used for reading data from the peripheral. Defaults to 8 bytes</param>
/// <param name="writeBufferSize">The size of the buffer used for writing data to the peripheral. Defaults to 8 bytes</param>
public I2cPeripheral(II2cBus bus, byte peripheralAddress, int readBufferSize = 8, int writeBufferSize = 8)
{
Bus = bus;
Expand All @@ -47,7 +54,7 @@ public I2cPeripheral(II2cBus bus, byte peripheralAddress, int readBufferSize = 8
/// </remarks>
public void Read(Span<byte> readBuffer)
{
Bus.Read(this.Address, readBuffer);
Bus.Read(Address, readBuffer);
}

/// <summary>
Expand All @@ -58,7 +65,7 @@ public void Read(Span<byte> readBuffer)
public void ReadRegister(byte address, Span<byte> readBuffer)
{
WriteBuffer.Span[0] = address;
Bus.Exchange(this.Address, WriteBuffer.Span[0..1], readBuffer);
Bus.Exchange(Address, WriteBuffer.Span[0..1], readBuffer);
}

/// <summary>
Expand All @@ -68,7 +75,7 @@ public void ReadRegister(byte address, Span<byte> readBuffer)
public byte ReadRegister(byte address)
{
WriteBuffer.Span[0] = address;
Bus.Exchange(this.Address, WriteBuffer.Span[0..1], ReadBuffer.Span[0..1]);
Bus.Exchange(Address, WriteBuffer.Span[0..1], ReadBuffer.Span[0..1]);
return ReadBuffer.Span[0];
}

Expand All @@ -81,7 +88,7 @@ public byte ReadRegister(byte address)
public ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.LittleEndian)
{
WriteBuffer.Span[0] = address;
Bus.Exchange(this.Address, WriteBuffer[0..1].Span, ReadBuffer[0..2].Span);
Bus.Exchange(Address, WriteBuffer[0..1].Span, ReadBuffer[0..2].Span);
if (order == ByteOrder.LittleEndian)
{
return (ushort)(ReadBuffer.Span[0] | (ReadBuffer.Span[1] << 8));
Expand All @@ -98,19 +105,15 @@ public ushort ReadRegisterAsUShort(byte address, ByteOrder order = ByteOrder.Lit
/// <param name="value">Value to be written (8-bits).</param>
public void Write(byte value)
{
// stuff the value into the write buffer
WriteBuffer.Span[0] = value;
this.Bus.Write(this.Address, WriteBuffer.Span[0..1]);
Bus.Write(Address, WriteBuffer.Span[0..1]);
}

/// <summary>
/// Write an array of bytes to the peripheral.
/// </summary>
/// <param name="data">Values to be written.</param>
public void Write(Span<byte> data)
{
this.Bus.Write(this.Address, data);
}
public void Write(Span<byte> data) => Bus.Write(Address, data);

/// <summary>
/// Write data a register in the peripheral.
Expand All @@ -122,7 +125,7 @@ public void WriteRegister(byte address, byte value)
// stuff the address and value into the write buffer
WriteBuffer.Span[0] = address;
WriteBuffer.Span[1] = value;
this.Bus.Write(this.Address, WriteBuffer.Span[0..2]);
Bus.Write(Address, WriteBuffer.Span[0..2]);
}

/// <summary>
Expand Down Expand Up @@ -205,14 +208,22 @@ public void WriteRegister(byte address, Span<byte> writeBuffer, ByteOrder order
break;
}
// write it
this.Bus.Write(Address, WriteBuffer.Span[0..(writeBuffer.Length + 1)]);
Bus.Write(Address, WriteBuffer.Span[0..(writeBuffer.Length + 1)]);
}

/// <summary>
/// Exchanges data with an I2C device through a specified write and read buffer
/// </summary>
/// <param name="writeBuffer">A span of bytes that represents the data to be written to the device</param>
/// <param name="readBuffer">A span of bytes where the data read from the device will be stored</param>
/// <param name="duplex">An optional parameter that specifies the duplex type of the communication.
/// It defaults to half-duplex.</param>
/// <exception cref="ArgumentException">Thrown when duplex is set to full-duplex, as I2C only supports half-duplex communication</exception>
public void Exchange(Span<byte> writeBuffer, Span<byte> readBuffer, DuplexType duplex = DuplexType.Half)
{
if (duplex == DuplexType.Full) { throw new ArgumentException("I2C doesn't support full-duplex communications. Only half-duplex is available because it only has a single data line."); }

Bus.Exchange(this.Address, writeBuffer, readBuffer);
Bus.Exchange(Address, writeBuffer, readBuffer);
}
}
}
}
15 changes: 8 additions & 7 deletions Source/Meadow.Foundation.Core/PollingSensorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,26 @@ public abstract class PollingSensorBase<UNIT>
/// The default is 5 seconds.</param>
public override void StartUpdating(TimeSpan? updateInterval = null)
{
lock (samplingLock)
lock (samplingLock)
{
if (IsSampling) { return; }

IsSampling = true;

// if an update interval has been passed in, override the default
if(updateInterval is { } ui) { base.UpdateInterval = ui; }
if (updateInterval is { } ui) { base.UpdateInterval = ui; }

base.SamplingTokenSource = new CancellationTokenSource();
CancellationToken ct = SamplingTokenSource.Token;

UNIT oldConditions;
ChangeResult<UNIT> result;

Task.Run(async () =>
var t = new Task(async () =>
{
while (true)
while (true)
{
if (ct.IsCancellationRequested)
if (ct.IsCancellationRequested)
{
observers.ForEach(x => x.OnCompleted());
IsSampling = false;
Expand All @@ -61,7 +61,8 @@ public override void StartUpdating(TimeSpan? updateInterval = null)

await Task.Delay(UpdateInterval);
}
}, SamplingTokenSource.Token);
}, SamplingTokenSource.Token, TaskCreationOptions.LongRunning);
t.Start();
}
}

Expand All @@ -70,7 +71,7 @@ public override void StartUpdating(TimeSpan? updateInterval = null)
/// </summary>
public override void StopUpdating()
{
lock (samplingLock)
lock (samplingLock)
{
if (!IsSampling) { return; }

Expand Down
5 changes: 2 additions & 3 deletions Source/Meadow.Foundation.Core/SamplingSensorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ protected virtual void RaiseEventsAndNotify(IChangeResult<UNIT> changeResult)
/// Convenience method to get the current sensor readings. For frequent reads, use
/// StartSampling() and StopSampling() in conjunction with the SampleBuffer.
/// </summary>
public virtual async Task<UNIT> Read()
public virtual Task<UNIT> Read()
{
Conditions = await ReadSensor();
return Conditions;
return ReadSensor();
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions Source/Meadow.Foundation.Core/Sensors/Buttons/PushButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public PushButton(IDigitalInputPort inputPort)

bool currentState = DigitalIn.State;

_ = Task.Run(async () =>
var t = new Task(async () =>
{
while (!ctsPolling.Token.IsCancellationRequested)
{
Expand All @@ -152,7 +152,7 @@ public PushButton(IDigitalInputPort inputPort)

await Task.Delay(ButtonPollingInterval);
}
});
}, ctsPolling.Token, TaskCreationOptions.LongRunning);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace Meadow.Foundation.Displays
{
/// <summary>
/// Provide an interface to the Ch1115 family of displays.
/// Provide an interface to the Ch1115 family of displays
/// </summary>
public partial class Ch1115 : IGraphicsDisplay, ISpiDevice
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public Emc2101(II2cBus i2cBus, byte address = (byte)Address.Default)
void Initialize()
{
EnableTachInput(true);

InvertFanSpeed(false);
PwmFrequencyScaler = 0x1F;
ConfigurePwmClock(true, false);
Expand All @@ -185,7 +185,7 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Temperature? Interna
{
ExternalTemperatureUpdated?.Invoke(this, new ChangeResult<Temperature>(tempEx, changeResult.Old?.ExternalTemperature));
}
if(changeResult.New.FanSpeed is { } fanSpeed)
if (changeResult.New.FanSpeed is { } fanSpeed)
{
FanSpeedUpdated?.Invoke(this, new ChangeResult<AngularVelocity>(fanSpeed, changeResult.Old?.FanSpeed));
}
Expand All @@ -199,28 +199,25 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Temperature? Interna
/// <returns>The latest sensor reading</returns>
protected override Task<(Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed)> ReadSensor()
{
return Task.Run(() =>
{
(Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed) conditions;

//internal temperature
conditions.InternalTemperature = new Temperature(i2cPeripheral.ReadRegister((byte)Registers.InternalTemperature), Temperature.UnitType.Celsius);

//external temperature
byte lsb = i2cPeripheral.ReadRegister((byte)Registers.ExternalTemperatureLSB);
byte msb = i2cPeripheral.ReadRegister((byte)Registers.ExternalTemperatureMSB);
short raw = (short)(msb << 8 | lsb);
raw >>= 5;
conditions.ExternalTemperature = new Temperature(raw * TemperatureBit, Temperature.UnitType.Celsius);

//fan speed
lsb = i2cPeripheral.ReadRegister((byte)Registers.TachLSB);
msb = i2cPeripheral.ReadRegister((byte)Registers.TachMSB);
short speed = (short)(msb << 8 | lsb);
conditions.FanSpeed = new AngularVelocity(FanRpmNumerator / speed, AngularVelocity.UnitType.RevolutionsPerMinute);

return conditions;
});
(Temperature? InternalTemperature, Temperature? ExternalTemperature, AngularVelocity? FanSpeed) conditions;

//internal temperature
conditions.InternalTemperature = new Temperature(i2cPeripheral.ReadRegister((byte)Registers.InternalTemperature), Temperature.UnitType.Celsius);

//external temperature
byte lsb = i2cPeripheral.ReadRegister((byte)Registers.ExternalTemperatureLSB);
byte msb = i2cPeripheral.ReadRegister((byte)Registers.ExternalTemperatureMSB);
short raw = (short)(msb << 8 | lsb);
raw >>= 5;
conditions.ExternalTemperature = new Temperature(raw * TemperatureBit, Temperature.UnitType.Celsius);

//fan speed
lsb = i2cPeripheral.ReadRegister((byte)Registers.TachLSB);
msb = i2cPeripheral.ReadRegister((byte)Registers.TachMSB);
short speed = (short)(msb << 8 | lsb);
conditions.FanSpeed = new AngularVelocity(FanRpmNumerator / speed, AngularVelocity.UnitType.RevolutionsPerMinute);

return Task.FromResult(conditions);
}

/// <summary>
Expand Down Expand Up @@ -286,13 +283,13 @@ public void ConfigureFanSpinup(FanSpinupDrive spinupDrive, FanSpinupTime spinupT
/// <param name="index">The LUT index to set</param>
/// <param name="temperatureThreshhold">the temperature threshhold</param>
/// <param name="pwmDutyCycle">the fan PWM duty cycle</param>
public void SetLookupTable(LutIndex index,
Temperature temperatureThreshhold,
public void SetLookupTable(LutIndex index,
Temperature temperatureThreshhold,
float pwmDutyCycle)
{
pwmDutyCycle = Math.Clamp(pwmDutyCycle, 0, 1);

if(temperatureThreshhold.Celsius > MaxLutTemperature)
if (temperatureThreshhold.Celsius > MaxLutTemperature)
{
temperatureThreshhold = new Units.Temperature(MaxLutTemperature, Units.Temperature.UnitType.Celsius);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Meadow.Units;
using Meadow.Utilities;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.Foundation.Sensors.Atmospheric
Expand Down Expand Up @@ -82,21 +83,21 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Pressure? Pressure,
/// Convenience method to get the current Pressure. For frequent reads, use
/// StartSampling() and StopSampling() in conjunction with the SampleBuffer.
/// </summary>
protected override async Task<(Pressure? Pressure, Pressure? RawPsiMeasurement)> ReadSensor()
protected override Task<(Pressure? Pressure, Pressure? RawPsiMeasurement)> ReadSensor()
{
return await Task.Run(async () =>
return Task.Run(() =>
{
//Send the command to the sensor to tell it to do the thing.
Peripheral.Write(mprlsMeasurementCommand);

//Datasheet says wait 5 ms.
await Task.Delay(5);
//Datasheet says wait 5ms
Thread.Sleep(5);

while (true)
{
Peripheral.Read(ReadBuffer.Span[0..1]);

//From section 6.5 of the datasheet.
//From section 6.5 of the datasheet
IsDevicePowered = BitHelpers.GetBitValue(ReadBuffer.Span[0], 6);
IsDeviceBusy = BitHelpers.GetBitValue(ReadBuffer.Span[0], 5);
HasMemoryIntegrityFailed = BitHelpers.GetBitValue(ReadBuffer.Span[0], 2);
Expand All @@ -112,7 +113,7 @@ protected override void RaiseEventsAndNotify(IChangeResult<(Pressure? Pressure,
throw new InvalidOperationException("Sensor internal memory integrity check failed!");
}

if (!(IsDeviceBusy))
if (!IsDeviceBusy)
{
break;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Meadow.Hardware;
using Meadow.Peripherals.Sensors;
using Meadow.Units;
using System;
using System.Threading.Tasks;

Expand Down Expand Up @@ -208,19 +207,16 @@ private Units.Temperature RegisterToTemp(Memory<byte> data)
/// Read the temperature
/// </summary>
/// <returns>The current temperature value</returns>
protected override async Task<Units.Temperature> ReadSensor()
protected override Task<Units.Temperature> ReadSensor()
{
return await Task.Run(() =>
{
// 12-bit data
// Negative numbers are represented in binary twos complement format. The
// Temperature Register is 0x0000 until the first conversion complete after a software
// reset or power - on.
// Measurement Temperature Value [°C] = Temperature Data [11:0] x 0.0625
Peripheral?.ReadRegister((byte)Register.Temperature, ReadBuffer.Span[0..2]);
// 12-bit data
// Negative numbers are represented in binary twos complement format. The
// Temperature Register is 0x0000 until the first conversion complete after a software
// reset or power - on.
// Measurement Temperature Value [°C] = Temperature Data [11:0] x 0.0625
Peripheral?.ReadRegister((byte)Register.Temperature, ReadBuffer.Span[0..2]);

return RegisterToTemp(ReadBuffer);
});
return Task.FromResult(RegisterToTemp(ReadBuffer));
}

/// <summary>
Expand Down
Loading

0 comments on commit e87fad2

Please sign in to comment.