Skip to content

Commit

Permalink
Fix/posix sleep (#3705)
Browse files Browse the repository at this point in the history
* fix(Thread_POSIX): sleep() poor performance #3703

* chore(vscode): add file associations

* fix(TaskManager): waits for all threads in the ThreadPool #3704

* fix(Thread): call std::this_thread::sleep_for() to sleep #3703

* fix(PollSet): wakeup fd is never read #3708

* feat(Thread): Add Thread::set/getAffinity() #3709

* doc(Thread): Thread::trySleep() assertion #3710

* fix(PollSet): wakeup fd is never read (windows portion and some other optimizations) #3708

* feat(SocketReactor): improvements #3713

* chore(ThreadTest): add missing include

* fix(PollSet): wakeup fd is never read #3708

* fix(Any): #3682 #3683 #3692 #3712

* fix(mingw): lowercase winsock2 and iphlpapi to allow cross compile #3711

* feat(Thread): Add Thread::set/getAffinity() #3709

* chore(SocketReactor): one-liners inlined, removed redundant try/catch in dospatch, remove unused onBusy()

* feat(SocketReactor): add socket to ErrorNotification

* fix(SocketReactor): pollTimeout assignment and ConnectorTest leak
  • Loading branch information
aleks-f authored Jul 26, 2022
1 parent d1b398d commit 86a4f00
Show file tree
Hide file tree
Showing 26 changed files with 555 additions and 272 deletions.
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@
"__bits": "cpp",
"variant": "cpp",
"condition_variable": "cpp",
"valarray": "cpp"
"valarray": "cpp",
"strstream": "cpp",
"future": "cpp",
"shared_mutex": "cpp"
},
"files.exclude": {
"**/.dep": true,
Expand Down
2 changes: 1 addition & 1 deletion Foundation/include/Poco/Any.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ union Placeholder
public:
struct Size
{
static const unsigned int value = SizeV;
enum { value = SizeV };
};

Placeholder(const Placeholder&) = delete;
Expand Down
20 changes: 14 additions & 6 deletions Foundation/include/Poco/TaskManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,17 @@ class Foundation_API TaskManager
using TaskPtr = AutoPtr<Task>;
using TaskList = std::list<TaskPtr>;

TaskManager();
/// Creates the TaskManager, using the
/// default ThreadPool.
TaskManager(const std::string& name = "",
int minCapacity = 2,
int maxCapacity = 16,
int idleTime = 60,
int stackSize = POCO_THREAD_STACK_SIZE);
/// Creates the TaskManager.

TaskManager(ThreadPool& pool);
/// Creates the TaskManager, using the
/// given ThreadPool.
/// given ThreadPool (should be used
/// by this TaskManager exclusively).

~TaskManager();
/// Destroys the TaskManager.
Expand Down Expand Up @@ -110,11 +114,15 @@ class Foundation_API TaskManager
void taskFailed(Task* pTask, const Exception& exc);

private:
using MutexT = FastMutex;
using ScopedLockT = MutexT::ScopedLock;

ThreadPool& _threadPool;
bool _ownPool;
TaskList _taskList;
Timestamp _lastProgressNotification;
NotificationCenter _nc;
mutable FastMutex _mutex;
mutable MutexT _mutex;

friend class Task;
};
Expand All @@ -125,7 +133,7 @@ class Foundation_API TaskManager
//
inline int TaskManager::count() const
{
FastMutex::ScopedLock lock(_mutex);
ScopedLockT lock(_mutex);

return (int) _taskList.size();
}
Expand Down
36 changes: 32 additions & 4 deletions Foundation/include/Poco/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "Poco/Foundation.h"
#include "Poco/Event.h"
#include "Poco/Mutex.h"
#include <thread>
#include <chrono>


#if defined(POCO_OS_FAMILY_WINDOWS)
Expand Down Expand Up @@ -207,6 +209,9 @@ class Foundation_API Thread: private ThreadImpl
/// wakeUp() before calling trySleep() will prevent the next
/// trySleep() call to actually suspend the thread (which, in
/// some scenarios, may be desirable behavior).
///
/// Note that, unlike Thread::sleep(), this function can only
/// be succesfully called from a thread started as Poco::Thread.

void wakeUp();
/// Wakes up the thread which is in the state of interruptible
Expand All @@ -231,6 +236,17 @@ class Foundation_API Thread: private ThreadImpl
static long currentOsTid();
/// Returns the operating system specific thread ID for the current thread.

