tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | 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 }