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