Skip to content

Commit a667c0c

Browse files
committed
MDEV-37463 - minimize recompilation required for tpool_min
On Linux, introduce object library tpool_common, which contains non-AIO code.It is linked to both full tpool library (with AIO), and tpool_min(without AIO). As a result, building tpool_min now requires only compiling a single small source file. aio::synchronous(), aio::flush_synchronous() are moved into aio specific source file, from common threadpool_generic.cc, in order to avoid ABI breakage (size of aiocb depends on HAVE_LIBAIO etc compile options on Linux)
1 parent 4995584 commit a667c0c

File tree

4 files changed

+70
-63
lines changed

4 files changed

+70
-63
lines changed

tpool/CMakeLists.txt

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11

2-
SET(SOURCES
3-
aio_simulated.cc
2+
SET(COMMON_SOURCES
43
tpool_structs.h
54
tpool.h
65
tpool_generic.cc
@@ -9,14 +8,21 @@ SET(SOURCES
98
wait_notification.cc
109
)
1110

12-
ADD_LIBRARY(tpool OBJECT ${SOURCES})
1311

14-
TARGET_INCLUDE_DIRECTORIES(tpool PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}"
15-
${PROJECT_SOURCE_DIR}/include)
16-
IF(WIN32)
17-
TARGET_SOURCES(tpool PRIVATE tpool_win.cc aio_win.cc)
18-
ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
19-
TARGET_SOURCES(tpool PRIVATE aio_linux.cc)
12+
IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
13+
ADD_LIBRARY(tpool OBJECT ${COMMON_SOURCES} aio_simulated.cc)
14+
IF(WIN32)
15+
TARGET_SOURCES(tpool PRIVATE tpool_win.cc aio_win.cc)
16+
ENDIF()
17+
TARGET_INCLUDE_DIRECTORIES(tpool PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include)
18+
ADD_LIBRARY(tpool_min ALIAS tpool)
19+
ELSE() # Linux
20+
ADD_LIBRARY(tpool_common OBJECT ${COMMON_SOURCES})
21+
# Ensure that aiocb used as opaque in common code, or ABI will be broken
22+
TARGET_COMPILE_DEFINITIONS(tpool_common PRIVATE -DTPOOL_OPAQUE_AIOCB)
23+
TARGET_INCLUDE_DIRECTORIES(tpool_common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include)
24+
ADD_LIBRARY(tpool STATIC aio_linux.cc aio_simulated.cc)
25+
TARGET_LINK_LIBRARIES(tpool PUBLIC tpool_common)
2026
OPTION(WITH_URING "Require that io_uring be used" OFF)
2127
OPTION(WITH_LIBAIO "Require that libaio is used" OFF)
2228
IF(WITH_URING)
@@ -57,12 +63,10 @@ ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
5763
# Create a "light" version of the library that does not link
5864
# to additional io libs, and is not compiled with
5965
# -DHAVE_LIBAIO or -DHAVE_URING flags.
60-
ADD_LIBRARY(tpool_min STATIC ${SOURCES} aio_linux.cc)
61-
TARGET_INCLUDE_DIRECTORIES(tpool_min
62-
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include)
66+
ADD_LIBRARY(tpool_min STATIC aio_linux.cc)
67+
TARGET_LINK_LIBRARIES(tpool_min PUBLIC tpool_common)
68+
ELSE()
69+
ADD_LIBRARY(tpool_min ALIAS tpool)
6370
ENDIF()
6471
ENDIF()
6572

66-
IF(NOT TARGET tpool_min)
67-
ADD_LIBRARY(tpool_min ALIAS tpool)
68-
ENDIF()

tpool/aio_simulated.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,50 @@ aio *create_simulated_aio(thread_pool *tp)
162162
return new simulated_aio(tp);
163163
}
164164

