Skip to content

Commit

Permalink
Use mlock to ensure the disk buffers don't get paged out.
Browse files Browse the repository at this point in the history
If mlock fails (e.g. because the corresponding ulimit is set too low),
print a warning and continue.

(Note that on some platforms, mlock requires the base address to be
page-aligned; the code doesn't currently try to achieve that because
it's not required on Linux.)
  • Loading branch information
atsampson authored and simoninns committed Jun 18, 2022
1 parent de7e7e9 commit 1e1aefd
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Linux-Application/DomesdayDuplicator/usbcapture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <atomic>
#include <sched.h>
#include <sys/mman.h>

// Notes on transfer and disk buffering:
//
Expand Down Expand Up @@ -439,6 +440,7 @@ void UsbCapture::allocateDiskBuffers(void)
// Allocate the disk buffers
diskBuffers = static_cast<unsigned char **>(calloc(NUMBEROFDISKBUFFERS, sizeof(unsigned char *)));
if (diskBuffers != nullptr) {
bool tryMlock = true;
for (quint32 bufferNumber = 0; bufferNumber < NUMBEROFDISKBUFFERS; bufferNumber++) {

diskBuffers[bufferNumber] = static_cast<unsigned char *>(malloc(TRANSFERSIZE * TRANSFERSPERDISKBUFFER));
Expand All @@ -451,7 +453,15 @@ void UsbCapture::allocateDiskBuffers(void)
transferFailure = true;
break;
}

// Lock the buffer into memory, preventing it from being paged out
if (tryMlock && mlock(diskBuffers[bufferNumber], TRANSFERSIZE * TRANSFERSPERDISKBUFFER) == -1) {
// Continue anyway, but print a warning
qInfo() << "UsbCapture::allocateDiskBuffers(): Unable to lock disk buffer into memory";
tryMlock = false;
}
}
if (tryMlock) qDebug() << "UsbCapture::allocateDiskBuffers(): Locked disk buffers into memory";
} else {
// Memory allocation has failed
qDebug() << "UsbCapture::allocateDiskBuffers(): Disk buffer array allocation failed!";
Expand All @@ -475,6 +485,9 @@ void UsbCapture::freeDiskBuffers(void)
// Free up the allocated disk buffers
if (diskBuffers != nullptr) {
for (qint32 bufferNumber = 0; bufferNumber < NUMBEROFDISKBUFFERS; bufferNumber++) {
// Don't keep the buffer in RAM any more (silently ignoring failure)
(void) munlock(diskBuffers[bufferNumber], TRANSFERSIZE * TRANSFERSPERDISKBUFFER);

if (diskBuffers[bufferNumber] != nullptr) {
free(diskBuffers[bufferNumber]);
}
Expand Down

0 comments on commit 1e1aefd

Please sign in to comment.