#include <jxl/memory_manager.h>
#include <jxl/parallel_runner.h>
#include <jxl/thread_parallel_runner.h>
#include <string.h>
#include <cstdint>
#include <cstdlib>
#include <thread>
#include "lib/threads/thread_parallel_runner_internal.h"
namespace {
void* ThreadMemoryManagerDefaultAlloc(void* opaque, size_t size) {
return malloc(size);
}
void ThreadMemoryManagerDefaultFree(void* opaque, void* address) {
free(address);
}
bool ThreadMemoryManagerInit(JxlMemoryManager* self,
const JxlMemoryManager* memory_manager) {
if (memory_manager) {
*self = *memory_manager;
} else {
memset(self, 0, sizeof(*self));
}
bool is_default_alloc = (self->alloc == nullptr);
bool is_default_free = (self->free == nullptr);
if (is_default_alloc != is_default_free) {
return false;
}
if (is_default_alloc) self->alloc = ThreadMemoryManagerDefaultAlloc;
if (is_default_free) self->free = ThreadMemoryManagerDefaultFree;
return true;
}
void* ThreadMemoryManagerAlloc(const JxlMemoryManager* memory_manager,
size_t size) {
return memory_manager->alloc(memory_manager->opaque, size);
}
void ThreadMemoryManagerFree(const JxlMemoryManager* memory_manager,
void* address) {
memory_manager->free(memory_manager->opaque, address);
}
}
JxlParallelRetCode JxlThreadParallelRunner(
void* runner_opaque, void* jpegxl_opaque, JxlParallelRunInit init,
JxlParallelRunFunction func, uint32_t start_range, uint32_t end_range) {
return jpegxl::ThreadParallelRunner::Runner(
runner_opaque, jpegxl_opaque, init, func, start_range, end_range);
}
void* JxlThreadParallelRunnerCreate(const JxlMemoryManager* memory_manager,
size_t num_worker_threads) {
JxlMemoryManager local_memory_manager;
if (!ThreadMemoryManagerInit(&local_memory_manager, memory_manager))
return nullptr;
void* alloc = ThreadMemoryManagerAlloc(&local_memory_manager,
sizeof(jpegxl::ThreadParallelRunner));
if (!alloc) return nullptr;
jpegxl::ThreadParallelRunner* runner =
new (alloc) jpegxl::ThreadParallelRunner(num_worker_threads);
runner->memory_manager = local_memory_manager;
return runner;
}
void JxlThreadParallelRunnerDestroy(void* runner_opaque) {
jpegxl::ThreadParallelRunner* runner =
reinterpret_cast<jpegxl::ThreadParallelRunner*>(runner_opaque);
if (runner) {
JxlMemoryManager local_memory_manager = runner->memory_manager;
runner->~ThreadParallelRunner();
ThreadMemoryManagerFree(&local_memory_manager, runner);
}
}
size_t JxlThreadParallelRunnerDefaultNumWorkerThreads() {
return std::thread::hardware_concurrency();
}