From 7ec14eb603babeca5fc582138f4539af7a445702 Mon Sep 17 00:00:00 2001
From: wangzhengquan <wangzhengquan85@126.com>
Date: 星期二, 19 一月 2021 17:13:51 +0800
Subject: [PATCH] docxygen
---
test/futex_demo.cpp | 161 ++++++++++++++++++++
test_net_socket/CMakeLists.txt | 8
doc/CMakeLists.txt | 28 +++
src/CMakeLists.txt | 55 +++---
test/futex_test.cpp | 148 ++++++++++++++++++
doc/linked-lock-free-code.png | 0
build.sh | 4
CMakeLists.txt | 11 +
doc/基于共享内存的生产者消费者模式的无锁队列的设计方案.md | 2
test/CMakeLists.txt | 22 ++
doc/Doxyfile.in | 4
11 files changed, 401 insertions(+), 42 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 00acf78..a295a37 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.5)
# set the project name and version
-project(B_BUS VERSION 3.0)
+project(B_BUS VERSION 2.2)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
@@ -17,8 +17,13 @@
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/include/usgcommon")
-list(APPEND EXTRA_LIBS ${PROJECT_SOURCE_DIR}/lib/libusgcommon.a pthread)
+list(APPEND EXTRA_LIBS ${PROJECT_SOURCE_DIR}/lib/libusgcommon.a pthread rt)
add_subdirectory(${PROJECT_SOURCE_DIR}/src)
add_subdirectory(${PROJECT_SOURCE_DIR}/test)
-add_subdirectory(${PROJECT_SOURCE_DIR}/test_net_socket)
\ No newline at end of file
+add_subdirectory(${PROJECT_SOURCE_DIR}/test_net_socket)
+# build api doc
+if (CMAKE_BUILD_TYPE MATCHES "^[Rr]elease")
+ # build the docs
+ add_subdirectory(${PROJECT_SOURCE_DIR}/doc)
+endif()
diff --git a/build.sh b/build.sh
index 772ddf4..df18217 100755
--- a/build.sh
+++ b/build.sh
@@ -37,9 +37,9 @@
# -DBUILD_SHARED_LIBS=ON
# -DCMAKE_INSTALL_PREFIX=$(pwd/../dest)
# -DQCA_MAN_INSTALL_DIR:PATH=/usr/share/man
-cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/../dest" -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DSUPPORT_RDMA=OFF ..
+cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/../dest" -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=ON -DSUPPORT_RDMA=OFF ..
cmake --build .
-#cmake --build . --target install
+cmake --build . --target install
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 0000000..95712a7
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1,28 @@
+# first we can indicate the documentation build as an option and set it to ON by default
+option(BUILD_DOC "Build documentation" ON)
+
+# check if Doxygen is installed
+find_package(Doxygen)
+if (DOXYGEN_FOUND)
+ # set input and output files
+ set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
+ set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
+
+ # request to configure the file
+ configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
+ message("Doxygen build started")
+
+ # note the option ALL which allows to build the docs together with the application
+ add_custom_target( doc_doxygen ALL
+ COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating API documentation with Doxygen"
+ VERBATIM )
+
+ install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/api"
+ DESTINATION doc
+ )
+
+else (DOXYGEN_FOUND)
+ message("Doxygen need to be installed to generate the doxygen documentation. To install type common `sudo apt install -y doxygen texlive-latex-base graphviz` ")
+endif (DOXYGEN_FOUND)
diff --git a/Doxyfile b/doc/Doxyfile.in
similarity index 98%
rename from Doxyfile
rename to doc/Doxyfile.in
index b7ad6bb..468cb0a 100644
--- a/Doxyfile
+++ b/doc/Doxyfile.in
@@ -58,7 +58,7 @@
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
-OUTPUT_DIRECTORY = build/doc
+OUTPUT_DIRECTORY = @CMAKE_CURRENT_BINARY_DIR@/api
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -771,7 +771,7 @@
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
-INPUT = src
+INPUT = @CMAKE_SOURCE_DIR@/src @CMAKE_CURRENT_SOURCE_DIR@
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/doc/code.png b/doc/linked-lock-free-code.png
similarity index 100%
rename from doc/code.png
rename to doc/linked-lock-free-code.png
Binary files differ
diff --git "a/doc/\345\237\272\344\272\216\345\205\261\344\272\253\345\206\205\345\255\230\347\232\204\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205\346\250\241\345\274\217\347\232\204\346\227\240\351\224\201\351\230\237\345\210\227\347\232\204\350\256\276\350\256\241\346\226\271\346\241\210.md" "b/doc/\345\237\272\344\272\216\345\205\261\344\272\253\345\206\205\345\255\230\347\232\204\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205\346\250\241\345\274\217\347\232\204\346\227\240\351\224\201\351\230\237\345\210\227\347\232\204\350\256\276\350\256\241\346\226\271\346\241\210.md"
index 54db603..6d45155 100644
--- "a/doc/\345\237\272\344\272\216\345\205\261\344\272\253\345\206\205\345\255\230\347\232\204\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205\346\250\241\345\274\217\347\232\204\346\227\240\351\224\201\351\230\237\345\210\227\347\232\204\350\256\276\350\256\241\346\226\271\346\241\210.md"
+++ "b/doc/\345\237\272\344\272\216\345\205\261\344\272\253\345\206\205\345\255\230\347\232\204\347\224\237\344\272\247\350\200\205\346\266\210\350\264\271\350\200\205\346\250\241\345\274\217\347\232\204\346\227\240\351\224\201\351\230\237\345\210\227\347\232\204\350\256\276\350\256\241\346\226\271\346\241\210.md"
@@ -15,7 +15,7 @@
## 2 鏃犻攣闃熷垪锛團ree Lock锛夌殑瀹炵幇
鏃犻攣闃熷垪鏄敤缁嗙矑搴︾殑鍘熷瓙閿佸疄鐜扮殑锛屽杩涚▼鎿嶄綔鏃舵棤闃诲骞跺彂鎬ц兘楂樸�傜綉涓婃湁浜旇姳鍏棬鐨勭浉鍏崇畻娉曞疄鐜般�傛垜瀵规瘮浜嗕竴涓嬶紝鍐冲畾閲囩敤涓嬮潰鐨勮繖涓�傝繖涓畻娉曟�ц兘濂芥槸涓�鏂归潰锛屽畠鍚屾椂涔熻В鍐充簡闃熷垪涓虹┖鏃跺苟鍙戞搷浣滃彲鑳藉嚭鐜扮殑闂锛屼互鍙夾BA鐨勯棶棰樸��
-
+
## 3 鐢熶骇鑰呮秷璐硅�呬箣闂寸殑鍗忎綔
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e0913e7..d659558 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -45,34 +45,35 @@
# install rules
install(TARGETS shm_queue DESTINATION lib)
install(FILES
- socket/socket_def.h
- socket/net_conn_pool.h
- socket/bus_server_socket.h
- socket/shm_socket.h
- socket/net_mod_socket.h
- socket/shm_stream_mod_socket.h
- socket/net_mod_server_socket_wrapper.h
- socket/net_mod_socket_io.h
- socket/net_mod_server_socket.h
- socket/shm_mod_socket.h
- socket/net_mod_socket_wrapper.h
- socket/bus_server_socket_wrapper.h
- key_def.h
- bus_error.h
- logger_factory.h
- queue/linked_lock_free_queue.h
- queue/array_lock_free_queue2.h
- queue/array_lock_free_queue.h
- queue/shm_queue.h
- queue/shm_queue_wrapper.h
- queue/lock_free_queue.h
- shm/hashtable.h
- shm/mem_pool.h
- shm/mm.h
- shm/shm_allocator.h
- shm/shm_mm_wraper.h
+ socket/socket_def.h
+ socket/net_conn_pool.h
+ socket/bus_server_socket.h
+ socket/shm_socket.h
+ socket/net_mod_socket.h
+ socket/shm_stream_mod_socket.h
+ socket/net_mod_server_socket_wrapper.h
+ socket/net_mod_socket_io.h
+ socket/net_mod_server_socket.h
+ socket/shm_mod_socket.h
+ socket/net_mod_socket_wrapper.h
+ socket/bus_server_socket_wrapper.h
+ key_def.h
+ bus_error.h
+ px_sem_util.h
+ logger_factory.h
+ queue/linked_lock_free_queue.h
+ queue/array_lock_free_queue2.h
+ queue/array_lock_free_queue.h
+ queue/shm_queue.h
+ queue/lock_free_queue.h
+ shm/hashtable.h
+ shm/mem_pool.h
+ shm/mm.h
+ shm/shm_mm_wrapper.h
+ shm/shm_allocator.h
+
DESTINATION include)
-install(FILES "${PROJECT_BINARY_DIR}/src/BusConfig.h"
+install(FILES "${PROJECT_BINARY_DIR}/src/bus_config.h"
DESTINATION include
)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index eebe164..a853353 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,11 +1,27 @@
# add the executable
add_executable(test1 test1.cpp )
-target_link_libraries(test1 PUBLIC ${EXTRA_LIBS} )
-
-target_include_directories(test1 PUBLIC
+target_link_libraries(test1 PRIVATE ${EXTRA_LIBS} )
+target_include_directories(test1 PRIVATE
"${PROJECT_BINARY_DIR}"
${EXTRA_INCLUDES}
)
+
+add_executable(futex_demo futex_demo.cpp )
+target_link_libraries(futex_demo PRIVATE ${EXTRA_LIBS} )
+target_include_directories(futex_demo PRIVATE
+ "${PROJECT_BINARY_DIR}"
+ ${EXTRA_INCLUDES}
+ )
+
+
+add_executable(futex_test futex_test.cpp )
+target_link_libraries(futex_test PRIVATE ${EXTRA_LIBS} )
+target_include_directories(futex_test PRIVATE
+ "${PROJECT_BINARY_DIR}"
+ ${EXTRA_INCLUDES}
+ )
+
+
# add the install targets
install(TARGETS test1 DESTINATION bin)
diff --git a/test/futex_demo.cpp b/test/futex_demo.cpp
new file mode 100644
index 0000000..d6887e8
--- /dev/null
+++ b/test/futex_demo.cpp
@@ -0,0 +1,161 @@
+/* futex_demo.c
+
+Usage: futex_demo [nloops]
+(Default: 5)
+
+Demonstrate the use of futexes in a program where parent and child
+use a pair of futexes located inside a shared anonymous mapping to
+synchronize access to a shared resource: the terminal. The two
+processes each write 'num-loops' messages to the terminal and employ
+a synchronization protocol that ensures that they alternate in
+writing messages.
+*/
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <linux/futex.h>
+#include <sys/time.h>
+#include "usg_common.h"
+#include <sys/mman.h>
+#include <sys/stat.h> /* For mode constants */
+#include <fcntl.h> /* For O_* constants */
+
+
+#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
+} while (0)
+
+static int *futex1, *futex2, *iaddr;
+
+ static int
+futex(int *uaddr, int futex_op, int val,
+ const struct timespec *timeout, int *uaddr2, int val3)
+{
+ return syscall(SYS_futex, uaddr, futex_op, val,
+ timeout, uaddr, val3);
+}
+
+/* Acquire the futex pointed to by 'futexp': wait for its value to
+ become 1, and then set the value to 0. */
+
+ static void
+fwait(int *futexp)
+{
+ int s;
+
+ /* __sync_bool_compare_and_swap(ptr, oldval, newval) is a gcc
+ built-in function. It atomically performs the equivalent of:
+
+ if (*ptr == oldval)
+ *ptr = newval;
+
+ It returns true if the test yielded true and *ptr was updated.
+ The alternative here would be to employ the equivalent atomic
+ machine-language instructions. For further information, see
+ the GCC Manual. */
+ while (1) {
+
+ /* Is the futex available? */
+
+ if (__sync_bool_compare_and_swap(futexp, 1, 0))
+ break; /* Yes */
+
+ /* Futex is not available; wait */
+
+ s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0);
+ if (s == -1 && errno != EAGAIN)
+ errExit("futex-FUTEX_WAIT");
+ }
+}
+
+/* Release the futex pointed to by 'futexp': if the futex currently
+ has the value 0, set its value to 1 and the wake any futex waiters,
+ so that if the peer is blocked in fpost(), it can proceed. */
+
+ static void
+fpost(int *futexp)
+{
+ int s;
+
+ /* __sync_bool_compare_and_swap() was described in comments above */
+
+ if (__sync_bool_compare_and_swap(futexp, 0, 1)) {
+
+ s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0);
+ if (s == -1)
+ errExit("futex-FUTEX_WAKE");
+ }
+}
+
+ int
+main(int argc, char *argv[])
+{
+ pid_t childPid;
+ int j, nloops;
+
+ int flags, opt, fd;
+ mode_t perms;
+ size_t size;
+
+ setbuf(stdout, NULL);
+
+ nloops = (argc > 1) ? atoi(argv[1]) : 5;
+
+ flags = O_RDWR | O_CREAT | O_EXCL;
+ perms = S_IRUSR | S_IWUSR;
+ size = sizeof(int) * 2;
+
+ fd = shm_open("futex_demo", flags, perms);
+ if (fd == -1)
+ errExit("shm_open");
+ if (ftruncate(fd, size) == -1)
+ errExit("ftruncate");
+
+ /* Create a shared anonymous mapping that will hold the futexes.
+ Since the futexes are being shared between processes, we
+ subsequently use the "shared" futex operations (i.e., not the
+ ones suffixed "_PRIVATE") */
+
+ iaddr = (int *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, fd, 0);
+ if (iaddr == MAP_FAILED)
+ errExit("mmap");
+
+ futex1 = &iaddr[0];
+ futex2 = &iaddr[1];
+
+ *futex1 = 0; /* State: unavailable */
+ *futex2 = 1; /* State: available */
+
+ /* Create a child process that inherits the shared anonymous
+ mapping */
+
+ childPid = fork();
+ if (childPid == -1)
+ errExit("fork");
+
+ if (childPid == 0) { /* Child */
+ for (j = 0; j < nloops; j++) {
+ fwait(futex1);
+ printf("Child (%ld) %d\n", (long) getpid(), j);
+ fpost(futex2);
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+
+ /* Parent falls through to here */
+
+ for (j = 0; j < nloops; j++) {
+ fwait(futex2);
+ printf("Parent (%ld) %d\n", (long) getpid(), j);
+ fpost(futex1);
+ }
+
+ wait(NULL);
+
+ exit(EXIT_SUCCESS);
+}
+
diff --git a/test/futex_test.cpp b/test/futex_test.cpp
new file mode 100644
index 0000000..55d77f4
--- /dev/null
+++ b/test/futex_test.cpp
@@ -0,0 +1,148 @@
+/* futex_demo.c
+
+Usage: futex_demo [nloops]
+(Default: 5)
+
+Demonstrate the use of futexes in a program where parent and child
+use a pair of futexes located inside a shared anonymous mapping to
+synchronize access to a shared resource: the terminal. The two
+processes each write 'num-loops' messages to the terminal and employ
+a synchronization protocol that ensures that they alternate in
+writing messages.
+*/
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <linux/futex.h>
+#include <sys/time.h>
+#include "usg_common.h"
+#include <sys/mman.h>
+#include <sys/stat.h> /* For mode constants */
+#include <fcntl.h> /* For O_* constants */
+
+
+#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
+} while (0)
+
+static int *futex1, *futex2, *iaddr;
+
+ static int
+futex(int *uaddr, int futex_op, int val,
+ const struct timespec *timeout, int *uaddr2, int val3)
+{
+ return syscall(SYS_futex, uaddr, futex_op, val,
+ timeout, uaddr, val3);
+}
+
+/* Acquire the futex pointed to by 'futexp': wait for its value to
+ become 1, and then set the value to 0. */
+
+ static void
+fwait(int *futexp)
+{
+ int s;
+
+ /* __sync_bool_compare_and_swap(ptr, oldval, newval) is a gcc
+ built-in function. It atomically performs the equivalent of:
+
+ if (*ptr == oldval)
+ *ptr = newval;
+
+ It returns true if the test yielded true and *ptr was updated.
+ The alternative here would be to employ the equivalent atomic
+ machine-language instructions. For further information, see
+ the GCC Manual. */
+ while (1) {
+
+ /* Is the futex available? */
+
+ if (__sync_bool_compare_and_swap(futexp, 1, 0))
+ break; /* Yes */
+
+ /* Futex is not available; wait */
+
+ s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0);
+ if (s == -1 && errno != EAGAIN)
+ errExit("futex-FUTEX_WAIT");
+ }
+}
+
+/* Release the futex pointed to by 'futexp': if the futex currently
+ has the value 0, set its value to 1 and the wake any futex waiters,
+ so that if the peer is blocked in fpost(), it can proceed. */
+
+ static void
+fpost(int *futexp)
+{
+ int s;
+
+ /* __sync_bool_compare_and_swap() was described in comments above */
+
+ if (__sync_bool_compare_and_swap(futexp, 0, 1)) {
+
+ s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0);
+ if (s == -1)
+ errExit("futex-FUTEX_WAKE");
+ }
+}
+
+ int
+main(int argc, char *argv[])
+{
+ pid_t childPid;
+ int j, nloops;
+
+ int opt, fd;
+ mode_t perms;
+ size_t size;
+ bool first = true;
+
+ setbuf(stdout, NULL);
+
+ nloops = (argc > 1) ? atoi(argv[1]) : 5;
+
+ perms = S_IRUSR | S_IWUSR;
+ size = sizeof(int) ;
+
+ fd = shm_open("futex_test", O_RDWR | O_CREAT | O_EXCL, perms);
+ if (fd == -1 && errno == EEXIST) {
+ fd = shm_open("futex_test", O_RDWR, perms);
+ first = false;
+ }
+
+ if(fd == -1) {
+ errExit("shm_open");
+ }
+ if (ftruncate(fd, size) == -1)
+ errExit("ftruncate");
+
+ /* Create a shared anonymous mapping that will hold the futexes.
+ Since the futexes are being shared between processes, we
+ subsequently use the "shared" futex operations (i.e., not the
+ ones suffixed "_PRIVATE") */
+
+ iaddr = (int *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (iaddr == MAP_FAILED)
+ errExit("mmap");
+
+ futex1 = iaddr;
+
+ if(first) {
+
+ *futex1 = 1;
+ }
+
+ /* State: available */
+
+ fwait(futex1);
+ printf("(%ld) 杩涘叆浜掓枼鍖篭n", (long) getpid());
+ sleep(5);
+ fpost(futex1);
+
+ exit(EXIT_SUCCESS);
+}
+
diff --git a/test_net_socket/CMakeLists.txt b/test_net_socket/CMakeLists.txt
index 938be49..dddf7f8 100644
--- a/test_net_socket/CMakeLists.txt
+++ b/test_net_socket/CMakeLists.txt
@@ -13,14 +13,14 @@
# add the executable
add_executable(test_net_mod_socket test_net_mod_socket.cpp ${CMAKE_CURRENT_BINARY_DIR}/net_mod_socket.sh)
-target_link_libraries(test_net_mod_socket PUBLIC shm_queue ${EXTRA_LIBS} )
+target_link_libraries(test_net_mod_socket PRIVATE shm_queue ${EXTRA_LIBS} )
add_executable(heart_beat heart_beat.cpp ${CMAKE_CURRENT_BINARY_DIR}/heart_beat.sh)
-target_link_libraries(heart_beat PUBLIC shm_queue )
-# target_link_libraries(heart_beat PUBLIC shm_queue ${EXTRA_LIBS} )
+target_link_libraries(heart_beat PRIVATE shm_queue )
+# target_link_libraries(heart_beat PRIVATE shm_queue ${EXTRA_LIBS} )
-target_include_directories(test_net_mod_socket PUBLIC
+target_include_directories(test_net_mod_socket PRIVATE
"${PROJECT_BINARY_DIR}"
${EXTRA_INCLUDES}
)
--
Gitblit v1.8.0