Merge pull request #756 from jpcima/new-alignment-issue

Implement a substitute for aligned-new
This commit is contained in:
JP Cimalando 2021-03-31 18:07:31 +02:00 committed by GitHub
commit 1ade3d5f5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 86 additions and 17 deletions

View file

@ -51,10 +51,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
add_compile_options(-mfloat-abi=hard)
endif()
endif()
check_cxx_compiler_flag(-faligned-new SFIZZ_HAVE_FALIGNED_NEW)
if(SFIZZ_HAVE_FALIGNED_NEW)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-faligned-new>)
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(CMAKE_CXX_STANDARD 17)
add_compile_options(/Zc:__cplusplus)

View file

@ -27,6 +27,7 @@ set(SFIZZ_HEADERS
sfizz/utility/Debug.h
sfizz/utility/LeakDetector.h
sfizz/utility/Macros.h
sfizz/utility/MemoryHelpers.h
sfizz/utility/NumericId.h
sfizz/utility/StringViewHelpers.h
sfizz/utility/SwapAndPop.h
@ -285,8 +286,8 @@ add_library(sfizz::internal ALIAS sfizz_internal)
target_sources(sfizz_internal PRIVATE ${SFIZZ_HEADERS} ${SFIZZ_SOURCES} ${FAUST_FILES})
target_include_directories(sfizz_internal PUBLIC "." "sfizz")
target_link_libraries(sfizz_internal
PUBLIC absl::strings absl::span sfizz::filesystem sfizz::atomic_queue sfizz::spin_mutex sfizz::bit_array sfizz::simde sfizz::hiir
PRIVATE sfizz::parser sfizz::messaging absl::flat_hash_map Threads::Threads st_audiofile sfizz::pugixml sfizz::spline sfizz::tunings sfizz::kissfft sfizz::cephes sfizz::cpuid sfizz::threadpool sfizz::jsl sfizz::atomic)
PUBLIC absl::strings absl::span sfizz::filesystem sfizz::atomic_queue sfizz::spin_mutex sfizz::bit_array sfizz::simde sfizz::hiir sfizz::jsl
PRIVATE sfizz::parser sfizz::messaging absl::flat_hash_map Threads::Threads st_audiofile sfizz::pugixml sfizz::spline sfizz::tunings sfizz::kissfft sfizz::cephes sfizz::cpuid sfizz::threadpool sfizz::atomic)
if(SFIZZ_USE_SNDFILE)
target_compile_definitions(sfizz_internal PUBLIC "SFIZZ_USE_SNDFILE=1")
target_link_libraries(sfizz_internal PUBLIC st_audiofile)

View file

