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 1 : static void thread_func(void *ptr) 24 : { 25 1 : int num = *(int *)ptr; 26 1 : 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 3999 : poBlockRW->MarkDirty(); 38 3999 : memset(poBlockRW->GetDataRef(), 0xFF, 100); 39 3998 : poBlockRef->DropLock(); 40 3998 : 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 : } 63 : else 64 : { 65 1 : GDALDataset *poDS = poDriver->Create("/vsimem/test_ref", 100, 2000, 1, 66 : GDT_Byte, nullptr); 67 1 : GDALClose(poDS); 68 : 69 1 : int counter = 0; 70 1 : const int nloops = bEndlessLoop ? 2 * 1000 * 1000 * 1000 : 1; 71 2 : for (int i = 0; i < nloops; ++i) 72 : { 73 1 : ++i; 74 1 : if ((i % 20) == 0) 75 0 : printf("%d\n", counter); 76 : 77 1 : hThread1 = CPLCreateJoinableThread(thread_func, &one); 78 1 : hThread2 = CPLCreateJoinableThread(thread_func, &two); 79 : 80 1 : CPLJoinThread(hThread1); 81 1 : CPLJoinThread(hThread2); 82 : 83 : GDALDataset *poDSRef = 84 1 : (GDALDataset *)GDALOpen("/vsimem/test1", GA_ReadOnly); 85 : const int cs = 86 1 : GDALChecksumImage(poDSRef->GetRasterBand(1), 0, 0, 100, 2000); 87 1 : EXPECT_EQ(cs, 29689); 88 1 : GDALClose(poDSRef); 89 : 90 1 : poDriver->Delete("/vsimem/test1"); 91 1 : poDriver->Delete("/vsimem/test2"); 92 : } 93 : 94 1 : poDriver->Delete("/vsimem/test_ref"); 95 : 96 1 : GDALDestroyDriverManager(); 97 : } 98 : } 99 : 100 : } // namespace