libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

thread_parallel_runner.cc (3838B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #include <jxl/memory_manager.h>
      7 #include <jxl/parallel_runner.h>
      8 #include <jxl/thread_parallel_runner.h>
      9 #include <string.h>
     10 
     11 #include <cstdint>
     12 #include <cstdlib>
     13 #include <thread>
     14 
     15 #include "lib/threads/thread_parallel_runner_internal.h"
     16 
     17 namespace {
     18 
     19 // Default JxlMemoryManager using malloc and free for the jpegxl_threads
     20 // library. Same as the default JxlMemoryManager for the jpegxl library
     21 // itself.
     22 
     23 // Default alloc and free functions.
     24 void* ThreadMemoryManagerDefaultAlloc(void* opaque, size_t size) {
     25   return malloc(size);
     26 }
     27 
     28 void ThreadMemoryManagerDefaultFree(void* opaque, void* address) {
     29   free(address);
     30 }
     31 
     32 // Initializes the memory manager instance with the passed one. The
     33 // MemoryManager passed in |memory_manager| may be NULL or contain NULL
     34 // functions which will be initialized with the default ones. If either alloc
     35 // or free are NULL, then both must be NULL, otherwise this function returns an
     36 // error.
     37 bool ThreadMemoryManagerInit(JxlMemoryManager* self,
     38                              const JxlMemoryManager* memory_manager) {
     39   if (memory_manager) {
     40     *self = *memory_manager;
     41   } else {
     42     memset(self, 0, sizeof(*self));
     43   }
     44   bool is_default_alloc = (self->alloc == nullptr);
     45   bool is_default_free = (self->free == nullptr);
     46   if (is_default_alloc != is_default_free) {
     47     return false;
     48   }
     49   if (is_default_alloc) self->alloc = ThreadMemoryManagerDefaultAlloc;
     50   if (is_default_free) self->free = ThreadMemoryManagerDefaultFree;
     51 
     52   return true;
     53 }
     54 
     55 void* ThreadMemoryManagerAlloc(const JxlMemoryManager* memory_manager,
     56                                size_t size) {
     57   return memory_manager->alloc(memory_manager->opaque, size);
     58 }
     59 
     60 void ThreadMemoryManagerFree(const JxlMemoryManager* memory_manager,
     61                              void* address) {
     62   memory_manager->free(memory_manager->opaque, address);
     63 }
     64 
     65 }  // namespace
     66 
     67 JxlParallelRetCode JxlThreadParallelRunner(
     68     void* runner_opaque, void* jpegxl_opaque, JxlParallelRunInit init,
     69     JxlParallelRunFunction func, uint32_t start_range, uint32_t end_range) {
     70   return jpegxl::ThreadParallelRunner::Runner(
     71       runner_opaque, jpegxl_opaque, init, func, start_range, end_range);
     72 }
     73 
     74 /// Starts the given number of worker threads and blocks until they are ready.
     75 /// "num_worker_threads" defaults to one per hyperthread. If zero, all tasks
     76 /// run on the main thread.
     77 void* JxlThreadParallelRunnerCreate(const JxlMemoryManager* memory_manager,
     78                                     size_t num_worker_threads) {
     79   JxlMemoryManager local_memory_manager;
     80   if (!ThreadMemoryManagerInit(&local_memory_manager, memory_manager))
     81     return nullptr;
     82 
     83   void* alloc = ThreadMemoryManagerAlloc(&local_memory_manager,
     84                                          sizeof(jpegxl::ThreadParallelRunner));
     85   if (!alloc) return nullptr;
     86   // Placement new constructor on allocated memory
     87   jpegxl::ThreadParallelRunner* runner =
     88       new (alloc) jpegxl::ThreadParallelRunner(num_worker_threads);
     89   runner->memory_manager = local_memory_manager;
     90 
     91   return runner;
     92 }
     93 
     94 void JxlThreadParallelRunnerDestroy(void* runner_opaque) {
     95   jpegxl::ThreadParallelRunner* runner =
     96       reinterpret_cast<jpegxl::ThreadParallelRunner*>(runner_opaque);
     97   if (runner) {
     98     JxlMemoryManager local_memory_manager = runner->memory_manager;
     99     // Call destructor directly since custom free function is used.
    100     runner->~ThreadParallelRunner();
    101     ThreadMemoryManagerFree(&local_memory_manager, runner);
    102   }
    103 }
    104 
    105 // Get default value for num_worker_threads parameter of
    106 // InitJxlThreadParallelRunner.
    107 size_t JxlThreadParallelRunnerDefaultNumWorkerThreads() {
    108   return std::thread::hardware_concurrency();
    109 }