diff --git a/CMakeLists.txt b/CMakeLists.txt
index a8227e218..abb2158ca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -743,6 +743,7 @@ endif()
if(MOD_SDORM_SQL)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq)
add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async)
+ add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async-qw)
endif()
if(MOD_APACHE)
@@ -863,6 +864,7 @@ endif()
if(NOT MOD_SDORM_SQL)
install(CODE "execute_process(COMMAND rm -rf ${PROJECT_NAME}-bin/web/te-benchmark-um-pq)")
install(CODE "execute_process(COMMAND rm -rf ${PROJECT_NAME}-bin/web/te-benchmark-um-pq-async)")
+ install(CODE "execute_process(COMMAND rm -rf ${PROJECT_NAME}-bin/web/te-benchmark-um-pq-async-qw)")
endif()
install(DIRECTORY ${PROJECT_SOURCE_DIR}/tests/ DESTINATION ${PROJECT_NAME}-bin/tests)
if(CYGWIN OR MINGW)
@@ -892,8 +894,10 @@ if(CYGWIN OR MINGW)
if(MOD_SDORM_SQL)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/cygte-benchmark-um-pq${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async/cygte-benchmark-um-pq-async${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
+ install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async-qw/cygte-benchmark-um-pq-async-qw${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte-benchmark-um-pq${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async/libte-benchmark-um-pq-async${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
+ install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async-qw/libte-benchmark-um-pq-async-qw${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
endif()
else()
install(FILES ${PROJECT_BINARY_DIR}/src/modules/libffead-modules${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
@@ -911,6 +915,7 @@ if(CYGWIN OR MINGW)
if(MOD_SDORM_SQL)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte-benchmark-um-pq${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async/libte-benchmark-um-pq-async${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
+ install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async-qw/libte-benchmark-um-pq-async-qw${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
endif()
install(FILES ${PROJECT_BINARY_DIR}/src/modules/libffead-modules${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
install(FILES ${PROJECT_BINARY_DIR}/src/framework/libffead-framework${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
@@ -927,6 +932,7 @@ if(CYGWIN OR MINGW)
if(MOD_SDORM_SQL)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte-benchmark-um-pq${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async/libte-benchmark-um-pq-async${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
+ install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async-qw/libte-benchmark-um-pq-async-qw${LIB_EXT}.a DESTINATION ${PROJECT_NAME}-bin/lib)
endif()
endif()
install(FILES ${PROJECT_BINARY_DIR}/ffead-cpp.exe DESTINATION ${PROJECT_NAME}-bin/)
@@ -952,6 +958,7 @@ else()
if(MOD_SDORM_SQL)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte-benchmark-um-pq${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async/libte-benchmark-um-pq-async${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
+ install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async-qw/libte-benchmark-um-pq-async-qw${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)
endif()
if(SRV_ALL)
install(FILES ${PROJECT_BINARY_DIR}/ffead-cpp DESTINATION ${PROJECT_NAME}-bin/)
diff --git a/Makefile.am b/Makefile.am
index 8e4827f47..986ad3576 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -249,6 +249,7 @@ if MOD_SDORM_MONGO
else
rm -rf ${prefix}/web/te-benchmark-um-pq
rm -rf ${prefix}/web/te-benchmark-um-pq-async
+ rm -rf ${prefix}/web/te-benchmark-um-pq-async-qw
endif
cp -Rf script/* ${prefix}/
-rm -f ${prefix}/lib/*.la ${prefix}/lib/*.lai
diff --git a/configure.ac b/configure.ac
index 9e3a2759f..478d2a1c6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1301,6 +1301,7 @@ AC_CONFIG_FILES([web/default/src/autotools/Makefile
web/te-benchmark-um/src/autotools/Makefile
web/te-benchmark-um-pq/src/autotools/Makefile
web/te-benchmark-um-pq-async/src/autotools/Makefile
+ web/te-benchmark-um-pq-async-qw/src/autotools/Makefile
web/te-benchmark-um-mgr/src/autotools/Makefile])
AC_OUTPUT
diff --git a/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework-forsql.sh b/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework-forsql.sh
index ddc6e3cd6..d3f4d23f2 100644
--- a/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework-forsql.sh
+++ b/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework-forsql.sh
@@ -45,6 +45,7 @@ sed -i 's|localhost|db|g' web/te-benchmark-um/config/sdormpostgresql.xml
sed -i 's|localhost|db|g' web/te-benchmark-um-mgr/config/sdorm.xml
sed -i 's|localhost|db|g' web/te-benchmark-um-pq/config/sdorm.xml
sed -i 's|localhost|db|g' web/te-benchmark-um-pq-async/config/sdorm.xml
+sed -i 's|localhost|db|g' web/te-benchmark-um-pq-async-qw/config/sdorm.xml
sed -i 's|127.0.0.1|db|g' resources/sample-odbcinst.ini
sed -i 's|127.0.0.1|db|g' resources/sample-odbc.ini
sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)||g' CMakeLists.txt
diff --git a/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework.sh b/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework.sh
index aa8ae2669..bef43e12e 100644
--- a/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework.sh
+++ b/docker/compose-techempower-tests/ffead-cpp/install_ffead-cpp-framework.sh
@@ -46,6 +46,7 @@ sed -i 's|localhost|db|g' web/te-benchmark-um/config/sdormpostgresql.xml
sed -i 's|localhost|db|g' web/te-benchmark-um-mgr/config/sdorm.xml
sed -i 's|localhost|db|g' web/te-benchmark-um-pq/config/sdorm.xml
sed -i 's|localhost|db|g' web/te-benchmark-um-pq-async/config/sdorm.xml
+sed -i 's|localhost|db|g' web/te-benchmark-um-pq-async-qw/config/sdorm.xml
sed -i 's|127.0.0.1|db|g' resources/sample-odbcinst.ini
sed -i 's|127.0.0.1|db|g' resources/sample-odbc.ini
sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)||g' CMakeLists.txt
diff --git a/docker/techempower-config/benchmark_config.json b/docker/techempower-config/benchmark_config.json
index b3f55ec6b..62603327d 100644
--- a/docker/techempower-config/benchmark_config.json
+++ b/docker/techempower-config/benchmark_config.json
@@ -1,27 +1,6 @@
{
"framework": "ffead-cpp",
"tests": [{
- "p3-b": {
- "db_url": "/te-benchmark-um-pq-async/db",
- "query_url": "/te-benchmark-um-pq-async/queries?queries=",
- "fortune_url": "/te-benchmark-um-pq-async/fortunes",
- "update_url": "/te-benchmark-um-pq-async/updates?queries=",
- "port": 8080,
- "approach": "Realistic",
- "classification": "Fullstack",
- "database": "postgres",
- "framework": "ffead-cpp",
- "language": "C++",
- "orm": "Raw",
- "platform": "None",
- "webserver": "ffead-cpp",
- "os": "Linux",
- "database_os": "Linux",
- "display_name": "ffead-cpp-p3-b",
- "notes": "async memory libpq batch patch profiled",
- "versus": "",
- "tags": []
- },
"v-picov": {
"json_url": "/te-benchmark-um-pq/json",
"plaintext_url": "/plaintext",
@@ -41,7 +20,7 @@
"webserver": "picov",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-v",
+ "display_name": "ffead-cpp [v]",
"notes": "",
"versus": "",
"tags": []
@@ -65,7 +44,7 @@
"webserver": "picov",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-v-prof",
+ "display_name": "ffead-cpp [v-prof]",
"notes": "",
"versus": "",
"tags": []
@@ -89,7 +68,7 @@
"webserver": "picov",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-v-prof-b",
+ "display_name": "ffead-cpp [v-prof-b]",
"notes": "",
"versus": "",
"tags": []
@@ -110,7 +89,7 @@
"webserver": "ffead-cpp",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-pg-raw-prof",
+ "display_name": "ffead-cpp [pg-raw-prof]",
"notes": "memory profiled",
"versus": "",
"tags": []
@@ -152,12 +131,12 @@
"webserver": "ffead-cpp",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-pg-raw-async-prof",
+ "display_name": "ffead-cpp [pg-raw-async-prof]",
"notes": "async memory profiled",
"versus": "",
"tags": []
},
- "postgresql-raw-async-pool-profiled": {
+ "postgresql-raw-async-clibpqb-profiled": {
"db_url": "/te-benchmark-um-pq-async/db",
"query_url": "/te-benchmark-um-pq-async/queries?queries=",
"fortune_url": "/te-benchmark-um-pq-async/fortunes",
@@ -173,8 +152,8 @@
"webserver": "ffead-cpp",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-pg-raw-async-prof-pool",
- "notes": "async memory profiled",
+ "display_name": "ffead-cpp [pg-raw-async-prof-b]",
+ "notes": "async memory libpq batch patch profiled",
"versus": "",
"tags": []
},
@@ -192,16 +171,16 @@
"webserver": "ffead-cpp",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-pg-raw-async-prof-pool-m",
+ "display_name": "ffead-cpp [pg-raw-async-prof-pool-m]",
"notes": "async memory profiled",
"versus": "",
"tags": []
},
- "postgresql-raw-async-clibpqb-profiled": {
- "db_url": "/te-benchmark-um-pq-async/db",
- "query_url": "/te-benchmark-um-pq-async/queries?queries=",
- "fortune_url": "/te-benchmark-um-pq-async/fortunes",
- "update_url": "/te-benchmark-um-pq-async/updates?queries=",
+ "postgresql-raw-async-qw-profiled": {
+ "db_url": "/te-benchmark-um-pq-async-qw/db",
+ "query_url": "/te-benchmark-um-pq-async-qw/queries?queries=",
+ "fortune_url": "/te-benchmark-um-pq-async-qw/fortunes",
+ "update_url": "/te-benchmark-um-pq-async-qw/updates?queries=",
"port": 8080,
"approach": "Realistic",
"classification": "Fullstack",
@@ -213,16 +192,16 @@
"webserver": "ffead-cpp",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-pg-raw-async-prof-b",
- "notes": "async memory libpq batch patch profiled",
+ "display_name": "ffead-cpp [pg-raw-async-qw-prof]",
+ "notes": "async memory profiled",
"versus": "",
"tags": []
},
- "postgresql-raw-async-clibpqb-pool-profiled": {
- "db_url": "/te-benchmark-um-pq-async/db",
- "query_url": "/te-benchmark-um-pq-async/queries?queries=",
- "fortune_url": "/te-benchmark-um-pq-async/fortunes",
- "update_url": "/te-benchmark-um-pq-async/updates?queries=",
+ "postgresql-raw-async-qw-clibpqb-profiled": {
+ "db_url": "/te-benchmark-um-pq-async-qw/db",
+ "query_url": "/te-benchmark-um-pq-async-qw/queries?queries=",
+ "fortune_url": "/te-benchmark-um-pq-async-qw/fortunes",
+ "update_url": "/te-benchmark-um-pq-async-qw/updates?queries=",
"port": 8080,
"approach": "Realistic",
"classification": "Fullstack",
@@ -234,10 +213,29 @@
"webserver": "ffead-cpp",
"os": "Linux",
"database_os": "Linux",
- "display_name": "ffead-cpp-pg-raw-async-prof-b-pool",
+ "display_name": "ffead-cpp [pg-raw-async-qw-prof-b]",
"notes": "async memory libpq batch patch profiled",
"versus": "",
"tags": []
+ },
+ "postgresql-raw-async-qw-pool-profiled-m": {
+ "query_url": "/te-benchmark-um-pq-async-qw/queriem?queries=",
+ "update_url": "/te-benchmark-um-pq-async-qw/updatem?queries=",
+ "port": 8080,
+ "approach": "Realistic",
+ "classification": "Fullstack",
+ "database": "postgres",
+ "framework": "ffead-cpp",
+ "language": "C++",
+ "orm": "Raw",
+ "platform": "None",
+ "webserver": "ffead-cpp",
+ "os": "Linux",
+ "database_os": "Linux",
+ "display_name": "ffead-cpp [pg-raw-async-qw-prof-pool-m]",
+ "notes": "async memory profiled",
+ "versus": "",
+ "tags": []
}
}]
-}
\ No newline at end of file
+}
diff --git a/docker/techempower-config/ffead-cpp-base-debug.dockerfile b/docker/techempower-config/ffead-cpp-base-debug.dockerfile
index b1927892d..2e9b546b2 100644
--- a/docker/techempower-config/ffead-cpp-base-debug.dockerfile
+++ b/docker/techempower-config/ffead-cpp-base-debug.dockerfile
@@ -12,7 +12,8 @@ RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selectio
#COPY te-benchmark-um/ /installs/te-benchmark-um/
#COPY te-benchmark-um-pq/ /installs/te-benchmark-um-pq/
#COPY te-benchmark-um-mgr/ /installs/te-benchmark-um-mgr/
-#COPY te-benchmark-um-mgr/ /installs/te-benchmark-um-pq-async/
+#COPY te-benchmark-um-pq-async/ /installs/te-benchmark-um-pq-async/
+#COPY te-benchmark-um-pq-async-qw/ /installs/te-benchmark-um-pq-async-qw/
WORKDIR ${IROOT}
diff --git a/docker/techempower-config/ffead-cpp-base.dockerfile b/docker/techempower-config/ffead-cpp-base.dockerfile
index 64f5bf8e4..8136d589f 100644
--- a/docker/techempower-config/ffead-cpp-base.dockerfile
+++ b/docker/techempower-config/ffead-cpp-base.dockerfile
@@ -12,7 +12,8 @@ RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selectio
#COPY te-benchmark-um/ /installs/te-benchmark-um/
#COPY te-benchmark-um-pq/ /installs/te-benchmark-um-pq/
#COPY te-benchmark-um-mgr/ /installs/te-benchmark-um-mgr/
-#COPY te-benchmark-um-mgr/ /installs/te-benchmark-um-pq-async/
+#COPY te-benchmark-um-pq-async/ /installs/te-benchmark-um-pq-async/
+#COPY te-benchmark-um-pq-async-qw/ /installs/te-benchmark-um-pq-async-qw/
WORKDIR ${IROOT}
diff --git a/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-clibpqb-profiled.dockerfile b/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-clibpqb-profiled.dockerfile
new file mode 100644
index 000000000..39fa5ceda
--- /dev/null
+++ b/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-clibpqb-profiled.dockerfile
@@ -0,0 +1,7 @@
+FROM sumeetchhetri/ffead-cpp-sql-raw-async-clibpqb-profiled-base:6.0
+
+ENV IROOT=/installs
+
+WORKDIR /
+
+CMD ./run_ffead.sh ffead-cpp-6.0-sql emb postgresql-raw-async-qw memory
diff --git a/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-pool-profiled-m.dockerfile b/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-pool-profiled-m.dockerfile
new file mode 100644
index 000000000..1c81c0d9e
--- /dev/null
+++ b/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-pool-profiled-m.dockerfile
@@ -0,0 +1,7 @@
+FROM sumeetchhetri/ffead-cpp-sql-raw-async-pool-profiled-base:6.0
+
+ENV IROOT=/installs
+
+WORKDIR /
+
+CMD ./run_ffead.sh ffead-cpp-6.0-sql emb postgresql-raw-async-qw memory
diff --git a/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-profiled.dockerfile b/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-profiled.dockerfile
new file mode 100644
index 000000000..fc1de0736
--- /dev/null
+++ b/docker/techempower-config/ffead-cpp-postgresql-raw-async-qw-profiled.dockerfile
@@ -0,0 +1,7 @@
+FROM sumeetchhetri/ffead-cpp-sql-raw-async-profiled-base:6.0
+
+ENV IROOT=/installs
+
+WORKDIR /
+
+CMD ./run_ffead.sh ffead-cpp-6.0-sql emb postgresql-raw-async-qw memory
diff --git a/docker/techempower-config/ffead-cpp-seastar-base.dockerfile b/docker/techempower-config/ffead-cpp-seastar-base.dockerfile
index 96d27508f..3cc136ff6 100644
--- a/docker/techempower-config/ffead-cpp-seastar-base.dockerfile
+++ b/docker/techempower-config/ffead-cpp-seastar-base.dockerfile
@@ -10,6 +10,7 @@ RUN rm -f /usr/local/lib/libffead-* /usr/local/lib/libte_benc* /usr/local/lib/li
ln -s ${IROOT}/ffead-cpp-6.0/lib/libte-benchmark-um-pq.so /usr/local/lib/libte-benchmark-um-pq.so && \
ln -s ${IROOT}/ffead-cpp-6.0/lib/libte-benchmark-um-mgr.so /usr/local/lib/libte-benchmark-um-mgr.so && \
ln -s ${IROOT}/ffead-cpp-6.0/lib/libte-benchmark-um-pq-async.so /usr/local/lib/libte-benchmark-um-pq-async.so && \
+ ln -s ${IROOT}/ffead-cpp-6.0/lib/libte-benchmark-um-pq-async-qw.so /usr/local/lib/libte-benchmark-um-pq-async-qw.so && \
ln -s ${IROOT}/ffead-cpp-6.0/lib/libffead-modules.so /usr/local/lib/libffead-modules.so && \
ln -s ${IROOT}/ffead-cpp-6.0/lib/libffead-framework.so /usr/local/lib/libffead-framework.so && \
ln -s ${IROOT}/ffead-cpp-6.0/lib/libinter.so /usr/local/lib/libinter.so && \
diff --git a/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-pool-profiled-base.dockerfile b/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-pool-profiled-base.dockerfile
index d02b57a97..7f3cf59bd 100644
--- a/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-pool-profiled-base.dockerfile
+++ b/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-pool-profiled-base.dockerfile
@@ -83,11 +83,6 @@ COPY sql-profiled-util.sh ${IROOT}/
RUN chmod 755 ${IROOT}/sql-profiled-util.sh
RUN ./sql-profiled-util.sh batch clang async pool
-#COPY TeBkUmLpqAsync.cpp ${IROOT}/ffead-cpp-src/web/te-benchmark-um-pq-async/src/
-#COPY TeBkUmLpqAsync.h ${IROOT}/ffead-cpp-src/web/te-benchmark-um-pq-async/include/
-#COPY LibpqDataSourceImpl.cpp ${IROOT}/ffead-cpp-src/src/modules/sdorm/sql/libpq/
-#COPY LibpqDataSourceImpl.h ${IROOT}/ffead-cpp-src/src/modules/sdorm/sql/libpq/
-
COPY sql-async-profiled-install-clang.sh install_ffead-cpp-sql-raw-profiled.sh ${IROOT}/
RUN chmod 755 ${IROOT}/sql-async-profiled-install-clang.sh ${IROOT}/install_ffead-cpp-sql-raw-profiled.sh
RUN ./sql-async-profiled-install-clang.sh batch
diff --git a/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-profiled-base.dockerfile b/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-profiled-base.dockerfile
index 589f89e57..38c674d7d 100644
--- a/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-profiled-base.dockerfile
+++ b/docker/techempower-config/ffead-cpp-sql-raw-async-clibpqb-profiled-base.dockerfile
@@ -83,11 +83,6 @@ COPY sql-profiled-util.sh ${IROOT}/
RUN chmod 755 ${IROOT}/sql-profiled-util.sh
RUN ./sql-profiled-util.sh batch clang async
-#COPY TeBkUmLpqAsync.cpp ${IROOT}/ffead-cpp-src/web/te-benchmark-um-pq-async/src/
-#COPY TeBkUmLpqAsync.h ${IROOT}/ffead-cpp-src/web/te-benchmark-um-pq-async/include/
-#COPY LibpqDataSourceImpl.cpp ${IROOT}/ffead-cpp-src/src/modules/sdorm/sql/libpq/
-#COPY LibpqDataSourceImpl.h ${IROOT}/ffead-cpp-src/src/modules/sdorm/sql/libpq/
-
COPY sql-async-profiled-install-clang.sh install_ffead-cpp-sql-raw-profiled.sh ${IROOT}/
RUN chmod 755 ${IROOT}/sql-async-profiled-install-clang.sh ${IROOT}/install_ffead-cpp-sql-raw-profiled.sh
RUN ./sql-async-profiled-install-clang.sh batch
diff --git a/docker/techempower-config/install_ffead-cpp-framework.sh b/docker/techempower-config/install_ffead-cpp-framework.sh
index 5c0baafa3..0ac91a59d 100644
--- a/docker/techempower-config/install_ffead-cpp-framework.sh
+++ b/docker/techempower-config/install_ffead-cpp-framework.sh
@@ -23,11 +23,13 @@ chmod 755 *.sh resources/*.sh rtdcf/autotools/*.sh
#rm -rf web/te-benchmark-um-pq
#rm -rf web/te-benchmark-um-mgr
#rm -rf web/te-benchmark-um-pq-async
+#rm -rf web/te-benchmark-um-pq-async-qw
mv ${IROOT}/server.sh script/
#mv ${IROOT}/te-benchmark-um web/
#mv ${IROOT}/te-benchmark-um-pq web/
#mv ${IROOT}/te-benchmark-um-mgr web/
#mv ${IROOT}/te-benchmark-um-pq-async web/
+#mv ${IROOT}/te-benchmark-um-pq-async-qw web/
sed -i 's|THRD_PSIZ=6|THRD_PSIZ='${SERV_THREADS}'|g' resources/server.prop
sed -i 's|W_THRD_PSIZ=2|W_THRD_PSIZ='${WRIT_THREADS}'|g' resources/server.prop
sed -i 's|ENABLE_CRS=true|ENABLE_CRS=false|g' resources/server.prop
@@ -54,6 +56,7 @@ sed -i 's|localhost|tfb-database|g' web/te-benchmark-um/config/sdormpostgresql.x
sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-pq/config/sdorm.xml
sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-mgr/config/sdorm.xml
sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-pq-async/config/sdorm.xml
+sed -i 's|localhost|tfb-database|g' web/te-benchmark-um-pq-async-qw/config/sdorm.xml
sed -i 's|127.0.0.1|tfb-database|g' resources/sample-odbcinst.ini
sed -i 's|127.0.0.1|tfb-database|g' resources/sample-odbc.ini
sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)||g' CMakeLists.txt
diff --git a/docker/techempower-config/install_ffead-cpp-sql-raw-profiled.sh b/docker/techempower-config/install_ffead-cpp-sql-raw-profiled.sh
index 5038e14e0..e6d4eb5a4 100644
--- a/docker/techempower-config/install_ffead-cpp-sql-raw-profiled.sh
+++ b/docker/techempower-config/install_ffead-cpp-sql-raw-profiled.sh
@@ -53,6 +53,18 @@ service postgresql start
sed -i 's|EVH_SINGLE=false|EVH_SINGLE=true|g' resources/server.prop
#sed -i 's|LOGGING_ENABLED=false|LOGGING_ENABLED=true|g' resources/server.prop
+
+if [ "$1" = "async" ]
+then
+ sed -i 's|REQUEST_HANDLER=RequestReaderHandler|REQUEST_HANDLER=RequestHandler2|g' resources/server.prop
+fi
+
+if [ "$1" = "async-qw" ]
+then
+ sed -i 's|REQUEST_HANDLER=RequestReaderHandler|REQUEST_HANDLER=RequestHandler2|g' resources/server.prop
+ sed -i 's|QUEUED_WRITES=false|QUEUED_WRITES=true|g' resources/server.prop
+fi
+
nohup bash -c "./server.sh > ffead.log &"
sleep 10
echo "ffead-cpp with sql-raw support launched"
@@ -76,6 +88,7 @@ wrk -H 'Host: localhost' -H 'Accept: application/json,text/html;q=0.9,applicatio
-H 'Connection: keep-alive' --latency -d 5 -c 512 --timeout 8 -t 2 "http://localhost:8080/te-benchmark-um-pq${SUFFIX}/updatem?queries=20"
wrk -H 'Host: localhost' -H 'Accept: application/json,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7' \
-H 'Connection: keep-alive' --latency -d 5 -c 512 --timeout 8 -t 2 "http://localhost:8080/te-benchmark-um-pq${SUFFIX}/update_?queries=20"
+
echo "normal shutdown"
rm -f serv.ctrl
pkill ffead-cpp
diff --git a/docker/techempower-config/run_ffead.sh b/docker/techempower-config/run_ffead.sh
index 3e0bdddf3..cbe2165ba 100644
--- a/docker/techempower-config/run_ffead.sh
+++ b/docker/techempower-config/run_ffead.sh
@@ -11,6 +11,7 @@ ln -s ${FFEAD_CPP_PATH}/lib/libte-benchmark-um.so /usr/local/lib/libte-benchmark
ln -s ${FFEAD_CPP_PATH}/lib/libte-benchmark-um-pq.so /usr/local/lib/libte-benchmark-um-pq.so
ln -s ${FFEAD_CPP_PATH}/lib/libte-benchmark-um-mgr.so /usr/local/lib/libte-benchmark-um-mgr.so
ln -s ${FFEAD_CPP_PATH}/lib/libte-benchmark-um-pq-async.so /usr/local/lib/libte-benchmark-um-pq-async.so
+ln -s ${FFEAD_CPP_PATH}/lib/libte-benchmark-um-pq-async-qw.so /usr/local/lib/libte-benchmark-um-pq-async-qw.so
ln -s ${FFEAD_CPP_PATH}/lib/libffead-modules.so /usr/local/lib/libffead-modules.so
ln -s ${FFEAD_CPP_PATH}/lib/libffead-framework.so /usr/local/lib/libffead-framework.so
ln -s ${FFEAD_CPP_PATH}/lib/libinter.so /usr/local/lib/libinter.so
@@ -46,35 +47,40 @@ service memcached stop
if [ "$3" = "mongo" ]
then
WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
- rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+ rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
cp -f ${WEB_DIR}/config/sdormmongo.xml ${WEB_DIR}/config/sdorm.xml
elif [ "$3" = "mongo-raw" ]
then
WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um-mgr
- rm -rf web/te-benchmark-um web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+ rm -rf web/te-benchmark-um web/te-benchmark-um-pq web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
elif [ "$3" = "mysql" ]
then
WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
- rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+ rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
cp -f ${WEB_DIR}/config/sdormmysql.xml ${WEB_DIR}/config/sdorm.xml
elif [ "$3" = "postgresql" ]
then
WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
- rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+ rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
cp -f web/te-benchmark-um/config/sdormpostgresql.xml web/te-benchmark-um/config/sdorm.xml
elif [ "$3" = "postgresql-raw" ]
then
WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um-pq
- rm -rf web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq-async
+ rm -rf web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
sed -i 's|true|false|g' ${WEB_DIR}/config/sdorm.xml
elif [ "$3" = "postgresql-raw-async" ]
then
WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um-pq-async
- rm -rf web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq
+ rm -rf web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async-qw
+ sed -i 's|false|true|g' ${WEB_DIR}/config/sdorm.xml
+elif [ "$3" = "postgresql-raw-async-qw" ]
+then
+ WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um-pq-async-qw
+ rm -rf web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
sed -i 's|false|true|g' ${WEB_DIR}/config/sdorm.xml
else
WEB_DIR=$FFEAD_CPP_PATH/web/te-benchmark-um
- rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+ rm -rf web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
fi
if [ "$4" = "memory" ]
@@ -104,6 +110,11 @@ chmod 700 rtdcf/*
if [ "$2" = "emb" ]
then
sed -i 's|EVH_SINGLE=false|EVH_SINGLE=true|g' resources/server.prop
+ sed -i 's|REQUEST_HANDLER=RequestReaderHandler|REQUEST_HANDLER=RequestHandler2|g' $FFEAD_CPP_PATH/resources/server.prop
+ if [ "$3" = "postgresql-raw-async-qw" ]
+ then
+ sed -i 's|QUEUED_WRITES=false|QUEUED_WRITES=true|g' $FFEAD_CPP_PATH/resources/server.prop
+ fi
for i in $(seq 0 $(($(nproc --all)-1))); do
taskset -c $i ./ffead-cpp $FFEAD_CPP_PATH &
done
@@ -205,7 +216,6 @@ then
cd ${IROOT}
sed -i 's|"TeBkUmLpqRouter"|"TeBkUmLpqRouterPicoV"|g' ${WEB_DIR}/config/application.xml
sed -i 's|EVH_SINGLE=false|EVH_SINGLE=true|g' $FFEAD_CPP_PATH/resources/server.prop
- sed -i 's|REQUEST_HANDLER=RequestReaderHandler|REQUEST_HANDLER=RequestHandler2|g' $FFEAD_CPP_PATH/resources/server.prop
for i in $(seq 0 $(($(nproc --all)-1))); do
taskset -c $i ./main --server_dir=$FFEAD_CPP_PATH --server_port=8080 &
done
diff --git a/docker/techempower-config/sql-async-profiled-install-clang-dbg.sh b/docker/techempower-config/sql-async-profiled-install-clang-dbg.sh
index 3b978e368..79eb5ea28 100644
--- a/docker/techempower-config/sql-async-profiled-install-clang-dbg.sh
+++ b/docker/techempower-config/sql-async-profiled-install-clang-dbg.sh
@@ -15,7 +15,9 @@ sed -i 's|cmake |CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake |g' $IROOT/ffead-c
#sed -i 's|-fprofile-instr-generate=/tmp/cprof.prof|-fprofile-instr-generate=/tmp/cprofdi.prof|g' $IROOT/ffead-cpp-sql-raw/rtdcf/CMakeLists.txt.template
apt update -yqq && apt install -yqq vim gdb net-tools telnet iputils-ping
./install_ffead-cpp-sql-raw-profiled.sh async
+./install_ffead-cpp-sql-raw-profiled.sh async-qw
#mv $IROOT/ffead-cpp-sql-raw $IROOT/ffead-cpp-6.0-sql
#sed -i 's|localhost|tfb-database|g' $IROOT/ffead-cpp-6.0-sql/web/te-benchmark-um-pq-async/config/sdorm.xml
+#sed -i 's|localhost|tfb-database|g' $IROOT/ffead-cpp-6.0-sql/web/te-benchmark-um-pq-async-qw/config/sdorm.xml
diff --git a/docker/techempower-config/sql-async-profiled-install-clang.sh b/docker/techempower-config/sql-async-profiled-install-clang.sh
index 1e94a15b7..ab2f407c0 100644
--- a/docker/techempower-config/sql-async-profiled-install-clang.sh
+++ b/docker/techempower-config/sql-async-profiled-install-clang.sh
@@ -14,6 +14,7 @@ cd $IROOT/
sed -i 's|cmake |CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake |g' $IROOT/ffead-cpp-sql-raw/resources/rundyn-automake.sh
#sed -i 's|-fprofile-instr-generate=/tmp/cprof.prof|-fprofile-instr-generate=/tmp/cprofdi.prof|g' $IROOT/ffead-cpp-sql-raw/rtdcf/CMakeLists.txt.template
./install_ffead-cpp-sql-raw-profiled.sh async
+./install_ffead-cpp-sql-raw-profiled.sh async-qw
rm -rf $IROOT/ffead-cpp-sql-raw
cd $IROOT/ffead-cpp-src
@@ -34,9 +35,11 @@ cd $IROOT/
sed -i 's|cmake |CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake |g' $IROOT/ffead-cpp-sql-raw/resources/rundyn-automake.sh
#sed -i 's|-fprofile-instr-use=/tmp/cprof.pgo|-fprofile-instr-use=/tmp/cprofdi.pgo|g' $IROOT/ffead-cpp-sql-raw/rtdcf/CMakeLists.txt.template
./install_ffead-cpp-sql-raw-profiled.sh async
+./install_ffead-cpp-sql-raw-profiled.sh async-qw
mv $IROOT/ffead-cpp-sql-raw $IROOT/ffead-cpp-6.0-sql
sed -i 's|localhost|tfb-database|g' $IROOT/ffead-cpp-6.0-sql/web/te-benchmark-um-pq-async/config/sdorm.xml
+sed -i 's|localhost|tfb-database|g' $IROOT/ffead-cpp-6.0-sql/web/te-benchmark-um-pq-async-qw/config/sdorm.xml
apt remove -yqq postgresql-13 postgresql-contrib-13 gnupg lsb-release
apt autoremove -yqq
diff --git a/docker/techempower-config/sql-async-profiled-install.sh b/docker/techempower-config/sql-async-profiled-install.sh
index df1a2d184..3e50afcbf 100644
--- a/docker/techempower-config/sql-async-profiled-install.sh
+++ b/docker/techempower-config/sql-async-profiled-install.sh
@@ -13,6 +13,7 @@ service postgresql stop
cd $IROOT/
#sed -i 's|cmake |cmake -DCMAKE_EXE_LINKER_FLAGS="-fprofile-dir=/tmp/profile-data -fprofile-generate" -DCMAKE_CXX_FLAGS="-march=native -fprofile-dir=/tmp/profile-data -fprofile-generate" |g' $IROOT/ffead-cpp-sql-raw/resources/rundyn-automake.sh
./install_ffead-cpp-sql-raw-profiled.sh async
+./install_ffead-cpp-sql-raw-profiled.sh async-qw
rm -rf $IROOT/ffead-cpp-sql-raw
cd $IROOT/ffead-cpp-src
@@ -29,9 +30,11 @@ service postgresql stop
cd $IROOT/
#sed -i 's|cmake |CXXFLAGS="-march=native -fprofile-dir=/tmp/profile-data -fprofile-use -fprofile-correction" cmake |g' $IROOT/ffead-cpp-sql-raw/resources/rundyn-automake.sh
./install_ffead-cpp-sql-raw-profiled.sh async
+./install_ffead-cpp-sql-raw-profiled.sh async-qw
mv $IROOT/ffead-cpp-sql-raw $IROOT/ffead-cpp-6.0-sql
sed -i 's|localhost|tfb-database|g' $IROOT/ffead-cpp-6.0-sql/web/te-benchmark-um-pq-async/config/sdorm.xml
+sed -i 's|localhost|tfb-database|g' $IROOT/ffead-cpp-6.0-sql/web/te-benchmark-um-pq-async-qw/config/sdorm.xml
apt remove -yqq postgresql-13 postgresql-contrib-13 gnupg lsb-release
apt autoremove -yqq
diff --git a/docker/techempower-config/sql-profiled-util.sh b/docker/techempower-config/sql-profiled-util.sh
index f964d42c2..048092b92 100644
--- a/docker/techempower-config/sql-profiled-util.sh
+++ b/docker/techempower-config/sql-profiled-util.sh
@@ -63,15 +63,19 @@ then
sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq)||g' CMakeLists.txt
sed -i 's|install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq/libte-benchmark-um-pq${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
sed -i 's|tfb-database|localhost|g' $IROOT/ffead-cpp-src/web/te-benchmark-um-pq-async/config/sdorm.xml
+ sed -i 's|tfb-database|localhost|g' $IROOT/ffead-cpp-src/web/te-benchmark-um-pq-async-qw/config/sdorm.xml
rm -rf web/te-benchmark-um-pq
if [ "$4" = "pool" ]
then
sed -i 's|"TeBkUmLpqAsyncRouter"|"TeBkUmLpqAsyncRouterPooled"|g' $IROOT/ffead-cpp-src/web/te-benchmark-um-pq-async/config/application.xml
sed -i 's|TeBkUmLpqAsyncRouter|TeBkUmLpqAsyncRouterPooled|g' $IROOT/ffead-cpp-src/web/te-benchmark-um-pq-async/config/cachememory.xml
+ sed -i 's|"TeBkUmLpqQwAsyncRouter"|"TeBkUmLpqQwAsyncRouterPooled"|g' $IROOT/ffead-cpp-src/web/te-benchmark-um-pq-async-qw/config/application.xml
fi
else
sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async)||g' CMakeLists.txt
sed -i 's|install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async/libte-benchmark-um-pq-async${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
+ sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async-qw)||g' CMakeLists.txt
+ sed -i 's|install(FILES ${PROJECT_BINARY_DIR}/web/te-benchmark-um-pq-async-qw/libte-benchmark-um-pq-async-qw${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
sed -i 's|tfb-database|localhost|g' $IROOT/ffead-cpp-src/web/te-benchmark-um-pq/config/sdorm.xml
- rm -rf web/te-benchmark-um-pq-async
+ rm -rf web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
fi
\ No newline at end of file
diff --git a/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest b/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest
index fe6857191..037394be5 100644
--- a/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest
+++ b/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest
@@ -212,6 +212,7 @@ RUN ninja install && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-mongo-raw
WORKDIR /tmp/ffead-cpp-src/build
@@ -220,6 +221,7 @@ RUN ninja install && \
cp -f /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um/config/cacheredis.xml /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um/config/cache.xml && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-mongo-orm
@@ -229,6 +231,7 @@ RUN ninja install && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-sql-raw
WORKDIR /tmp/ffead-cpp-src/build
@@ -241,6 +244,7 @@ RUN cp -f /tmp/ffead-cpp-src/web/te-benchmark-um/sql-src/TeBkUmWorldsql.h /tmp/f
cp /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/resources/sample-odbc.ini /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/resources/odbc.ini && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-sql-orm
diff --git a/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest-nb b/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest-nb
index 9dcdb08da..eb86b979a 100644
--- a/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest-nb
+++ b/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest-nb
@@ -197,6 +197,7 @@ RUN ninja install && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-mongo-raw
WORKDIR /tmp/ffead-cpp-src/build
@@ -205,6 +206,7 @@ RUN ninja install && \
cp -f /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um/config/cacheredis.xml /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um/config/cache.xml && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-mongo-orm
@@ -214,6 +216,7 @@ RUN ninja install && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-sql-raw
WORKDIR /tmp/ffead-cpp-src/build
@@ -226,6 +229,7 @@ RUN cp -f /tmp/ffead-cpp-src/web/te-benchmark-um/sql-src/TeBkUmWorldsql.h /tmp/f
cp /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/resources/sample-odbc.ini /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/resources/odbc.ini && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-sql-orm
diff --git a/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest_localhost b/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest_localhost
index fbeb18bfe..548bc6df3 100644
--- a/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest_localhost
+++ b/docker/test/DockerFile-UbuntuBionic-x64-ffead-cpp-fortest_localhost
@@ -92,6 +92,7 @@ RUN ninja install && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-mongo-raw
WORKDIR /tmp/ffead-cpp-src/build
@@ -100,6 +101,7 @@ RUN ninja install && \
cp -f /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um/config/cacheredis.xml /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um/config/cache.xml && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-mongo-orm
@@ -109,6 +111,7 @@ RUN ninja install && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-sql-raw
WORKDIR /tmp/ffead-cpp-src/build
@@ -121,6 +124,7 @@ RUN cp -f /tmp/ffead-cpp-src/web/te-benchmark-um/sql-src/TeBkUmWorldsql.h /tmp/f
cp /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/resources/sample-odbc.ini /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/resources/odbc.ini && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async && \
+ rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-pq-async-qw && \
rm -rf /tmp/ffead-cpp-src/ffead-cpp-6.0-bin/web/te-benchmark-um-mgr && \
mv /tmp/ffead-cpp-src/ffead-cpp-6.0-bin /tmp/ffead-cpp-sql-orm
diff --git a/docker/test/mongodb/create.js b/docker/test/mongodb/create.js
index 31de0e8a8..dc1a1e6ca 100644
--- a/docker/test/mongodb/create.js
+++ b/docker/test/mongodb/create.js
@@ -1,4 +1,4 @@
-use hello_world
+db = db.getSiblingDB('hello_world')
db.world.drop()
for (var i = 1; i <= 10000; i++) {
db.world.save( { _id: i, id: i, randomNumber: Math.min(Math.floor(Math.random() * 10000) + 1, 10000) })
diff --git a/docker/test/mysql/create.sql b/docker/test/mysql/create.sql
index ed15cb5ff..f1a5756d2 100644
--- a/docker/test/mysql/create.sql
+++ b/docker/test/mysql/create.sql
@@ -2,6 +2,15 @@
# http://stackoverflow.com/questions/37719818/the-server-time-zone-value-aest-is-unrecognized-or-represents-more-than-one-ti
SET GLOBAL time_zone = '+00:00';
+CREATE USER 'benchmarkdbuser'@'%' IDENTIFIED WITH mysql_native_password BY 'benchmarkdbpass';
+CREATE USER 'benchmarkdbuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'benchmarkdbpass';
+
+-- GitHub Actions/CI run the database server on the same system as the benchmarks.
+-- Because we setup MySQL with the skip-name-resolve option, the IP address 127.0.0.1 might not be resolved to localhost
+-- anymore. This does not seem to matter, as long as Unix sockets are being used (e.g. when setting up the docker image),
+-- because the host is set to be localhost implicitly, but it matters for local TCP connections.
+CREATE USER 'benchmarkdbuser'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'benchmarkdbpass';
+
# modified from SO answer http://stackoverflow.com/questions/5125096/for-loop-in-mysql
CREATE DATABASE hello_world;
USE hello_world;
@@ -12,10 +21,9 @@ CREATE TABLE world (
PRIMARY KEY (id)
)
ENGINE=INNODB;
-CREATE USER 'benchmarkdbuser'@'%' IDENTIFIED WITH mysql_native_password BY 'benchmarkdbpass';
-CREATE USER 'benchmarkdbuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'benchmarkdbpass';
GRANT ALL PRIVILEGES ON hello_world.world TO 'benchmarkdbuser'@'%';
GRANT ALL PRIVILEGES ON hello_world.world TO 'benchmarkdbuser'@'localhost';
+GRANT ALL PRIVILEGES ON hello_world.world TO 'benchmarkdbuser'@'127.0.0.1';
DELIMITER #
CREATE PROCEDURE load_data()
@@ -46,6 +54,7 @@ CREATE TABLE fortune (
ENGINE=INNODB;
GRANT ALL PRIVILEGES ON hello_world.fortune TO 'benchmarkdbuser'@'%';
GRANT ALL PRIVILEGES ON hello_world.fortune TO 'benchmarkdbuser'@'localhost';
+GRANT ALL PRIVILEGES ON hello_world.fortune TO 'benchmarkdbuser'@'127.0.0.1';
INSERT INTO fortune (message) VALUES ('fortune: No such file or directory');
INSERT INTO fortune (message) VALUES ('A computer scientist is someone who fixes things that aren''t broken.');
diff --git a/docker/test/postgresql/pg_hba.conf b/docker/test/postgresql/pg_hba.conf
index ca7334d74..ac4b3621d 100644
--- a/docker/test/postgresql/pg_hba.conf
+++ b/docker/test/postgresql/pg_hba.conf
@@ -97,4 +97,4 @@ host all all ::1/128 md5
#local replication postgres peer
#host replication postgres 127.0.0.1/32 md5
#host replication postgres ::1/128 md5
-host all all 0.0.0.0/0 md5
\ No newline at end of file
+host all all 0.0.0.0/0 md5
diff --git a/docker/test/postgresql/pgdg.list b/docker/test/postgresql/pgdg.list
index 2fa46e28c..64b218835 100644
--- a/docker/test/postgresql/pgdg.list
+++ b/docker/test/postgresql/pgdg.list
@@ -1,2 +1,2 @@
deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
-deb-src http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
\ No newline at end of file
+deb-src http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
diff --git a/docker/test/postgresql/postgresql.conf b/docker/test/postgresql/postgresql.conf
index e6abe3799..5a5f2eb1e 100644
--- a/docker/test/postgresql/postgresql.conf
+++ b/docker/test/postgresql/postgresql.conf
@@ -40,9 +40,9 @@
data_directory = '/ssd/postgresql' # use data in another directory
# (change requires restart)
-hba_file = '/etc/postgresql/13/main/pg_hba.conf' # host-based authentication file
+hba_file = '/etc/postgresql/14/main/pg_hba.conf' # host-based authentication file
# (change requires restart)
-ident_file = '/etc/postgresql/13/main/pg_ident.conf' # ident configuration file
+ident_file = '/etc/postgresql/14/main/pg_ident.conf' # ident configuration file
# (change requires restart)
# If external_pid_file is not explicitly set, no extra PID file is written.
@@ -574,4 +574,4 @@ max_pred_locks_per_transaction = 256 # min 10
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------
-#custom_variable_classes = '' # list of custom variable class names
\ No newline at end of file
+#custom_variable_classes = '' # list of custom variable class names
diff --git a/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp b/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp
index 887134c85..eb36f8be1 100644
--- a/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp
+++ b/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp
@@ -28,7 +28,7 @@ RUN mv ffead-cpp-master ffead-cpp-src
RUN rm -f master.zip
WORKDIR /tmp/ffead-cpp-src
-RUN rm -rf web/default web/oauthApp web/flexApp web/markers web/te-benchmark web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+RUN rm -rf web/default web/oauthApp web/flexApp web/markers web/te-benchmark web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/flexApp)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/oauthApp)||g' CMakeLists.txt
@@ -38,6 +38,7 @@ RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um)||g' CM
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-mgr)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async)||g' CMakeLists.txt
+RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async-qw)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/default/libdefault${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/flexApp/libflexApp${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/oauthApp/liboauthApp${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
@@ -47,6 +48,7 @@ RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um/libte-benc
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-mgr/libte-benchmark-um-mgr${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq/libte-benchmark-um-pq${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async/libte-benchmark-um-pq-async${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
+RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async-qw/libte-benchmark-um-pq-async-qw${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|web/default/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/flexApp/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/oauthApp/src/autotools/Makefile||g' configure.ac
@@ -56,6 +58,7 @@ RUN sed -i 's|web/te-benchmark-um/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/te-benchmark-um-mgr/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/te-benchmark-um-pq/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/te-benchmark-um-pq-async/src/autotools/Makefile||g' configure.ac
+RUN sed -i 's|web/te-benchmark-um-pq-async-qw/src/autotools/Makefile||g' configure.ac
RUN cmake -DSRV_EMB=on -DMOD_REDIS=on -DMOD_SDORM_MONGO=on .
RUN make install -j4
diff --git a/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp_autoconf b/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp_autoconf
index 434fc581c..f128d928c 100644
--- a/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp_autoconf
+++ b/docker/webrtc-peerjs/DockerFile-UbuntuBionic-x64-ffead-cpp_autoconf
@@ -28,7 +28,7 @@ RUN mv ffead-cpp-master ffead-cpp-src
RUN rm -f master.zip
WORKDIR /tmp/ffead-cpp-src
-RUN rm -rf web/default web/oauthApp web/flexApp web/markers web/te-benchmark web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async
+RUN rm -rf web/default web/oauthApp web/flexApp web/markers web/te-benchmark web/te-benchmark-um web/te-benchmark-um-mgr web/te-benchmark-um-pq web/te-benchmark-um-pq-async web/te-benchmark-um-pq-async-qw
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/default)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/flexApp)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/oauthApp)||g' CMakeLists.txt
@@ -38,6 +38,7 @@ RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um)||g' CM
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-mgr)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq)||g' CMakeLists.txt
RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async)||g' CMakeLists.txt
+RUN sed -i 's|add_subdirectory(${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async-qw)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/default/libdefault${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/flexApp/libflexApp${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/oauthApp/liboauthApp${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
@@ -47,6 +48,7 @@ RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um/libte-benc
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-mgr/libte-benchmark-um-mgr${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq/libte-benchmark-um-pq${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async/libte-benchmark-um-pq-async${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
+RUN sed -i 's|install(FILES ${PROJECT_SOURCE_DIR}/web/te-benchmark-um-pq-async-qw/libte-benchmark-um-pq-async-qw${LIB_EXT} DESTINATION ${PROJECT_NAME}-bin/lib)||g' CMakeLists.txt
RUN sed -i 's|web/default/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/flexApp/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/oauthApp/src/autotools/Makefile||g' configure.ac
@@ -56,6 +58,7 @@ RUN sed -i 's|web/te-benchmark-um/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/te-benchmark-um-mgr/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/te-benchmark-um-pq/src/autotools/Makefile||g' configure.ac
RUN sed -i 's|web/te-benchmark-um-pq-async/src/autotools/Makefile||g' configure.ac
+RUN sed -i 's|web/te-benchmark-um-pq-async-qw/src/autotools/Makefile||g' configure.ac
RUN chmod +x autogen.sh
RUN ./autogen.sh
diff --git a/meson.build b/meson.build
index a7ac844f8..7709e75a2 100644
--- a/meson.build
+++ b/meson.build
@@ -339,6 +339,7 @@ endif
if get_option('MOD_SDORM_SQL') == true
subdir('web/te-benchmark-um-pq')
subdir('web/te-benchmark-um-pq-async')
+ subdir('web/te-benchmark-um-pq-async-qw')
endif
emb_includes = ['src/modules/common','src/modules/cache','src/modules/cache/memory','src/modules/cache/redis',
diff --git a/resources/server.prop b/resources/server.prop
index 2a8a664c8..120f72886 100644
--- a/resources/server.prop
+++ b/resources/server.prop
@@ -107,4 +107,4 @@ ENABLE_STATIC_RESP=true
STATIC_PATH_RESP=/plaintext|text/plain|Hello, World!
REQUEST_HANDLER=RequestReaderHandler
-
+QUEUED_WRITES=false
diff --git a/script/server.sh b/script/server.sh
index 0925e2fa6..18bd636ef 100644
--- a/script/server.sh
+++ b/script/server.sh
@@ -4,10 +4,10 @@ export MALLOC_CHECK_=0
IS_OS_DARWIN=`uname|tr '[A-Z]' '[a-z]'|awk 'index($0,"darwin") != 0 {print "darwin"}'`
IS_BSD=`uname|tr '[A-Z]' '[a-z]'|awk 'index($0,"bsd") != 0 {print "bsd"}'`
if [ "$IS_OS_DARWIN" != "" ]; then
- alias nproc="sysctl -n hw.ncpu"
+ #alias nproc="sysctl -n hw.ncpu"
export FFEAD_CPP_PATH=`cd "$(dirname server.sh)" && ABSPATH=$(pwd) && cd -`
elif [ "$IS_BSD" != "" ]; then
- alias nproc="sysctl -n hw.ncpu"
+ #alias nproc="sysctl -n hw.ncpu"
export FFEAD_CPP_PATH=`echo $(dirname $(readlink -f $0))`
else
export FFEAD_CPP_PATH=`echo $(dirname $(readlink -f $0))`
diff --git a/src/modules/common/AppDefines.h b/src/modules/common/AppDefines.h
index a13ba4d9b..04134750a 100644
--- a/src/modules/common/AppDefines.h
+++ b/src/modules/common/AppDefines.h
@@ -14,15 +14,15 @@
limitations under the License.
*/
-#define BUILD_MESON 1
+#define BUILD_CMAKE 1
-/* #undef INC_MEMORYCACHE */
-#define INC_REDISCACHE 1
-#define INC_MEMCACHED 1
+#define INC_MEMORYCACHE 1
+/* #undef INC_REDISCACHE */
+/* #undef INC_MEMCACHED */
#define INC_SDORM 1
#define INC_SDORM_SQL 1
#define INC_SDORM_MONGO 1
-#define INC_BINSER 1
+/* #undef INC_BINSER */
#define INC_JOBS 1
#define APPLE 1
/* #undef MINGW */
@@ -39,26 +39,26 @@
/* #undef USE_WIN_IOCP */
/* #undef USE_IO_URING */
-#define HAVE_LIBPQ 1
+#define HAVE_LIBPQ /usr/local/lib/libpq.dylib
#define HAVE_REGEX 1
-/* #undef HAVE_SSLINC */
-#define HAVE_SSLLIB 1
-#define HAVE_REDISINC 1
-#define HAVE_REDISLIB 1
-#define HAVE_MEMCACHEDINC 1
-#define HAVE_MEMCACHEDLIB 1
-#define HAVE_CURLLIB 1
+#define HAVE_SSLINC 1
+#define HAVE_SSLLIB /usr/local/opt/openssl/lib/libssl.dylib
+/* #undef HAVE_REDISINC */
+/* #undef HAVE_REDISLIB */
+/* #undef HAVE_MEMCACHEDINC */
+/* #undef HAVE_MEMCACHEDLIB */
+#define HAVE_CURLLIB /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.0.sdk/usr/lib/libcurl.tbd
#define HAVE_EXECINFOINC 1
-/* #undef HAVE_UUIDINC */
+#define HAVE_UUIDINC 1
/* #undef HAVE_OSSPUUIDINC */
/* #undef HAVE_OSSPUUIDINC_2 */
/* #undef HAVE_BSDUUIDINC */
#define HAVE_SQLINC 1
-#define HAVE_ODBCLIB 1
+#define HAVE_ODBCLIB /usr/local/lib/libodbc.dylib
#define HAVE_MONGOINC 1
-#define HAVE_MONGOCLIB 1
+#define HAVE_MONGOCLIB /usr/local/lib/libmongoc-1.0.dylib
#define HAVE_BSONINC 1
-#define HAVE_BSONLIB 1
+#define HAVE_BSONLIB /usr/local/lib/libbson-1.0.dylib
#define INC_JOBS 1
/* #undef OS_BSD */
/* #undef OS_SOLARIS */
@@ -78,8 +78,8 @@
/* #undef HAVE_LIBPQ_BATCH */
/* #undef HAVE_LIBPQ_PIPELINE */
/* #undef IS_SENDFILE */
-#define HAVE_RAPID_JSON 1
-#define HAVE_PUGI_XML 1
+/* #undef HAVE_RAPID_JSON */
+/* #undef HAVE_PUGI_XML */
/* #undef HAVE_SYSINFO */
#ifdef HAVE_ODBCLIB
@@ -91,6 +91,7 @@
#define INC_DVIEW 1
#define INC_DCP 1
#define INC_XMLSER 1
+#define BUILD_CMAKE 1
#ifdef APPLE
#define OS_DARWIN 1
diff --git a/src/modules/common/blockingconcurrentqueue.h b/src/modules/common/blockingconcurrentqueue.h
index 0d66284fe..66579b6ca 100644
--- a/src/modules/common/blockingconcurrentqueue.h
+++ b/src/modules/common/blockingconcurrentqueue.h
@@ -1,419 +1,23 @@
// Provides an efficient blocking version of moodycamel::ConcurrentQueue.
-// ©2015-2016 Cameron Desrochers. Distributed under the terms of the simplified
+// ©2015-2020 Cameron Desrochers. Distributed under the terms of the simplified
// BSD license, available at the top of concurrentqueue.h.
+// Also dual-licensed under the Boost Software License (see LICENSE.md)
// Uses Jeff Preshing's semaphore implementation (under the terms of its
-// separate zlib license, embedded below).
+// separate zlib license, see lightweightsemaphore.h).
#pragma once
#include "concurrentqueue.h"
+#include "lightweightsemaphore.h"
+
#include
#include
#include
#include
#include
-#if defined(_WIN32)
-// Avoid including windows.h in a header; we only need a handful of
-// items, so we'll redeclare them here (this is relatively safe since
-// the API generally has to remain stable between Windows versions).
-// I know this is an ugly hack but it still beats polluting the global
-// namespace with thousands of generic names or adding a .cpp for nothing.
-extern "C" {
- struct _SECURITY_ATTRIBUTES;
- __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes, long lInitialCount, long lMaximumCount, const wchar_t* lpName);
- __declspec(dllimport) int __stdcall CloseHandle(void* hObject);
- __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void* hHandle, unsigned long dwMilliseconds);
- __declspec(dllimport) int __stdcall ReleaseSemaphore(void* hSemaphore, long lReleaseCount, long* lpPreviousCount);
-}
-#elif defined(__MACH__)
-#include
-#elif defined(__unix__)
-#include
-#endif
-
namespace moodycamel
{
-namespace details
-{
- // Code in the mpmc_sema namespace below is an adaptation of Jeff Preshing's
- // portable + lightweight semaphore implementations, originally from
- // https://github.com/preshing/cpp11-on-multicore/blob/master/common/sema.h
- // LICENSE:
- // Copyright (c) 2015 Jeff Preshing
- //
- // This software is provided 'as-is', without any express or implied
- // warranty. In no event will the authors be held liable for any damages
- // arising from the use of this software.
- //
- // Permission is granted to anyone to use this software for any purpose,
- // including commercial applications, and to alter it and redistribute it
- // freely, subject to the following restrictions:
- //
- // 1. The origin of this software must not be misrepresented; you must not
- // claim that you wrote the original software. If you use this software
- // in a product, an acknowledgement in the product documentation would be
- // appreciated but is not required.
- // 2. Altered source versions must be plainly marked as such, and must not be
- // misrepresented as being the original software.
- // 3. This notice may not be removed or altered from any source distribution.
- namespace mpmc_sema
- {
-#if defined(_WIN32)
- class Semaphore
- {
- private:
- void* m_hSema;
-
- Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
- Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
-
- public:
- Semaphore(int initialCount = 0)
- {
- assert(initialCount >= 0);
- const long maxLong = 0x7fffffff;
- m_hSema = CreateSemaphoreW(nullptr, initialCount, maxLong, nullptr);
- }
-
- ~Semaphore()
- {
- CloseHandle(m_hSema);
- }
-
- void wait()
- {
- const unsigned long infinite = 0xffffffff;
- WaitForSingleObject(m_hSema, infinite);
- }
-
- bool try_wait()
- {
- const unsigned long RC_WAIT_TIMEOUT = 0x00000102;
- return WaitForSingleObject(m_hSema, 0) != RC_WAIT_TIMEOUT;
- }
-
- bool timed_wait(std::uint64_t usecs)
- {
- const unsigned long RC_WAIT_TIMEOUT = 0x00000102;
- return WaitForSingleObject(m_hSema, (unsigned long)(usecs / 1000)) != RC_WAIT_TIMEOUT;
- }
-
- void signal(int count = 1)
- {
- ReleaseSemaphore(m_hSema, count, nullptr);
- }
- };
-#elif defined(__MACH__)
- //---------------------------------------------------------
- // Semaphore (Apple iOS and OSX)
- // Can't use POSIX semaphores due to http://lists.apple.com/archives/darwin-kernel/2009/Apr/msg00010.html
- //---------------------------------------------------------
- class Semaphore
- {
- private:
- semaphore_t m_sema;
-
- Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
- Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
-
- public:
- Semaphore(int initialCount = 0)
- {
- assert(initialCount >= 0);
- semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
- }
-
- ~Semaphore()
- {
- semaphore_destroy(mach_task_self(), m_sema);
- }
-
- void wait()
- {
- semaphore_wait(m_sema);
- }
-
- bool try_wait()
- {
- return timed_wait(0);
- }
-
- bool timed_wait(std::uint64_t timeout_usecs)
- {
- mach_timespec_t ts;
- ts.tv_sec = static_cast(timeout_usecs / 1000000);
- ts.tv_nsec = (timeout_usecs % 1000000) * 1000;
-
- // added in OSX 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/modules/Darwin.html
- kern_return_t rc = semaphore_timedwait(m_sema, ts);
-
- return rc != KERN_OPERATION_TIMED_OUT && rc != KERN_ABORTED;
- }
-
- void signal()
- {
- semaphore_signal(m_sema);
- }
-
- void signal(int count)
- {
- while (count-- > 0)
- {
- semaphore_signal(m_sema);
- }
- }
- };
-#elif defined(__unix__)
- //---------------------------------------------------------
- // Semaphore (POSIX, Linux)
- //---------------------------------------------------------
- class Semaphore
- {
- private:
- sem_t m_sema;
-
- Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
- Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
-
- public:
- Semaphore(int initialCount = 0)
- {
- assert(initialCount >= 0);
- sem_init(&m_sema, 0, initialCount);
- }
-
- ~Semaphore()
- {
- sem_destroy(&m_sema);
- }
-
- void wait()
- {
- // http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error
- int rc;
- do {
- rc = sem_wait(&m_sema);
- } while (rc == -1 && errno == EINTR);
- }
-
- bool try_wait()
- {
- int rc;
- do {
- rc = sem_trywait(&m_sema);
- } while (rc == -1 && errno == EINTR);
- return !(rc == -1 && errno == EAGAIN);
- }
-
- bool timed_wait(std::uint64_t usecs)
- {
- struct timespec ts;
- const int usecs_in_1_sec = 1000000;
- const int nsecs_in_1_sec = 1000000000;
- clock_gettime(CLOCK_REALTIME, &ts);
- ts.tv_sec += usecs / usecs_in_1_sec;
- ts.tv_nsec += (usecs % usecs_in_1_sec) * 1000;
- // sem_timedwait bombs if you have more than 1e9 in tv_nsec
- // so we have to clean things up before passing it in
- if (ts.tv_nsec >= nsecs_in_1_sec) {
- ts.tv_nsec -= nsecs_in_1_sec;
- ++ts.tv_sec;
- }
-
- int rc;
- do {
- rc = sem_timedwait(&m_sema, &ts);
- } while (rc == -1 && errno == EINTR);
- return !(rc == -1 && errno == ETIMEDOUT);
- }
-
- void signal()
- {
- sem_post(&m_sema);
- }
-
- void signal(int count)
- {
- while (count-- > 0)
- {
- sem_post(&m_sema);
- }
- }
- };
-#else
-#error Unsupported platform! (No semaphore wrapper available)
-#endif
-
- //---------------------------------------------------------
- // LightweightSemaphore
- //---------------------------------------------------------
- class LightweightSemaphore
- {
- public:
- typedef std::make_signed::type ssize_t;
-
- private:
- std::atomic m_count;
- Semaphore m_sema;
-
- bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1)
- {
- ssize_t oldCount;
- // Is there a better way to set the initial spin count?
- // If we lower it to 1000, testBenaphore becomes 15x slower on my Core i7-5930K Windows PC,
- // as threads start hitting the kernel semaphore.
- int spin = 10000;
- while (--spin >= 0)
- {
- oldCount = m_count.load(std::memory_order_relaxed);
- if ((oldCount > 0) && m_count.compare_exchange_strong(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed))
- return true;
- std::atomic_signal_fence(std::memory_order_acquire); // Prevent the compiler from collapsing the loop.
- }
- oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
- if (oldCount > 0)
- return true;
- if (timeout_usecs < 0)
- {
- m_sema.wait();
- return true;
- }
- if (m_sema.timed_wait((std::uint64_t)timeout_usecs))
- return true;
- // At this point, we've timed out waiting for the semaphore, but the
- // count is still decremented indicating we may still be waiting on
- // it. So we have to re-adjust the count, but only if the semaphore
- // wasn't signaled enough times for us too since then. If it was, we
- // need to release the semaphore too.
- while (true)
- {
- oldCount = m_count.load(std::memory_order_acquire);
- if (oldCount >= 0 && m_sema.try_wait())
- return true;
- if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed))
- return false;
- }
- }
-
- ssize_t waitManyWithPartialSpinning(ssize_t max, std::int64_t timeout_usecs = -1)
- {
- assert(max > 0);
- ssize_t oldCount;
- int spin = 10000;
- while (--spin >= 0)
- {
- oldCount = m_count.load(std::memory_order_relaxed);
- if (oldCount > 0)
- {
- ssize_t newCount = oldCount > max ? oldCount - max : 0;
- if (m_count.compare_exchange_strong(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed))
- return oldCount - newCount;
- }
- std::atomic_signal_fence(std::memory_order_acquire);
- }
- oldCount = m_count.fetch_sub(1, std::memory_order_acquire);
- if (oldCount <= 0)
- {
- if (timeout_usecs < 0)
- m_sema.wait();
- else if (!m_sema.timed_wait((std::uint64_t)timeout_usecs))
- {
- while (true)
- {
- oldCount = m_count.load(std::memory_order_acquire);
- if (oldCount >= 0 && m_sema.try_wait())
- break;
- if (oldCount < 0 && m_count.compare_exchange_strong(oldCount, oldCount + 1, std::memory_order_relaxed, std::memory_order_relaxed))
- return 0;
- }
- }
- }
- if (max > 1)
- return 1 + tryWaitMany(max - 1);
- return 1;
- }
-
- public:
- LightweightSemaphore(ssize_t initialCount = 0) : m_count(initialCount)
- {
- assert(initialCount >= 0);
- }
-
- bool tryWait()
- {
- ssize_t oldCount = m_count.load(std::memory_order_relaxed);
- while (oldCount > 0)
- {
- if (m_count.compare_exchange_weak(oldCount, oldCount - 1, std::memory_order_acquire, std::memory_order_relaxed))
- return true;
- }
- return false;
- }
-
- void wait()
- {
- if (!tryWait())
- waitWithPartialSpinning();
- }
-
- bool wait(std::int64_t timeout_usecs)
- {
- return tryWait() || waitWithPartialSpinning(timeout_usecs);
- }
-
- // Acquires between 0 and (greedily) max, inclusive
- ssize_t tryWaitMany(ssize_t max)
- {
- assert(max >= 0);
- ssize_t oldCount = m_count.load(std::memory_order_relaxed);
- while (oldCount > 0)
- {
- ssize_t newCount = oldCount > max ? oldCount - max : 0;
- if (m_count.compare_exchange_weak(oldCount, newCount, std::memory_order_acquire, std::memory_order_relaxed))
- return oldCount - newCount;
- }
- return 0;
- }
-
- // Acquires at least one, and (greedily) at most max
- ssize_t waitMany(ssize_t max, std::int64_t timeout_usecs)
- {
- assert(max >= 0);
- ssize_t result = tryWaitMany(max);
- if (result == 0 && max > 0)
- result = waitManyWithPartialSpinning(max, timeout_usecs);
- return result;
- }
-
- ssize_t waitMany(ssize_t max)
- {
- ssize_t result = waitMany(max, -1);
- assert(result > 0);
- return result;
- }
-
- void signal(ssize_t count = 1)
- {
- assert(count >= 0);
- ssize_t oldCount = m_count.fetch_add(count, std::memory_order_release);
- ssize_t toRelease = -oldCount < count ? -oldCount : count;
- if (toRelease > 0)
- {
- m_sema.signal((int)toRelease);
- }
- }
-
- ssize_t availableApprox() const
- {
- ssize_t count = m_count.load(std::memory_order_relaxed);
- return count > 0 ? count : 0;
- }
- };
- } // end namespace mpmc_sema
-} // end namespace details
-
-
// This is a blocking version of the queue. It has an almost identical interface to
// the normal non-blocking version, with the addition of various wait_dequeue() methods
// and the removal of producer-specific dequeue methods.
@@ -422,7 +26,7 @@ class BlockingConcurrentQueue
{
private:
typedef ::moodycamel::ConcurrentQueue ConcurrentQueue;
- typedef details::mpmc_sema::LightweightSemaphore LightweightSemaphore;
+ typedef ::moodycamel::LightweightSemaphore LightweightSemaphore;
public:
typedef typename ConcurrentQueue::producer_token_t producer_token_t;
@@ -432,7 +36,7 @@ class BlockingConcurrentQueue
typedef typename ConcurrentQueue::size_t size_t;
typedef typename std::make_signed::type ssize_t;
- static const size_t BLOCK_SIZE_ = ConcurrentQueue::BLOCK_SIZE_;
+ static const size_t BLOCK_SIZE = ConcurrentQueue::BLOCK_SIZE;
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = ConcurrentQueue::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD;
static const size_t EXPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::EXPLICIT_INITIAL_INDEX_SIZE;
static const size_t IMPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::IMPLICIT_INITIAL_INDEX_SIZE;
@@ -451,8 +55,8 @@ class BlockingConcurrentQueue
// queue is fully constructed before it starts being used by other threads (this
// includes making the memory effects of construction visible, possibly with a
// memory barrier).
- explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE_)
- : inner(capacity), sema(create(), &BlockingConcurrentQueue::template destroy)
+ explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
+ : inner(capacity), sema(create(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy)
{
assert(reinterpret_cast((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
if (!sema) {
@@ -461,7 +65,7 @@ class BlockingConcurrentQueue
}
BlockingConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers)
- : inner(minCapacity, maxExplicitProducers, maxImplicitProducers), sema(create(), &BlockingConcurrentQueue::template destroy)
+ : inner(minCapacity, maxExplicitProducers, maxImplicitProducers), sema(create(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy)
{
assert(reinterpret_cast((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
if (!sema) {
@@ -754,7 +358,9 @@ class BlockingConcurrentQueue
template
inline void wait_dequeue(U& item)
{
- sema->wait();
+ while (!sema->wait()) {
+ continue;
+ }
while (!inner.try_dequeue(item)) {
continue;
}
@@ -795,7 +401,9 @@ class BlockingConcurrentQueue
template
inline void wait_dequeue(consumer_token_t& token, U& item)
{
- sema->wait();
+ while (!sema->wait()) {
+ continue;
+ }
while (!inner.try_dequeue(token, item)) {
continue;
}
@@ -943,18 +551,11 @@ class BlockingConcurrentQueue
private:
- template
- static inline U* create()
- {
- auto p = (Traits::malloc)(sizeof(U));
- return p != nullptr ? new (p) U : nullptr;
- }
-
- template
- static inline U* create(A1&& a1)
+ template
+ static inline U* create(A1&& a1, A2&& a2)
{
- auto p = (Traits::malloc)(sizeof(U));
- return p != nullptr ? new (p) U(std::forward(a1)) : nullptr;
+ void* p = (Traits::malloc)(sizeof(U));
+ return p != nullptr ? new (p) U(std::forward(a1), std::forward(a2)) : nullptr;
}
template
diff --git a/src/modules/common/concurrentqueue.h b/src/modules/common/concurrentqueue.h
index d48a2e4a4..3ced1c7b2 100644
--- a/src/modules/common/concurrentqueue.h
+++ b/src/modules/common/concurrentqueue.h
@@ -5,7 +5,7 @@
// http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue
// Simplified BSD license:
-// Copyright (c) 2013-2016, Cameron Desrochers.
+// Copyright (c) 2013-2020, Cameron Desrochers.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
@@ -27,10 +27,11 @@
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Also dual-licensed under the Boost Software License (see LICENSE.md)
#pragma once
-#if defined(__GNUC__)
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
// Disable -Wconversion warnings (spuriously triggered when Traits::size_t and
// Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings
// upon assigning any computed values)
@@ -42,6 +43,13 @@
#endif
#endif
+#if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
+// VS2019 with /W4 warns about constant conditional expressions but unless /std=c++17 or higher
+// does not support `if constexpr`, so we have no choice but to simply disable the warning
+#pragma warning(push)
+#pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
#if defined(__APPLE__)
#include "TargetConditionals.h"
#endif
@@ -96,7 +104,7 @@ namespace moodycamel { namespace details {
static const thread_id_t invalid_thread_id2 = 0xFFFFFFFFU; // Not technically guaranteed to be invalid, but is never used in practice. Note that all Win32 thread IDs are presently multiples of 4.
static inline thread_id_t thread_id() { return static_cast(::GetCurrentThreadId()); }
} }
-#elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE)
+#elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE) || defined(MOODYCAMEL_NO_THREAD_LOCAL)
namespace moodycamel { namespace details {
static_assert(sizeof(std::thread::id) == 4 || sizeof(std::thread::id) == 8, "std::thread::id is expected to be either 4 or 8 bytes");
@@ -146,10 +154,21 @@ namespace moodycamel { namespace details {
typedef std::uintptr_t thread_id_t;
static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr
static const thread_id_t invalid_thread_id2 = 1; // Member accesses off a null pointer are also generally invalid. Plus it's not aligned.
- static inline thread_id_t thread_id() { static MOODYCAMEL_THREADLOCAL int x; return reinterpret_cast(&x); }
+ inline thread_id_t thread_id() { static MOODYCAMEL_THREADLOCAL int x; return reinterpret_cast(&x); }
} }
#endif
+// Constexpr if
+#ifndef MOODYCAMEL_CONSTEXPR_IF
+#if (defined(_MSC_VER) && defined(_HAS_CXX17) && _HAS_CXX17) || __cplusplus > 201402L
+#define MOODYCAMEL_CONSTEXPR_IF if constexpr
+#define MOODYCAMEL_MAYBE_UNUSED [[maybe_unused]]
+#else
+#define MOODYCAMEL_CONSTEXPR_IF if
+#define MOODYCAMEL_MAYBE_UNUSED
+#endif
+#endif
+
// Exceptions
#ifndef MOODYCAMEL_EXCEPTIONS_ENABLED
#if (defined(_MSC_VER) && defined(_CPPUNWIND)) || (defined(__GNUC__) && defined(__EXCEPTIONS)) || (!defined(_MSC_VER) && !defined(__GNUC__))
@@ -162,8 +181,8 @@ namespace moodycamel { namespace details {
#define MOODYCAMEL_RETHROW throw
#define MOODYCAMEL_THROW(expr) throw (expr)
#else
-#define MOODYCAMEL_TRY if (true)
-#define MOODYCAMEL_CATCH(...) else if (false)
+#define MOODYCAMEL_TRY MOODYCAMEL_CONSTEXPR_IF (true)
+#define MOODYCAMEL_CATCH(...) else MOODYCAMEL_CONSTEXPR_IF (false)
#define MOODYCAMEL_RETHROW
#define MOODYCAMEL_THROW(expr)
#endif
@@ -214,6 +233,44 @@ namespace moodycamel { namespace details {
#endif
#endif
+namespace moodycamel { namespace details {
+#ifndef MOODYCAMEL_ALIGNAS
+// VS2013 doesn't support alignas or alignof, and align() requires a constant literal
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+#define MOODYCAMEL_ALIGNAS(alignment) __declspec(align(alignment))
+#define MOODYCAMEL_ALIGNOF(obj) __alignof(obj)
+#define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) typename details::Vs2013Aligned::value, T>::type
+ template struct Vs2013Aligned { }; // default, unsupported alignment
+ template struct Vs2013Aligned<1, T> { typedef __declspec(align(1)) T type; };
+ template struct Vs2013Aligned<2, T> { typedef __declspec(align(2)) T type; };
+ template struct Vs2013Aligned<4, T> { typedef __declspec(align(4)) T type; };
+ template struct Vs2013Aligned<8, T> { typedef __declspec(align(8)) T type; };
+ template struct Vs2013Aligned<16, T> { typedef __declspec(align(16)) T type; };
+ template struct Vs2013Aligned<32, T> { typedef __declspec(align(32)) T type; };
+ template struct Vs2013Aligned<64, T> { typedef __declspec(align(64)) T type; };
+ template struct Vs2013Aligned<128, T> { typedef __declspec(align(128)) T type; };
+ template struct Vs2013Aligned<256, T> { typedef __declspec(align(256)) T type; };
+#else
+ template struct identity { typedef T type; };
+#define MOODYCAMEL_ALIGNAS(alignment) alignas(alignment)
+#define MOODYCAMEL_ALIGNOF(obj) alignof(obj)
+#define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) alignas(alignof(obj)) typename details::identity::type
+#endif
+#endif
+} }
+
+
+// TSAN can false report races in lock-free code. To enable TSAN to be used from projects that use this one,
+// we can apply per-function compile-time suppression.
+// See https://clang.llvm.org/docs/ThreadSanitizer.html#has-feature-thread-sanitizer
+#define MOODYCAMEL_NO_TSAN
+#if defined(__has_feature)
+ #if __has_feature(thread_sanitizer)
+ #undef MOODYCAMEL_NO_TSAN
+ #define MOODYCAMEL_NO_TSAN __attribute__((no_sanitize("thread")))
+ #endif // TSAN
+#endif // TSAN
+
// Compiler-specific likely/unlikely hints
namespace moodycamel { namespace details {
#if defined(__GNUC__)
@@ -282,7 +339,7 @@ struct ConcurrentQueueDefaultTraits
// but many producers, a smaller block size should be favoured. For few producers
// and/or many elements, a larger block size is preferred. A sane default
// is provided. Must be a power of 2.
- static const size_t BLOCK_SIZE_ = 32;
+ static const size_t BLOCK_SIZE = 32;
// For explicit producers (i.e. when using a producer token), the block is
// checked for being empty by iterating through a list of flags, one per element.
@@ -315,6 +372,12 @@ struct ConcurrentQueueDefaultTraits
// that this limit is enforced at the block level (for performance reasons), i.e.
// it's rounded up to the nearest block size.
static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max::value;
+
+ // The number of times to spin before sleeping when waiting on a semaphore.
+ // Recommended values are on the order of 1000-10000 unless the number of
+ // consumer threads exceeds the number of idle cores (in which case try 0-100).
+ // Only affects instances of the BlockingConcurrentQueue.
+ static const int MAX_SEMA_SPINS = 10000;
#ifndef MCDBGQ_USE_RELACY
@@ -689,7 +752,7 @@ class ConcurrentQueue
typedef typename Traits::index_t index_t;
typedef typename Traits::size_t size_t;
- static const size_t BLOCK_SIZE_ = static_cast(Traits::BLOCK_SIZE_);
+ static const size_t BLOCK_SIZE = static_cast(Traits::BLOCK_SIZE);
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = static_cast(Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD);
static const size_t EXPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::EXPLICIT_INITIAL_INDEX_SIZE);
static const size_t IMPLICIT_INITIAL_INDEX_SIZE = static_cast(Traits::IMPLICIT_INITIAL_INDEX_SIZE);
@@ -700,7 +763,7 @@ class ConcurrentQueue
#pragma warning(disable: 4307) // + integral constant overflow (that's what the ternary expression is for!)
#pragma warning(disable: 4309) // static_cast: Truncation of constant value
#endif
- static const size_t MAX_SUBQUEUE_SIZE = (details::const_numeric_max::value - static_cast(Traits::MAX_SUBQUEUE_SIZE) < BLOCK_SIZE_) ? details::const_numeric_max::value : ((static_cast(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE_ - 1)) / BLOCK_SIZE_ * BLOCK_SIZE_);
+ static const size_t MAX_SUBQUEUE_SIZE = (details::const_numeric_max::value - static_cast(Traits::MAX_SUBQUEUE_SIZE) < BLOCK_SIZE) ? details::const_numeric_max::value : ((static_cast(Traits::MAX_SUBQUEUE_SIZE) + (BLOCK_SIZE - 1)) / BLOCK_SIZE * BLOCK_SIZE);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
@@ -708,7 +771,7 @@ class ConcurrentQueue
static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::size_t must be an unsigned integral type");
static_assert(!std::numeric_limits::is_signed && std::is_integral::value, "Traits::index_t must be an unsigned integral type");
static_assert(sizeof(index_t) >= sizeof(size_t), "Traits::index_t must be at least as wide as Traits::size_t");
- static_assert((BLOCK_SIZE_ > 1) && !(BLOCK_SIZE_ & (BLOCK_SIZE_ - 1)), "Traits::BLOCK_SIZE_ must be a power of 2 (and at least 2)");
+ static_assert((BLOCK_SIZE > 1) && !(BLOCK_SIZE & (BLOCK_SIZE - 1)), "Traits::BLOCK_SIZE must be a power of 2 (and at least 2)");
static_assert((EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD > 1) && !(EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD & (EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD - 1)), "Traits::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD must be a power of 2 (and greater than 1)");
static_assert((EXPLICIT_INITIAL_INDEX_SIZE > 1) && !(EXPLICIT_INITIAL_INDEX_SIZE & (EXPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::EXPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)");
static_assert((IMPLICIT_INITIAL_INDEX_SIZE > 1) && !(IMPLICIT_INITIAL_INDEX_SIZE & (IMPLICIT_INITIAL_INDEX_SIZE - 1)), "Traits::IMPLICIT_INITIAL_INDEX_SIZE must be a power of 2 (and greater than 1)");
@@ -726,7 +789,7 @@ class ConcurrentQueue
// queue is fully constructed before it starts being used by other threads (this
// includes making the memory effects of construction visible, possibly with a
// memory barrier).
- explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE_)
+ explicit ConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
: producerListTail(nullptr),
producerCount(0),
initialBlockPoolIndex(0),
@@ -735,7 +798,7 @@ class ConcurrentQueue
{
implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed);
populate_initial_implicit_producer_hash();
- populate_initial_block_list(capacity / BLOCK_SIZE_ + ((capacity & (BLOCK_SIZE_ - 1)) == 0 ? 0 : 1));
+ populate_initial_block_list(capacity / BLOCK_SIZE + ((capacity & (BLOCK_SIZE - 1)) == 0 ? 0 : 1));
#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
// Track all the producers using a fully-resolved typed list for
@@ -759,7 +822,7 @@ class ConcurrentQueue
{
implicitProducerHashResizeInProgress.clear(std::memory_order_relaxed);
populate_initial_implicit_producer_hash();
- size_t blocks = (((minCapacity + BLOCK_SIZE_ - 1) / BLOCK_SIZE_) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers + maxImplicitProducers);
+ size_t blocks = (((minCapacity + BLOCK_SIZE - 1) / BLOCK_SIZE) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers + maxImplicitProducers);
populate_initial_block_list(blocks);
#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
@@ -785,7 +848,7 @@ class ConcurrentQueue
}
// Destroy implicit producer hash tables
- if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE != 0) {
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE != 0) {
auto hash = implicitProducerHash.load(std::memory_order_relaxed);
while (hash != nullptr) {
auto prev = hash->prev;
@@ -910,8 +973,8 @@ class ConcurrentQueue
// Thread-safe.
inline bool enqueue(T const& item)
{
- if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- return inner_enqueue(item);
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
+ else return inner_enqueue(item);
}
// Enqueues a single item (by moving it, if possible).
@@ -921,8 +984,8 @@ class ConcurrentQueue
// Thread-safe.
inline bool enqueue(T&& item)
{
- if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- return inner_enqueue(std::move(item));
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
+ else return inner_enqueue(std::move(item));
}
// Enqueues a single item (by copying it) using an explicit producer token.
@@ -952,8 +1015,8 @@ class ConcurrentQueue
template
bool enqueue_bulk(It itemFirst, size_t count)
{
- if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- return inner_enqueue_bulk(itemFirst, count);
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
+ else return inner_enqueue_bulk(itemFirst, count);
}
// Enqueues several items using an explicit producer token.
@@ -975,8 +1038,8 @@ class ConcurrentQueue
// Thread-safe.
inline bool try_enqueue(T const& item)
{
- if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- return inner_enqueue(item);
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
+ else return inner_enqueue(item);
}
// Enqueues a single item (by moving it, if possible).
@@ -986,8 +1049,8 @@ class ConcurrentQueue
// Thread-safe.
inline bool try_enqueue(T&& item)
{
- if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- return inner_enqueue(std::move(item));
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
+ else return inner_enqueue(std::move(item));
}
// Enqueues a single item (by copying it) using an explicit producer token.
@@ -1016,8 +1079,8 @@ class ConcurrentQueue
template
bool try_enqueue_bulk(It itemFirst, size_t count)
{
- if (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
- return inner_enqueue_bulk(itemFirst, count);
+ MOODYCAMEL_CONSTEXPR_IF (INITIAL_IMPLICIT_PRODUCER_HASH_SIZE == 0) return false;
+ else return inner_enqueue_bulk(itemFirst, count);
}
// Enqueues several items using an explicit producer token.
@@ -1374,7 +1437,7 @@ class ConcurrentQueue
inline void add(N* node)
{
-#if MCDBGQ_NOLOCKFREE_FREELIST
+#ifdef MCDBGQ_NOLOCKFREE_FREELIST
debug::DebugLock lock(mutex);
#endif
// We know that the should-be-on-freelist bit is 0 at this point, so it's safe to
@@ -1388,7 +1451,7 @@ class ConcurrentQueue
inline N* try_get()
{
-#if MCDBGQ_NOLOCKFREE_FREELIST
+#ifdef MCDBGQ_NOLOCKFREE_FREELIST
debug::DebugLock lock(mutex);
#endif
auto head = freeListHead.load(std::memory_order_acquire);
@@ -1460,7 +1523,7 @@ class ConcurrentQueue
static const std::uint32_t REFS_MASK = 0x7FFFFFFF;
static const std::uint32_t SHOULD_BE_ON_FREELIST = 0x80000000;
-#if MCDBGQ_NOLOCKFREE_FREELIST
+#ifdef MCDBGQ_NOLOCKFREE_FREELIST
debug::DebugMutex mutex;
#endif
};
@@ -1477,7 +1540,7 @@ class ConcurrentQueue
Block()
: next(nullptr), elementsCompletelyDequeued(0), freeListRefs(0), freeListNext(nullptr), shouldBeOnFreeList(false), dynamicallyAllocated(true)
{
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
owner = nullptr;
#endif
}
@@ -1485,9 +1548,9 @@ class ConcurrentQueue
template
inline bool is_empty() const
{
- if (context == explicit_context && BLOCK_SIZE_ <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
+ MOODYCAMEL_CONSTEXPR_IF (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
// Check flags
- for (size_t i = 0; i < BLOCK_SIZE_; ++i) {
+ for (size_t i = 0; i < BLOCK_SIZE; ++i) {
if (!emptyFlags[i].load(std::memory_order_relaxed)) {
return false;
}
@@ -1499,42 +1562,42 @@ class ConcurrentQueue
}
else {
// Check counter
- if (elementsCompletelyDequeued.load(std::memory_order_relaxed) == BLOCK_SIZE_) {
+ if (elementsCompletelyDequeued.load(std::memory_order_relaxed) == BLOCK_SIZE) {
std::atomic_thread_fence(std::memory_order_acquire);
return true;
}
- assert(elementsCompletelyDequeued.load(std::memory_order_relaxed) <= BLOCK_SIZE_);
+ assert(elementsCompletelyDequeued.load(std::memory_order_relaxed) <= BLOCK_SIZE);
return false;
}
}
// Returns true if the block is now empty (does not apply in explicit context)
template
- inline bool set_empty(index_t i)
+ inline bool set_empty(MOODYCAMEL_MAYBE_UNUSED index_t i)
{
- if (context == explicit_context && BLOCK_SIZE_ <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
+ MOODYCAMEL_CONSTEXPR_IF (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
// Set flag
- assert(!emptyFlags[BLOCK_SIZE_ - 1 - static_cast(i & static_cast(BLOCK_SIZE_ - 1))].load(std::memory_order_relaxed));
- emptyFlags[BLOCK_SIZE_ - 1 - static_cast(i & static_cast(BLOCK_SIZE_ - 1))].store(true, std::memory_order_release);
+ assert(!emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].load(std::memory_order_relaxed));
+ emptyFlags[BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1))].store(true, std::memory_order_release);
return false;
}
else {
// Increment counter
auto prevVal = elementsCompletelyDequeued.fetch_add(1, std::memory_order_release);
- assert(prevVal < BLOCK_SIZE_);
- return prevVal == BLOCK_SIZE_ - 1;
+ assert(prevVal < BLOCK_SIZE);
+ return prevVal == BLOCK_SIZE - 1;
}
}
// Sets multiple contiguous item statuses to 'empty' (assumes no wrapping and count > 0).
// Returns true if the block is now empty (does not apply in explicit context).
template
- inline bool set_many_empty(index_t i, size_t count)
+ inline bool set_many_empty(MOODYCAMEL_MAYBE_UNUSED index_t i, size_t count)
{
- if (context == explicit_context && BLOCK_SIZE_ <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
+ MOODYCAMEL_CONSTEXPR_IF (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
// Set flags
std::atomic_thread_fence(std::memory_order_release);
- i = BLOCK_SIZE_ - 1 - static_cast(i & static_cast(BLOCK_SIZE_ - 1)) - count + 1;
+ i = BLOCK_SIZE - 1 - static_cast(i & static_cast(BLOCK_SIZE - 1)) - count + 1;
for (size_t j = 0; j != count; ++j) {
assert(!emptyFlags[i + j].load(std::memory_order_relaxed));
emptyFlags[i + j].store(true, std::memory_order_relaxed);
@@ -1544,32 +1607,32 @@ class ConcurrentQueue
else {
// Increment counter
auto prevVal = elementsCompletelyDequeued.fetch_add(count, std::memory_order_release);
- assert(prevVal + count <= BLOCK_SIZE_);
- return prevVal + count == BLOCK_SIZE_;
+ assert(prevVal + count <= BLOCK_SIZE);
+ return prevVal + count == BLOCK_SIZE;
}
}
template
inline void set_all_empty()
{
- if (context == explicit_context && BLOCK_SIZE_ <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
+ MOODYCAMEL_CONSTEXPR_IF (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
// Set all flags
- for (size_t i = 0; i != BLOCK_SIZE_; ++i) {
+ for (size_t i = 0; i != BLOCK_SIZE; ++i) {
emptyFlags[i].store(true, std::memory_order_relaxed);
}
}
else {
// Reset counter
- elementsCompletelyDequeued.store(BLOCK_SIZE_, std::memory_order_relaxed);
+ elementsCompletelyDequeued.store(BLOCK_SIZE, std::memory_order_relaxed);
}
}
template
inline void reset_empty()
{
- if (context == explicit_context && BLOCK_SIZE_ <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
+ MOODYCAMEL_CONSTEXPR_IF (context == explicit_context && BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD) {
// Reset flags
- for (size_t i = 0; i != BLOCK_SIZE_; ++i) {
+ for (size_t i = 0; i != BLOCK_SIZE; ++i) {
emptyFlags[i].store(false, std::memory_order_relaxed);
}
}
@@ -1579,42 +1642,30 @@ class ConcurrentQueue
}
}
- inline T* operator[](index_t idx) MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE_ - 1)); }
- inline T const* operator[](index_t idx) const MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE_ - 1)); }
+ inline T* operator[](index_t idx) MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); }
+ inline T const* operator[](index_t idx) const MOODYCAMEL_NOEXCEPT { return static_cast(static_cast(elements)) + static_cast(idx & static_cast(BLOCK_SIZE - 1)); }
private:
- // IMPORTANT: This must be the first member in Block, so that if T depends on the alignment of
- // addresses returned by malloc, that alignment will be preserved. Apparently clang actually
- // generates code that uses this assumption for AVX instructions in some cases. Ideally, we
- // should also align Block to the alignment of T in case it's higher than malloc's 16-byte
- // alignment, but this is hard to do in a cross-platform way. Assert for this case:
- static_assert(std::alignment_of::value <= std::alignment_of::value, "The queue does not support super-aligned types at this time");
- // Additionally, we need the alignment of Block itself to be a multiple of max_align_t since
- // otherwise the appropriate padding will not be added at the end of Block in order to make
- // arrays of Blocks all be properly aligned (not just the first one). We use a union to force
- // this.
- union {
- char elements[sizeof(T) * BLOCK_SIZE_];
- details::max_align_t dummy;
- };
+ static_assert(std::alignment_of::value <= sizeof(T), "The queue does not support types with an alignment greater than their size at this time");
+ MOODYCAMEL_ALIGNED_TYPE_LIKE(char[sizeof(T) * BLOCK_SIZE], T) elements;
public:
Block* next;
std::atomic elementsCompletelyDequeued;
- std::atomic emptyFlags[BLOCK_SIZE_ <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD ? BLOCK_SIZE_ : 1];
+ std::atomic emptyFlags[BLOCK_SIZE <= EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD ? BLOCK_SIZE : 1];
public:
std::atomic freeListRefs;
std::atomic freeListNext;
std::atomic shouldBeOnFreeList;
bool dynamicallyAllocated; // Perhaps a better name for this would be 'isNotPartOfInitialBlockPool'
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
void* owner;
#endif
};
- static_assert(std::alignment_of::value >= std::alignment_of::value, "Internal error: Blocks must be at least as aligned as the type they are wrapping");
+ static_assert(std::alignment_of::value >= std::alignment_of::value, "Internal error: Blocks must be at least as aligned as the type they are wrapping");
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
public:
struct MemStats;
private:
@@ -1637,7 +1688,7 @@ class ConcurrentQueue
{
}
- virtual ~ProducerBase() { };
+ virtual ~ProducerBase() { }
template
inline bool dequeue(U& element)
@@ -1685,7 +1736,7 @@ class ConcurrentQueue
ConcurrentQueue* parent;
protected:
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
friend struct MemStats;
#endif
};
@@ -1697,8 +1748,8 @@ class ConcurrentQueue
struct ExplicitProducer : public ProducerBase
{
- explicit ExplicitProducer(ConcurrentQueue* parent) :
- ProducerBase(parent, true),
+ explicit ExplicitProducer(ConcurrentQueue* parent_) :
+ ProducerBase(parent_, true),
blockIndex(nullptr),
pr_blockIndexSlotsUsed(0),
pr_blockIndexSize(EXPLICIT_INITIAL_INDEX_SIZE >> 1),
@@ -1706,7 +1757,7 @@ class ConcurrentQueue
pr_blockIndexEntries(nullptr),
pr_blockIndexRaw(nullptr)
{
- size_t poolBasedIndexSize = details::ceil_to_pow_2(parent->initialBlockPoolSize) >> 1;
+ size_t poolBasedIndexSize = details::ceil_to_pow_2(parent_->initialBlockPoolSize) >> 1;
if (poolBasedIndexSize > pr_blockIndexSize) {
pr_blockIndexSize = poolBasedIndexSize;
}
@@ -1722,11 +1773,11 @@ class ConcurrentQueue
if (this->tailBlock != nullptr) { // Note this means there must be a block index too
// First find the block that's partially dequeued, if any
Block* halfDequeuedBlock = nullptr;
- if ((this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE_ - 1)) != 0) {
+ if ((this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) != 0) {
// The head's not on a block boundary, meaning a block somewhere is partially dequeued
// (or the head block is the tail block and was fully dequeued, but the head/tail are still not on a boundary)
size_t i = (pr_blockIndexFront - pr_blockIndexSlotsUsed) & (pr_blockIndexSize - 1);
- while (details::circular_less_than(pr_blockIndexEntries[i].base + BLOCK_SIZE_, this->headIndex.load(std::memory_order_relaxed))) {
+ while (details::circular_less_than(pr_blockIndexEntries[i].base + BLOCK_SIZE, this->headIndex.load(std::memory_order_relaxed))) {
i = (i + 1) & (pr_blockIndexSize - 1);
}
assert(details::circular_less_than(pr_blockIndexEntries[i].base, this->headIndex.load(std::memory_order_relaxed)));
@@ -1743,12 +1794,12 @@ class ConcurrentQueue
size_t i = 0; // Offset into block
if (block == halfDequeuedBlock) {
- i = static_cast(this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE_ - 1));
+ i = static_cast(this->headIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1));
}
// Walk through all the items in the block; if this is the tail block, we need to stop when we reach the tail index
- auto lastValidIndex = (this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE_ - 1)) == 0 ? BLOCK_SIZE_ : static_cast(this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE_ - 1));
- while (i != BLOCK_SIZE_ && (block != this->tailBlock || i != lastValidIndex)) {
+ auto lastValidIndex = (this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1)) == 0 ? BLOCK_SIZE : static_cast(this->tailIndex.load(std::memory_order_relaxed) & static_cast(BLOCK_SIZE - 1));
+ while (i != BLOCK_SIZE && (block != this->tailBlock || i != lastValidIndex)) {
(*block)[i++]->~T();
}
} while (block != this->tailBlock);
@@ -1784,7 +1835,7 @@ class ConcurrentQueue
{
index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed);
index_t newTailIndex = 1 + currentTailIndex;
- if ((currentTailIndex & static_cast(BLOCK_SIZE_ - 1)) == 0) {
+ if ((currentTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) {
// We reached the end of a block, start a new one
auto startBlock = this->tailBlock;
auto originalBlockIndexSlotsUsed = pr_blockIndexSlotsUsed;
@@ -1805,8 +1856,8 @@ class ConcurrentQueue
// <= to it.
auto head = this->headIndex.load(std::memory_order_relaxed);
assert(!details::circular_less_than(currentTailIndex, head));
- if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE_)
- || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE_ < currentTailIndex - head))) {
+ if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE)
+ || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) {
// We can't enqueue in another block because there's not enough leeway -- the
// tail could surpass the head by the time the block fills up! (Or we'll exceed
// the size limit, if the second part of the condition was true.)
@@ -1818,7 +1869,10 @@ class ConcurrentQueue
// to allocate a new index. Note pr_blockIndexRaw can only be nullptr if
// the initial allocation failed in the constructor.
- if (allocMode == CannotAlloc || !new_block_index(pr_blockIndexSlotsUsed)) {
+ MOODYCAMEL_CONSTEXPR_IF (allocMode == CannotAlloc) {
+ return false;
+ }
+ else if (!new_block_index(pr_blockIndexSlotsUsed)) {
return false;
}
}
@@ -1828,7 +1882,7 @@ class ConcurrentQueue
if (newBlock == nullptr) {
return false;
}
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
newBlock->owner = this;
#endif
newBlock->ConcurrentQueue::Block::template reset_empty();
@@ -1842,8 +1896,8 @@ class ConcurrentQueue
this->tailBlock = newBlock;
++pr_blockIndexSlotsUsed;
}
-
- if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) {
+
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast(nullptr)) T(std::forward(element)))) {
// The constructor may throw. We want the element not to appear in the queue in
// that case (without corrupting the queue):
MOODYCAMEL_TRY {
@@ -1869,7 +1923,7 @@ class ConcurrentQueue
blockIndex.load(std::memory_order_relaxed)->front.store(pr_blockIndexFront, std::memory_order_release);
pr_blockIndexFront = (pr_blockIndexFront + 1) & (pr_blockIndexSize - 1);
- if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) {
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast(nullptr)) T(std::forward(element)))) {
this->tailIndex.store(newTailIndex, std::memory_order_release);
return true;
}
@@ -1943,8 +1997,8 @@ class ConcurrentQueue
// When an index wraps, we need to preserve the sign of the offset when dividing it by the
// block size (in order to get a correct signed block count offset in all cases):
auto headBase = localBlockIndex->entries[localBlockIndexHead].base;
- auto blockBaseIndex = index & ~static_cast(BLOCK_SIZE_ - 1);
- auto offset = static_cast(static_cast::type>(blockBaseIndex - headBase) / BLOCK_SIZE_);
+ auto blockBaseIndex = index & ~static_cast(BLOCK_SIZE - 1);
+ auto offset = static_cast(static_cast::type>(blockBaseIndex - headBase) / BLOCK_SIZE);
auto block = localBlockIndex->entries[(localBlockIndexHead + offset) & (localBlockIndex->size - 1)].block;
// Dequeue
@@ -1962,12 +2016,12 @@ class ConcurrentQueue
block->ConcurrentQueue::Block::template set_empty(index);
}
} guard = { block, index };
-
- element = std::move(el);
+
+ element = std::move(el); // NOLINT
}
else {
- element = std::move(el);
- el.~T();
+ element = std::move(el); // NOLINT
+ el.~T(); // NOLINT
block->ConcurrentQueue::Block::template set_empty(index);
}
@@ -1983,7 +2037,7 @@ class ConcurrentQueue
}
template
- bool enqueue_bulk(It itemFirst, size_t count)
+ bool MOODYCAMEL_NO_TSAN enqueue_bulk(It itemFirst, size_t count)
{
// First, we need to make sure we have enough room to enqueue all of the elements;
// this means pre-allocating blocks and putting them in the block index (but only if
@@ -1996,13 +2050,13 @@ class ConcurrentQueue
Block* firstAllocatedBlock = nullptr;
// Figure out how many blocks we'll need to allocate, and do so
- size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE_ - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE_ - 1));
- index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE_ - 1);
+ size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1));
+ index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1);
if (blockBaseDiff > 0) {
// Allocate as many blocks as possible from ahead
while (blockBaseDiff > 0 && this->tailBlock != nullptr && this->tailBlock->next != firstAllocatedBlock && this->tailBlock->next->ConcurrentQueue::Block::template is_empty()) {
- blockBaseDiff -= static_cast(BLOCK_SIZE_);
- currentTailIndex += static_cast(BLOCK_SIZE_);
+ blockBaseDiff -= static_cast(BLOCK_SIZE);
+ currentTailIndex += static_cast(BLOCK_SIZE);
this->tailBlock = this->tailBlock->next;
firstAllocatedBlock = firstAllocatedBlock == nullptr ? this->tailBlock : firstAllocatedBlock;
@@ -2015,14 +2069,21 @@ class ConcurrentQueue
// Now allocate as many blocks as necessary from the block pool
while (blockBaseDiff > 0) {
- blockBaseDiff -= static_cast(BLOCK_SIZE_);
- currentTailIndex += static_cast(BLOCK_SIZE_);
+ blockBaseDiff -= static_cast(BLOCK_SIZE);
+ currentTailIndex += static_cast(BLOCK_SIZE);
auto head = this->headIndex.load(std::memory_order_relaxed);
assert(!details::circular_less_than(currentTailIndex, head));
- bool full = !details::circular_less_than(head, currentTailIndex + BLOCK_SIZE_) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE_ < currentTailIndex - head));
+ bool full = !details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head));
if (pr_blockIndexRaw == nullptr || pr_blockIndexSlotsUsed == pr_blockIndexSize || full) {
- if (allocMode == CannotAlloc || full || !new_block_index(originalBlockIndexSlotsUsed)) {
+ MOODYCAMEL_CONSTEXPR_IF (allocMode == CannotAlloc) {
+ // Failed to allocate, undo changes (but keep injected blocks)
+ pr_blockIndexFront = originalBlockIndexFront;
+ pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed;
+ this->tailBlock = startBlock == nullptr ? firstAllocatedBlock : startBlock;
+ return false;
+ }
+ else if (full || !new_block_index(originalBlockIndexSlotsUsed)) {
// Failed to allocate, undo changes (but keep injected blocks)
pr_blockIndexFront = originalBlockIndexFront;
pr_blockIndexSlotsUsed = originalBlockIndexSlotsUsed;
@@ -2045,7 +2106,7 @@ class ConcurrentQueue
return false;
}
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
newBlock->owner = this;
#endif
newBlock->ConcurrentQueue::Block::template set_all_empty();
@@ -2078,7 +2139,7 @@ class ConcurrentQueue
block = block->next;
}
- if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) {
+ MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (static_cast(nullptr)) T(details::deref_noexcept(itemFirst)))) {
blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release);
}
}
@@ -2088,16 +2149,16 @@ class ConcurrentQueue
currentTailIndex = startTailIndex;
auto endBlock = this->tailBlock;
this->tailBlock = startBlock;
- assert((startTailIndex & static_cast(BLOCK_SIZE_ - 1)) != 0 || firstAllocatedBlock != nullptr || count == 0);
- if ((startTailIndex & static_cast(BLOCK_SIZE_ - 1)) == 0 && firstAllocatedBlock != nullptr) {
+ assert((startTailIndex & static_cast(BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock != nullptr || count == 0);
+ if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0 && firstAllocatedBlock != nullptr) {
this->tailBlock = firstAllocatedBlock;
}
while (true) {
- auto stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE_ - 1)) + static_cast(BLOCK_SIZE_);
+ index_t stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE);
if (details::circular_less_than(newTailIndex, stopIndex)) {
stopIndex = newTailIndex;
}
- if (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))) {
+ MOODYCAMEL_CONSTEXPR_IF (MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (static_cast(nullptr)) T(details::deref_noexcept(itemFirst)))) {
while (currentTailIndex != stopIndex) {
new ((*this->tailBlock)[currentTailIndex++]) T(*itemFirst++);
}
@@ -2112,7 +2173,7 @@ class ConcurrentQueue
// may only define a (noexcept) move constructor, and so calls to the
// cctor will not compile, even if they are in an if branch that will never
// be executed
- new ((*this->tailBlock)[currentTailIndex]) T(details::nomove_if<(bool)!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst)))>::eval(*itemFirst));
+ new ((*this->tailBlock)[currentTailIndex]) T(details::nomove_if(nullptr)) T(details::deref_noexcept(itemFirst)))>::eval(*itemFirst));
++currentTailIndex;
++itemFirst;
}
@@ -2130,12 +2191,12 @@ class ConcurrentQueue
if (!details::is_trivially_destructible::value) {
auto block = startBlock;
- if ((startTailIndex & static_cast(BLOCK_SIZE_ - 1)) == 0) {
+ if ((startTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) {
block = firstAllocatedBlock;
}
currentTailIndex = startTailIndex;
while (true) {
- stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE_ - 1)) + static_cast(BLOCK_SIZE_);
+ stopIndex = (currentTailIndex & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE);
if (details::circular_less_than(constructedStopIndex, stopIndex)) {
stopIndex = constructedStopIndex;
}
@@ -2159,8 +2220,9 @@ class ConcurrentQueue
this->tailBlock = this->tailBlock->next;
}
- if (!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (nullptr) T(details::deref_noexcept(itemFirst))) && firstAllocatedBlock != nullptr) {
- blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release);
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, decltype(*itemFirst), new (static_cast(nullptr)) T(details::deref_noexcept(itemFirst)))) {
+ if (firstAllocatedBlock != nullptr)
+ blockIndex.load(std::memory_order_relaxed)->front.store((pr_blockIndexFront - 1) & (pr_blockIndexSize - 1), std::memory_order_release);
}
this->tailIndex.store(newTailIndex, std::memory_order_release);
@@ -2177,7 +2239,7 @@ class ConcurrentQueue
desiredCount = desiredCount < max ? desiredCount : max;
std::atomic_thread_fence(std::memory_order_acquire);
- auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed);;
+ auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed);
tail = this->tailIndex.load(std::memory_order_acquire);
auto actualCount = static_cast(tail - (myDequeueCount - overcommit));
@@ -2196,15 +2258,15 @@ class ConcurrentQueue
auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire);
auto headBase = localBlockIndex->entries[localBlockIndexHead].base;
- auto firstBlockBaseIndex = firstIndex & ~static_cast(BLOCK_SIZE_ - 1);
- auto offset = static_cast(static_cast::type>(firstBlockBaseIndex - headBase) / BLOCK_SIZE_);
+ auto firstBlockBaseIndex = firstIndex & ~static_cast(BLOCK_SIZE - 1);
+ auto offset = static_cast(static_cast::type>(firstBlockBaseIndex - headBase) / BLOCK_SIZE);
auto indexIndex = (localBlockIndexHead + offset) & (localBlockIndex->size - 1);
// Iterate the blocks and dequeue
auto index = firstIndex;
do {
auto firstIndexInBlock = index;
- auto endIndex = (index & ~static_cast(BLOCK_SIZE_ - 1)) + static_cast(BLOCK_SIZE_);
+ index_t endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE);
endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex;
auto block = localBlockIndex->entries[indexIndex].block;
if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, details::deref_noexcept(itemFirst) = std::move((*(*block)[index])))) {
@@ -2238,7 +2300,7 @@ class ConcurrentQueue
indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1);
firstIndexInBlock = index;
- endIndex = (index & ~static_cast(BLOCK_SIZE_ - 1)) + static_cast(BLOCK_SIZE_);
+ endIndex = (index & ~static_cast(BLOCK_SIZE - 1)) + static_cast(BLOCK_SIZE);
endIndex = details::circular_less_than(firstIndex + static_cast(actualCount), endIndex) ? firstIndex + static_cast(actualCount) : endIndex;
} while (index != firstIndex + actualCount);
@@ -2331,7 +2393,7 @@ class ConcurrentQueue
private:
#endif
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
friend struct MemStats;
#endif
};
@@ -2343,8 +2405,8 @@ class ConcurrentQueue
struct ImplicitProducer : public ProducerBase
{
- ImplicitProducer(ConcurrentQueue* parent) :
- ProducerBase(parent, false),
+ ImplicitProducer(ConcurrentQueue* parent_) :
+ ProducerBase(parent_, false),
nextBlockIndexCapacity(IMPLICIT_INITIAL_INDEX_SIZE),
blockIndex(nullptr)
{
@@ -2372,7 +2434,7 @@ class ConcurrentQueue
assert(index == tail || details::circular_less_than(index, tail));
bool forceFreeLastBlock = index != tail; // If we enter the loop, then the last (tail) block will not be freed
while (index != tail) {
- if ((index & static_cast(BLOCK_SIZE_ - 1)) == 0 || block == nullptr) {
+ if ((index & static_cast(BLOCK_SIZE - 1)) == 0 || block == nullptr) {
if (block != nullptr) {
// Free the old block
this->parent->add_block_to_free_list(block);
@@ -2387,7 +2449,7 @@ class ConcurrentQueue
// Even if the queue is empty, there's still one block that's not on the free list
// (unless the head index reached the end of it, in which case the tail will be poised
// to create a new block).
- if (this->tailBlock != nullptr && (forceFreeLastBlock || (tail & static_cast(BLOCK_SIZE_ - 1)) != 0)) {
+ if (this->tailBlock != nullptr && (forceFreeLastBlock || (tail & static_cast(BLOCK_SIZE - 1)) != 0)) {
this->parent->add_block_to_free_list(this->tailBlock);
}
@@ -2411,14 +2473,14 @@ class ConcurrentQueue
{
index_t currentTailIndex = this->tailIndex.load(std::memory_order_relaxed);
index_t newTailIndex = 1 + currentTailIndex;
- if ((currentTailIndex & static_cast(BLOCK_SIZE_ - 1)) == 0) {
+ if ((currentTailIndex & static_cast(BLOCK_SIZE - 1)) == 0) {
// We reached the end of a block, start a new one
auto head = this->headIndex.load(std::memory_order_relaxed);
assert(!details::circular_less_than(currentTailIndex, head));
- if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE_) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE_ < currentTailIndex - head))) {
+ if (!details::circular_less_than(head, currentTailIndex + BLOCK_SIZE) || (MAX_SUBQUEUE_SIZE != details::const_numeric_max::value && (MAX_SUBQUEUE_SIZE == 0 || MAX_SUBQUEUE_SIZE - BLOCK_SIZE < currentTailIndex - head))) {
return false;
}
-#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
+#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
debug::DebugLock lock(mutex);
#endif
// Find out where we'll be inserting this block in the block index
@@ -2434,12 +2496,12 @@ class ConcurrentQueue
idxEntry->value.store(nullptr, std::memory_order_relaxed);
return false;
}
-#if MCDBGQ_TRACKMEM
+#ifdef MCDBGQ_TRACKMEM
newBlock->owner = this;
#endif
newBlock->ConcurrentQueue::Block::template reset_empty();
-
- if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) {
+
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast(nullptr)) T(std::forward(element)))) {
// May throw, try to insert now before we publish the fact that we have this new block
MOODYCAMEL_TRY {
new ((*newBlock)[currentTailIndex]) T(std::forward(element));
@@ -2457,7 +2519,7 @@ class ConcurrentQueue
this->tailBlock = newBlock;
- if (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (nullptr) T(std::forward(element)))) {
+ MOODYCAMEL_CONSTEXPR_IF (!MOODYCAMEL_NOEXCEPT_CTOR(T, U, new (static_cast(nullptr)) T(std::forward(element)))) {
this->tailIndex.store(newTailIndex, std::memory_order_release);
return true;
}
@@ -2492,7 +2554,7 @@ class ConcurrentQueue
auto& el = *((*block)[index]);
if (!MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, element = std::move(el))) {
-#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
+#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
// Note: Acquiring the mutex with every dequeue instead of only when a block
// is released is very sub-optimal, but it is, after all, purely debug code.
debug::DebugLock lock(producer->mutex);
@@ -2512,16 +2574,16 @@ class ConcurrentQueue
}
}
} guard = { block, index, entry, this->parent };
-
- element = std::move(el);
+
+ element = std::move(el); // NOLINT
}
else {
- element = std::move(el);
- el.~T();
-
+ element = std::move(el); // NOLINT
+ el.~T(); // NOLINT
+
if (block->ConcurrentQueue::Block::template set_empty(index)) {
{
-#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
+#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
debug::DebugLock lock(mutex);
#endif
// Add the block back into the global free pool (and remove from block index)
@@ -2541,6 +2603,10 @@ class ConcurrentQueue
return false;
}
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4706) // assignment within conditional expression
+#endif
template
bool enqueue_bulk(It itemFirst, size_t count)
{
@@ -2559,15 +2625,15 @@ class ConcurrentQueue
auto endBlock = this->tailBlock;
// Figure out how many blocks we'll need to allocate, and do so
- size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE_ - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE_ - 1));
- index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE_ - 1);
+ size_t blockBaseDiff = ((startTailIndex + count - 1) & ~static_cast(BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1));
+ index_t currentTailIndex = (startTailIndex - 1) & ~static_cast(BLOCK_SIZE - 1);
if (blockBaseDiff > 0) {
-#if MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
+#ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
debug::DebugLock lock(mutex);
#endif
do {
- blockBaseDiff -= static_cast(BLOCK_SIZE_);
- currentTailIndex += static_cast