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

Sample tracks eats buffers #3169

Closed
zonkmachine opened this issue Dec 19, 2016 · 12 comments
Closed

Sample tracks eats buffers #3169

zonkmachine opened this issue Dec 19, 2016 · 12 comments
Labels
Milestone

Comments

@zonkmachine
Copy link
Member

zonkmachine commented Dec 19, 2016

Since #1088 LMMS Memory Manager (~LMMS 1.1.0), buffers acquired through the SamplePlayHandle() aren't handed back after playing. If you stop a sample played from a SampleTrack the buffer is properly released but if the sample plays all the way through it's gone.
This is best demonstrated by activating the metronome and hitting play. At 180 bpm it will take almost three minutes to chomp up all 512 of them at my machine and close down business.

BufferManager: out of buffers
Aborted (core dumped)

These leaked buffers will stay gone as long as LMMS is running, even if you load another project or a default one. Gone...

@softrabbit
Copy link
Member

There's a SampleBuffer being created in one of the constructors, https://github.com/LMMS/lmms/blob/master/src/core/SamplePlayHandle.cpp#L38
...but never deleted?

@zonkmachine
Copy link
Member Author

Yeah, I noticed that one and I tried to just wrap a sharedObject::ref( ) around it like in the other constructors but didn't know how to do it properly.

@softrabbit
Copy link
Member

Like m_sampleBuffer( sharedObject::ref( new SampleBuffer( sampleFile ) ) ) ? That's my guess on how to do it.

The bug might be somewhere else, but that small flaw jumped out right away when reading the code.

@zonkmachine
Copy link
Member Author

Like m_sampleBuffer( sharedObject::ref( new SampleBuffer( sampleFile ) ) ) ? That's my guess on how to do it.

That's exactly what I tried. Just tried it again and it makes no difference. I'm going to have one more go at fixing this.

@zonkmachine
Copy link
Member Author

zonkmachine commented Dec 20, 2016

It looks like we first create an m_sampleBuffer in the SampleTCO
https://github.com/LMMS/lmms/blob/master/src/tracks/SampleTrack.cpp#L59
and then another one in SamplePlayHandle(). ?

Edit: fixed link...

@zonkmachine
Copy link
Member Author

I think I'll pass this one... Rude little buffers. 😠

@softrabbit
Copy link
Member

softrabbit commented Dec 20, 2016

Crashes quite reliably at bar 128:0:0 using metronome. No crash for me when simulating metronome in a bar & beat-track using the same samples.

SamplePlayHandles for the metronome are created in Mixer,

addPlayHandle( new SamplePlayHandle( "misc/metronome02.ogg" ) );
which calls the constructor discussed above.

Not sure if SampleTCO is relevant, isn't that for sample tracks?

@zonkmachine
Copy link
Member Author

Not sure if SampleTCO is relevant, isn't that for sample tracks?

Right, sorry, I explained this poorly. It's the sample tracks that crash, and the metronome is managed as a sample track, hence the example. If you loop any sample in a sample track for the number of buffers, 512, you run out of them.

@zonkmachine zonkmachine changed the title SamplePlayHandle() eats buffers... Sample tracks eats buffers... Dec 20, 2016
@zonkmachine zonkmachine changed the title Sample tracks eats buffers... Sample tracks eats buffers Dec 20, 2016
@softrabbit
Copy link
Member

softrabbit commented Dec 21, 2016

So far, I've checked these through some qDebug() calls (playing the metronome):

  • BufferManager::release() is called 512 times fewer than BufferManager::acquire()
  • The SamplePlayHandle constructor and destructor calls match in numbers, so that's OK.
  • Printing out reference counts in sharedObject::ref() and ::unref() I get no output from ::ref() and always 0 from ::unref(). Which would mean the code in the metronome case works as it should and my previous suspicion at Sample tracks eats buffers #3169 (comment) was wrong. (The first reference is counted at creation).

So, delete is called for each buffer through the sharedObject mechanism but still the buffers hang around? Forget that thought, my mind was playing tricks on me...

@zonkmachine
Copy link
Member Author

zonkmachine commented Dec 21, 2016

OT: Comment moved to separate bug 3173...
Edit: This is a separate bug. Fixed in #3173

@zonkmachine
Copy link
Member Author

I tried wav, ogg and flac and the sample type made no difference.
Here's a stack trace.

BufferManager: out of buffers

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7fffb0f94700 (LWP 10549)]
0x00007ffff410ec37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff410ec37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff4112028 in __GI_abort () at abort.c:89
#2  0x00007ffff684fc92 in qt_message_output (msgType=msgType@entry=QtFatalMsg, buf=0x7fffa802f5c8 "BufferManager: out of buffers")
    at global/qglobal.cpp:2383
#3  0x00007ffff684fff9 in qt_message(QtMsgType, const char *, typedef __va_list_tag __va_list_tag *) (msgType=msgType@entry=QtFatalMsg, 
    msg=0x638f73 "BufferManager: out of buffers", ap=ap@entry=0x7fffb0f93b18) at global/qglobal.cpp:2429
#4  0x00007ffff6850804 in qFatal (msg=<optimized out>) at global/qglobal.cpp:2612
#5  0x00000000004ec6e5 in BufferManager::acquire () at /home/zonkmachine/builds/lmms/lmms/src/core/BufferManager.cpp:63
#6  0x0000000000566181 in AudioPort::doProcessing (this=0x7fffeae17820) at /home/zonkmachine/builds/lmms/lmms/src/core/audio/AudioPort.cpp:116
#7  0x0000000000514bbb in ThreadableJob::process (this=0x7fffeae17820) at /home/zonkmachine/builds/lmms/lmms/include/ThreadableJob.h:74
#8  0x000000000052c01b in MixerWorkerThread::JobQueue::run (this=0x9443e0 <MixerWorkerThread::globalJobQueue>)
    at /home/zonkmachine/builds/lmms/lmms/src/core/MixerWorkerThread.cpp:75
#9  0x000000000052c275 in MixerWorkerThread::startAndWaitForJobs () at /home/zonkmachine/builds/lmms/lmms/src/core/MixerWorkerThread.cpp:148
#10 0x0000000000526e7e in Mixer::renderNextBuffer (this=0xc07d10) at /home/zonkmachine/builds/lmms/lmms/src/core/Mixer.cpp:462
#11 0x000000000052880b in Mixer::fifoWriter::run (this=0xe94f20) at /home/zonkmachine/builds/lmms/lmms/src/core/Mixer.cpp:1098
#12 0x00007ffff685a32f in QThreadPrivate::start (arg=0xe94f20) at thread/qthread_unix.cpp:349
#13 0x00007ffff7bc4184 in start_thread (arg=0x7fffb0f94700) at pthread_create.c:312
#14 0x00007ffff41d237d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

@zonkmachine
Copy link
Member Author

Load a couple of big files into LMMS, be it sample track or AFP. When you delete the tracks the memory isn't freed up. It was in 1.1.3 . Maybe open a separate issue for this.

sdasda7777 pushed a commit to sdasda7777/lmms that referenced this issue Jun 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants