Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced Thread Pool Implementation #304

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions ddsrouter_cmake/cmake/test/test_target.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,24 @@ function(add_test_executable TEST_EXECUTABLE_NAME TEST_SOURCES TEST_NAME TEST_LI

get_win32_path_dependencies(${TEST_EXECUTABLE_NAME} TEST_FRIENDLY_PATH)

foreach(test_name ${TEST_LIST})
add_test(NAME ${TEST_NAME}.${test_name}
COMMAND ${TEST_EXECUTABLE_NAME}
--gtest_filter=${TEST_NAME}.${test_name}:**/${TEST_NAME}.${test_name}/**)

if(TEST_FRIENDLY_PATH)
set_tests_properties(${TEST_NAME}.${test_name} PROPERTIES ENVIRONMENT "PATH=${TEST_FRIENDLY_PATH}")
endif(TEST_FRIENDLY_PATH)
endforeach()
if( TEST_LIST )
# If list of tests is not empty, add each test separatly
foreach(test_name ${TEST_LIST})
add_test(NAME ${TEST_NAME}.${test_name}
COMMAND ${TEST_EXECUTABLE_NAME}
--gtest_filter=${TEST_NAME}**.${test_name}:**/${TEST_NAME}**.${test_name}/**)

if(TEST_FRIENDLY_PATH)
set_tests_properties(${TEST_NAME}.${test_name} PROPERTIES ENVIRONMENT "PATH=${TEST_FRIENDLY_PATH}")
endif(TEST_FRIENDLY_PATH)
endforeach()
else()
# If no tests are provided, create a single test
message(STATUS "Creating general test ${TEST_NAME}.")
add_test(NAME ${TEST_NAME}
COMMAND ${TEST_EXECUTABLE_NAME})
endif( TEST_LIST )


target_compile_definitions(${TEST_EXECUTABLE_NAME}
PRIVATE FASTDDS_ENFORCE_LOG_INFO
Expand Down
66 changes: 63 additions & 3 deletions ddsrouter_utils/include/ddsrouter_utils/math/math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,85 @@ namespace eprosima {
namespace ddsrouter {
namespace utils {

/**
* @brief Optimize % 2 operation
*
* @param number
*
* @return whether \c number is odd
*/
DDSROUTER_UTILS_DllAPI bool is_even(
uint32_t number) noexcept;

/**
* @brief Module (%) operation with performance optimization
*
* This function optimizes the % operation, that executes a division, by optimizing these cases:
* - If the dividend is smaller or equal than the divisor, the result is the dividend
* - If the dividend is smaller than the divisor, the result is the dividend
* - If the dividend is equal than the divisor, the result is 0
* - If the divisor is 2, the result is the dividend % 2 calculated by a logic AND operation
* - If the divisor is a power of 2, the result is calculated by a logic AND operation
* - Otherwise uses % operation
*
* @param dividend Dividend
* @param divisor Divisor (must be greater than 0 so the operation make sense)
*
* @attention if divisor is 0, the result is \c dividend
* @pre \c divisor must not be 0
*
* @return The result of the operation %
*
* @return The result of the operation
* @attention Do only use this function with non literal values. Literal values are optimized by compiler.
*/
DDSROUTER_UTILS_DllAPI uint32_t fast_module(
uint32_t dividend,
uint32_t divisor) noexcept;

/**
* @brief Integer Division (/) operation with performance optimization
*
* This function optimizes the / operation by optimizing these cases:
* - If \c dividend is smaller or equal than the \c, the result is \c dividend
* - If the \c is 2, the result is \c dividend % 2 calculated by a logic AND operation
* - If the \c is a power of 2, the result is calculated by a logic AND operation
* - Otherwise uses / operation
*
* @param dividend Dividend
* @param divisor Divisor
*
* @pre \c divisor must not be 0
*
* @return The result of the operation /
*
* @attention Do only use this function with non literal values. Literal values are optimized by compiler.
*/
DDSROUTER_UTILS_DllAPI uint32_t fast_division(
uint32_t dividend,
uint32_t divisor) noexcept;

/**
* @brief Calculate the sum of an arithmetic progression from an initial to a final number.
*
* This function uses the fast operation to calculate an arithmetic sum:
* S = ((a1 + an) / 2) * (n)
*
* @pre \c interval must be greater than 0
* @pre \c steps must be greater than 0
*
* @param lowest lowest element of the arithmetic progression
* @param interval interval between two elements of the arithmetic progression
* @param steps number of steps of the arithmetic progression
*
* @return The result of the sum
*
* EXAMPLE OF USE
* 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = arithmetic_progression_sum(1, 1, 10)
* 0 + 2 + 4 + 6 + 8 = arithmetic_progression_sum(0, 2, 5)
*/
DDSROUTER_UTILS_DllAPI uint32_t arithmetic_progression_sum(
uint32_t lowest,
uint32_t interval,
uint32_t steps) noexcept;

} /* namespace utils */
} /* namespace ddsrouter */
} /* namespace eprosima */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* @file OwnedTask.hpp
*
* This file contains class Task definition.
*/