bool setAffinity(int coreId);
/// Sets the thread affinity to the coreID.
/// Returns true if succesful.
/// Returns false if not succesful or not
/// implemented.

int getAffinity() const;
/// Returns the thread affinity.
/// Negative value means the thread has
/// no CPU core affinity.

protected:
ThreadLocalStorage& tls();
/// Returns a reference to the thread's local storage.
Expand Down Expand Up @@ -317,15 +333,15 @@ inline bool Thread::isRunning() const
}


inline void Thread::sleep(long milliseconds)
inline void Thread::yield()
{
sleepImpl(milliseconds);
yieldImpl();
}


inline void Thread::yield()
inline void Thread::sleep(long milliseconds)
{
yieldImpl();
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
}


Expand Down Expand Up @@ -381,6 +397,18 @@ inline long Thread::currentOsTid()
return currentOsTidImpl();
}

inline bool Thread::setAffinity(int coreId)
{
return setAffinityImpl(coreId);
}


inline int Thread::getAffinity() const
{
return getAffinityImpl();
}


} // namespace Poco


Expand Down
4 changes: 3 additions & 1 deletion Foundation/include/Poco/Thread_POSIX.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,12 @@ class Foundation_API ThreadImpl
void joinImpl();
bool joinImpl(long milliseconds);
bool isRunningImpl() const;
static void sleepImpl(long milliseconds);
static void yieldImpl();
static ThreadImpl* currentImpl();
static TIDImpl currentTidImpl();
static long currentOsTidImpl();
bool setAffinityImpl(int coreID);
int getAffinityImpl() const;

protected:
static void* runnableEntry(void* pThread);
Expand Down Expand Up @@ -146,6 +147,7 @@ class Foundation_API ThreadImpl
bool started;
bool joined;
std::string name;
int affinity;
mutable FastMutex mutex;
};

Expand Down
15 changes: 14 additions & 1 deletion Foundation/include/Poco/Thread_VX.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,12 @@ class Foundation_API ThreadImpl
void joinImpl();
bool joinImpl(long milliseconds);
bool isRunningImpl() const;
static void sleepImpl(long milliseconds);
static void yieldImpl();
static ThreadImpl* currentImpl();
static TIDImpl currentTidImpl();
static long currentOsTidImpl();
bool setAffinityImpl(int coreID);
int getAffinityImpl() const;

protected:
static void runnableEntry(void* pThread, int, int, int, int, int, int, int, int, int);
Expand Down Expand Up @@ -171,6 +172,18 @@ inline ThreadImpl::TIDImpl ThreadImpl::tidImpl() const
}


inline bool ThreadImpl::setAffinityImpl(int)
{
return false;
}


inline int ThreadImpl::getAffinityImpl() const
{
return -1;
}


} // namespace Poco


Expand Down
9 changes: 2 additions & 7 deletions Foundation/include/Poco/Thread_WIN32.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ class Foundation_API ThreadImpl
void joinImpl();
bool joinImpl(long milliseconds);
bool isRunningImpl() const;
static void sleepImpl(long milliseconds);
static void yieldImpl();
static ThreadImpl* currentImpl();
static TIDImpl currentTidImpl();
static long currentOsTidImpl();
bool setAffinityImpl(int);
int getAffinityImpl() const;

protected:
#if defined(_DLL)
Expand Down Expand Up @@ -155,12 +156,6 @@ inline int ThreadImpl::getMaxOSPriorityImpl(int /* policy */)
}


inline void ThreadImpl::sleepImpl(long milliseconds)
{
Sleep(DWORD(milliseconds));
}


inline void ThreadImpl::yieldImpl()
{
Sleep(0);
Expand Down
21 changes: 14 additions & 7 deletions Foundation/include/Poco/Thread_WINCE.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ class Foundation_API ThreadImpl
void joinImpl();
bool joinImpl(long milliseconds);
bool isRunningImpl() const;
static void sleepImpl(long milliseconds);
static void yieldImpl();
static ThreadImpl* currentImpl();
static TIDImpl currentTidImpl();
static long currentOsTidImpl();
bool setAffinityImpl(int);
int getAffinityImpl() const;

protected:
static DWORD WINAPI runnableEntry(LPVOID pThread);
Expand Down Expand Up @@ -151,12 +152,6 @@ inline int ThreadImpl::getMaxOSPriorityImpl(int /* policy */)
}


