Browse Source

More stoat stuff, WIP, RtLinkedList gives trouble for it

tags/v1.9.9
falkTX 6 years ago
parent
commit
69b804f649
5 changed files with 113 additions and 25 deletions
  1. +1
    -0
      data/stoat/whitelist.txt
  2. +3
    -3
      source/backend/plugin/CarlaPlugin.cpp
  3. +22
    -13
      source/backend/plugin/CarlaPluginInternal.cpp
  4. +23
    -8
      source/backend/plugin/CarlaPluginInternal.hpp
  5. +64
    -1
      source/utils/RtLinkedList.hpp

+ 1
- 0
data/stoat/whitelist.txt View File

@@ -216,3 +216,4 @@ LinuxSampler::InstrumentManager::LoadInstrumentInBackground
llround
llabs
clock_gettime
RtLinkedList$vtable3

+ 3
- 3
source/backend/plugin/CarlaPlugin.cpp View File

@@ -1864,9 +1864,9 @@ void CarlaPlugin::idle()
#endif
}

const CarlaMutexLocker sl(pData->postRtEvents.mutex);
const CarlaMutexLocker sl(pData->postRtEvents.getDataMutex());

for (RtLinkedList<PluginPostRtEvent>::Itenerator it = pData->postRtEvents.data.begin2(); it.valid(); it.next())
for (RtLinkedList<PluginPostRtEvent>::Itenerator it = pData->postRtEvents.getDataIterator(); it.valid(); it.next())
{
const PluginPostRtEvent& event(it.getValue(kPluginPostRtEventFallback));
CARLA_SAFE_ASSERT_CONTINUE(event.type != kPluginPostRtEventNull);
@@ -2032,7 +2032,7 @@ void CarlaPlugin::idle()
}
}

pData->postRtEvents.data.clear();
pData->postRtEvents.clearData();
}

bool CarlaPlugin::tryLock(const bool forcedOffline) noexcept


+ 22
- 13
source/backend/plugin/CarlaPluginInternal.cpp View File

@@ -501,40 +501,49 @@ void CarlaPlugin::ProtectedData::Latency::recreateBuffers(const uint32_t newChan
// ProtectedData::PostRtEvents

CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() noexcept
: mutex(),
dataPool(128, 128),
: dataPool(128, 128),
dataPendingRT(dataPool),
data(dataPool),
dataPendingRT(dataPool) {}
dataMutex(),
dataPendingMutex() {}

CarlaPlugin::ProtectedData::PostRtEvents::~PostRtEvents() noexcept
{
clear();
dataMutex.lock();
data.clear();
dataMutex.unlock();

dataPendingMutex.lock();
dataPendingRT.clear();
dataPendingMutex.unlock();
}

void CarlaPlugin::ProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) noexcept
{
// FIXME
mutex.lock();
CARLA_SAFE_ASSERT_RETURN(dataPendingMutex.tryLock(),);
dataPendingRT.append(e);
mutex.unlock();
dataPendingMutex.unlock();
}

void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() noexcept
{
if (mutex.tryLock())
if (dataMutex.tryLock())
{
if (dataPendingRT.count() > 0)
dataPendingRT.moveTo(data, true);
mutex.unlock();
dataMutex.unlock();
}
}

void CarlaPlugin::ProtectedData::PostRtEvents::clear() noexcept
void CarlaPlugin::ProtectedData::PostRtEvents::clearData() noexcept
{
mutex.lock();
const bool tryLockOk(dataMutex.tryLock());
CARLA_SAFE_ASSERT(! tryLockOk);
data.clear();
dataPendingRT.clear();
mutex.unlock();

if (tryLockOk)
dataMutex.unlock();
}

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


+ 23
- 8
source/backend/plugin/CarlaPluginInternal.hpp View File

@@ -282,19 +282,34 @@ struct CarlaPlugin::ProtectedData {

} latency;

struct PostRtEvents {
CarlaMutex mutex;
RtLinkedList<PluginPostRtEvent>::Pool dataPool;
RtLinkedList<PluginPostRtEvent> data;
RtLinkedList<PluginPostRtEvent> dataPendingRT;

class PostRtEvents {
public:
PostRtEvents() noexcept;
~PostRtEvents() noexcept;
void appendRT(const PluginPostRtEvent& event) noexcept;
void trySplice() noexcept;
void clear() noexcept;
void clearData() noexcept;

inline CarlaMutex& getDataMutex() noexcept
{
return dataMutex;
}

inline RtLinkedList<PluginPostRtEvent>::Itenerator getDataIterator() const noexcept
{
return data.begin2();
}

private:
RtLinkedList<PluginPostRtEvent>::Pool dataPool;
RtLinkedList<PluginPostRtEvent> dataPendingRT;
RtLinkedList<PluginPostRtEvent> data;
CarlaMutex dataMutex;

// TESTING for thread-safety, remove later
CarlaMutex dataPendingMutex;

CARLA_DECLARE_NON_COPY_STRUCT(PostRtEvents)
CARLA_DECLARE_NON_COPY_CLASS(PostRtEvents)

} postRtEvents;



+ 64
- 1
source/utils/RtLinkedList.hpp View File

@@ -1,6 +1,6 @@
/*
* High-level, real-time safe, templated, C++ doubly-linked list
* Copyright (C) 2013-2014 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2013-2018 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -107,6 +107,69 @@ public:
RtLinkedList(Pool& memPool) noexcept
: fMemPool(memPool) {}

#ifdef STOAT_TEST_BUILD
// overridden for stoat
bool append(const T& value) noexcept
{
if (typename AbstractLinkedList<T>::Data* const data = _allocate())
return this->_add_internal(data, value, true, &this->fQueue);
return false;
}

void clear() noexcept
{
if (this->fCount == 0)
return;

for (typename AbstractLinkedList<T>::ListHead *entry = this->fQueue.next, *entry2 = entry->next;
entry != &this->fQueue; entry = entry2, entry2 = entry->next)
{
typename AbstractLinkedList<T>::Data* const data = list_entry(entry, typename AbstractLinkedList<T>::Data, siblings);
CARLA_SAFE_ASSERT_CONTINUE(data != nullptr);

this->_deallocate(data);
}

this->_init();
}

T getFirst(T& fallback, const bool removeObj) noexcept
{
CARLA_SAFE_ASSERT_RETURN(this->fCount > 0, fallback);

typename AbstractLinkedList<T>::ListHead* const entry = this->fQueue.next;

typename AbstractLinkedList<T>::Data* const data = list_entry(entry, typename AbstractLinkedList<T>::Data, siblings);
CARLA_SAFE_ASSERT_RETURN(data != nullptr, fallback);

if (! removeObj)
return data->value;

const T value(data->value);

_deleteRT(entry, data);

return value;
}

void _deleteRT(typename AbstractLinkedList<T>::ListHead* const entry, typename AbstractLinkedList<T>::Data* const data) noexcept
{
CARLA_SAFE_ASSERT_RETURN(entry != nullptr,);
CARLA_SAFE_ASSERT_RETURN(entry->prev != nullptr,);
CARLA_SAFE_ASSERT_RETURN(entry->next != nullptr,);

--this->fCount;

entry->next->prev = entry->prev;
entry->prev->next = entry->next;

entry->next = nullptr;
entry->prev = nullptr;

_deallocate(data);
}
#endif

bool append_sleepy(const T& value) noexcept
{
return _add_sleepy(value, true);


Loading…
Cancel
Save