Skip to content

Commit

Permalink
used CPU time reduced with WInterHill client
Browse files Browse the repository at this point in the history
I observed over 30% CPU usage with WinterHill even if no stream is played.
This patch reduced it down to 2%.
Not tested with Longmynd but shall work.
Tested with Minitiouner Express but a last verification need to be done.
While tesing I oserved a very few times  Dequeue and Peek exceptions.
The code is hacked to prevent this.
  • Loading branch information
dl1rf committed May 1, 2024
1 parent de7ebdc commit 802d7d7
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
1 change: 1 addition & 0 deletions MediaSources/Longmynd/LongmyndSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ private void Udp_client_DataReceived(object sender, byte[] e)
{
udp_buffer.Enqueue(e[c]);
}
ts_thread.NewDataPresent();
}

private void Udp_client_ConnectionStatusChanged(object sender, string e)
Expand Down
20 changes: 18 additions & 2 deletions MediaSources/Minitiouner/MinitiounerSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -597,12 +597,16 @@ void FlushTS2()

byte ReadTS2(ref byte[] data, ref uint dataRead)
{
return hardware_interface.transport_read(PicoTunerInterface.TS2, ref data, ref dataRead);
byte err = hardware_interface.transport_read(PicoTunerInterface.TS2, ref data, ref dataRead);
DataReceived(PicoTunerInterface.TS2);
return err;
}

byte ReadTS1(ref byte[] data, ref uint dataRead)
{
return hardware_interface.transport_read(PicoTunerInterface.TS1, ref data, ref dataRead);
byte err = hardware_interface.transport_read(PicoTunerInterface.TS1, ref data, ref dataRead);
DataReceived(PicoTunerInterface.TS1);
return err;
}


Expand All @@ -612,6 +616,18 @@ void FlushTS1()
}


private void DataReceived(byte TS)
{
if (TS == 1)
{
ts_thread.NewDataPresent();
}
else
{
ts_thread2.NewDataPresent();
}
}

private void hardware_init(bool manual, string i2c_serial, string ts_serial, string ts2_serial)
{

Expand Down
1 change: 1 addition & 0 deletions MediaSources/Winterhill/WinterhillSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ private void WinterhillSource_DataReceived(object sender, byte[] e)
{
udp_buffer[device].Enqueue(e[c]);
}
ts_threads[device].NewDataPresent();
}

private void WinterhillSource_ConnectionStatusChanged(object sender, string e)
Expand Down
37 changes: 27 additions & 10 deletions Transport/TSThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,27 @@ public class TSThread
private ReadTS read_ts_callback = null;
private string identifier = "";

private EventWaitHandle thread_wait_event_handle;

public TSThread(CircularBuffer _raw_ts_data_queue, FlushTS _flush_ts_callback, ReadTS _read_ts_callback, string _identifier)
{
Log.Information(" >> Starting TS Thread <<");
Log.Information(" >> Registering Raw TS Queue << ");

thread_wait_event_handle = new EventWaitHandle(false, EventResetMode.AutoReset);

registered_consumers.Add(_raw_ts_data_queue);

flush_ts_callback = _flush_ts_callback;
read_ts_callback = _read_ts_callback;
identifier = _identifier;
}

public void NewDataPresent()
{
thread_wait_event_handle.Set();
}

public void RegisterTSConsumer(CircularBuffer raw_ts_data_queue)
{
Log.Information(" >> Registering New Queue << ");
Expand All @@ -42,12 +51,14 @@ public void stop_ts()
{
Log.Information("Stopping TS: " + identifier);
ts_build_queue = false;
thread_wait_event_handle.Set(); // fire worker thread to handle stop event
}

public void start_ts()
{
Log.Information("Starting TS:" + identifier);
ts_build_queue = true;
thread_wait_event_handle.Set(); // fire worker thread to handle start event
}

public void worker_thread()
Expand All @@ -60,9 +71,12 @@ public void worker_thread()
Log.Information("TS Thread: Starting...");

byte[] data = new byte[4096];
uint dataRead = 0;

while (true)
{
// Wait on an Event.
thread_wait_event_handle.WaitOne();

if (ts_build_queue == false)
{
Expand All @@ -82,20 +96,23 @@ public void worker_thread()
registered_consumers[0].Clear();
bufferingData = true;
}

uint dataRead = 0;

if (read_ts_callback(ref data, ref dataRead) != 0)
Log.Information("Read Error");

if (dataRead > 0)
if (bufferingData == true)
{
for ( int c = 0; c < dataRead; c++)
dataRead = 0;

if (read_ts_callback(ref data, ref dataRead) != 0)
Log.Information("Read Error");

if (dataRead > 0)
{
for (int consumers = 0; consumers < registered_consumers.Count; consumers++)
for (int c = 0; c < dataRead; c++)
{
if (registered_consumers[consumers] != null)
registered_consumers[consumers].Enqueue(data[c]);
for (int consumers = 0; consumers < registered_consumers.Count; consumers++)
{
if (registered_consumers[consumers] != null)
registered_consumers[consumers].Enqueue(data[c]);
}
}
}
}
Expand Down
25 changes: 21 additions & 4 deletions Utilities/CircularBuffer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand Down Expand Up @@ -73,11 +74,19 @@ public byte Dequeue()
{
if (Count == 0)
{
throw new InvalidOperationException("Buffer is empty.");
// throw new InvalidOperationException("Buffer is empty.");
/* remark DL1RF: I observed this exception a few times.
* There seem to be a glitch between threads.
* Log an Error instead and return 0 as fake data here
* This happend while stop playing or leaving the program at all
* Occured only a very times.
*/
Log.Error("Dequeue(): Buffer is empty.");
return 0;
}

byte item = buffer[tail];
buffer[tail] = 0;
// buffer[tail] = 0; // mod dl1rf: I think no need to do this.
tail = (tail + 1) % capacity;
Count--;

Expand All @@ -91,7 +100,15 @@ public byte Peek()
{
if (Count == 0)
{
throw new InvalidOperationException("Buffer is empty.");
// throw new InvalidOperationException("Buffer is empty.");
/* remark DL1RF: I observed this exception a few times.
* There seem to be a glitch between threads.
* Log an Error instead and return 0 as fake data here
* This happend while stop playing or leaving the program at all
* Occured only a very few times.
*/
Log.Error("Peek(): Buffer is empty.");
return 0;
}

return buffer[tail];
Expand Down

0 comments on commit 802d7d7

Please sign in to comment.