Browse Source

Experiment with mlock and barriers

tags/1.9.4
falkTX 12 years ago
parent
commit
b82cc00be9
4 changed files with 61 additions and 3 deletions
  1. +3
    -0
      source/backend/plugin/BridgePlugin.cpp
  2. +16
    -0
      source/utils/CarlaMathUtils.hpp
  3. +34
    -0
      source/utils/CarlaRingBuffer.hpp
  4. +8
    -3
      source/utils/Lv2AtomQueue.hpp

+ 3
- 0
source/backend/plugin/BridgePlugin.cpp View File

@@ -1896,6 +1896,9 @@ public:
carla_stdout(" sizeof(BridgeShmControl): " P_SIZE, sizeof(BridgeShmControl));
carla_stdout(" sizeof(BridgeTimeInfo): " P_SIZE, sizeof(BridgeTimeInfo));

// lock memory
fShmControl.lockMemory();

// initial values
fShmControl.writeOpcode(kPluginBridgeOpcodeNull);
fShmControl.writeInt(static_cast<int32_t>(sizeof(BridgeShmControl)));


+ 16
- 0
source/utils/CarlaMathUtils.hpp View File

@@ -79,6 +79,22 @@ const T& carla_fixValue(const T& min, const T& max, const T& value) noexcept
return value;
}

/*
* Get next power of 2.
*/
static inline
uint32_t carla_nextPowerOf2(uint32_t size)
{
// http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
--size;
size |= size >> 1;
size |= size >> 2;
size |= size >> 4;
size |= size >> 8;
size |= size >> 16;
return ++size;
}

// -----------------------------------------------------------------------
// math functions (extended)



+ 34
- 0
source/utils/CarlaRingBuffer.hpp View File

@@ -20,6 +20,13 @@

#include "CarlaUtils.hpp"

#ifndef CARLA_OS_WIN
# include <sys/mman.h>
# ifdef CARLA_OS_MAC
# include <libkern/OSAtomic.h>
# endif
#endif

// -----------------------------------------------------------------------
// RingBuffer structs

@@ -97,6 +104,7 @@ public:

if (fBuffer->invalidateCommit)
{
memoryBarrier();
fBuffer->written = fBuffer->head;
fBuffer->invalidateCommit = false;
return false;
@@ -115,6 +123,19 @@ public:
return (fBuffer->head != fBuffer->tail);
}

void lockMemory() const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);

#ifdef CARLA_OS_WIN
::VirtualLock(fBuffer, sizeof(BufferStruct));
::VirtualLock(fBuffer->buf, fBuffer->size);
#else
::mlock(fBuffer, sizeof(BufferStruct));
::mlock(fBuffer->buf, fBuffer->size);
#endif
}

// -------------------------------------------------------------------

char readChar() noexcept
@@ -219,6 +240,7 @@ protected:
std::memcpy(charbuf, fBuffer->buf + tail, size);
}

memoryBarrier();
fBuffer->tail = static_cast<int32_t>(readto);
}

@@ -261,12 +283,24 @@ protected:
std::memcpy(fBuffer->buf + wrtn, charbuf, size);
}

memoryBarrier();
fBuffer->written = static_cast<int32_t>(writeto);
}

private:
BufferStruct* fBuffer;

static void memoryBarrier()
{
#if defined(CARLA_OS_MAC)
::OSMemoryBarrier();
#elif defined(CARLA_OS_WIN)
::MemoryBarrier();
#elif (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
::__sync_synchronize();
#endif
}

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(RingBufferControl)
};


+ 8
- 3
source/utils/Lv2AtomQueue.hpp View File

@@ -18,6 +18,7 @@
#ifndef LV2_ATOM_QUEUE_HPP_INCLUDED
#define LV2_ATOM_QUEUE_HPP_INCLUDED

#include "CarlaMathUtils.hpp"
#include "CarlaMutex.hpp"
#include "CarlaRingBuffer.hpp"

@@ -49,6 +50,9 @@ public:

void createBuffer(const uint32_t size) noexcept
{
if (fLv2Buffer.size == size && ! fIsDummy)
return;

if (fLv2Buffer.buf != nullptr)
{
if (! fIsDummy)
@@ -59,9 +63,10 @@ public:
// shouldn't really happen please...
CARLA_SAFE_ASSERT_RETURN(size > 0,);

fLv2Buffer.size = size;
fLv2Buffer.buf = new char[size];
fLv2Buffer.size = carla_nextPowerOf2(size);
fLv2Buffer.buf = new char[fLv2Buffer.size];
setRingBuffer(&fLv2Buffer, true);
lockMemory();
}

// used for tmp buffers only
@@ -182,7 +187,7 @@ public:
if (! fRingBufferCtrl.isDataAvailable())
return false;

if (const LV2_Atom* retAtom = fRingBufferCtrl.readAtom(portIndex))
if (const LV2_Atom* const retAtom = fRingBufferCtrl.readAtom(portIndex))
{
*atom = retAtom;
return true;


Loading…
Cancel
Save