inline void ThreadImpl::sleepImpl(long milliseconds)
{
Sleep(DWORD(milliseconds));
}


inline void ThreadImpl::yieldImpl()
{
Sleep(0);
Expand All @@ -181,6 +176,18 @@ inline ThreadImpl::TIDImpl ThreadImpl::tidImpl() const
}


inline bool ThreadImpl::setAffinityImpl(int)
{
return false;
}


inline int ThreadImpl::getAffinityImpl() const
{
return -1;
}


} // namespace Poco


Expand Down
6 changes: 4 additions & 2 deletions Foundation/include/Poco/UnWindows.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
#endif
#endif

// disable min/max macros
#define NOMINMAX

#if !defined(POCO_NO_WINDOWS_H)
#include <windows.h>
#ifdef __MINGW32__
#include <Winsock2.h>
#include <Iphlpapi.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
#endif // __MINGW32__
#endif
Expand Down
3 changes: 1 addition & 2 deletions Foundation/src/Task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ void Task::run()
pOwner->taskFailed(this, SystemException("unknown exception"));
}
_state = TASK_FINISHED;
if (pOwner)
pOwner->taskFinished(this);
if (pOwner) pOwner->taskFinished(this);
}


Expand Down
28 changes: 20 additions & 8 deletions Foundation/src/TaskManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Poco/TaskManager.h"
#include "Poco/TaskNotification.h"
#include "Poco/ThreadPool.h"
#include "Poco/Timespan.h"


namespace Poco {
Expand All @@ -23,20 +24,31 @@ namespace Poco {
const int TaskManager::MIN_PROGRESS_NOTIFICATION_INTERVAL = 100000; // 100 milliseconds


TaskManager::TaskManager():
_threadPool(ThreadPool::defaultPool())
TaskManager::TaskManager(const std::string& name,
int minCapacity,
int maxCapacity,
int idleTime,
int stackSize):
_threadPool(*new ThreadPool(name, minCapacity, maxCapacity, idleTime, stackSize)),
_ownPool(true)
{
// prevent skipping the first progress update
_lastProgressNotification -= Timespan(MIN_PROGRESS_NOTIFICATION_INTERVAL*2);
}


TaskManager::TaskManager(ThreadPool& pool):
_threadPool(pool)
_threadPool(pool),
_ownPool(false)
{
// prevent skipping the first progress update
_lastProgressNotification -= Timespan(MIN_PROGRESS_NOTIFICATION_INTERVAL*2);
}


TaskManager::~TaskManager()
{
if (_ownPool) delete &_threadPool;
}


Expand All @@ -46,7 +58,7 @@ void TaskManager::start(Task* pTask)
pAutoTask->setOwner(this);
pAutoTask->setState(Task::TASK_STARTING);

FastMutex::ScopedLock lock(_mutex);
ScopedLockT lock(_mutex);
_taskList.push_back(pAutoTask);
try
{
Expand All @@ -65,7 +77,7 @@ void TaskManager::start(Task* pTask)

void TaskManager::cancelAll()
{
FastMutex::ScopedLock lock(_mutex);
ScopedLockT lock(_mutex);

for (auto& pTask: _taskList)
{
Expand All @@ -82,7 +94,7 @@ void TaskManager::joinAll()

TaskManager::TaskList TaskManager::taskList() const
{
FastMutex::ScopedLock lock(_mutex);
ScopedLockT lock(_mutex);

return _taskList;
}
Expand Down Expand Up @@ -114,7 +126,7 @@ void TaskManager::taskStarted(Task* pTask)

void TaskManager::taskProgress(Task* pTask, float progress)
{
ScopedLockWithUnlock<FastMutex> lock(_mutex);
ScopedLockWithUnlock<MutexT> lock(_mutex);

if (_lastProgressNotification.isElapsed(MIN_PROGRESS_NOTIFICATION_INTERVAL))
{
Expand All @@ -135,7 +147,7 @@ void TaskManager::taskFinished(Task* pTask)
{
_nc.postNotification(new TaskFinishedNotification(pTask));

FastMutex::ScopedLock lock(_mutex);
ScopedLockT lock(_mutex);
for (TaskList::iterator it = _taskList.begin(); it != _taskList.end(); ++it)
{
if (*it == pTask)
Expand Down
Loading

0 comments on commit 86a4f00

Please sign in to comment.