3

Problem

I have a graphical console widget that receives output from an interpreter. Unfortunately the console is not fast enough to paint the output in real-time. So I had to implement a buffer(FIFO Thread Safe Queue) that delayed the writes to the console by 5ms. So when normally a loop of 1000 prints would be done in less than 1 ms, it would take 5000ms to print everything.

Sequence diagram for the buffer:

Sequence diagram for a time delayed buffer sendCode: Send code that the interpreter can compile and run.

writeLine:Write output from the interpreter to the buffer.

startTimer:Starts a timer that times out every 5ms.

getLine:Get the oldest line out of the buffer. Called every 5ms.

line: Line that gets sent to the console where it is displayed.

What I Need

While this strategy of delaying the output works for now, it is not very practical when real-time solutions are needed. I know one other strategy which is to set a buffer size. Then when the buffer size is reached, flush the output. This is a much better strategy since the console will not be choking considering lines are being sent in blocks.

But the problem is that if I set a buffer size of say 50 lines, the user will not see any output until 50 lines have been printed. Reducing the buffer size does not really help either, because then it's meant to reduce stress on the console.

How can I make a buffer system so the output is printed in real-time while not having the console dying on me.

6
  • 3
    Why don't you combine those two solutions? Create a buffer with a fixed size. If after 5ms since the last addition, the buffer is not empty, flush it.
    – Wikiti
    Sep 12, 2017 at 8:20
  • @Wikiti By addition, do you mean to console or to the buffer ? Sep 12, 2017 at 8:53
  • daegontaven To the buffer.
    – Wikiti
    Sep 12, 2017 at 8:55
  • @Wikiti So every 5ms it calls a function that checks if the buffer is not empty and flushes.Also should I flush or do something else if the buffer is full when I try to write ? It's still not working. What am I doing wrong ? Sep 12, 2017 at 9:29
  • If the buffer if full when writting, you need to flush it as soon as it's filled. Once flushed, continue the writting operation. Also, you may want to create a custom function to manually flush the buffer.
    – Wikiti
    Sep 12, 2017 at 10:17

2 Answers 2

8

To add more flesh to the bones of Wikiti's comments.

You need a fixed sized buffer and a timer set to n ms.

  1. When you write code to the buffer, if the buffer was empty, (re-)start the timer to n ms.

  2. If you write to the buffer and it is full then flush it to the console, clear the buffer and stop the timer.

  3. If the timer expires and there is code in the buffer, flush it to the console, clear the buffer and stop the timer.

  4. If the timer expires and there isn't code in the buffer, stop the timer.

This algorithm should be sufficient. It may take a bit of trial and error to get a good balance of buffer size and timer delay to get the smoothest console interaction. You may also find some mileage in making the flush/clear/stop available as a manual flush function though this isn't strictly necessary.

4
  • Mother of God, it works. I've never seen such speed. You saved me. This is by far the most correct answer I've seen yet. It definitely took some trial, but I didn't think I would solve it so fast. Amazing ! Sep 12, 2017 at 12:03
  • @daegontaven You're most welcome. Hat tip to Wikiti as well of course.
    – Alex
    Sep 12, 2017 at 12:19
  • Of course @Wikiti deserves recognition too. Once again thank you ! Sep 12, 2017 at 12:22
  • Thank you for packing my comments in a response and extending them with your knowledge! I'm glad that your question is solved, @daegontaven.
    – Wikiti
    Sep 13, 2017 at 9:31
0

You need a thread safe queue FIFO data collection (self-made via locks or libraries), that removes the first message in the buffer if there is an overflow. Your UI||Console Thread queries your data structure and pop everything if there is something to be printed (your buffer has data). -> Do not wait till the buffer is full.

All messages have a time stamp they where entered and a priority. Discard all messages that are to old in conjunction with their time stamp.

Additionally increase the buffer size of your console. I dont know of any console that dies because of too many calls to printf() or wrappers there of.

2
  • This answer is not very helpful. A lot of what you said is pretty obvious and is already said in my question. Please consider explaining in a bit more detail.Thank you. Sep 12, 2017 at 9:26
  • Your statement about the buffer size is unclear. Why has the buffer size anything to do with the console output. Wait the timespan you think your console needs to be ready again, then print the next info you want to print. You cant have your cake and eat it too eg: print all info && print in realtime.
    – Git
    Sep 12, 2017 at 10:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.