@ -117,7 +117,9 @@ void streamFromFile(sfz::AudioReader& reader, uint32_t numFrames, sfz::Oversampl
}
sfz::FilePool::FilePool(sfz::Logger& logger)
: logger(logger), threadPool(globalThreadPool())
: logger(logger),
filesToLoad(alignedNew<FileQueue>()),
threadPool(globalThreadPool())
{
loadingJobs.reserve(config::maxVoices);
lastUsedFiles.reserve(config::maxVoices);
@ -350,8 +352,8 @@ sfz::FileDataHolder sfz::FilePool::getFilePromise(const std::shared_ptr<FileId>&
return {};
}
QueuedFileData queuedData { fileId, &preloaded->second, std::chrono::high_resolution_clock::now() };
if (!filesToLoad.try_push(queuedData)) {
DBG("[sfizz] Could not enqueue the file to load for " << fileId << " (queue capacity " << filesToLoad.capacity() << ")");
if (!filesToLoad->try_push(queuedData)) {
DBG("[sfizz] Could not enqueue the file to load for " << fileId << " (queue capacity " << filesToLoad->capacity() << ")");
return {};
}
@ -498,7 +500,7 @@ void sfz::FilePool::dispatchingJob() noexcept
while (dispatchBarrier.wait(), dispatchFlag) {
std::lock_guard<std::mutex> guard { loadingJobsMutex };
if (filesToLoad.try_pop(queuedData)) {
if (filesToLoad->try_pop(queuedData)) {
if (queuedData.id.expired()) {
// file ID was nulled, it means the region was deleted, ignore
}

View file

@ -35,6 +35,7 @@
#include "Logger.h"
#include "SpinMutex.h"
#include "utility/LeakDetector.h"
#include "utility/MemoryHelpers.h"
#include <ghc/fs_std.hpp>
#include <absl/container/flat_hash_map.h>
#include <absl/types/optional.h>
@ -43,6 +44,7 @@
#include <chrono>
#include <thread>
#include <future>
#include <memory>
class ThreadPool;
namespace sfz {
@ -348,7 +350,10 @@ private:
FileData* data { nullptr };
TimePoint queuedTime {};
};
atomic_queue::AtomicQueue2<QueuedFileData, config::maxVoices> filesToLoad;
using FileQueue = atomic_queue::AtomicQueue2<QueuedFileData, config::maxVoices>;
aligned_unique_ptr<FileQueue> filesToLoad;
void dispatchingJob() noexcept;
void garbageJob() noexcept;
void loadingJob(QueuedFileData data) noexcept;

View file

@ -43,6 +43,8 @@ void printStatistics(std::vector<T>& data)
}
sfz::Logger::Logger()
: callbackTimeQueue(alignedNew<CallbackTimeQueue>()),
fileTimeQueue(alignedNew<FileTimeQueue>())
{
keepRunning.test_and_set();
clearFlag.test_and_set();
@ -106,7 +108,7 @@ void sfz::Logger::logCallbackTime(const CallbackBreakdown& breakdown, int numVoi
callbackTime.breakdown = breakdown;
callbackTime.numVoices = numVoices;
callbackTime.numSamples = numSamples;
callbackTimeQueue.try_push(callbackTime);
callbackTimeQueue->try_push(callbackTime);
}
void sfz::Logger::logFileTime(std::chrono::duration<double> waitDuration, std::chrono::duration<double> loadDuration, uint32_t fileSize, absl::string_view filename)
@ -119,7 +121,7 @@ void sfz::Logger::logFileTime(std::chrono::duration<double> waitDuration, std::c
fileTime.loadDuration = loadDuration;
fileTime.fileSize = fileSize;
fileTime.filename = filename;
fileTimeQueue.try_push(fileTime);
fileTimeQueue->try_push(fileTime);
}
void sfz::Logger::setPrefix(absl::string_view prefix)
@ -136,11 +138,11 @@ void sfz::Logger::moveEvents() noexcept
{
while(keepRunning.test_and_set()) {
CallbackTime callbackTime;
while (callbackTimeQueue.try_pop(callbackTime))
while (callbackTimeQueue->try_pop(callbackTime))
callbackTimes.push_back(callbackTime);
FileTime fileTime;
while (fileTimeQueue.try_pop(fileTime))
while (fileTimeQueue->try_pop(fileTime))
fileTimes.push_back(fileTime);
if (!clearFlag.test_and_set()) {

View file

@ -7,6 +7,7 @@
#pragma once
#include "Config.h"
#include "utility/LeakDetector.h"
#include "utility/MemoryHelpers.h"
#include <atomic_queue/atomic_queue.h>
#include <absl/strings/string_view.h>
#include <vector>
@ -14,6 +15,7 @@
#include <chrono>
#include <functional>
#include <thread>
#include <memory>
namespace sfz
{
@ -131,8 +133,11 @@ private:
bool loggingEnabled { config::loggingEnabled };
std::string prefix { "" };
atomic_queue::AtomicQueue2<CallbackTime, config::loggerQueueSize, true, true, false, true> callbackTimeQueue;
atomic_queue::AtomicQueue2<FileTime, config::loggerQueueSize, true, true, false, true> fileTimeQueue;
using CallbackTimeQueue = atomic_queue::AtomicQueue2<CallbackTime, config::loggerQueueSize, true, true, false, true>;
using FileTimeQueue = atomic_queue::AtomicQueue2<FileTime, config::loggerQueueSize, true, true, false, true>;
aligned_unique_ptr<CallbackTimeQueue> callbackTimeQueue;
aligned_unique_ptr<FileTimeQueue> fileTimeQueue;
std::vector<CallbackTime> callbackTimes;
std::vector<FileTime> fileTimes;

View file

@ -0,0 +1,58 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include <jsl/allocator>
#include <memory>
namespace sfz {
/**
* @brief Allocate and initialize an object of type T, using sufficient
* alignment for the type.
* This provides compatibility with systems which do not support aligned-new.
*/
template <class T, size_t A = alignof(T), class... Args>
T* alignedNew(Args&& ...args)
{
using allocator = jsl::aligned_allocator<T, A>;
struct deleter {
void operator()(T* x) const noexcept { allocator().deallocate(x, sizeof(T)); }
};
std::unique_ptr<T, deleter> ptr { allocator().allocate(1) };
allocator().construct(ptr.get(), std::forward<Args>(args)...);
return ptr.release();
}
/**
* @brief Deinitialize and deallocate the aligned object of type T. It must have
* been previously instantiated by alignedNew.
*/
template <class T, size_t A = alignof(T)>
void alignedDelete(T* ptr)
{
using allocator = jsl::aligned_allocator<T, A>;
if (ptr) {
allocator().destroy(ptr);
allocator().deallocate(ptr, 1);
}
}
/**
* @brief Deletes an object using alignedDelete.
*/
template <class T, size_t A = alignof(T)>
struct aligned_deleter {
void operator()(T* x) const noexcept { alignedDelete<T, A>(x); }
};
/**
* @brief Unique pointer which uses alignedDelete as the cleanup function.
*/
template <class T, size_t A = alignof(T)>
using aligned_unique_ptr = std::unique_ptr<T, aligned_deleter<T, A>>;
} // namespace sfz