165+
void aio::finish_synchronous(aiocb *cb)
166+
{
167+
if (!cb->m_err && cb->m_ret_len != cb->m_len)
168+
{
169+
/* partial read/write */
170+
cb->m_buffer= (char *) cb->m_buffer + cb->m_ret_len;
171+
cb->m_len-= (unsigned int) cb->m_ret_len;
172+
cb->m_offset+= cb->m_ret_len;
173+
synchronous(cb);
174+
}
175+
}
176+
177+
/**
178+
Process the cb synchronously
179+
*/
180+
void aio::synchronous(aiocb *cb)
181+
{
182+
intptr_t ret_len;
183+
int err= 0;
184+
switch (cb->m_opcode)
185+
{
186+
case aio_opcode::AIO_PREAD:
187+
ret_len= pread(cb->m_fh, cb->m_buffer, cb->m_len, cb->m_offset);
188+
break;
189+
case aio_opcode::AIO_PWRITE:
190+
ret_len= pwrite(cb->m_fh, cb->m_buffer, cb->m_len, cb->m_offset);
191+
break;
192+
default:
193+
abort();
194+
}
195+
196+
if (ret_len < 0)
197+
{
198+
#ifdef _WIN32
199+
err= GetLastError();
200+
#else
201+
err= errno;
202+
#endif
203+
ret_len= 0;
204+
}
205+
cb->m_ret_len = ret_len;
206+
cb->m_err = err;
207+
if (ret_len)
208+
finish_synchronous(cb);
209+
}
210+
165211
} // namespace tpool

tpool/tpool.h

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ enum class aio_opcode
138138
};
139139
constexpr size_t MAX_AIO_USERDATA_LEN= 4 * sizeof(void*);
140140

141+
#ifdef TPOOL_OPAQUE_AIOCB
142+
struct aiocb;
143+
#else
141144
/** IO control block, includes parameters for the IO, and the callback*/
142145

143146
struct aiocb
@@ -181,6 +184,7 @@ struct aiocb
181184
}
182185
};
183186

187+
#endif /* TPOOL_OPAQUE_AIOCB */
184188

185189
/**
186190
AIO interface
@@ -202,17 +206,7 @@ class aio
202206
protected:
203207
static void synchronous(aiocb *cb);
204208
/** finish a partial read/write callback synchronously */
205-
static inline void finish_synchronous(aiocb *cb)
206-
{
207-
if (!cb->m_err && cb->m_ret_len != cb->m_len)
208-
{
209-
/* partial read/write */
210-
cb->m_buffer= (char *) cb->m_buffer + cb->m_ret_len;
211-
cb->m_len-= (unsigned int) cb->m_ret_len;
212-
cb->m_offset+= cb->m_ret_len;
213-
synchronous(cb);
214-
}
215-
}
209+
static void finish_synchronous(aiocb *cb);
216210
};
217211

218212
class timer

tpool/tpool_generic.cc

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -46,43 +46,6 @@ namespace tpool
4646
static const std::chrono::milliseconds LONG_TASK_DURATION = std::chrono::milliseconds(500);
4747
static const int OVERSUBSCRIBE_FACTOR = 2;
4848

49-
/**
50-
Process the cb synchronously
51-
*/
52-
void aio::synchronous(aiocb *cb)
53-
{
54-
#ifdef _WIN32
55-
size_t ret_len;
56-
#else
57-
ssize_t ret_len;
58-
#endif
59-
int err= 0;
60-
switch (cb->m_opcode)
61-
{
62-
case aio_opcode::AIO_PREAD:
63-
ret_len= pread(cb->m_fh, cb->m_buffer, cb->m_len, cb->m_offset);
64-
break;
65-
case aio_opcode::AIO_PWRITE:
66-
ret_len= pwrite(cb->m_fh, cb->m_buffer, cb->m_len, cb->m_offset);
67-
break;
68-
default:
69-
abort();
70-
}
71-
#ifdef _WIN32
72-
if (static_cast<int>(ret_len) < 0)
73-
err= GetLastError();
74-
#else
75-
if (ret_len < 0)
76-
{
77-
err= errno;
78-
ret_len= 0;
79-
}
80-
#endif
81-
cb->m_ret_len = ret_len;
82-
cb->m_err = err;
83-
if (ret_len)
84-
finish_synchronous(cb);
85-
}
8649

8750

8851
/**

0 commit comments

Comments
 (0)