#pragma once

#include <functional>

#include <ddsrouter_utils/thread/task/ITask.hpp>
#include <ddsrouter_utils/thread/manager/IManager.hpp>

namespace eprosima {
namespace ddsrouter {
namespace utils {
namespace thread {

template <typename ... Args>
class OneShotConnector
{
public:

static void execute(IManager* tp, const std::function<void(Args...)>& callback, Args... args);

static void execute(IManager* tp, std::function<void(Args...)>&& callback, Args... args);

};
using SimpleOneShotConnector = OneShotConnector<>;

} /* namespace thread */
} /* namespace utils */
} /* namespace ddsrouter */
} /* namespace eprosima */

// Include implementation template file
#include <ddsrouter_utils/thread/connector/impl/OneShotConnector.ipp>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* @file SlotConnector.hpp
*
* This file contains class SlotConnector definition.
*/

#pragma once

#include <functional>

#include <ddsrouter_utils/thread/task/ITask.hpp>
#include <ddsrouter_utils/thread/manager/IManager.hpp>

namespace eprosima {
namespace ddsrouter {
namespace utils {
namespace thread {

template <typename ... Args>
class SlotConnector
{
public:

SlotConnector(
IManager* manager,
const std::function<void(Args...)>& callback);

SlotConnector(
IManager* manager,
std::function<void(Args...)>&& callback);

~SlotConnector() = default;

void execute(Args...);

protected:

IManager* manager_;

std::function<void (Args...)> callback_;

};
using SimpleSlotConnector = SlotConnector<>;

} /* namespace thread */
} /* namespace utils */
} /* namespace ddsrouter */
} /* namespace eprosima */

// Include implementation template file
#include <ddsrouter_utils/thread/connector/impl/SlotConnector.ipp>
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* @file OneShotConnector.hpp
*
* This file contains class OneShotConnector implementation.
*/

#pragma once

#include <ddsrouter_utils/thread/task/ArgsOwnedTask.hpp>

namespace eprosima {
namespace ddsrouter {
namespace utils {
namespace thread {

template <typename ... Args>
void OneShotConnector<Args...>::execute(
IManager* manager,
const std::function<void(Args...)>& callback,
Args... args)
{
manager->execute(
std::make_unique<ArgsOwnedTask<Args...>>(
callback,
args...
)
);
}

template <typename ... Args>
void OneShotConnector<Args...>::execute(
IManager* manager,
std::function<void(Args...)>&& callback,
Args... args)
{
manager->execute(
std::make_unique<ArgsOwnedTask<Args...>>(
std::move(callback),
args...
)
);
}

// template <typename ... Args>
// void OneShotConnector<Args...>::execute(
// IManager* manager,
// std::function<void(Args...)> callback,
// Args... args)
// {
// manager->execute(
// std::make_unique<ArgsOwnedTask<Args...>>(
// callback,
// args...
// )
// );
// }

} /* namespace thread */
} /* namespace event */
} /* namespace ddsrouter */
} /* namespace eprosima */
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* @file SlotConnector.hpp
*
* This file contains class SlotConnector implementation.
*/

#pragma once

#include <ddsrouter_utils/thread/task/ArgsReferenceTask.hpp>

namespace eprosima {
namespace ddsrouter {
namespace utils {
namespace thread {

template <typename ... Args>
SlotConnector<Args...>::SlotConnector(
IManager* manager,
const std::function<void(Args...)>& callback)
: manager_(manager)
, callback_(callback)
{
}

template <typename ... Args>
SlotConnector<Args...>::SlotConnector(
IManager* manager,
std::function<void(Args...)>&& callback)
: manager_(manager)
, callback_(std::move(callback))
{
}

template <typename ... Args>
void SlotConnector<Args...>::execute(Args... args)
{
manager_->execute(
std::make_unique<ArgsReferenceTask<Args...>>(
&callback_,
args...
)
);
}

} /* namespace thread */
} /* namespace event */
} /* namespace ddsrouter */
} /* namespace eprosima */
Loading