Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to push + drop old data #12

Closed
andrewcsmith opened this issue Jul 23, 2017 · 3 comments
Closed

Option to push + drop old data #12

andrewcsmith opened this issue Jul 23, 2017 · 3 comments

Comments

@andrewcsmith
Copy link
Contributor

I'm working on some audio programming applications where I'd actually like to drop the old data in the queue (and still push), rather than drop the new stuff (and never push it). Would it be possible to implement a version of this method on the Producer?

This is a very common application in audio programming -- we always want to update the buffer with the newest data, even if no one's listening -- so it would be great to have available in a library like this one.

@andrewcsmith
Copy link
Contributor Author

FYI, I've posted this on Reddit, but also put the question out to one of the creators behind PortAudio via email. It could potentially be a bad idea, in which case I'm happy to close the comment.

@polyfractal
Copy link
Owner

Answered a bit on Reddit, but I think the answer is basically there's no particular reason the queue was setup like this, other than personal preference at the time. I haven't thought too deeply about it (my rust laptop just died, so haven't had a chance to fiddle around with it), but I don't see why it wouldn't work.

It'd take some adjusting of who bumps which pointer, and obviously the push/pop semantics change. I think the best way to implement it is probably to specialize each of the queue types and then just create a different one via param on the builder function. That way it doesn't need a bunch of conditionals everywhere, semantics are clear, etc.

But again, I haven't thought too heavily on this, so there may be a better way to do it. I don't see any reason why i t couldn't be done though!

@andrewcsmith
Copy link
Contributor Author

Via Phil Burk, of portaudio & portmidi -- he said that basically two threads should never modify the one index, even if it's atomic. The reasoning is that although increment can be atomic with atomic usizes, read-buffer-and-increment cannot, so you don't know whether you're getting corrupted data.

Even if the reader only has immutable access to the read index, you still have a potential problem:

  1. Reader queries read index
  2. Writer queries "space available"; not enough space available in buffer
  3. Writer overwrites memory at current read index
  4. Writer increments read index
  5. Reader reads the new memory from writer using read index stored from step 1

It sounds implausible, but in a practical (audio) situation chances are that your writer is in the audio callback thread and is running at top priority, above just about everything else on the system. Your reader then gets pushed to the back, assuming they're competing for the same core anyway, and sleeps for a moment while the writer finishes its work.

Anyway, I'm closing this, but thanks for taking a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants