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-05-13 13:33:37 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      10             :  * copy of this software and associated documentation files (the "Software"),
      11             :  * to deal in the Software without restriction, including without limitation
      12             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      13             :  * and/or sell copies of the Software, and to permit persons to whom the
      14             :  * Software is furnished to do so, subject to the following conditions:
      15             :  *
      16             :  * The above copyright notice and this permission notice shall be included
      17             :  * in all copies or substantial portions of the Software.
      18             :  *
      19             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      20             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      22             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      24             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      25             :  * DEALINGS IN THE SOFTWARE.
      26             :  ****************************************************************************/
      27             : 
      28             : #include "cpl_multiproc.h"
      29             : #include "gdal_alg.h"
      30             : #include "gdal_priv.h"
      31             : 
      32             : #include "gtest_include.h"
      33             : 
      34             : namespace
      35             : {
      36             : 
      37             : // ---------------------------------------------------------------------------
      38             : 
      39           2 : static void thread_func(void *ptr)
      40             : {
      41           2 :     int num = *(int *)ptr;
      42           2 :     GDALDriver *poDriver = (GDALDriver *)GDALGetDriverByName("ENVI");
      43             :     GDALDataset *poDSRef =
      44           2 :         (GDALDataset *)GDALOpen("/vsimem/test_ref", GA_ReadOnly);
      45           2 :     GDALDataset *poDS = poDriver->Create(CPLSPrintf("/vsimem/test%d", num), 100,
      46             :                                          2000, 1, GDT_Byte, nullptr);
      47           2 :     GDALRasterBand *poBand = poDS->GetRasterBand(1);
      48           2 :     GDALRasterBand *poBandRef = poDSRef->GetRasterBand(1);
      49        4002 :     for (int i = 0; i < 2000; i++)
      50             :     {
      51        4000 :         GDALRasterBlock *poBlockRef = poBandRef->GetLockedBlockRef(0, i);
      52        4000 :         GDALRasterBlock *poBlockRW = poBand->GetLockedBlockRef(0, i);
      53        4000 :         poBlockRW->MarkDirty();
      54        4000 :         memset(poBlockRW->GetDataRef(), 0xFF, 100);
      55        4000 :         poBlockRef->DropLock();
      56        4000 :         poBlockRW->DropLock();
      57             :     }
      58           2 :     GDALClose(poDS);
      59           2 :     GDALClose(poDSRef);
      60           2 : }
      61             : 
      62           4 : TEST(testmultithreadedwriting, test)
      63             : {
      64           1 :     bool bEndlessLoop = CPLTestBool(CPLGetConfigOption("ENDLESS_LOOPS", "NO"));
      65             : 
      66             :     CPLJoinableThread *hThread1;
      67             :     CPLJoinableThread *hThread2;
      68             : 
      69           1 :     GDALAllRegister();
      70           1 :     GDALSetCacheMax(10000);
      71             : 
      72           1 :     int one = 1;
      73           1 :     int two = 2;
      74           1 :     GDALDriver *poDriver = (GDALDriver *)GDALGetDriverByName("ENVI");
      75           1 :     if (poDriver == nullptr)
      76             :     {
      77           0 :         GTEST_SKIP() << "ENVI driver missing";
      78             :         return;
      79             :     }
      80             :     GDALDataset *poDS =
      81           1 :         poDriver->Create("/vsimem/test_ref", 100, 2000, 1, GDT_Byte, nullptr);
      82           1 :     GDALClose(poDS);
      83             : 
      84           1 :     int counter = 0;
      85           1 :     const int nloops = bEndlessLoop ? 2 * 1000 * 1000 * 1000 : 1;
      86           2 :     for (int i = 0; i < nloops; ++i)
      87             :     {
      88           1 :         ++i;
      89           1 :         if ((i % 20) == 0)
      90           0 :             printf("%d\n", counter);
      91             : 
      92           1 :         hThread1 = CPLCreateJoinableThread(thread_func, &one);
      93           1 :         hThread2 = CPLCreateJoinableThread(thread_func, &two);
      94             : 
      95           1 :         CPLJoinThread(hThread1);
      96           1 :         CPLJoinThread(hThread2);
      97             : 
      98             :         GDALDataset *poDSRef =
      99           1 :             (GDALDataset *)GDALOpen("/vsimem/test1", GA_ReadOnly);
     100             :         const int cs =
     101           1 :             GDALChecksumImage(poDSRef->GetRasterBand(1), 0, 0, 100, 2000);
     102           1 :         EXPECT_EQ(cs, 29689);
     103           1 :         GDALClose(poDSRef);
     104             : 
     105           1 :         poDriver->Delete("/vsimem/test1");
     106           1 :         poDriver->Delete("/vsimem/test2");
     107             :     }
     108             : 
     109           1 :     poDriver->Delete("/vsimem/test_ref");
     110             : 
     111           1 :     GDALDestroyDriverManager();
     112             : }
     113             : 
     114             : }  // namespace

Generated by: LCOV version 1.14