LCOV - code coverage report
Current view: top level - gcore - gdal_thread_pool.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 37 39 94.9 %
Date: 2026-02-21 16:21:44 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Global thread pool
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys dot com>
       6             :  *
       7             :  **********************************************************************
       8             :  * Copyright (c) 2020, Even Rouault, <even dot rouault at spatialys dot com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_conv.h"
      14             : #include "cpl_multiproc.h"
      15             : #include "cpl_string.h"
      16             : #include "cpl_worker_thread_pool.h"
      17             : #include "gdal_thread_pool.h"
      18             : 
      19             : #include <algorithm>
      20             : #include <mutex>
      21             : 
      22             : // For unclear reasons, attempts at making this a std::unique_ptr<>, even
      23             : // through a GetCompressThreadPool() method like GetMutexThreadPool(), lead
      24             : // to "ctest -R autotest_alg" (and other autotest components as well)
      25             : // to hang forever once the tests have terminated.
      26             : static CPLWorkerThreadPool *gpoCompressThreadPool = nullptr;
      27             : 
      28        1383 : static std::mutex &GetMutexThreadPool()
      29             : {
      30             :     static std::mutex gMutexThreadPool;
      31        1383 :     return gMutexThreadPool;
      32             : }
      33             : 
      34         254 : CPLWorkerThreadPool *GDALGetGlobalThreadPool(int nThreads)
      35             : {
      36         254 :     std::lock_guard oGuard(GetMutexThreadPool());
      37         254 :     if (gpoCompressThreadPool == nullptr)
      38             :     {
      39           5 :         gpoCompressThreadPool = new CPLWorkerThreadPool();
      40           5 :         if (!gpoCompressThreadPool->Setup(nThreads, nullptr, nullptr, false))
      41             :         {
      42           0 :             delete gpoCompressThreadPool;
      43           0 :             gpoCompressThreadPool = nullptr;
      44             :         }
      45             :     }
      46         249 :     else if (nThreads > gpoCompressThreadPool->GetThreadCount())
      47             :     {
      48             :         // Increase size of thread pool
      49           3 :         gpoCompressThreadPool->Setup(nThreads, nullptr, nullptr, false);
      50             :     }
      51         508 :     return gpoCompressThreadPool;
      52             : }
      53             : 
      54        1129 : void GDALDestroyGlobalThreadPool()
      55             : {
      56        1129 :     std::lock_guard oGuard(GetMutexThreadPool());
      57        1129 :     delete gpoCompressThreadPool;
      58        1129 :     gpoCompressThreadPool = nullptr;
      59        1129 : }
      60             : 
      61             : /************************************************************************/
      62             : /*                         GDALGetNumThreads()                          */
      63             : /************************************************************************/
      64             : 
      65             : /** Return the number of threads to use, taking into account the
      66             :  * GDAL_NUM_THREADS configuration option.
      67             :  *
      68             :  * @param nMaxVal Maximum number of threads, or -1 if none
      69             :  * @param bDefaultAllCPUs Whether the default value should be CPLGetNumCPUs()
      70             :  * @param[out] ppszValue Pointer to a string to set the string value used, or
      71             :  *                       nullptr if not needed.
      72             :  * @param[out] pbOK Pointer to a boolean indicating if the option value was
      73             :  *                  correct, or nullptr if not needed.
      74             :  *
      75             :  * @return value between 1 and std::max(1, nMaxVal)
      76             :  *
      77             :  * @since 3.13
      78             :  */
      79        9864 : int GDALGetNumThreads(int nMaxVal, bool bDefaultAllCPUs, const char **ppszValue,
      80             :                       bool *pbOK)
      81             : {
      82        9864 :     return GDALGetNumThreads(nullptr, nullptr, nMaxVal, bDefaultAllCPUs,
      83        9864 :                              ppszValue, pbOK);
      84             : }
      85             : 
      86             : /************************************************************************/
      87             : /*                         GDALGetNumThreads()                          */
      88             : /************************************************************************/
      89             : 
      90             : /** Return the number of threads to use, taking into account first the
      91             :  * specified item in a list of options, and falling back to the
      92             :  * GDAL_NUM_THREADS configuration option.
      93             :  *
      94             :  * @param papszOptions null terminated list of options (or nullptr)
      95             :  * @param pszItemName item name in papszOptions (or nullptr)
      96             :  * @param nMaxVal Maximum number of threads, or -1 if none
      97             :  * @param bDefaultAllCPUs Whether the default value should be CPLGetNumCPUs()
      98             :  * @param[out] ppszValue Pointer to a string to set the string value used, or
      99             :  *                       nullptr if not needed.
     100             :  * @param[out] pbOK Pointer to a boolean indicating if the option value was
     101             :  *                  correct, or nullptr if not needed.
     102             :  *
     103             :  * @return value between 1 and std::max(1, nMaxVal)
     104             :  *
     105             :  * @since 3.13
     106             :  */
     107       21292 : int GDALGetNumThreads(CSLConstList papszOptions, const char *pszItemName,
     108             :                       int nMaxVal, bool bDefaultAllCPUs, const char **ppszValue,
     109             :                       bool *pbOK)
     110             : {
     111       21292 :     const char *pszNumThreads = nullptr;
     112       21292 :     if (papszOptions && pszItemName)
     113        3905 :         pszNumThreads = CSLFetchNameValue(papszOptions, pszItemName);
     114       21292 :     return GDALGetNumThreads(pszNumThreads, nMaxVal, bDefaultAllCPUs, ppszValue,
     115       21292 :                              pbOK);
     116             : }
     117             : 
     118             : /************************************************************************/
     119             : /*                         GDALGetNumThreads()                          */
     120             : /************************************************************************/
     121             : 
     122             : /** Return the number of threads to use, taking into account first the
     123             :  * specified value, and if null, falling back to the
     124             :  * GDAL_NUM_THREADS configuration option.
     125             :  *
     126             :  * @param pszNumThreads Value to parse to get the number of threads. If null,
     127             :  *                      the GDAL_NUM_THREADS configuration option is used.
     128             :  * @param nMaxVal Maximum number of threads, or -1 if none
     129             :  * @param bDefaultAllCPUs Whether the default value should be CPLGetNumCPUs()
     130             :  * @param[out] ppszValue Pointer to a string to set the string value used, or
     131             :  *                       nullptr if not needed.
     132             :  * @param[out] pbOK Pointer to a boolean indicating if the option value was
     133             :  *                  correct, or nullptr if not needed.
     134             :  *
     135             :  * @return value between 1 and std::max(1, nMaxVal)
     136             :  *
     137             :  * @since 3.13
     138             :  */
     139       23948 : int GDALGetNumThreads(const char *pszNumThreads, int nMaxVal,
     140             :                       bool bDefaultAllCPUs, const char **ppszValue, bool *pbOK)
     141             : {
     142       23948 :     if (!pszNumThreads)
     143             :     {
     144       23136 :         pszNumThreads = CPLGetConfigOption("GDAL_NUM_THREADS",
     145             :                                            bDefaultAllCPUs ? "ALL_CPUS" : "1");
     146             :     }
     147       23948 :     if (ppszValue)
     148       10746 :         *ppszValue = pszNumThreads;
     149       23948 :     int nThreads = EQUAL(pszNumThreads, "ALL_CPUS") ? CPLGetNumCPUs()
     150       21338 :                                                     : atoi(pszNumThreads);
     151       23948 :     if (pbOK)
     152       17969 :         *pbOK = EQUAL(pszNumThreads, "ALL_CPUS") ||
     153        8771 :                 CPLGetValueType(pszNumThreads) == CPL_VALUE_INTEGER;
     154       23948 :     if (nMaxVal > 0)
     155       17523 :         nThreads = std::min(nThreads, nMaxVal);
     156       23948 :     return std::max(nThreads, 1);
     157             : }

Generated by: LCOV version 1.14