Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Core
4 : * Purpose: Test block cache under multi-threading
5 : * Author: Even Rouault, <even dot rouault at spatialys dot com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2015, 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 "gdal_priv.h"
17 : #include "gdal.h"
18 :
19 : #include "test_data.h"
20 :
21 : #include "gtest_include.h"
22 :
23 : namespace
24 : {
25 :
26 : // ---------------------------------------------------------------------------
27 :
28 1 : static void thread_func(void * /* unused */)
29 : {
30 1 : printf("begin thread %p\n", (void *)CPLGetPID());
31 1 : CPLSetThreadLocalConfigOption("GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK",
32 : "0.6");
33 1 : GDALDatasetH hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
34 : char buf[20 * 20];
35 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
36 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
37 1 : CPLSetThreadLocalConfigOption("GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK",
38 : "0");
39 1 : GDALClose(hDS);
40 1 : printf("end of thread\n\n");
41 1 : }
42 :
43 3 : static void thread_func2(void * /* unused */)
44 : {
45 3 : printf("begin thread %p\n", (void *)CPLGetPID());
46 3 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_DROP_LOCK",
47 : "0.6");
48 3 : GDALFlushCacheBlock();
49 3 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_DROP_LOCK",
50 : "0");
51 3 : printf("end of thread\n\n");
52 3 : }
53 :
54 1 : static void thread_func3(void * /* unused */)
55 : {
56 1 : printf("begin thread %p\n", (void *)CPLGetPID());
57 1 : CPLSleep(0.3);
58 1 : printf("begin GDALFlushCacheBlock\n");
59 1 : GDALFlushCacheBlock();
60 1 : printf("end of thread\n\n");
61 1 : }
62 :
63 1 : static void thread_func4(void * /* unused */)
64 : {
65 1 : printf("begin thread %p\n", (void *)CPLGetPID());
66 1 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_RB_LOCK",
67 : "0.6");
68 1 : GDALFlushCacheBlock();
69 1 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_RB_LOCK",
70 : "0");
71 1 : printf("end of thread\n\n");
72 1 : }
73 :
74 : // ---------------------------------------------------------------------------
75 :
76 4 : TEST(testblockcachelimits, test)
77 : {
78 : CPLJoinableThread *hThread;
79 :
80 : // CPLSetConfigOption("CPL_DEBUG", "ON");
81 :
82 1 : printf("main thread %p\n", (void *)CPLGetPID());
83 :
84 1 : CPLSetConfigOption("GDAL_CACHEMAX", "0");
85 1 : CPLSetConfigOption("GDAL_DEBUG_BLOCK_CACHE", "ON");
86 1 : GDALAllRegister();
87 :
88 1 : GDALDatasetH hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
89 :
90 : char buf[20 * 20];
91 1 : printf("cache fill\n");
92 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
93 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
94 1 : printf("end of cache fill\n");
95 1 : printf("buf[0]=%d\n\n", (int)buf[0]);
96 :
97 1 : hThread = CPLCreateJoinableThread(thread_func, nullptr);
98 1 : CPLSleep(0.3);
99 :
100 1 : printf("re read block\n");
101 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
102 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
103 1 : printf("end of re read block\n");
104 1 : printf("buf[0]=%d\n", (int)buf[0]);
105 1 : CPLJoinThread(hThread);
106 :
107 1 : hThread = CPLCreateJoinableThread(thread_func2, nullptr);
108 1 : CPLSleep(0.3);
109 :
110 1 : printf("re read block\n");
111 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
112 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
113 1 : printf("end of re read block\n");
114 1 : printf("buf[0]=%d\n", (int)buf[0]);
115 1 : CPLJoinThread(hThread);
116 :
117 1 : hThread = CPLCreateJoinableThread(thread_func3, nullptr);
118 :
119 1 : printf("re read block\n");
120 1 : CPLSetThreadLocalConfigOption("GDAL_RB_TRYGET_SLEEP_AFTER_TAKE_LOCK",
121 : "0.6");
122 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
123 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
124 1 : CPLSetThreadLocalConfigOption("GDAL_RB_TRYGET_SLEEP_AFTER_TAKE_LOCK", "0");
125 1 : printf("end of re read block\n");
126 1 : printf("buf[0]=%d\n", (int)buf[0]);
127 1 : CPLJoinThread(hThread);
128 :
129 1 : hThread = CPLCreateJoinableThread(thread_func2, nullptr);
130 1 : CPLSleep(0.3);
131 1 : printf("before GDALFlushRasterCache\n");
132 1 : GDALFlushRasterCache(GDALGetRasterBand(hDS, 1));
133 1 : printf("after GDALFlushRasterCache\n");
134 :
135 1 : CPLJoinThread(hThread);
136 1 : ASSERT_EQ(GDALGetCacheUsed64(), 0);
137 :
138 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
139 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
140 1 : hThread = CPLCreateJoinableThread(thread_func2, nullptr);
141 1 : CPLSleep(0.3);
142 1 : GDALClose(hDS);
143 1 : CPLJoinThread(hThread);
144 :
145 1 : hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
146 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
147 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
148 1 : hThread = CPLCreateJoinableThread(thread_func4, nullptr);
149 1 : CPLSleep(0.3);
150 1 : GDALClose(hDS);
151 1 : CPLJoinThread(hThread);
152 :
153 1 : GDALDestroyDriverManager();
154 : }
155 :
156 : } // namespace
|