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 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "cpl_conv.h"
31 : #include "cpl_multiproc.h"
32 : #include "cpl_string.h"
33 : #include "gdal_priv.h"
34 : #include "gdal.h"
35 :
36 : #include "test_data.h"
37 :
38 : #include "gtest_include.h"
39 :
40 : namespace
41 : {
42 :
43 : // ---------------------------------------------------------------------------
44 :
45 1 : static void thread_func(void * /* unused */)
46 : {
47 1 : printf("begin thread %p\n", (void *)CPLGetPID());
48 1 : CPLSetThreadLocalConfigOption("GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK",
49 : "0.6");
50 1 : GDALDatasetH hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
51 : char buf[20 * 20];
52 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
53 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
54 1 : CPLSetThreadLocalConfigOption("GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK",
55 : "0");
56 1 : GDALClose(hDS);
57 1 : printf("end of thread\n\n");
58 1 : }
59 :
60 3 : static void thread_func2(void * /* unused */)
61 : {
62 3 : printf("begin thread %p\n", (void *)CPLGetPID());
63 3 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_DROP_LOCK",
64 : "0.6");
65 3 : GDALFlushCacheBlock();
66 3 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_DROP_LOCK",
67 : "0");
68 3 : printf("end of thread\n\n");
69 3 : }
70 :
71 1 : static void thread_func3(void * /* unused */)
72 : {
73 1 : printf("begin thread %p\n", (void *)CPLGetPID());
74 1 : CPLSleep(0.3);
75 1 : printf("begin GDALFlushCacheBlock\n");
76 1 : GDALFlushCacheBlock();
77 1 : printf("end of thread\n\n");
78 1 : }
79 :
80 1 : static void thread_func4(void * /* unused */)
81 : {
82 1 : printf("begin thread %p\n", (void *)CPLGetPID());
83 1 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_RB_LOCK",
84 : "0.6");
85 1 : GDALFlushCacheBlock();
86 1 : CPLSetThreadLocalConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_RB_LOCK",
87 : "0");
88 1 : printf("end of thread\n\n");
89 1 : }
90 :
91 : // ---------------------------------------------------------------------------
92 :
93 4 : TEST(testblockcachelimits, test)
94 : {
95 : CPLJoinableThread *hThread;
96 :
97 : // CPLSetConfigOption("CPL_DEBUG", "ON");
98 :
99 1 : printf("main thread %p\n", (void *)CPLGetPID());
100 :
101 1 : CPLSetConfigOption("GDAL_CACHEMAX", "0");
102 1 : CPLSetConfigOption("GDAL_DEBUG_BLOCK_CACHE", "ON");
103 1 : GDALAllRegister();
104 :
105 1 : GDALDatasetH hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
106 :
107 : char buf[20 * 20];
108 1 : printf("cache fill\n");
109 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
110 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
111 1 : printf("end of cache fill\n");
112 1 : printf("buf[0]=%d\n\n", (int)buf[0]);
113 :
114 1 : hThread = CPLCreateJoinableThread(thread_func, nullptr);
115 1 : CPLSleep(0.3);
116 :
117 1 : printf("re read block\n");
118 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
119 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
120 1 : printf("end of re read block\n");
121 1 : printf("buf[0]=%d\n", (int)buf[0]);
122 1 : CPLJoinThread(hThread);
123 :
124 1 : hThread = CPLCreateJoinableThread(thread_func2, nullptr);
125 1 : CPLSleep(0.3);
126 :
127 1 : printf("re read block\n");
128 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
129 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
130 1 : printf("end of re read block\n");
131 1 : printf("buf[0]=%d\n", (int)buf[0]);
132 1 : CPLJoinThread(hThread);
133 :
134 1 : hThread = CPLCreateJoinableThread(thread_func3, nullptr);
135 :
136 1 : printf("re read block\n");
137 1 : CPLSetThreadLocalConfigOption("GDAL_RB_TRYGET_SLEEP_AFTER_TAKE_LOCK",
138 : "0.6");
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 : CPLSetThreadLocalConfigOption("GDAL_RB_TRYGET_SLEEP_AFTER_TAKE_LOCK", "0");
142 1 : printf("end of re read block\n");
143 1 : printf("buf[0]=%d\n", (int)buf[0]);
144 1 : CPLJoinThread(hThread);
145 :
146 1 : hThread = CPLCreateJoinableThread(thread_func2, nullptr);
147 1 : CPLSleep(0.3);
148 1 : printf("before GDALFlushRasterCache\n");
149 1 : GDALFlushRasterCache(GDALGetRasterBand(hDS, 1));
150 1 : printf("after GDALFlushRasterCache\n");
151 :
152 1 : CPLJoinThread(hThread);
153 1 : ASSERT_EQ(GDALGetCacheUsed64(), 0);
154 :
155 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
156 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
157 1 : hThread = CPLCreateJoinableThread(thread_func2, nullptr);
158 1 : CPLSleep(0.3);
159 1 : GDALClose(hDS);
160 1 : CPLJoinThread(hThread);
161 :
162 1 : hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
163 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(GDALGetRasterBand(hDS, 1), GF_Read, 0, 0,
164 : 20, 20, buf, 20, 20, GDT_Byte, 0, 0));
165 1 : hThread = CPLCreateJoinableThread(thread_func4, nullptr);
166 1 : CPLSleep(0.3);
167 1 : GDALClose(hDS);
168 1 : CPLJoinThread(hThread);
169 :
170 1 : GDALDestroyDriverManager();
171 : }
172 :
173 : } // namespace
|