LCOV - code coverage report
Current view: top level - autotest/cpp - testmultithreadedwriting.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 44 46 95.7 %
Date: 2024-11-21 22:18:42 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * Project:  GDAL Core
       3             :  * Purpose:  Test block cache & writing behaviour under multi-threading
       4             :  * Author:   Even Rouault, <even dot rouault at spatialys dot com>
       5             :  *
       6             :  ******************************************************************************
       7             :  * Copyright (c) 2016, Even Rouault <even dot rouault at spatialys dot com>
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  ****************************************************************************/
      11             : 
      12             : #include "cpl_multiproc.h"
      13             : #include "gdal_alg.h"
      14             : #include "gdal_priv.h"
      15             : 
      16             : #include "gtest_include.h"
      17             : 
      18             : namespace
      19             : {
      20             : 
      21             : // ---------------------------------------------------------------------------
      22             : 
      23           2 : static void thread_func(void *ptr)
      24             : {
      25           2 :     int num = *(int *)ptr;
      26           2 :     GDALDriver *poDriver = (GDALDriver *)GDALGetDriverByName("ENVI");
      27             :     GDALDataset *poDSRef =
      28           2 :         (GDALDataset *)GDALOpen("/vsimem/test_ref", GA_ReadOnly);
      29           2 :     GDALDataset *poDS = poDriver->Create(CPLSPrintf("/vsimem/test%d", num), 100,
      30             :                                          2000, 1, GDT_Byte, nullptr);
      31           2 :     GDALRasterBand *poBand = poDS->GetRasterBand(1);
      32           2 :     GDALRasterBand *poBandRef = poDSRef->GetRasterBand(1);
      33        4002 :     for (int i = 0; i < 2000; i++)
      34             :     {
      35        4000 :         GDALRasterBlock *poBlockRef = poBandRef->GetLockedBlockRef(0, i);
      36        4000 :         GDALRasterBlock *poBlockRW = poBand->GetLockedBlockRef(0, i);
      37        4000 :         poBlockRW->MarkDirty();
      38        4000 :         memset(poBlockRW->GetDataRef(), 0xFF, 100);
      39        4000 :         poBlockRef->DropLock();
      40        4000 :         poBlockRW->DropLock();
      41             :     }
      42           2 :     GDALClose(poDS);
      43           2 :     GDALClose(poDSRef);
      44           2 : }
      45             : 
      46           4 : TEST(testmultithreadedwriting, test)
      47             : {
      48           1 :     bool bEndlessLoop = CPLTestBool(CPLGetConfigOption("ENDLESS_LOOPS", "NO"));
      49             : 
      50             :     CPLJoinableThread *hThread1;
      51             :     CPLJoinableThread *hThread2;
      52             : 
      53           1 :     GDALAllRegister();
      54           1 :     GDALSetCacheMax(10000);
      55             : 
      56           1 :     int one = 1;
      57           1 :     int two = 2;
      58           1 :     GDALDriver *poDriver = (GDALDriver *)GDALGetDriverByName("ENVI");
      59           1 :     if (poDriver == nullptr)
      60             :     {
      61           0 :         GTEST_SKIP() << "ENVI driver missing";
      62             :         return;
      63             :     }
      64             :     GDALDataset *poDS =
      65           1 :         poDriver->Create("/vsimem/test_ref", 100, 2000, 1, GDT_Byte, nullptr);
      66           1 :     GDALClose(poDS);
      67             : 
      68           1 :     int counter = 0;
      69           1 :     const int nloops = bEndlessLoop ? 2 * 1000 * 1000 * 1000 : 1;
      70           2 :     for (int i = 0; i < nloops; ++i)
      71             :     {
      72           1 :         ++i;
      73           1 :         if ((i % 20) == 0)
      74           0 :             printf("%d\n", counter);
      75             : 
      76           1 :         hThread1 = CPLCreateJoinableThread(thread_func, &one);
      77           1 :         hThread2 = CPLCreateJoinableThread(thread_func, &two);
      78             : 
      79           1 :         CPLJoinThread(hThread1);
      80           1 :         CPLJoinThread(hThread2);
      81             : 
      82             :         GDALDataset *poDSRef =
      83           1 :             (GDALDataset *)GDALOpen("/vsimem/test1", GA_ReadOnly);
      84             :         const int cs =
      85           1 :             GDALChecksumImage(poDSRef->GetRasterBand(1), 0, 0, 100, 2000);
      86           1 :         EXPECT_EQ(cs, 29689);
      87           1 :         GDALClose(poDSRef);
      88             : 
      89           1 :         poDriver->Delete("/vsimem/test1");
      90           1 :         poDriver->Delete("/vsimem/test2");
      91             :     }
      92             : 
      93           1 :     poDriver->Delete("/vsimem/test_ref");
      94             : 
      95           1 :     GDALDestroyDriverManager();
      96             : }
      97             : 
      98             : }  // namespace

Generated by: LCOV version 1.14