Skip to content

Commit

Permalink
Merge pull request #5 from SuperV1234/master
Browse files Browse the repository at this point in the history
Make library easy to install, put everything into `tp` namespace, add optional `boost::future` support
  • Loading branch information
inkooboo authored Jan 6, 2017
2 parents 3550bd8 + 28cdbe0 commit dd570aa
Show file tree
Hide file tree
Showing 18 changed files with 934 additions and 712 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
boost*
build*
thread_pool-build*
*.pro.user
*.pro.user
*.user
23 changes: 16 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
# thread-poll-cpp build script
cmake_minimum_required(VERSION 3.0)

project(thread-pool-cpp)
list(APPEND CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")

cmake_minimum_required(VERSION 2.8)
project(thread-pool-cpp)
add_definitions(-std=c++14 -Wall -Werror -O3)

ADD_DEFINITIONS(
-std=c++1y -Wall -Werror -O3
)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thread_pool)
# Get all include files
set(THREAD_POOL_CPP_INC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/")
include_directories("${THREAD_POOL_CPP_INC_DIR}")
file(GLOB_RECURSE INSTALL_FILES_LIST "${THREAD_POOL_CPP_INC_DIR}/*")

add_subdirectory(tests)
add_subdirectory(benchmark)

# Install as header-only library
set_source_files_properties(${INSTALL_FILES_LIST} PROPERTIES HEADER_FILE_ONLY 1)
add_library(HEADER_ONLY_TARGET STATIC ${INSTALL_FILES_LIST})
set_target_properties(HEADER_ONLY_TARGET PROPERTIES LINKER_LANGUAGE CXX)
install(DIRECTORY ${THREAD_POOL_CPP_INC_DIR} DESTINATION "include")
2 changes: 2 additions & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#benchmark

include_directories("${THREAD_POOL_CPP_INC_DIR}")

find_package(Boost REQUIRED COMPONENTS system)

include_directories(${CMAKE_CURRENT_SOURCE_DIR})
Expand Down
123 changes: 73 additions & 50 deletions benchmark/benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,141 +12,161 @@
#include <vector>
#include <future>

using namespace tp;

using ThreadPoolStd = ThreadPool<>;

static const size_t CONCURRENCY = 16;
static const size_t REPOST_COUNT = 1000000;

struct Heavy {
struct Heavy
{
bool verbose;
std::vector<char> resource;

Heavy(bool verbose = false)
: verbose(verbose)
, resource(100*1024*1024)
Heavy(bool verbose = false) : verbose(verbose), resource(100 * 1024 * 1024)
{
if (verbose) {
if(verbose)
{
std::cout << "heavy default constructor" << std::endl;
}
}

Heavy(const Heavy &o)
: verbose(o.verbose)
, resource(o.resource)
Heavy(const Heavy& o) : verbose(o.verbose), resource(o.resource)
{
if (verbose) {
if(verbose)
{
std::cout << "heavy copy constructor" << std::endl;
}
}

Heavy(Heavy &&o)
: verbose(o.verbose)
, resource(std::move(o.resource))
Heavy(Heavy&& o) : verbose(o.verbose), resource(std::move(o.resource))
{
if (verbose) {
if(verbose)
{
std::cout << "heavy move constructor" << std::endl;
}
}

Heavy & operator==(const Heavy &o)
Heavy& operator==(const Heavy& o)
{
verbose = o.verbose;
resource = o.resource;
if (verbose) {
if(verbose)
{
std::cout << "heavy copy operator" << std::endl;
}
return *this;
}

Heavy & operator==(const Heavy &&o)
Heavy& operator==(const Heavy&& o)
{
verbose = o.verbose;
resource = std::move(o.resource);
if (verbose) {
if(verbose)
{
std::cout << "heavy move operator" << std::endl;
}
return *this;
}

~Heavy()
{
if (verbose) {
std::cout << "heavy destructor. " << (resource.size() ? "Owns resource" : "Doesn't own resource") << std::endl;
if(verbose)
{
std::cout << "heavy destructor. "
<< (resource.size() ? "Owns resource"
: "Doesn't own resource")
<< std::endl;
}
}
};


struct RepostJob {
//Heavy heavy;
struct RepostJob
{
// Heavy heavy;

ThreadPool *thread_pool;
ThreadPoolStd* thread_pool;
#ifndef WITHOUT_ASIO
AsioThreadPool *asio_thread_pool;
AsioThreadPool* asio_thread_pool;
#endif

volatile size_t counter;
long long int begin_count;
std::promise<void> *waiter;
std::promise<void>* waiter;

RepostJob(ThreadPool *thread_pool, std::promise<void> *waiter)
RepostJob(ThreadPoolStd* thread_pool, std::promise<void>* waiter)
: thread_pool(thread_pool)
#ifndef WITHOUT_ASIO
, asio_thread_pool(0)
,
asio_thread_pool(0)
#endif
, counter(0)
, waiter(waiter)
,
counter(0), waiter(waiter)
{
begin_count = std::chrono::high_resolution_clock::now().time_since_epoch().count();
begin_count = std::chrono::high_resolution_clock::now()
.time_since_epoch()
.count();
}

#ifndef WITHOUT_ASIO
RepostJob(AsioThreadPool *asio_thread_pool, std::promise<void> *waiter)
: thread_pool(0)
, asio_thread_pool(asio_thread_pool)
, counter(0)
, waiter(waiter)
RepostJob(AsioThreadPool* asio_thread_pool, std::promise<void>* waiter)
: thread_pool(0), asio_thread_pool(asio_thread_pool), counter(0),
waiter(waiter)
{
begin_count = std::chrono::high_resolution_clock::now().time_since_epoch().count();
begin_count = std::chrono::high_resolution_clock::now()
.time_since_epoch()
.count();
}
#endif

void operator()()
{
if (counter++ < REPOST_COUNT) {
if(counter++ < REPOST_COUNT)
{
#ifndef WITHOUT_ASIO
if (asio_thread_pool) {
if(asio_thread_pool)
{
asio_thread_pool->post(*this);
return;
}
#endif
if (thread_pool) {
if(thread_pool)
{
thread_pool->post(*this);
return;
}
}
else {
long long int end_count = std::chrono::high_resolution_clock::now().time_since_epoch().count();
std::cout << "reposted " << counter
<< " in " << (double)(end_count - begin_count)/(double)1000000 << " ms"
<< std::endl;
else
{
long long int end_count = std::chrono::high_resolution_clock::now()
.time_since_epoch()
.count();
std::cout << "reposted " << counter << " in "
<< (double)(end_count - begin_count) / (double)1000000
<< " ms" << std::endl;
waiter->set_value();
}
}
};

int main(int, const char *[])
int main(int, const char* [])
{
std::cout << "Benchmark job reposting" << std::endl;

{
std::cout << "***thread pool cpp***" << std::endl;

std::promise<void> waiters[CONCURRENCY];
ThreadPool thread_pool;
for (auto &waiter : waiters) {
ThreadPoolStd thread_pool;
for(auto& waiter : waiters)
{
thread_pool.post(RepostJob(&thread_pool, &waiter));
}

for (auto &waiter : waiters) {
for(auto& waiter : waiters)
{
waiter.get_future().wait();
}
}
Expand All @@ -156,18 +176,21 @@ int main(int, const char *[])
std::cout << "***asio thread pool***" << std::endl;

size_t workers_count = std::thread::hardware_concurrency();
if (0 == workers_count) {
if(0 == workers_count)
{
workers_count = 1;
}

AsioThreadPool asio_thread_pool(workers_count);

std::promise<void> waiters[CONCURRENCY];
for (auto &waiter : waiters) {
for(auto& waiter : waiters)
{
asio_thread_pool.post(RepostJob(&asio_thread_pool, &waiter));
}

for (auto &waiter : waiters) {
for(auto& waiter : waiters)
{
waiter.get_future().wait();
}
}
Expand Down
86 changes: 86 additions & 0 deletions cmake/Findthread-pool-cpp.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright (c) 2015-2016 Vittorio Romeo
# License: Academic Free License ("AFL") v. 3.0
# AFL License page: http://opensource.org/licenses/AFL-3.0
# http://vittorioromeo.info | [email protected]

# Adapted from Louise Dionne's FindHana.cmake file

# Copyright Louis Dionne 2015
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

# TODO: document variables:
# THREAD_POOL_CPP_FOUND
# THREAD_POOL_CPP_INCLUDE_DIR
# THREAD_POOL_CPP_CLONE_DIR
# THREAD_POOL_CPP_ENABLE_TESTS

find_path(
THREAD_POOL_CPP_INCLUDE_DIR

NAMES vrm/core.hpp
DOC "Include directory for the thread-pool-cpp library"

PATH_SUFFIXES include/

PATHS
"${PROJECT_SOURCE_DIR}/../thread-pool-cpp/"
"${PROJECT_SOURCE_DIR}/../thread_pool_cpp/"
${THREAD_POOL_CPP_ROOT}
$ENV{THREAD_POOL_CPP_ROOT}
/usr/local/
/usr/
/sw/
/opt/local/
/opt/csw/
/opt/
"${PROJECT_SOURCE_DIR}/extlibs/thread-pool-cpp/"
"${PROJECT_SOURCE_DIR}/extlibs/thread_pool_cpp/"
"${CMAKE_CURRENT_LIST_DIR}/../../"

NO_DEFAULT_PATH
)

if (NOT EXISTS "${THREAD_POOL_CPP_INCLUDE_DIR}" AND DEFINED THREAD_POOL_CPP_CLONE_DIR)
set(_build_dir "${CMAKE_CURRENT_BINARY_DIR}/thread-pool-cpp")

if (DEFINED THREAD_POOL_CPP_ENABLE_TESTS)
set(_test_cmd ${CMAKE_COMMAND} --build ${_build_dir} --target check)
else()
set(_test_cmd "")
endif()

include(ExternalProject)
ExternalProject_Add(thread_pool_cpp
PREFIX ${_build_dir}
STAMP_DIR ${_build_dir}/_stamps
TMP_DIR ${_build_dir}/_tmp

# Since we don't have any files to download, we set the DOWNLOAD_DIR
# to TMP_DIR to avoid creating a useless empty directory.
DOWNLOAD_DIR ${_build_dir}/_tmp

# Download step
GIT_REPOSITORY https://github.com/SuperV1234/thread-pool-cpp
GIT_TAG master
TIMEOUT 20

# Configure step
SOURCE_DIR "${THREAD_POOL_CPP_CLONE_DIR}"
CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}

BINARY_DIR "${_build_dir}"
BUILD_COMMAND ""

# Install step (nothing to be done)
INSTALL_COMMAND ""

# Test step
TEST_COMMAND ${_test_cmd}
)

set(THREAD_POOL_CPP_INCLUDE_DIR "${THREAD_POOL_CPP_CLONE_DIR}/include")
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(THREAD_POOL_CPP DEFAULT_MSG THREAD_POOL_CPP_INCLUDE_DIR)
3 changes: 3 additions & 0 deletions include/thread_pool.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

#include "./thread_pool/thread_pool.hpp"
Loading

0 comments on commit dd570aa

Please sign in to comment.