diff options
Diffstat (limited to 'winpr/libwinpr/pool/test')
-rw-r--r-- | winpr/libwinpr/pool/test/CMakeLists.txt | 30 | ||||
-rw-r--r-- | winpr/libwinpr/pool/test/TestPoolIO.c | 8 | ||||
-rw-r--r-- | winpr/libwinpr/pool/test/TestPoolSynch.c | 8 | ||||
-rw-r--r-- | winpr/libwinpr/pool/test/TestPoolThread.c | 41 | ||||
-rw-r--r-- | winpr/libwinpr/pool/test/TestPoolTimer.c | 8 | ||||
-rw-r--r-- | winpr/libwinpr/pool/test/TestPoolWork.c | 136 |
6 files changed, 231 insertions, 0 deletions
diff --git a/winpr/libwinpr/pool/test/CMakeLists.txt b/winpr/libwinpr/pool/test/CMakeLists.txt new file mode 100644 index 0000000..9758fff --- /dev/null +++ b/winpr/libwinpr/pool/test/CMakeLists.txt @@ -0,0 +1,30 @@ + +set(MODULE_NAME "TestPool") +set(MODULE_PREFIX "TEST_POOL") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestPoolIO.c + TestPoolSynch.c + TestPoolThread.c + TestPoolTimer.c + TestPoolWork.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +target_link_libraries(${MODULE_NAME} winpr) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/pool/test/TestPoolIO.c b/winpr/libwinpr/pool/test/TestPoolIO.c new file mode 100644 index 0000000..d68586e --- /dev/null +++ b/winpr/libwinpr/pool/test/TestPoolIO.c @@ -0,0 +1,8 @@ + +#include <winpr/crt.h> +#include <winpr/pool.h> + +int TestPoolIO(int argc, char* argv[]) +{ + return 0; +} diff --git a/winpr/libwinpr/pool/test/TestPoolSynch.c b/winpr/libwinpr/pool/test/TestPoolSynch.c new file mode 100644 index 0000000..4d6f381 --- /dev/null +++ b/winpr/libwinpr/pool/test/TestPoolSynch.c @@ -0,0 +1,8 @@ + +#include <winpr/crt.h> +#include <winpr/pool.h> + +int TestPoolSynch(int argc, char* argv[]) +{ + return 0; +} diff --git a/winpr/libwinpr/pool/test/TestPoolThread.c b/winpr/libwinpr/pool/test/TestPoolThread.c new file mode 100644 index 0000000..d006ae6 --- /dev/null +++ b/winpr/libwinpr/pool/test/TestPoolThread.c @@ -0,0 +1,41 @@ + +#include <winpr/crt.h> +#include <winpr/pool.h> + +/** + * Improve Scalability With New Thread Pool APIs: + * http://msdn.microsoft.com/en-us/magazine/cc16332.aspx + * + * Developing with Thread Pool Enhancements: + * http://msdn.microsoft.com/en-us/library/cc308561.aspx + * + * Introduction to the Windows Threadpool: + * http://blogs.msdn.com/b/harip/archive/2010/10/11/introduction-to-the-windows-threadpool-part-1.aspx + * http://blogs.msdn.com/b/harip/archive/2010/10/12/introduction-to-the-windows-threadpool-part-2.aspx + */ + +int TestPoolThread(int argc, char* argv[]) +{ + TP_POOL* pool = NULL; + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!(pool = CreateThreadpool(NULL))) + { + printf("CreateThreadpool failed\n"); + return -1; + } + + if (!SetThreadpoolThreadMinimum(pool, 8)) /* default is 0 */ + { + printf("SetThreadpoolThreadMinimum failed\n"); + return -1; + } + + SetThreadpoolThreadMaximum(pool, 64); /* default is 500 */ + + CloseThreadpool(pool); + + return 0; +} diff --git a/winpr/libwinpr/pool/test/TestPoolTimer.c b/winpr/libwinpr/pool/test/TestPoolTimer.c new file mode 100644 index 0000000..c749bc7 --- /dev/null +++ b/winpr/libwinpr/pool/test/TestPoolTimer.c @@ -0,0 +1,8 @@ + +#include <winpr/crt.h> +#include <winpr/pool.h> + +int TestPoolTimer(int argc, char* argv[]) +{ + return 0; +} diff --git a/winpr/libwinpr/pool/test/TestPoolWork.c b/winpr/libwinpr/pool/test/TestPoolWork.c new file mode 100644 index 0000000..ec50a22 --- /dev/null +++ b/winpr/libwinpr/pool/test/TestPoolWork.c @@ -0,0 +1,136 @@ + +#include <winpr/wtypes.h> +#include <winpr/crt.h> +#include <winpr/pool.h> +#include <winpr/interlocked.h> + +static LONG count = 0; + +static void CALLBACK test_WorkCallback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work) +{ + printf("Hello %s: %03" PRId32 " (thread: 0x%08" PRIX32 ")\n", (char*)context, + InterlockedIncrement(&count), GetCurrentThreadId()); + + for (int index = 0; index < 100; index++) + { + BYTE a[1024]; + BYTE b[1024]; + BYTE c[1024] = { 0 }; + + FillMemory(a, ARRAYSIZE(a), 0xAA); + FillMemory(b, ARRAYSIZE(b), 0xBB); + + CopyMemory(c, a, ARRAYSIZE(a)); + CopyMemory(c, b, ARRAYSIZE(b)); + } +} + +static BOOL test1(void) +{ + PTP_WORK work = NULL; + printf("Global Thread Pool\n"); + work = CreateThreadpoolWork(test_WorkCallback, "world", NULL); + + if (!work) + { + printf("CreateThreadpoolWork failure\n"); + return FALSE; + } + + /** + * You can post a work object one or more times (up to MAXULONG) without waiting for prior + * callbacks to complete. The callbacks will execute in parallel. To improve efficiency, the + * thread pool may throttle the threads. + */ + + for (int index = 0; index < 10; index++) + SubmitThreadpoolWork(work); + + WaitForThreadpoolWorkCallbacks(work, FALSE); + CloseThreadpoolWork(work); + return TRUE; +} + +static BOOL test2(void) +{ + BOOL rc = FALSE; + PTP_POOL pool = NULL; + PTP_WORK work = NULL; + PTP_CLEANUP_GROUP cleanupGroup = NULL; + TP_CALLBACK_ENVIRON environment; + printf("Private Thread Pool\n"); + + if (!(pool = CreateThreadpool(NULL))) + { + printf("CreateThreadpool failure\n"); + return FALSE; + } + + if (!SetThreadpoolThreadMinimum(pool, 4)) + { + printf("SetThreadpoolThreadMinimum failure\n"); + goto fail; + } + + SetThreadpoolThreadMaximum(pool, 8); + InitializeThreadpoolEnvironment(&environment); + SetThreadpoolCallbackPool(&environment, pool); + cleanupGroup = CreateThreadpoolCleanupGroup(); + + if (!cleanupGroup) + { + printf("CreateThreadpoolCleanupGroup failure\n"); + goto fail; + } + + SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL); + work = CreateThreadpoolWork(test_WorkCallback, "world", &environment); + + if (!work) + { + printf("CreateThreadpoolWork failure\n"); + goto fail; + } + + for (int index = 0; index < 10; index++) + SubmitThreadpoolWork(work); + + WaitForThreadpoolWorkCallbacks(work, FALSE); + rc = TRUE; +fail: + + if (cleanupGroup) + { + CloseThreadpoolCleanupGroupMembers(cleanupGroup, TRUE, NULL); + CloseThreadpoolCleanupGroup(cleanupGroup); + DestroyThreadpoolEnvironment(&environment); + /** + * See Remarks at + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682043(v=vs.85).aspx If there + * is a cleanup group associated with the work object, it is not necessary to call + * CloseThreadpoolWork ! calling the CloseThreadpoolCleanupGroupMembers function releases + * the work, wait, and timer objects associated with the cleanup group. + */ +#if 0 + CloseThreadpoolWork(work); // this would segfault, see comment above. */ +#endif + } + + CloseThreadpool(pool); + return rc; +} + +int TestPoolWork(int argc, char* argv[]) +{ + + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + + if (!test1()) + return -1; + + if (!test2()) + return -1; + + return 0; +} |