summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/threads
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/threads')
-rw-r--r--ml/dlib/dlib/threads/async.cpp48
-rw-r--r--ml/dlib/dlib/threads/async.h105
-rw-r--r--ml/dlib/dlib/threads/async_abstract.h67
-rw-r--r--ml/dlib/dlib/threads/auto_mutex_extension.h180
-rw-r--r--ml/dlib/dlib/threads/auto_mutex_extension_abstract.h185
-rw-r--r--ml/dlib/dlib/threads/auto_unlock_extension.h116
-rw-r--r--ml/dlib/dlib/threads/auto_unlock_extension_abstract.h116
-rw-r--r--ml/dlib/dlib/threads/create_new_thread_extension.h46
-rw-r--r--ml/dlib/dlib/threads/create_new_thread_extension_abstract.h33
-rw-r--r--ml/dlib/dlib/threads/multithreaded_object_extension.cpp241
-rw-r--r--ml/dlib/dlib/threads/multithreaded_object_extension.h153
-rw-r--r--ml/dlib/dlib/threads/multithreaded_object_extension_abstract.h186
-rw-r--r--ml/dlib/dlib/threads/parallel_for_extension.h676
-rw-r--r--ml/dlib/dlib/threads/parallel_for_extension_abstract.h469
-rw-r--r--ml/dlib/dlib/threads/posix.h6
-rw-r--r--ml/dlib/dlib/threads/read_write_mutex_extension.h177
-rw-r--r--ml/dlib/dlib/threads/read_write_mutex_extension_abstract.h146
-rw-r--r--ml/dlib/dlib/threads/rmutex_extension.h109
-rw-r--r--ml/dlib/dlib/threads/rmutex_extension_abstract.h107
-rw-r--r--ml/dlib/dlib/threads/rsignaler_extension.h90
-rw-r--r--ml/dlib/dlib/threads/rsignaler_extension_abstract.h123
-rw-r--r--ml/dlib/dlib/threads/thread_function_extension.h215
-rw-r--r--ml/dlib/dlib/threads/thread_function_extension_abstract.h146
-rw-r--r--ml/dlib/dlib/threads/thread_pool_extension.cpp347
-rw-r--r--ml/dlib/dlib/threads/thread_pool_extension.h1392
-rw-r--r--ml/dlib/dlib/threads/thread_pool_extension_abstract.h842
-rw-r--r--ml/dlib/dlib/threads/thread_specific_data_extension.h141
-rw-r--r--ml/dlib/dlib/threads/thread_specific_data_extension_abstract.h87
-rw-r--r--ml/dlib/dlib/threads/threaded_object_extension.cpp290
-rw-r--r--ml/dlib/dlib/threads/threaded_object_extension.h123
-rw-r--r--ml/dlib/dlib/threads/threaded_object_extension_abstract.h199
-rw-r--r--ml/dlib/dlib/threads/threads_kernel.h18
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_1.cpp83
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_1.h158
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_2.cpp75
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_2.h180
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_abstract.h302
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_shared.cpp318
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_shared.h274
-rw-r--r--ml/dlib/dlib/threads/windows.h6
40 files changed, 0 insertions, 8575 deletions
diff --git a/ml/dlib/dlib/threads/async.cpp b/ml/dlib/dlib/threads/async.cpp
deleted file mode 100644
index 6aa947bcb..000000000
--- a/ml/dlib/dlib/threads/async.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2016 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_AsYNC_CPP_
-#define DLIB_AsYNC_CPP_
-
-// C++11 things don't work in old versions of visual studio
-#if !defined( _MSC_VER) || _MSC_VER >= 1900
-
-#include "async.h"
-#include <stdlib.h>
-#include "../string.h"
-#include <thread>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- unsigned long default_num_threads()
- {
- try
- {
- char* nt = getenv("DLIB_NUM_THREADS");
- if (nt)
- return string_cast<unsigned long>(nt);
- } catch(string_cast_error&) {}
- return std::thread::hardware_concurrency();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- thread_pool& default_thread_pool()
- {
- static thread_pool tp(impl::default_num_threads());
- return tp;
- }
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif
-
-#endif // DLIB_AsYNC_CPP_
-
-
diff --git a/ml/dlib/dlib/threads/async.h b/ml/dlib/dlib/threads/async.h
deleted file mode 100644
index bc6fe5575..000000000
--- a/ml/dlib/dlib/threads/async.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (C) 2016 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_AsYNC_Hh_
-#define DLIB_AsYNC_Hh_
-
-// C++11 things don't work in old versions of visual studio
-#if !defined( _MSC_VER) || _MSC_VER >= 1900
-
-#include "async_abstract.h"
-#include "thread_pool_extension.h"
-#include <future>
-#include <functional>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename T> struct selector {};
-
- template <typename T, typename U, typename V>
- void call_prom_set_value(
- T& prom,
- U& fun,
- selector<V>
- )
- {
- prom.set_value(fun());
- }
-
- template <typename T, typename U>
- void call_prom_set_value(
- T& prom,
- U& fun,
- selector<void>
- )
- {
- fun();
- prom.set_value();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- thread_pool& default_thread_pool();
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename Function,
- typename ...Args
- >
- std::future<typename std::result_of<Function(Args...)>::type> async(
- thread_pool& tp,
- Function&& f,
- Args&&... args
- )
- {
- auto prom = std::make_shared<std::promise<typename std::result_of<Function(Args...)>::type>>();
- std::future<typename std::result_of<Function(Args...)>::type> ret = prom->get_future();
- using bind_t = decltype(std::bind(std::forward<Function>(f), std::forward<Args>(args)...));
- auto fun = std::make_shared<bind_t>(std::bind(std::forward<Function>(f), std::forward<Args>(args)...));
- tp.add_task_by_value([fun, prom]()
- {
- try
- {
- impl::call_prom_set_value(*prom, *fun, impl::selector<typename std::result_of<Function(Args...)>::type>());
- }
- catch(...)
- {
- prom->set_exception(std::current_exception());
- }
- });
- return std::move(ret);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename Function,
- typename ...Args
- >
- std::future<typename std::result_of<Function(Args...)>::type> async(
- Function&& f,
- Args&&... args
- )
- {
- return async(default_thread_pool(), std::forward<Function>(f), std::forward<Args>(args)...);
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#ifdef NO_MAKEFILE
-#include "async.cpp"
-#endif
-
-#endif
-#endif // DLIB_AsYNC_Hh_
-
-
-
diff --git a/ml/dlib/dlib/threads/async_abstract.h b/ml/dlib/dlib/threads/async_abstract.h
deleted file mode 100644
index a9fa1e458..000000000
--- a/ml/dlib/dlib/threads/async_abstract.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2016 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_AsYNC_ABSTRACT_Hh_
-#ifdef DLIB_AsYNC_ABSTRACT_Hh_
-
-#include "thread_pool_extension_abstract.h"
-#include <future>
-#include <functional>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- thread_pool& default_thread_pool(
- );
- /*!
- ensures
- - returns a reference to a global thread_pool. If the DLIB_NUM_THREADS
- environment variable is set to an integer then the thread pool will contain
- DLIB_NUM_THREADS threads, otherwise it will contain
- std::thread::hardware_concurrency() threads.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename Function,
- typename ...Args
- >
- std::future<typename std::result_of<Function(Args...)>::type> async(
- thread_pool& tp,
- Function&& f,
- Args&&... args
- );
- /*!
- requires
- - f must be a function and f(args...) must be a valid expression.
- ensures
- - This function behaves just like std::async(std::launch::async, f, args)
- except that instead of spawning a new thread to process each task it submits
- the task to the provided dlib::thread_pool. Therefore, dlib::async() is
- guaranteed to use a bounded number of threads unlike std::async(). This also
- means that calls to dlib::async() will block if there aren't any free threads
- in the thread pool.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename Function,
- typename ...Args
- >
- std::future<typename std::result_of<Function(Args...)>::type> async(
- Function&& f,
- Args&&... args
- );
- /*!
- ensures
- - Calling this function is equivalent to directly calling async(default_thread_pool(), f, args...)
- !*/
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_AsYNC_ABSTRACT_Hh_
-
diff --git a/ml/dlib/dlib/threads/auto_mutex_extension.h b/ml/dlib/dlib/threads/auto_mutex_extension.h
deleted file mode 100644
index 595c1b176..000000000
--- a/ml/dlib/dlib/threads/auto_mutex_extension.h
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_AUTO_MUTEX_EXTENSIOn_
-#define DLIB_AUTO_MUTEX_EXTENSIOn_
-
-#include "threads_kernel.h"
-#include "rmutex_extension.h"
-#include "read_write_mutex_extension.h"
-#include "auto_mutex_extension_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class auto_mutex
- {
- /*!
- INITIAL VALUE
- - if (m != 0) then
- - the mutex pointed to by m is locked
- - if (r != 0) then
- - the mutex pointed to by r is locked
- - if (rw != 0) then
- - the mutex pointed to by rw is locked
- - exactly one of r, m, or rw is not 0.
-
- CONVENTION
- - if (m != 0) then
- - the mutex pointed to by m is locked
- - if (r != 0) then
- - the mutex pointed to by r is locked
- - if (rw != 0) then
- - the mutex pointed to by rw is locked
- - exactly one of r, m, or rw is not 0.
- !*/
- public:
-
- explicit auto_mutex (
- const mutex& m_
- ) : m(&m_),
- r(0),
- rw(0)
- {
- m->lock();
- }
-
- explicit auto_mutex (
- const rmutex& r_
- ) : m(0),
- r(&r_),
- rw(0)
- {
- r->lock();
- }
-
- explicit auto_mutex (
- const read_write_mutex& rw_
- ) : m(0),
- r(0),
- rw(&rw_)
- {
- rw->lock();
- }
-
- void unlock()
- {
- if (m != 0)
- {
- m->unlock();
- m = 0;
- }
- else if (r != 0)
- {
- r->unlock();
- r = 0;
- }
- else if (rw != 0)
- {
- rw->unlock();
- rw = 0;
- }
- }
-
- ~auto_mutex (
- )
- {
- unlock();
- }
-
- private:
-
- const mutex* m;
- const rmutex* r;
- const read_write_mutex* rw;
-
- // restricted functions
- auto_mutex(auto_mutex&); // copy constructor
- auto_mutex& operator=(auto_mutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class auto_mutex_readonly
- {
- public:
-
- explicit auto_mutex_readonly (
- const read_write_mutex& rw_
- ) : rw(rw_), _has_write_lock(false), _has_read_lock(true)
- {
- rw.lock_readonly();
- }
-
- ~auto_mutex_readonly (
- )
- {
- unlock();
- }
-
- void lock_readonly (
- )
- {
- if (!_has_read_lock)
- {
- unlock();
- rw.lock_readonly();
- _has_read_lock = true;
- }
- }
-
- void lock_write (
- )
- {
- if (!_has_write_lock)
- {
- unlock();
- rw.lock();
- _has_write_lock = true;
- }
- }
-
- void unlock (
- )
- {
- if (_has_write_lock)
- {
- rw.unlock();
- _has_write_lock = false;
- }
- else if (_has_read_lock)
- {
- rw.unlock_readonly();
- _has_read_lock = false;
- }
- }
-
- bool has_read_lock (
- ) { return _has_read_lock; }
-
- bool has_write_lock (
- ) { return _has_write_lock; }
-
- private:
-
- const read_write_mutex& rw;
- bool _has_write_lock;
- bool _has_read_lock;
-
- // restricted functions
- auto_mutex_readonly(auto_mutex_readonly&); // copy constructor
- auto_mutex_readonly& operator=(auto_mutex_readonly&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_AUTO_MUTEX_EXTENSIOn_
-
diff --git a/ml/dlib/dlib/threads/auto_mutex_extension_abstract.h b/ml/dlib/dlib/threads/auto_mutex_extension_abstract.h
deleted file mode 100644
index 1990c834e..000000000
--- a/ml/dlib/dlib/threads/auto_mutex_extension_abstract.h
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_AUTO_MUTEX_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_AUTO_MUTEX_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-#include "rmutex_extension_abstract.h"
-#include "read_write_mutex_extension_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class auto_mutex
- {
- /*!
- INITIAL VALUE
- The mutex given in the constructor is locked and associated with this
- object.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a mechanism for automatically locking and unlocking
- a mutex object.
- !*/
- public:
-
- explicit auto_mutex (
- const mutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - m will be locked
- !*/
-
- explicit auto_mutex (
- const rmutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - m will be locked
- !*/
-
- explicit auto_mutex (
- const read_write_mutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - m will be locked via m.lock() (i.e. a write lock will be obtained)
- !*/
-
- void unlock(
- );
- /*!
- ensures
- - if (unlock() has not already been called) then
- - The mutex associated with *this has been unlocked. This is useful if
- you want to unlock a mutex before the auto_mutex destructor executes.
- !*/
-
- ~auto_mutex (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed
- - calls unlock()
- !*/
-
- private:
- // restricted functions
- auto_mutex(auto_mutex&); // copy constructor
- auto_mutex& operator=(auto_mutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class auto_mutex_readonly
- {
- /*!
- INITIAL VALUE
- The mutex given in the constructor is locked using a read-only lock and
- associated with this object.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a mechanism for automatically locking and unlocking
- a read_write_mutex object. In particular, a readonly lock is used.
- !*/
- public:
-
- explicit auto_mutex_readonly (
- const read_write_mutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - a readonly lock will be obtained on m using m.lock_readonly()
- - #has_read_lock() == true
- !*/
-
- ~auto_mutex_readonly (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed
- - the mutex associated with *this has been unlocked
- !*/
-
- bool has_read_lock (
- );
- /*!
- ensures
- - returns true if this object has called read_write_mutex::lock_readonly()
- on its associated mutex and has yet to release that lock.
- !*/
-
- bool has_write_lock (
- );
- /*!
- ensures
- - returns true if this object has called read_write_mutex::lock() on its
- associated mutex and has yet to release that lock.
- !*/
-
- void lock_readonly (
- );
- /*!
- ensures
- - This function converts the lock on the associated mutex into a readonly lock.
- Specifically:
- if (!has_read_lock()) then
- - if (has_write_lock()) then
- - unlocks the associated mutex and then relocks it by calling
- read_write_mutex::lock_readonly()
- - else
- - locks the associated mutex by calling read_write_mutex::lock_readonly()
- - #has_read_lock() == true
- - Note that the lock switch is not atomic. This means that whatever
- resource is protected by the mutex might have been modified during the
- call to lock_readonly().
- !*/
-
- void lock_write (
- );
- /*!
- ensures
- - This function converts the lock on the associated mutex into a write lock.
- Specifically:
- if (!has_write_lock()) then
- - if (has_read_lock()) then
- - unlocks the associated mutex and then relocks it by calling
- read_write_mutex::lock()
- - else
- - locks the associated mutex by calling read_write_mutex::lock()
- - #has_write_lock() == true
- - Note that the lock switch is not atomic. This means that whatever
- resource is protected by the mutex might have been modified during the
- call to lock_write().
- !*/
-
- void unlock (
- );
- /*!
- ensures
- - if (has_read_lock() || has_write_lock()) then
- - unlocks the associated mutex. This is useful if you want to unlock a
- mutex before the auto_mutex_readonly destructor executes.
- - #has_read_lock() == false
- - #has_write_lock() == false
- !*/
-
- private:
- // restricted functions
- auto_mutex_readonly(auto_mutex_readonly&); // copy constructor
- auto_mutex_readonly& operator=(auto_mutex_readonly&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_AUTO_MUTEX_EXTENSIOn_ABSTRACT_
-
diff --git a/ml/dlib/dlib/threads/auto_unlock_extension.h b/ml/dlib/dlib/threads/auto_unlock_extension.h
deleted file mode 100644
index cd1d4db9a..000000000
--- a/ml/dlib/dlib/threads/auto_unlock_extension.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_AUTO_UNLOCK_EXTENSIOn_
-#define DLIB_AUTO_UNLOCK_EXTENSIOn_
-
-#include "threads_kernel.h"
-#include "rmutex_extension.h"
-#include "read_write_mutex_extension.h"
-#include "auto_unlock_extension_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class auto_unlock
- {
- /*!
- INITIAL VALUE
- - if (m != 0) then
- - the mutex pointed to by m is locked
- - if (r != 0) then
- - the mutex pointed to by r is locked
- - if (rw != 0) then
- - the mutex pointed to by rw is locked
- - exactly one of r, m, or rw is not 0.
-
- CONVENTION
- - if (m != 0) then
- - the mutex pointed to by m is locked
- - if (r != 0) then
- - the mutex pointed to by r is locked
- - if (rw != 0) then
- - the mutex pointed to by rw is locked
- - exactly one of r, m, or rw is not 0.
- !*/
- public:
-
- explicit auto_unlock (
- const mutex& m_
- ) : m(&m_),
- r(0),
- rw(0)
- {}
-
- explicit auto_unlock (
- const rmutex& r_
- ) : m(0),
- r(&r_),
- rw(0)
- {}
-
- explicit auto_unlock (
- const read_write_mutex& rw_
- ) : m(0),
- r(0),
- rw(&rw_)
- {}
-
- ~auto_unlock (
- )
- {
- if (m != 0)
- m->unlock();
- else if (r != 0)
- r->unlock();
- else
- rw->unlock();
- }
-
- private:
-
- const mutex* m;
- const rmutex* r;
- const read_write_mutex* rw;
-
- // restricted functions
- auto_unlock(auto_unlock&); // copy constructor
- auto_unlock& operator=(auto_unlock&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class auto_unlock_readonly
- {
-
- public:
-
- explicit auto_unlock_readonly (
- const read_write_mutex& rw_
- ) :
- rw(rw_)
- {}
-
- ~auto_unlock_readonly (
- )
- {
- rw.unlock_readonly();
- }
-
- private:
-
- const read_write_mutex& rw;
-
- // restricted functions
- auto_unlock_readonly(auto_unlock_readonly&); // copy constructor
- auto_unlock_readonly& operator=(auto_unlock_readonly&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_AUTO_UNLOCK_EXTENSIOn_
-
-
diff --git a/ml/dlib/dlib/threads/auto_unlock_extension_abstract.h b/ml/dlib/dlib/threads/auto_unlock_extension_abstract.h
deleted file mode 100644
index f947d4879..000000000
--- a/ml/dlib/dlib/threads/auto_unlock_extension_abstract.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_AUTO_UNLOCK_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_AUTO_UNLOCK_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-#include "rmutex_extension_abstract.h"
-#include "read_write_mutex_extension_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class auto_unlock
- {
- /*!
- INITIAL VALUE
- The mutex given in the constructor is associated with this object.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a mechanism for automatically unlocking
- a mutex object. It is useful when you already have a locked mutex
- and want to make sure it gets unlocked even if an exception is thrown
- or you quit the function at a weird spot.
- !*/
- public:
-
- explicit auto_unlock (
- const mutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - does not modify m in any way
- !*/
-
- explicit auto_unlock (
- const rmutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - does not modify m in any way
- !*/
-
- explicit auto_unlock (
- const read_write_mutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - does not modify m in any way
- !*/
-
- ~auto_unlock (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed
- - calls unlock() on the mutex associated with *this
- !*/
-
- private:
- // restricted functions
- auto_unlock(auto_unlock&); // copy constructor
- auto_unlock& operator=(auto_unlock&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- class auto_unlock_readonly
- {
- /*!
- INITIAL VALUE
- The mutex given in the constructor is associated with this object.
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a mechanism for automatically unlocking
- a read_write_mutex object. It is useful when you already have a locked mutex
- and want to make sure it gets unlocked even if an exception is thrown
- or you quit the function at a weird spot. Note that the mutex
- is unlocked by calling unlock_readonly() on it.
- !*/
- public:
-
- explicit auto_unlock_readonly (
- const read_write_mutex& m
- );
- /*!
- ensures
- - #*this is properly initialized
- - does not modify m in any way
- !*/
-
- ~auto_unlock_readonly (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed
- - calls unlock_readonly() on the mutex associated with *this
- !*/
-
- private:
- // restricted functions
- auto_unlock_readonly(auto_unlock_readonly&); // copy constructor
- auto_unlock_readonly& operator=(auto_unlock_readonly&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_AUTO_UNLOCK_EXTENSIOn_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/threads/create_new_thread_extension.h b/ml/dlib/dlib/threads/create_new_thread_extension.h
deleted file mode 100644
index 8f419b6be..000000000
--- a/ml/dlib/dlib/threads/create_new_thread_extension.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_CREATE_NEW_THREAD_EXTENSIOn_
-#define DLIB_CREATE_NEW_THREAD_EXTENSIOn_
-
-#include "threads_kernel_abstract.h"
-#include "create_new_thread_extension_abstract.h"
-#include "../threads.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- void (T::*funct)()
- >
- inline void dlib_create_new_thread_helper (
- void* obj
- )
- {
- T* o = static_cast<T*>(obj);
- (o->*funct)();
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- void (T::*funct)()
- >
- inline bool create_new_thread (
- T& obj
- )
- {
- return create_new_thread(dlib_create_new_thread_helper<T,funct>,&obj);
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_CREATE_NEW_THREAD_EXTENSIOn_
-
-
diff --git a/ml/dlib/dlib/threads/create_new_thread_extension_abstract.h b/ml/dlib/dlib/threads/create_new_thread_extension_abstract.h
deleted file mode 100644
index 43fbc474d..000000000
--- a/ml/dlib/dlib/threads/create_new_thread_extension_abstract.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_CREATE_NEW_THREAD_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_CREATE_NEW_THREAD_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T,
- void (T::*funct)()
- >
- bool create_new_thread (
- T& obj
- );
- /*!
- ensures
- - creates a new thread and calls obj.*funct() from it.
- - returns true upon success and false upon failure to create the new thread.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_CREATE_NEW_THREAD_EXTENSIOn_ABSTRACT_
-
-
-
diff --git a/ml/dlib/dlib/threads/multithreaded_object_extension.cpp b/ml/dlib/dlib/threads/multithreaded_object_extension.cpp
deleted file mode 100644
index def4af5f2..000000000
--- a/ml/dlib/dlib/threads/multithreaded_object_extension.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MULTITHREADED_OBJECT_EXTENSIOn_CPP
-#define DLIB_MULTITHREADED_OBJECT_EXTENSIOn_CPP
-
-#include "multithreaded_object_extension.h"
-#include "create_new_thread_extension.h"
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- multithreaded_object::
- multithreaded_object (
- ):
- s(m_),
- is_running_(false),
- should_stop_(false),
- threads_started(0)
- {
- }
-
-// ----------------------------------------------------------------------------------------
-
- multithreaded_object::
- ~multithreaded_object (
- )
- {
- try
- {
- DLIB_ASSERT(number_of_threads_alive() == 0,
- "\tmultithreaded_object::~multithreaded_object()"
- << "\n\tYou have let a multithreaded object destruct itself before terminating its threads"
- << "\n\tthis: " << this
- );
- }
- catch (std::exception& e)
- {
- std::cerr << e.what() << std::endl;
- assert(false);
- abort();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void multithreaded_object::
- clear (
- )
- {
- auto_mutex M(m_);
- stop();
- wait();
- dead_threads.clear();
- is_running_ = false;
- should_stop_ = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool multithreaded_object::
- is_running (
- ) const
- {
- auto_mutex M(m_);
- return is_running_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long multithreaded_object::
- number_of_threads_registered (
- ) const
- {
- auto_mutex M(m_);
- return thread_ids.size() + dead_threads.size();
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long multithreaded_object::
- number_of_threads_alive (
- ) const
- {
- auto_mutex M(m_);
- return threads_started;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void multithreaded_object::
- wait (
- ) const
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(thread_ids.is_in_domain(get_thread_id()) == false,
- "\tvoid multithreaded_object::wait()"
- << "\n\tYou can NOT call this function from one of the threads registered in this object"
- << "\n\tthis: " << this
- );
-
- while (threads_started > 0)
- s.wait();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void multithreaded_object::
- start (
- )
- {
- auto_mutex M(m_);
- const unsigned long num_threads_registered = dead_threads.size() + thread_ids.size();
- // start any dead threads
- for (unsigned long i = threads_started; i < num_threads_registered; ++i)
- {
- if (create_new_thread<multithreaded_object,&multithreaded_object::thread_helper>(*this) == false)
- {
- should_stop_ = true;
- is_running_ = false;
- throw thread_error();
- }
- ++threads_started;
- }
- is_running_ = true;
- should_stop_ = false;
- s.broadcast();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void multithreaded_object::
- pause (
- )
- {
- auto_mutex M(m_);
- is_running_ = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void multithreaded_object::
- stop (
- )
- {
- auto_mutex M(m_);
- should_stop_ = true;
- is_running_ = false;
- s.broadcast();
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool multithreaded_object::
- should_stop (
- ) const
- {
- auto_mutex M(m_);
- DLIB_ASSERT(thread_ids.is_in_domain(get_thread_id()),
- "\tbool multithreaded_object::should_stop()"
- << "\n\tYou can only call this function from one of the registered threads in this object"
- << "\n\tthis: " << this
- );
- while (is_running_ == false && should_stop_ == false)
- s.wait();
- return should_stop_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- multithreaded_object::raii_thread_helper::
- raii_thread_helper(
- multithreaded_object& self_,
- thread_id_type id_
- ) : self(self_), id(id_){}
-
- multithreaded_object::raii_thread_helper::
- ~raii_thread_helper()
- {
- auto_mutex M(self.m_);
- if (self.thread_ids.is_in_domain(id))
- {
- mfp temp;
- thread_id_type id_temp;
- self.thread_ids.remove(id,id_temp,temp);
- // put this thread's registered function back into the dead_threads queue
- self.dead_threads.enqueue(temp);
- }
-
- --self.threads_started;
- // If this is the last thread to terminate then
- // signal that that is the case.
- if (self.threads_started == 0)
- {
- self.is_running_ = false;
- self.should_stop_ = false;
- self.s.broadcast();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void multithreaded_object::
- thread_helper(
- )
- {
- mfp mf;
- thread_id_type id = get_thread_id();
-
- // this guy's destructor does all the necessary cleanup in this function
- raii_thread_helper raii(*this, id);
-
- // if there is a dead_thread sitting around then pull it
- // out and put it into mf
- {
- auto_mutex M(m_);
- if (dead_threads.size() > 0)
- {
- dead_threads.dequeue(mf);
- mfp temp(mf);
- thread_ids.add(id,temp);
- }
- }
-
- if (mf.is_set())
- {
- // call the registered thread function
- mf();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MULTITHREADED_OBJECT_EXTENSIOn_CPP
-
-
diff --git a/ml/dlib/dlib/threads/multithreaded_object_extension.h b/ml/dlib/dlib/threads/multithreaded_object_extension.h
deleted file mode 100644
index 9dd37fdcc..000000000
--- a/ml/dlib/dlib/threads/multithreaded_object_extension.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_MULTITHREADED_OBJECT_EXTENSIOn_
-#define DLIB_MULTITHREADED_OBJECT_EXTENSIOn_
-
-#include "multithreaded_object_extension_abstract.h"
-#include "threads_kernel.h"
-#include "auto_mutex_extension.h"
-#include "rmutex_extension.h"
-#include "rsignaler_extension.h"
-#include "../algs.h"
-#include "../assert.h"
-#include "../map.h"
-#include "../member_function_pointer.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class multithreaded_object
- {
- /*!
- INITIAL VALUE
- - is_running_ == false
- - should_stop_ == false
- - thread_ids.size() == 0
- - dead_threads.size() == 0
- - threads_started == 0
-
- CONVENTION
- - number_of_threads_registered() == thread_ids.size() + dead_threads.size()
- - number_of_threads_alive() == threads_started
-
- - is_running() == is_running_
- - should_stop() == should_stop_
-
- - thread_ids == a map of current thread ids to the member function
- pointers that that thread runs.
- - threads_started == the number of threads that have been spawned to run
- thread_helper but haven't ended yet.
-
- - dead_threads == a queue that contains all the member function pointers
- for threads that are currently registered but not running
-
- - m_ == the mutex used to protect all our variables
- - s == the signaler for m_
- !*/
-
- public:
-
- multithreaded_object (
- );
-
- virtual ~multithreaded_object (
- ) = 0;
-
- void clear (
- );
-
- bool is_running (
- ) const;
-
- unsigned long number_of_threads_alive (
- ) const;
-
- unsigned long number_of_threads_registered (
- ) const;
-
- void wait (
- ) const;
-
- void start (
- );
-
- void pause (
- );
-
- void stop (
- );
-
- protected:
-
- bool should_stop (
- ) const;
-
- template <
- typename T
- >
- void register_thread (
- T& object,
- void (T::*thread)()
- )
- {
- auto_mutex M(m_);
- try
- {
- mfp mf;
- mf.set(object,thread);
- dead_threads.enqueue(mf);
- if (is_running_)
- start();
- }
- catch (...)
- {
- is_running_ = false;
- should_stop_ = true;
- s.broadcast();
- throw;
- }
- }
-
- private:
-
- class raii_thread_helper
- {
- public:
- raii_thread_helper(multithreaded_object& self_, thread_id_type id_);
- ~raii_thread_helper();
-
- multithreaded_object& self;
- thread_id_type id;
- };
-
- void thread_helper(
- );
-
- typedef member_function_pointer<> mfp;
-
- rmutex m_;
- rsignaler s;
- map<thread_id_type,mfp,memory_manager<char>::kernel_2a>::kernel_1a thread_ids;
- queue<mfp,memory_manager<char>::kernel_2a>::kernel_1a dead_threads;
-
- bool is_running_;
- bool should_stop_;
- unsigned long threads_started;
-
- // restricted functions
- multithreaded_object(multithreaded_object&); // copy constructor
- multithreaded_object& operator=(multithreaded_object&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "multithreaded_object_extension.cpp"
-#endif
-
-#endif // DLIB_MULTITHREADED_OBJECT_EXTENSIOn_
-
diff --git a/ml/dlib/dlib/threads/multithreaded_object_extension_abstract.h b/ml/dlib/dlib/threads/multithreaded_object_extension_abstract.h
deleted file mode 100644
index e7862b78f..000000000
--- a/ml/dlib/dlib/threads/multithreaded_object_extension_abstract.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_MULTITHREADED_OBJECT_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_MULTITHREADED_OBJECT_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class multithreaded_object
- {
- /*!
- INITIAL VALUE
- - is_running() == false
- - number_of_threads_alive() == 0
- - number_of_threads_registered() == 0
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a multithreaded object. It is similar to
- the threaded_object except it allows you to have many threads in a
- single object rather than just one. To use it you inherit from it
- and register the member functions in your new class that you want
- to run in their own threads by calling register_thread(). Then when
- you call start() it will spawn all the registered functions
- in their own threads.
- !*/
-
- public:
-
- multithreaded_object (
- );
- /*!
- ensures
- - #*this is properly initialized
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- virtual ~multithreaded_object (
- ) = 0;
- /*!
- requires
- - number_of_threads_alive() == 0
- (i.e. in the destructor for the object you derive from this one you
- must wait for all the threads to end.)
- ensures
- - all resources allocated by *this have been freed.
- !*/
-
- void clear(
- );
- /*!
- ensures
- - #*this has its initial value
- - blocks until all threads have terminated
- throws
- - std::bad_alloc or dlib::thread_error
- if an exception is thrown then *this is unusable
- until clear() is called and succeeds
- !*/
-
- bool is_running (
- ) const;
- /*!
- ensures
- - if (number_of_threads_alive() > 0 && the threads are currently supposed to be executing) then
- - returns true
- - else
- - returns false
- !*/
-
- unsigned long number_of_threads_alive (
- ) const;
- /*!
- ensures
- - returns the number of threads that are currently alive (i.e.
- the number of threads that have started but not yet terminated)
- !*/
-
- unsigned long number_of_threads_registered (
- ) const;
- /*!
- ensures
- - returns the number of threads that have been registered by
- calls to register_thread()
- !*/
-
- void wait (
- ) const;
- /*!
- requires
- - is not called from one of this object's threads
- ensures
- - if (number_of_threads_alive() > 0) then
- - blocks until all the threads in this object have terminated
- (i.e. blocks until number_of_threads_alive() == 0)
- !*/
-
- void start (
- );
- /*!
- ensures
- - #number_of_threads_alive() == number_of_threads_registered()
- - #is_running() == true
- - #should_stop() == false
- - all the threads registered are up and running.
- throws
- - std::bad_alloc or dlib::thread_error
- If either of these exceptions are thrown then
- #is_running() == false and should_stop() == true
- !*/
-
- void pause (
- );
- /*!
- ensures
- - #is_running() == false
- !*/
-
- void stop (
- );
- /*!
- ensures
- - #should_stop() == true
- - #is_running() == false
- !*/
-
- protected:
-
- template <
- typename T
- >
- void register_thread (
- T& object,
- void (T::*thread)()
- );
- /*!
- requires
- - (object.*thread)() forms a valid function call
- - the thread function does not throw
- ensures
- - registers the member function pointed to by thread as one of the threads
- that runs when is_running() == true
- - #number_of_threads_registered() == number_of_threads_registered() + 1
- - if (is_running() == true)
- - spawns this new member function in its own thread
- - #number_of_threads_alive() += number_of_threads_alive() + 1
- throws
- - std::bad_alloc or dlib::thread_error
- If either of these exceptions are thrown then
- #is_running() == false and should_stop() == true
- !*/
-
- bool should_stop (
- ) const;
- /*!
- requires
- - is only called from one of the registered threads in this object
- ensures
- - if (is_running() == false && should_stop() == false) then
- - blocks until (#is_running() == true || #should_stop() == true)
- - if (this thread is supposed to terminate) then
- - returns true
- - else
- - returns false
- !*/
-
- private:
-
- // restricted functions
- multithreaded_object(multithreaded_object&); // copy constructor
- multithreaded_object& operator=(multithreaded_object&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_MULTITHREADED_OBJECT_EXTENSIOn_ABSTRACT_
-
diff --git a/ml/dlib/dlib/threads/parallel_for_extension.h b/ml/dlib/dlib/threads/parallel_for_extension.h
deleted file mode 100644
index 60b64b1b4..000000000
--- a/ml/dlib/dlib/threads/parallel_for_extension.h
+++ /dev/null
@@ -1,676 +0,0 @@
-// Copyright (C) 2013 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_PARALLEL_FoR_Hh_
-#define DLIB_PARALLEL_FoR_Hh_
-
-#include "parallel_for_extension_abstract.h"
-#include "thread_pool_extension.h"
-#include "../console_progress_indicator.h"
-#include "async.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
-
- template <typename T>
- class helper_parallel_for
- {
- public:
- helper_parallel_for (
- T& obj_,
- void (T::*funct_)(long)
- ) :
- obj(obj_),
- funct(funct_)
- {}
-
- T& obj;
- void (T::*funct)(long);
-
- void process_block (long begin, long end)
- {
- for (long i = begin; i < end; ++i)
- (obj.*funct)(i);
- }
- };
-
- template <typename T>
- class helper_parallel_for_funct
- {
- public:
- helper_parallel_for_funct (
- const T& funct_
- ) : funct(funct_) {}
-
- const T& funct;
-
- void run(long i)
- {
- funct(i);
- }
- };
-
- template <typename T>
- class helper_parallel_for_funct2
- {
- public:
- helper_parallel_for_funct2 (
- const T& funct_
- ) : funct(funct_) {}
-
- const T& funct;
-
- void run(long begin, long end)
- {
- funct(begin, end);
- }
- };
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long, long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- if (tp.num_threads_in_pool() != 0)
- {
- const long num = end-begin;
- const long num_workers = static_cast<long>(tp.num_threads_in_pool());
- // How many samples to process in a single task (aim for chunks_per_thread jobs per worker)
- const long block_size = std::max(1L, num/(num_workers*chunks_per_thread));
- for (long i = 0; i < num; i+=block_size)
- {
- tp.add_task(obj, funct, begin+i, begin+std::min(i+block_size, num));
- }
- tp.wait_for_all_tasks();
- }
- else
- {
- // Since there aren't any threads in the pool we might as well just invoke
- // the function directly since that's all the thread_pool object would do.
- // But doing it ourselves skips a mutex lock.
- (obj.*funct)(begin, end);
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long, long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- thread_pool tp(num_threads);
- parallel_for_blocked(tp, begin, end, obj, funct, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::helper_parallel_for_funct2<T> helper(funct);
- parallel_for_blocked(tp, begin, end, helper, &impl::helper_parallel_for_funct2<T>::run, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- thread_pool tp(num_threads);
- parallel_for_blocked(tp, begin, end, funct, chunks_per_thread);
- }
-
- template <typename T>
- void parallel_for_blocked (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- parallel_for_blocked(default_thread_pool(), begin, end, funct, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::helper_parallel_for<T> helper(obj, funct);
- parallel_for_blocked(tp, begin, end, helper, &impl::helper_parallel_for<T>::process_block, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- thread_pool tp(num_threads);
- parallel_for(tp, begin, end, obj, funct, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::helper_parallel_for_funct<T> helper(funct);
- parallel_for(tp, begin, end, helper, &impl::helper_parallel_for_funct<T>::run, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- thread_pool tp(num_threads);
- parallel_for(tp, begin, end, funct, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- parallel_for(default_thread_pool(), begin, end, funct, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace impl
- {
- template <typename T>
- class parfor_verbose_helper
- {
- public:
- parfor_verbose_helper(T& obj_, void (T::*funct_)(long), long begin, long end) :
- obj(obj_), funct(funct_), pbar(end-begin)
- {
- count = 0;
- wrote_to_screen = pbar.print_status(0);
- }
-
- ~parfor_verbose_helper()
- {
- if (wrote_to_screen)
- std::cout << std::endl;
- }
-
- mutable long count;
- T& obj;
- void (T::*funct)(long);
- mutable console_progress_indicator pbar;
- mutable bool wrote_to_screen;
- mutex m;
-
- void operator()(long i) const
- {
- (obj.*funct)(i);
- {
- auto_mutex lock(m);
- wrote_to_screen = pbar.print_status(++count) || wrote_to_screen;
- }
- }
-
- };
-
- template <typename T>
- class parfor_verbose_helper3
- {
- public:
- parfor_verbose_helper3(T& obj_, void (T::*funct_)(long,long), long begin, long end) :
- obj(obj_), funct(funct_), pbar(end-begin)
- {
- count = 0;
- wrote_to_screen = pbar.print_status(0);
- }
-
- ~parfor_verbose_helper3()
- {
- if (wrote_to_screen)
- std::cout << std::endl;
- }
-
- mutable long count;
- T& obj;
- void (T::*funct)(long,long);
- mutable console_progress_indicator pbar;
- mutable bool wrote_to_screen;
- mutex m;
-
- void operator()(long begin, long end) const
- {
- (obj.*funct)(begin, end);
- {
- auto_mutex lock(m);
- count += end-begin;
- wrote_to_screen = pbar.print_status(count) || wrote_to_screen;
- }
- }
- };
-
- template <typename T>
- class parfor_verbose_helper2
- {
- public:
- parfor_verbose_helper2(const T& obj_, long begin, long end) : obj(obj_), pbar(end-begin)
- {
- count = 0;
- wrote_to_screen = pbar.print_status(0);
- }
-
- ~parfor_verbose_helper2()
- {
- if (wrote_to_screen)
- std::cout << std::endl;
- }
-
- mutable long count;
- const T& obj;
- mutable console_progress_indicator pbar;
- mutable bool wrote_to_screen;
- mutex m;
-
- void operator()(long i) const
- {
- obj(i);
- {
- auto_mutex lock(m);
- wrote_to_screen = pbar.print_status(++count) || wrote_to_screen;
- }
- }
-
- void operator()(long begin, long end) const
- {
- obj(begin, end);
- {
- auto_mutex lock(m);
- count += end-begin;
- wrote_to_screen = pbar.print_status(count) || wrote_to_screen;
- }
- }
- };
- }
-
- template <typename T>
- void parallel_for_verbose (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper<T> helper(obj, funct, begin, end);
- parallel_for(tp, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper<T> helper(obj, funct, begin, end);
- parallel_for(num_threads, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper2<T> helper(funct, begin, end);
- parallel_for(tp, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper2<T> helper(funct, begin, end);
- parallel_for(num_threads, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper2<T> helper(funct, begin, end);
- parallel_for(begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long,long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper3<T> helper(obj, funct, begin, end);
- parallel_for_blocked(tp, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long,long),
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper3<T> helper(obj, funct, begin, end);
- parallel_for_blocked(num_threads, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper2<T> helper(funct, begin, end);
- parallel_for_blocked(tp, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper2<T> helper(funct, begin, end);
- parallel_for_blocked(num_threads, begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- )
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(begin <= end && chunks_per_thread > 0,
- "\t void parallel_for_blocked_verbose()"
- << "\n\t Invalid inputs were given to this function"
- << "\n\t begin: " << begin
- << "\n\t end: " << end
- << "\n\t chunks_per_thread: " << chunks_per_thread
- );
-
- impl::parfor_verbose_helper2<T> helper(funct, begin, end);
- parallel_for_blocked(begin, end, helper, chunks_per_thread);
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_PARALLEL_FoR_Hh_
-
diff --git a/ml/dlib/dlib/threads/parallel_for_extension_abstract.h b/ml/dlib/dlib/threads/parallel_for_extension_abstract.h
deleted file mode 100644
index ffd2e0c44..000000000
--- a/ml/dlib/dlib/threads/parallel_for_extension_abstract.h
+++ /dev/null
@@ -1,469 +0,0 @@
-// Copyright (C) 2013 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_PARALLEL_FoR_ABSTRACT_Hh_
-#ifdef DLIB_PARALLEL_FoR_ABSTRACT_Hh_
-
-#include "thread_pool_extension_abstract.h"
-#include "async_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long, long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This is a convenience function for submitting a block of jobs to a thread_pool.
- In particular, given the half open range [begin, end), this function will
- split the range into approximately tp.num_threads_in_pool()*chunks_per_thread
- blocks, which it will then submit to the thread_pool. The given thread_pool
- will then call (obj.*funct)() on each of the subranges.
- - To be precise, suppose we have broken the range [begin, end) into the
- following subranges:
- - [begin[0], end[0])
- - [begin[1], end[1])
- - [begin[2], end[2])
- ...
- - [begin[n], end[n])
- Then parallel_for_blocked() submits each of these subranges to tp for
- processing such that (obj.*funct)(begin[i], end[i]) is invoked for all valid
- values of i. Moreover, the subranges are non-overlapping and completely
- cover the total range of [begin, end).
- - This function will not perform any memory allocations or create any system
- resources such as mutex objects.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long, long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following block of code:
- thread_pool tp(num_threads);
- parallel_for_blocked(tp, begin, end, obj, funct, chunks_per_thread);
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - chunks_per_thread > 0
- - begin <= end
- ensures
- - This is a convenience function for submitting a block of jobs to a
- thread_pool. In particular, given the range [begin, end), this function will
- split the range into approximately tp.num_threads_in_pool()*chunks_per_thread
- blocks, which it will then submit to the thread_pool. The given thread_pool
- will then call funct() on each of the subranges.
- - To be precise, suppose we have broken the range [begin, end) into the
- following subranges:
- - [begin[0], end[0])
- - [begin[1], end[1])
- - [begin[2], end[2])
- ...
- - [begin[n], end[n])
- Then parallel_for_blocked() submits each of these subranges to tp for
- processing such that funct(begin[i], end[i]) is invoked for all valid values
- of i.
- - This function will not perform any memory allocations or create any system
- resources such as mutex objects.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following block of code:
- thread_pool tp(num_threads);
- parallel_for_blocked(tp, begin, end, funct, chunks_per_thread);
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following block of code:
- parallel_for_blocked(default_thread_pool(), begin, end, funct, chunks_per_thread);
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following function call:
- parallel_for_blocked(tp, begin, end, [&](long begin_sub, long end_sub)
- {
- for (long i = begin_sub; i < end_sub; ++i)
- (obj.*funct)(i);
- }, chunks_per_thread);
- - Therefore, this routine invokes (obj.*funct)(i) for all i in the range
- [begin, end). However, it does so using tp.num_threads_in_pool() parallel
- threads.
- - This function will not perform any memory allocations or create any system
- resources such as mutex objects.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following block of code:
- thread_pool tp(num_threads);
- parallel_for(tp, begin, end, obj, funct, chunks_per_thread);
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following function call:
- parallel_for_blocked(tp, begin, end, [&](long begin_sub, long end_sub)
- {
- for (long i = begin_sub; i < end_sub; ++i)
- funct(i);
- }, chunks_per_thread);
- - Therefore, this routine invokes funct(i) for all i in the range [begin, end).
- However, it does so using tp.num_threads_in_pool() parallel threads.
- - This function will not perform any memory allocations or create any system
- resources such as mutex objects.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following block of code:
- thread_pool tp(num_threads);
- parallel_for(tp, begin, end, funct, chunks_per_thread);
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is equivalent to the following block of code:
- parallel_for(default_thread_pool(), begin, end, funct, chunks_per_thread);
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for() routine defined above except
- that it will print messages to cout showing the progress in executing the
- parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for() routine defined above except
- that it will print messages to cout showing the progress in executing the
- parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for() routine defined above except
- that it will print messages to cout showing the progress in executing the
- parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for() routine defined above except
- that it will print messages to cout showing the progress in executing the
- parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_verbose (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for() routine defined above except
- that it will print messages to cout showing the progress in executing the
- parallel for loop.
- - It will also use the default_thread_pool().
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- thread_pool& tp,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long,long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for_blocked() routine defined
- above except that it will print messages to cout showing the progress in
- executing the parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- T& obj,
- void (T::*funct)(long,long),
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for_blocked() routine defined
- above except that it will print messages to cout showing the progress in
- executing the parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- thread_pool& tp,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for_blocked() routine defined
- above except that it will print messages to cout showing the progress in
- executing the parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- unsigned long num_threads,
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for_blocked() routine defined
- above except that it will print messages to cout showing the progress in
- executing the parallel for loop.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void parallel_for_blocked_verbose (
- long begin,
- long end,
- const T& funct,
- long chunks_per_thread = 8
- );
- /*!
- requires
- - begin <= end
- - chunks_per_thread > 0
- ensures
- - This function is identical to the parallel_for_blocked() routine defined
- above except that it will print messages to cout showing the progress in
- executing the parallel for loop.
- - It will also use the default_thread_pool()
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_PARALLEL_FoR_ABSTRACT_Hh_
-
-
diff --git a/ml/dlib/dlib/threads/posix.h b/ml/dlib/dlib/threads/posix.h
deleted file mode 100644
index 7226743e1..000000000
--- a/ml/dlib/dlib/threads/posix.h
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEl_1_
-#include "threads_kernel_2.h"
-#endif
-
diff --git a/ml/dlib/dlib/threads/read_write_mutex_extension.h b/ml/dlib/dlib/threads/read_write_mutex_extension.h
deleted file mode 100644
index 20e5d5ed8..000000000
--- a/ml/dlib/dlib/threads/read_write_mutex_extension.h
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_READ_WRITE_MUTEX_EXTENSIOn_
-#define DLIB_READ_WRITE_MUTEX_EXTENSIOn_
-
-#include "threads_kernel.h"
-#include "read_write_mutex_extension_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class read_write_mutex
- {
- /*!
- INITIAL VALUE
- - max_locks == defined by constructor
- - available_locks == max_locks
- - write_lock_in_progress == false
- - write_lock_active == false
-
- CONVENTION
- - Each time someone gets a read only lock they take one of the "available locks"
- and each write lock takes all possible locks (i.e. max_locks). The number of
- available locks is recorded in available_locks. Any time you try to lock this
- object and there aren't available locks you have to wait.
-
- - max_locks == max_readonly_locks()
-
- - if (some thread is on the process of obtaining a write lock) then
- - write_lock_in_progress == true
- - else
- - write_lock_in_progress == false
-
- - if (some thread currently has a write lock on this mutex) then
- - write_lock_active == true
- - else
- - write_lock_active == false
- !*/
-
- public:
-
- read_write_mutex (
- ) : s(m),
- max_locks(0xFFFFFFFF),
- available_locks(max_locks),
- write_lock_in_progress(false),
- write_lock_active(false)
- {}
-
- explicit read_write_mutex (
- unsigned long max_locks_
- ) : s(m),
- max_locks(max_locks_),
- available_locks(max_locks_),
- write_lock_in_progress(false),
- write_lock_active(false)
- {
- // make sure requires clause is not broken
- DLIB_ASSERT(max_locks > 0,
- "\t read_write_mutex::read_write_mutex(max_locks)"
- << "\n\t You must give a non-zero value for max_locks"
- << "\n\t this: " << this
- );
- }
-
- ~read_write_mutex (
- )
- {}
-
- void lock (
- ) const
- {
- m.lock();
-
- // If another write lock is already in progress then wait for it to finish
- // before we start trying to grab all the available locks. This way we
- // don't end up fighting over the locks.
- while (write_lock_in_progress)
- s.wait();
-
- // grab the right to perform a write lock
- write_lock_in_progress = true;
-
- // now start grabbing all the locks
- unsigned long locks_obtained = available_locks;
- available_locks = 0;
- while (locks_obtained != max_locks)
- {
- s.wait();
- locks_obtained += available_locks;
- available_locks = 0;
- }
-
- write_lock_in_progress = false;
- write_lock_active = true;
-
- m.unlock();
- }
-
- void unlock (
- ) const
- {
- m.lock();
-
- // only do something if there really was a lock in place
- if (write_lock_active)
- {
- available_locks = max_locks;
- write_lock_active = false;
- s.broadcast();
- }
-
- m.unlock();
- }
-
- void lock_readonly (
- ) const
- {
- m.lock();
-
- while (available_locks == 0)
- s.wait();
-
- --available_locks;
-
- m.unlock();
- }
-
- void unlock_readonly (
- ) const
- {
- m.lock();
-
- // If this condition is false then it means there are no more readonly locks
- // to free. So we don't do anything.
- if (available_locks != max_locks && !write_lock_active)
- {
- ++available_locks;
-
- // only perform broadcast when there is another thread that might be listening
- if (available_locks == 1 || write_lock_in_progress)
- {
- s.broadcast();
- }
- }
-
- m.unlock();
- }
-
- unsigned long max_readonly_locks (
- ) const
- {
- return max_locks;
- }
-
- private:
- mutex m;
- signaler s;
- const unsigned long max_locks;
- mutable unsigned long available_locks;
- mutable bool write_lock_in_progress;
- mutable bool write_lock_active;
-
- // restricted functions
- read_write_mutex(read_write_mutex&); // copy constructor
- read_write_mutex& operator=(read_write_mutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_READ_WRITE_MUTEX_EXTENSIOn_
-
-
diff --git a/ml/dlib/dlib/threads/read_write_mutex_extension_abstract.h b/ml/dlib/dlib/threads/read_write_mutex_extension_abstract.h
deleted file mode 100644
index 18672b057..000000000
--- a/ml/dlib/dlib/threads/read_write_mutex_extension_abstract.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (C) 2010 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_READWRITE_MUTEX_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_READWRITE_MUTEX_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class read_write_mutex
- {
- /*!
- INITIAL VALUE
- read_write_mutex is in the fully unlocked state
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a mutex intended to be used for synchronous
- thread control of shared data. When a thread wants to access some
- shared data it locks out other threads by calling lock() and calls
- unlock() when it is finished.
-
- This mutex also has the additional ability to distinguish between
- a lock for the purposes of modifying some shared data, a write lock,
- and a lock for the purposes of only reading shared data, a readonly
- lock. The lock() and unlock() functions are used for write locks while
- the lock_readonly() and unlock_readonly() are for readonly locks.
-
- The difference between a readonly and write lock can be understood as
- follows. The read_write_mutex will allow many threads to obtain simultaneous
- readonly locks but will only allow a single thread to obtain a write lock.
- Moreover, while the write lock is obtained no other threads are allowed
- to have readonly locks.
- !*/
- public:
-
- read_write_mutex (
- );
- /*!
- ensures
- - #*this is properly initialized
- - max_readonly_locks() == 0xFFFFFFFF
- (i.e. about 4 billion)
- throws
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create the read_write_mutex.
- !*/
-
- explicit read_write_mutex (
- unsigned long max_locks
- );
- /*!
- requires
- - max_locks > 0
- ensures
- - #*this is properly initialized
- - max_readonly_locks() == max_locks
- throws
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create the read_write_mutex.
- !*/
-
- ~read_write_mutex (
- );
- /*!
- requires
- - *this is not locked
- ensures
- - all resources allocated by *this have been freed
- !*/
-
- void lock (
- ) const;
- /*!
- requires
- - The thread calling this function does not have any kind of lock on this
- object
- ensures
- - if (there is any kind of lock on *this) then
- - the calling thread is put to sleep until a write lock becomes available.
- Once available, a write lock is obtained on this mutex and this function
- terminates.
- - else
- - a write lock is obtained on this mutex and the calling thread is not put to sleep
- !*/
-
- void unlock (
- ) const;
- /*!
- ensures
- - if (there is a write lock on *this) then
- - #*this is unlocked (i.e. other threads may now lock this object)
- - else
- - the call to unlock() has no effect
- !*/
-
- unsigned long max_readonly_locks (
- ) const;
- /*!
- ensures
- - returns the maximum number of concurrent readonly locks this object will allow.
- !*/
-
- void lock_readonly (
- ) const;
- /*!
- requires
- - The thread calling this function does not already have a write
- lock on this object
- ensures
- - if (there is a write lock on *this or there are no free readonly locks) then
- - the calling thread is put to sleep until there is no longer a write lock
- and a free readonly lock is available. Once this is the case, a readonly
- lock is obtained and this function terminates.
- - else
- - a readonly lock is obtained on *this and the calling thread is not put
- to sleep. Note that multiple readonly locks can be obtained at once.
- !*/
-
- void unlock_readonly (
- ) const;
- /*!
- ensures
- - if (there is a readonly lock on *this) then
- - one readonly lock is removed from *this.
- - else
- - the call to unlock_readonly() has no effect.
- !*/
-
- private:
- // restricted functions
- read_write_mutex(read_write_mutex&); // copy constructor
- read_write_mutex& operator=(read_write_mutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_READWRITE_MUTEX_EXTENSIOn_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/threads/rmutex_extension.h b/ml/dlib/dlib/threads/rmutex_extension.h
deleted file mode 100644
index b7bf998be..000000000
--- a/ml/dlib/dlib/threads/rmutex_extension.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_RMUTEX_EXTENSIOn_
-#define DLIB_RMUTEX_EXTENSIOn_
-
-#include "threads_kernel.h"
-#include "rmutex_extension_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class rmutex
- {
- /*!
- INITIAL VALUE
- count == 0
- thread_id == 0
-
- CONVENTION
- - count == lock_count()
-
- - if (no thread currently has a lock on this mutex) then
- - count == 0
- - else
- - count == the number of times the thread that owns this mutex has
- called lock()
- - thread_id == the id of this thread.
- !*/
- public:
-
- rmutex (
- ) : s(m),
- thread_id(0),
- count(0)
- {}
-
- ~rmutex (
- )
- {}
-
- unsigned long lock_count (
- ) const
- {
- return count;
- }
-
- void lock (
- unsigned long times = 1
- ) const
- {
- const thread_id_type current_thread_id = get_thread_id();
- m.lock();
- if (thread_id == current_thread_id)
- {
- // we already own this mutex in this case
- count += times;
- }
- else
- {
- // wait for our turn to claim this rmutex
- while (count != 0)
- s.wait();
-
- count = times;
- thread_id = current_thread_id;
- }
- m.unlock();
- }
-
- void unlock (
- unsigned long times = 1
- ) const
- {
- const thread_id_type current_thread_id = get_thread_id();
- m.lock();
- if (thread_id == current_thread_id)
- {
- if (count <= times)
- {
- count = 0;
- s.signal();
- }
- else
- {
- count -= times;
- }
- }
- m.unlock();
- }
-
- private:
- mutex m;
- signaler s;
- mutable thread_id_type thread_id;
- mutable unsigned long count;
-
- // restricted functions
- rmutex(rmutex&); // copy constructor
- rmutex& operator=(rmutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_RMUTEX_EXTENSIOn_
-
diff --git a/ml/dlib/dlib/threads/rmutex_extension_abstract.h b/ml/dlib/dlib/threads/rmutex_extension_abstract.h
deleted file mode 100644
index 144dbf4d7..000000000
--- a/ml/dlib/dlib/threads/rmutex_extension_abstract.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (C) 2005 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_RMUTEX_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_RMUTEX_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class rmutex
- {
- /*!
- INITIAL VALUE
- rmutex is in the unlocked state
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a recursive mutex intended to be used for synchronous
- thread control of shared data. When a thread wants to access some
- shared data it locks out other threads by calling lock() and calls
- unlock() when it is finished.
-
- The difference between this and the normal mutex object is that it is safe to
- call lock() from a thread that already has a lock on this mutex. Doing
- so just increments a counter but otherwise has no effect on the mutex.
- Note that unlock() must be called for each call to lock() to release the
- mutex.
- !*/
- public:
-
- rmutex (
- );
- /*!
- ensures
- - #*this is properly initialized
- throws
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create the rmutex.
- !*/
-
- ~rmutex (
- );
- /*!
- requires
- - *this is not locked
- ensures
- - all resources allocated by *this have been freed
- !*/
-
- unsigned long lock_count (
- ) const;
- /*!
- requires
- - the calling thread has a lock on this mutex
- ensures
- - returns the number of times the thread has called lock()
- !*/
-
- void lock (
- unsigned long times = 1
- ) const;
- /*!
- ensures
- - if (*this is currently locked by another thread) then
- - the thread that called lock() on *this is put to sleep until
- it becomes available.
- - #lock_count() == times
- - if (*this is currently unlocked) then
- - #*this becomes locked and the current thread is NOT put to sleep
- but now "owns" #*this
- - #lock_count() == times
- - if (*this is locked and owned by the current thread) then
- - the calling thread retains its lock on *this and isn't put to sleep.
- - #lock_count() == lock_count() + times
- !*/
-
- void unlock (
- unsigned long times = 1
- ) const;
- /*!
- ensures
- - if (*this is currently locked and owned by the thread calling unlock) then
- - if (lock_count() <= times ) then
- - #*this is unlocked (i.e. other threads may now lock this object)
- - else
- - #*this will remain locked
- - #lock_count() == lock_count() - times
- - else
- - the call to unlock() has no effect
- !*/
-
-
- private:
- // restricted functions
- rmutex(rmutex&); // copy constructor
- rmutex& operator=(rmutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_RMUTEX_EXTENSIOn_ABSTRACT_
-
diff --git a/ml/dlib/dlib/threads/rsignaler_extension.h b/ml/dlib/dlib/threads/rsignaler_extension.h
deleted file mode 100644
index bfb5a7ecb..000000000
--- a/ml/dlib/dlib/threads/rsignaler_extension.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_RSIGNALER_EXTENSIOn_
-#define DLIB_RSIGNALER_EXTENSIOn_
-
-#include "rsignaler_extension_abstract.h"
-#include "rmutex_extension.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class rsignaler
- {
- public:
- rsignaler (
- const rmutex& associated_mutex
- ) :
- assoc_mutex(associated_mutex),
- s(m)
- {}
-
- ~rsignaler (
- )
- {}
-
- void wait (
- ) const
- {
- m.lock();
- const unsigned long lock_count = assoc_mutex.lock_count();
- assoc_mutex.unlock(lock_count);
- s.wait();
- m.unlock();
- assoc_mutex.lock(lock_count);
- }
-
- bool wait_or_timeout (
- unsigned long milliseconds
- ) const
- {
- m.lock();
- const unsigned long lock_count = assoc_mutex.lock_count();
- assoc_mutex.unlock(lock_count);
- bool res = s.wait_or_timeout(milliseconds);
- m.unlock();
- assoc_mutex.lock(lock_count);
- return res;
- }
-
- void signal (
- ) const
- {
- m.lock();
- s.signal();
- m.unlock();
- }
-
- void broadcast (
- ) const
- {
- m.lock();
- s.broadcast();
- m.unlock();
- }
-
- const rmutex& get_mutex (
- ) const { return assoc_mutex; }
-
- private:
-
- const rmutex& assoc_mutex;
- mutex m;
- signaler s;
-
-
- // restricted functions
- rsignaler(rsignaler&); // copy constructor
- rsignaler& operator=(rsignaler&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_RSIGNALER_EXTENSIOn_
-
-
-
diff --git a/ml/dlib/dlib/threads/rsignaler_extension_abstract.h b/ml/dlib/dlib/threads/rsignaler_extension_abstract.h
deleted file mode 100644
index ae5f450d7..000000000
--- a/ml/dlib/dlib/threads/rsignaler_extension_abstract.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_RSIGNALER_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_RSIGNALER_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-#include "rmutex_extension_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class rsignaler
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents an event signaling system for threads. It gives
- a thread the ability to wake up other threads that are waiting for a
- particular signal.
-
- Each rsignaler object is associated with one and only one rmutex object.
- More than one rsignaler object may be associated with a single rmutex
- but a signaler object may only be associated with a single rmutex.
-
- NOTE:
- You must guard against spurious wakeups. This means that a thread
- might return from a call to wait even if no other thread called
- signal. This is rare but must be guarded against.
-
- Also note that this object is identical to the signaler object
- except that it works with rmutex objects rather than mutex objects.
- !*/
-
- public:
-
- rsignaler (
- const rmutex& associated_mutex
- );
- /*!
- ensures
- - #*this is properly initialized
- - #get_mutex() == associated_mutex
- throws
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create the signaler.
- !*/
-
-
- ~rsignaler (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed
- !*/
-
- void wait (
- ) const;
- /*!
- requires
- - get_mutex() is locked and owned by the calling thread
- ensures
- - atomically unlocks get_mutex() and blocks the calling thread
- - calling thread may wake if another thread calls signal() or broadcast()
- on *this
- - when wait() returns the calling thread again has a lock on get_mutex()
- !*/
-
- bool wait_or_timeout (
- unsigned long milliseconds
- ) const;
- /*!
- requires
- - get_mutex() is locked and owned by the calling thread
- ensures
- - atomically unlocks get_mutex() and blocks the calling thread
- - calling thread may wake if another thread calls signal() or broadcast()
- on *this
- - after the specified number of milliseconds has elapsed the calling thread
- will wake once get_mutex() is free
- - when wait returns the calling thread again has a lock on get_mutex()
-
- - returns false if the call to wait_or_timeout timed out
- - returns true if the call did not time out
- !*/
-
- void signal (
- ) const;
- /*!
- ensures
- - if (at least one thread is waiting on *this) then
- - at least one of the waiting threads will wake
- !*/
-
- void broadcast (
- ) const;
- /*!
- ensures
- - any and all threads waiting on *this will wake
- !*/
-
- const rmutex& get_mutex (
- ) const;
- /*!
- ensures
- - returns a const reference to the rmutex associated with *this
- !*/
-
-
- private:
- // restricted functions
- rsignaler(rsignaler&); // copy constructor
- rsignaler& operator=(rsignaler&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_RSIGNALER_EXTENSIOn_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/threads/thread_function_extension.h b/ml/dlib/dlib/threads/thread_function_extension.h
deleted file mode 100644
index 7ecdd6520..000000000
--- a/ml/dlib/dlib/threads/thread_function_extension.h
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREAD_FUNCTIOn_
-#define DLIB_THREAD_FUNCTIOn_
-
-#include <memory>
-
-#include "thread_function_extension_abstract.h"
-#include "threads_kernel.h"
-#include "auto_mutex_extension.h"
-#include "threaded_object_extension.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class thread_function : private threaded_object
- {
-
- class base_funct
- {
- public:
- virtual void go() = 0;
- virtual ~base_funct() {}
- };
-
- template <typename F, typename T1, typename T2, typename T3, typename T4>
- class super_funct_4 : public base_funct
- {
- public:
- super_funct_4 ( F funct, T1 arg1, T2 arg2, T3 arg3, T4 arg4) :
- f(funct),
- a1(arg1),
- a2(arg2),
- a3(arg3),
- a4(arg4)
- {
- }
-
- void go() { f(a1, a2, a3, a4); }
-
-
- F f;
- T1 a1;
- T2 a2;
- T3 a3;
- T4 a4;
- };
-
- template <typename F, typename T1, typename T2, typename T3>
- class super_funct_3 : public base_funct
- {
- public:
- super_funct_3 ( F funct, T1 arg1, T2 arg2, T3 arg3):
- f(funct),
- a1(arg1),
- a2(arg2),
- a3(arg3)
- {
- }
-
- void go() { f(a1, a2, a3); }
-
-
- F f;
- T1 a1;
- T2 a2;
- T3 a3;
- };
-
- template <typename F, typename T1, typename T2>
- class super_funct_2 : public base_funct
- {
- public:
- super_funct_2 ( F funct, T1 arg1, T2 arg2) :
- f(funct),
- a1(arg1),
- a2(arg2)
- {
- }
-
- void go() { f(a1, a2); }
-
-
- F f;
- T1 a1;
- T2 a2;
- };
-
- template <typename F, typename T>
- class super_funct_1 : public base_funct
- {
- public:
- super_funct_1 ( F funct, T arg) : f(funct), a(arg)
- {
- }
-
- void go() { f(a); }
-
-
- F f;
- T a;
- };
-
- template <typename F>
- class super_funct_0 : public base_funct
- {
- public:
- super_funct_0 ( F funct) : f(funct)
- {
- }
-
- void go() { f(); }
-
- F f;
- };
-
- public:
-
- template <typename F>
- thread_function (
- F funct
- )
- {
- f.reset(new super_funct_0<F>(funct));
- start();
- }
-
- template <typename F, typename T>
- thread_function (
- F funct,
- T arg
- )
- {
- f.reset(new super_funct_1<F,T>(funct,arg));
- start();
- }
-
- template <typename F, typename T1, typename T2>
- thread_function (
- F funct,
- T1 arg1,
- T2 arg2
- )
- {
- f.reset(new super_funct_2<F,T1,T2>(funct, arg1, arg2));
- start();
- }
-
- template <typename F, typename T1, typename T2, typename T3>
- thread_function (
- F funct,
- T1 arg1,
- T2 arg2,
- T3 arg3
- )
- {
- f.reset(new super_funct_3<F,T1,T2,T3>(funct, arg1, arg2, arg3));
- start();
- }
-
- template <typename F, typename T1, typename T2, typename T3, typename T4>
- thread_function (
- F funct,
- T1 arg1,
- T2 arg2,
- T3 arg3,
- T4 arg4
- )
- {
- f.reset(new super_funct_4<F,T1,T2,T3,T4>(funct, arg1, arg2, arg3, arg4));
- start();
- }
-
- ~thread_function (
- )
- {
- threaded_object::wait();
- }
-
- bool is_alive (
- ) const
- {
- return threaded_object::is_alive();
- }
-
- void wait (
- ) const
- {
- threaded_object::wait();
- }
-
- private:
-
- void thread ()
- {
- f->go();
- }
-
- std::unique_ptr<base_funct> f;
-
- // restricted functions
- thread_function(thread_function&); // copy constructor
- thread_function& operator=(thread_function&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREAD_FUNCTIOn_
-
-
-
diff --git a/ml/dlib/dlib/threads/thread_function_extension_abstract.h b/ml/dlib/dlib/threads/thread_function_extension_abstract.h
deleted file mode 100644
index 65ea998ac..000000000
--- a/ml/dlib/dlib/threads/thread_function_extension_abstract.h
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_THREAD_FUNCTIOn_ABSTRACT_
-#ifdef DLIB_THREAD_FUNCTIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class thread_function
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a thread on a global C++ function or function
- object. That is, it allows you to run a function in its own thread.
- !*/
- public:
-
- template <typename F>
- thread_function (
- F funct
- );
- /*!
- ensures
- - #*this is properly initialized
- - the function funct has been started in its own thread
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- template <typename F, typename T1>
- thread_function (
- F funct,
- T1 arg1
- );
- /*!
- ensures
- - #*this is properly initialized
- - A thread has been created and it will call funct(arg1)
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- template <typename F, typename T1, typename T2>
- thread_function (
- F funct,
- T1 arg1,
- T2 arg2
- );
- /*!
- ensures
- - #*this is properly initialized
- - A thread has been created and it will call funct(arg1, arg2)
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- template <typename F, typename T1, typename T2, typename T3>
- thread_function (
- F funct,
- T1 arg1,
- T2 arg2,
- T3 arg3
- );
- /*!
- ensures
- - #*this is properly initialized
- - A thread has been created and it will call funct(arg1, arg2, arg3)
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- template <typename F, typename T1, typename T2, typename T3, typename T4>
- thread_function (
- F funct,
- T1 arg1,
- T2 arg2,
- T3 arg3,
- T4 arg4
- );
- /*!
- ensures
- - #*this is properly initialized
- - A thread has been created and it will call funct(arg1, arg2, arg3, arg4)
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- ~thread_function (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed.
- - blocks until is_alive() == false
- !*/
-
- bool is_alive (
- ) const;
- /*!
- ensures
- - if (this object's thread has yet to terminate) then
- - returns true
- - else
- - returns false
- !*/
-
- void wait (
- ) const;
- /*!
- ensures
- - if (is_alive() == true) then
- - blocks until this object's thread terminates
- !*/
-
- private:
-
- // restricted functions
- thread_function(thread_function&); // copy constructor
- thread_function& operator=(thread_function&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREAD_FUNCTIOn_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/threads/thread_pool_extension.cpp b/ml/dlib/dlib/threads/thread_pool_extension.cpp
deleted file mode 100644
index 00d99b910..000000000
--- a/ml/dlib/dlib/threads/thread_pool_extension.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREAD_POOl_CPPh_
-#define DLIB_THREAD_POOl_CPPh_
-
-#include "thread_pool_extension.h"
-#include <memory>
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- thread_pool_implementation::
- thread_pool_implementation (
- unsigned long num_threads
- ) :
- task_done_signaler(m),
- task_ready_signaler(m),
- we_are_destructing(false)
- {
- tasks.resize(num_threads);
- threads.resize(num_threads);
- for (unsigned long i = 0; i < num_threads; ++i)
- {
- threads[i] = std::thread([&](){this->thread();});
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void thread_pool_implementation::
- shutdown_pool (
- )
- {
- {
- auto_mutex M(m);
-
- // first wait for all pending tasks to finish
- bool found_task = true;
- while (found_task)
- {
- found_task = false;
- for (unsigned long i = 0; i < tasks.size(); ++i)
- {
- // If task bucket i has a task that is currently supposed to be processed
- if (tasks[i].is_empty() == false)
- {
- found_task = true;
- break;
- }
- }
-
- if (found_task)
- task_done_signaler.wait();
- }
-
- // now tell the threads to kill themselves
- we_are_destructing = true;
- task_ready_signaler.broadcast();
- }
-
- // wait for all threads to terminate
- for (auto& t : threads)
- t.join();
- threads.clear();
-
- // Throw any unhandled exceptions. Since shutdown_pool() is only called in the
- // destructor this will kill the program.
- for (auto&& task : tasks)
- task.propagate_exception();
- }
-
-// ----------------------------------------------------------------------------------------
-
- thread_pool_implementation::
- ~thread_pool_implementation()
- {
- shutdown_pool();
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long thread_pool_implementation::
- num_threads_in_pool (
- ) const
- {
- auto_mutex M(m);
- return tasks.size();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void thread_pool_implementation::
- wait_for_task (
- uint64 task_id
- ) const
- {
- auto_mutex M(m);
- if (tasks.size() != 0)
- {
- const unsigned long idx = task_id_to_index(task_id);
- while (tasks[idx].task_id == task_id)
- task_done_signaler.wait();
-
- for (auto&& task : tasks)
- task.propagate_exception();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void thread_pool_implementation::
- wait_for_all_tasks (
- ) const
- {
- const thread_id_type thread_id = get_thread_id();
-
- auto_mutex M(m);
- bool found_task = true;
- while (found_task)
- {
- found_task = false;
- for (unsigned long i = 0; i < tasks.size(); ++i)
- {
- // If task bucket i has a task that is currently supposed to be processed
- // and it originated from the calling thread
- if (tasks[i].is_empty() == false && tasks[i].thread_id == thread_id)
- {
- found_task = true;
- break;
- }
- }
-
- if (found_task)
- task_done_signaler.wait();
- }
-
- // throw any exceptions generated by the tasks
- for (auto&& task : tasks)
- task.propagate_exception();
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool thread_pool_implementation::
- is_worker_thread (
- const thread_id_type id
- ) const
- {
- for (unsigned long i = 0; i < worker_thread_ids.size(); ++i)
- {
- if (worker_thread_ids[i] == id)
- return true;
- }
-
- // if there aren't any threads in the pool then we consider all threads
- // to be worker threads
- if (tasks.size() == 0)
- return true;
- else
- return false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void thread_pool_implementation::
- thread (
- )
- {
- {
- // save the id of this worker thread into worker_thread_ids
- auto_mutex M(m);
- thread_id_type id = get_thread_id();
- worker_thread_ids.push_back(id);
- }
-
- task_state_type task;
- while (we_are_destructing == false)
- {
- long idx = 0;
-
- // wait for a task to do
- { auto_mutex M(m);
- while ( (idx = find_ready_task()) == -1 && we_are_destructing == false)
- task_ready_signaler.wait();
-
- if (we_are_destructing)
- break;
-
- tasks[idx].is_being_processed = true;
- task = tasks[idx];
- }
-
- std::exception_ptr eptr = nullptr;
- try
- {
- // now do the task
- if (task.bfp)
- task.bfp();
- else if (task.mfp0)
- task.mfp0();
- else if (task.mfp1)
- task.mfp1(task.arg1);
- else if (task.mfp2)
- task.mfp2(task.arg1, task.arg2);
- }
- catch(...)
- {
- eptr = std::current_exception();
- }
-
- // Now let others know that we finished the task. We do this
- // by clearing out the state of this task
- { auto_mutex M(m);
- tasks[idx].is_being_processed = false;
- tasks[idx].task_id = 0;
- tasks[idx].bfp.clear();
- tasks[idx].mfp0.clear();
- tasks[idx].mfp1.clear();
- tasks[idx].mfp2.clear();
- tasks[idx].arg1 = 0;
- tasks[idx].arg2 = 0;
- tasks[idx].eptr = eptr;
- task_done_signaler.broadcast();
- }
-
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- long thread_pool_implementation::
- find_empty_task_slot (
- ) const
- {
- for (auto&& task : tasks)
- task.propagate_exception();
-
- for (unsigned long i = 0; i < tasks.size(); ++i)
- {
- if (tasks[i].is_empty())
- return i;
- }
-
- return -1;
- }
-
-// ----------------------------------------------------------------------------------------
-
- long thread_pool_implementation::
- find_ready_task (
- ) const
- {
- for (unsigned long i = 0; i < tasks.size(); ++i)
- {
- if (tasks[i].is_ready())
- return i;
- }
-
- return -1;
- }
-
-// ----------------------------------------------------------------------------------------
-
- uint64 thread_pool_implementation::
- make_next_task_id (
- long idx
- )
- {
- uint64 id = tasks[idx].next_task_id * tasks.size() + idx;
- tasks[idx].next_task_id += 1;
- return id;
- }
-
-// ----------------------------------------------------------------------------------------
-
- unsigned long thread_pool_implementation::
- task_id_to_index (
- uint64 id
- ) const
- {
- return static_cast<unsigned long>(id%tasks.size());
- }
-
-// ----------------------------------------------------------------------------------------
-
- uint64 thread_pool_implementation::
- add_task_internal (
- const bfp_type& bfp,
- std::shared_ptr<function_object_copy>& item
- )
- {
- auto_mutex M(m);
- const thread_id_type my_thread_id = get_thread_id();
-
- // find a thread that isn't doing anything
- long idx = find_empty_task_slot();
- if (idx == -1 && is_worker_thread(my_thread_id))
- {
- // this function is being called from within a worker thread and there
- // aren't any other worker threads free so just perform the task right
- // here
-
- M.unlock();
- bfp();
-
- // return a task id that is both non-zero and also one
- // that is never normally returned. This way calls
- // to wait_for_task() will never block given this id.
- return 1;
- }
-
- // wait until there is a thread that isn't doing anything
- while (idx == -1)
- {
- task_done_signaler.wait();
- idx = find_empty_task_slot();
- }
-
- tasks[idx].thread_id = my_thread_id;
- tasks[idx].task_id = make_next_task_id(idx);
- tasks[idx].bfp = bfp;
- tasks[idx].function_copy.swap(item);
-
- task_ready_signaler.signal();
-
- return tasks[idx].task_id;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool thread_pool_implementation::
- is_task_thread (
- ) const
- {
- auto_mutex M(m);
- return is_worker_thread(get_thread_id());
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-
-#endif // DLIB_THREAD_POOl_CPPh_
-
diff --git a/ml/dlib/dlib/threads/thread_pool_extension.h b/ml/dlib/dlib/threads/thread_pool_extension.h
deleted file mode 100644
index bc2e1782c..000000000
--- a/ml/dlib/dlib/threads/thread_pool_extension.h
+++ /dev/null
@@ -1,1392 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREAD_POOl_Hh_
-#define DLIB_THREAD_POOl_Hh_
-
-#include <exception>
-#include <memory>
-#include <thread>
-
-#include "thread_pool_extension_abstract.h"
-#include "multithreaded_object_extension.h"
-#include "../member_function_pointer.h"
-#include "../bound_function_pointer.h"
-#include "threads_kernel.h"
-#include "auto_mutex_extension.h"
-#include "../uintn.h"
-#include "../array.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class thread_pool_implementation;
-
- template <
- typename T
- >
- class future
- {
- /*!
- INITIAL VALUE
- - task_id == 0
- - tp.get() == 0
-
- CONVENTION
- - is_ready() == (tp.get() == 0)
- - get() == var
-
- - if (tp.get() != 0)
- - tp == a pointer to the thread_pool_implementation that is using this future object
- - task_id == the task id of the task in the thread pool tp that is using
- this future object.
- !*/
- public:
-
- future (
- ) : task_id(0) {}
-
- future (
- const T& item
- ) : task_id(0), var(item) {}
-
- future (
- const future& item
- ) :task_id(0), var(item.get()) {}
-
- ~future (
- ) { wait(); }
-
- future& operator=(
- const T& item
- ) { get() = item; return *this; }
-
- future& operator=(
- const future& item
- ) { get() = item.get(); return *this; }
-
- operator T& (
- ) { return get(); }
-
- operator const T& (
- ) const { return get(); }
-
- T& get (
- ) { wait(); return var; }
-
- const T& get (
- ) const { wait(); return var; }
-
- bool is_ready (
- ) const { return tp.get() == 0; }
-
- private:
-
- friend class thread_pool;
-
- inline void wait () const;
-
- mutable uint64 task_id;
- mutable std::shared_ptr<thread_pool_implementation> tp;
-
- T var;
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- inline void swap (
- future<T>& a,
- future<T>& b
- ) { dlib::exchange(a.get(), b.get()); }
- // Note that dlib::exchange() just calls std::swap. I'm only using it because
- // this works around some bugs in certain compilers.
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T> bool operator== (const future<T>& a, const future<T>& b) { return a.get() == b.get(); }
- template <typename T> bool operator!= (const future<T>& a, const future<T>& b) { return a.get() != b.get(); }
- template <typename T> bool operator<= (const future<T>& a, const future<T>& b) { return a.get() <= b.get(); }
- template <typename T> bool operator>= (const future<T>& a, const future<T>& b) { return a.get() >= b.get(); }
- template <typename T> bool operator< (const future<T>& a, const future<T>& b) { return a.get() < b.get(); }
- template <typename T> bool operator> (const future<T>& a, const future<T>& b) { return a.get() > b.get(); }
-
- template <typename T> bool operator== (const future<T>& a, const T& b) { return a.get() == b; }
- template <typename T> bool operator== (const T& a, const future<T>& b) { return a == b.get(); }
- template <typename T> bool operator!= (const future<T>& a, const T& b) { return a.get() != b; }
- template <typename T> bool operator!= (const T& a, const future<T>& b) { return a != b.get(); }
- template <typename T> bool operator<= (const future<T>& a, const T& b) { return a.get() <= b; }
- template <typename T> bool operator<= (const T& a, const future<T>& b) { return a <= b.get(); }
- template <typename T> bool operator>= (const future<T>& a, const T& b) { return a.get() >= b; }
- template <typename T> bool operator>= (const T& a, const future<T>& b) { return a >= b.get(); }
- template <typename T> bool operator< (const future<T>& a, const T& b) { return a.get() < b; }
- template <typename T> bool operator< (const T& a, const future<T>& b) { return a < b.get(); }
- template <typename T> bool operator> (const future<T>& a, const T& b) { return a.get() > b; }
- template <typename T> bool operator> (const T& a, const future<T>& b) { return a > b.get(); }
-
-// ----------------------------------------------------------------------------------------
-
- class thread_pool_implementation
- {
- /*!
- CONVENTION
- - num_threads_in_pool() == tasks.size()
- - if (the destructor has been called) then
- - we_are_destructing == true
- - else
- - we_are_destructing == false
-
- - is_task_thread() == is_worker_thread(get_thread_id())
-
- - m == the mutex used to protect everything in this object
- - worker_thread_ids == an array that contains the thread ids for
- all the threads in the thread pool
- !*/
- typedef bound_function_pointer::kernel_1a_c bfp_type;
-
- friend class thread_pool;
- explicit thread_pool_implementation (
- unsigned long num_threads
- );
-
- public:
- ~thread_pool_implementation(
- );
-
- void wait_for_task (
- uint64 task_id
- ) const;
-
- unsigned long num_threads_in_pool (
- ) const;
-
- void wait_for_all_tasks (
- ) const;
-
- bool is_task_thread (
- ) const;
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)()
- )
- {
- auto_mutex M(m);
- const thread_id_type my_thread_id = get_thread_id();
-
- // find a thread that isn't doing anything
- long idx = find_empty_task_slot();
- if (idx == -1 && is_worker_thread(my_thread_id))
- {
- // this function is being called from within a worker thread and there
- // aren't any other worker threads free so just perform the task right
- // here
-
- M.unlock();
- (obj.*funct)();
-
- // return a task id that is both non-zero and also one
- // that is never normally returned. This way calls
- // to wait_for_task() will never block given this id.
- return 1;
- }
-
- // wait until there is a thread that isn't doing anything
- while (idx == -1)
- {
- task_done_signaler.wait();
- idx = find_empty_task_slot();
- }
-
- tasks[idx].thread_id = my_thread_id;
- tasks[idx].task_id = make_next_task_id(idx);
- tasks[idx].mfp0.set(obj,funct);
-
- task_ready_signaler.signal();
-
- return tasks[idx].task_id;
- }
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)(long),
- long arg1
- )
- {
- auto_mutex M(m);
- const thread_id_type my_thread_id = get_thread_id();
-
- // find a thread that isn't doing anything
- long idx = find_empty_task_slot();
- if (idx == -1 && is_worker_thread(my_thread_id))
- {
- // this function is being called from within a worker thread and there
- // aren't any other worker threads free so just perform the task right
- // here
-
- M.unlock();
- (obj.*funct)(arg1);
-
- // return a task id that is both non-zero and also one
- // that is never normally returned. This way calls
- // to wait_for_task() will never block given this id.
- return 1;
- }
-
- // wait until there is a thread that isn't doing anything
- while (idx == -1)
- {
- task_done_signaler.wait();
- idx = find_empty_task_slot();
- }
-
- tasks[idx].thread_id = my_thread_id;
- tasks[idx].task_id = make_next_task_id(idx);
- tasks[idx].mfp1.set(obj,funct);
- tasks[idx].arg1 = arg1;
-
- task_ready_signaler.signal();
-
- return tasks[idx].task_id;
- }
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)(long,long),
- long arg1,
- long arg2
- )
- {
- auto_mutex M(m);
- const thread_id_type my_thread_id = get_thread_id();
-
- // find a thread that isn't doing anything
- long idx = find_empty_task_slot();
- if (idx == -1 && is_worker_thread(my_thread_id))
- {
- // this function is being called from within a worker thread and there
- // aren't any other worker threads free so just perform the task right
- // here
-
- M.unlock();
- (obj.*funct)(arg1, arg2);
-
- // return a task id that is both non-zero and also one
- // that is never normally returned. This way calls
- // to wait_for_task() will never block given this id.
- return 1;
- }
-
- // wait until there is a thread that isn't doing anything
- while (idx == -1)
- {
- task_done_signaler.wait();
- idx = find_empty_task_slot();
- }
-
- tasks[idx].thread_id = my_thread_id;
- tasks[idx].task_id = make_next_task_id(idx);
- tasks[idx].mfp2.set(obj,funct);
- tasks[idx].arg1 = arg1;
- tasks[idx].arg2 = arg2;
-
- task_ready_signaler.signal();
-
- return tasks[idx].task_id;
- }
-
- struct function_object_copy
- {
- virtual ~function_object_copy(){}
- };
-
- template <typename T>
- struct function_object_copy_instance : function_object_copy
- {
- function_object_copy_instance(const T& item_) : item(item_) {}
- T item;
- virtual ~function_object_copy_instance(){}
- };
-
- uint64 add_task_internal (
- const bfp_type& bfp,
- std::shared_ptr<function_object_copy>& item
- );
- /*!
- ensures
- - adds a task to call the given bfp object.
- - swaps item into the internal task object which will have a lifetime
- at least as long as the running task.
- - returns the task id for this new task
- !*/
-
- uint64 add_task_internal (
- const bfp_type& bfp
- ) { std::shared_ptr<function_object_copy> temp; return add_task_internal(bfp, temp); }
- /*!
- ensures
- - adds a task to call the given bfp object.
- - returns the task id for this new task
- !*/
-
- void shutdown_pool (
- );
- /*!
- ensures
- - causes all threads to terminate and blocks the
- caller until this happens.
- !*/
-
- private:
-
- bool is_worker_thread (
- const thread_id_type id
- ) const;
- /*!
- requires
- - m is locked
- ensures
- - if (thread with given id is one of the thread pool's worker threads or num_threads_in_pool() == 0) then
- - returns true
- - else
- - returns false
- !*/
-
- void thread (
- );
- /*!
- this is the function that executes the threads in the thread pool
- !*/
-
- long find_empty_task_slot (
- ) const;
- /*!
- requires
- - m is locked
- ensures
- - if (there is currently a empty task slot) then
- - returns the index of that task slot in tasks
- - there is a task slot
- - else
- - returns -1
- !*/
-
- long find_ready_task (
- ) const;
- /*!
- requires
- - m is locked
- ensures
- - if (there is currently a task to do) then
- - returns the index of that task in tasks
- - else
- - returns -1
- !*/
-
- uint64 make_next_task_id (
- long idx
- );
- /*!
- requires
- - m is locked
- - 0 <= idx < tasks.size()
- ensures
- - returns the next index to be used for tasks that are placed in
- tasks[idx]
- !*/
-
- unsigned long task_id_to_index (
- uint64 id
- ) const;
- /*!
- requires
- - m is locked
- - num_threads_in_pool() != 0
- ensures
- - returns the index in tasks corresponding to the given id
- !*/
-
- struct task_state_type
- {
- task_state_type() : is_being_processed(false), task_id(0), next_task_id(2), arg1(0), arg2(0), eptr(nullptr) {}
-
- bool is_ready () const
- /*!
- ensures
- - if (is_empty() == false && no thread is currently processing this task) then
- - returns true
- - else
- - returns false
- !*/
- {
- return !is_being_processed && !is_empty();
- }
-
- bool is_empty () const
- /*!
- ensures
- - if (this task state is empty. i.e. it doesn't contain a task to be processed) then
- - returns true
- - else
- - returns false
- !*/
- {
- return task_id == 0;
- }
-
- bool is_being_processed; // true when a thread is working on this task
- uint64 task_id; // the id of this task. 0 means this task is empty
- thread_id_type thread_id; // the id of the thread that requested this task
-
- uint64 next_task_id;
-
- long arg1;
- long arg2;
-
- member_function_pointer<> mfp0;
- member_function_pointer<long> mfp1;
- member_function_pointer<long,long> mfp2;
- bfp_type bfp;
-
- std::shared_ptr<function_object_copy> function_copy;
- mutable std::exception_ptr eptr; // non-null if the task threw an exception
-
- void propagate_exception() const
- {
- if (eptr)
- {
- auto tmp = eptr;
- eptr = nullptr;
- std::rethrow_exception(tmp);
- }
- }
-
- };
-
- array<task_state_type> tasks;
- array<thread_id_type> worker_thread_ids;
-
- mutex m;
- signaler task_done_signaler;
- signaler task_ready_signaler;
- bool we_are_destructing;
-
- std::vector<std::thread> threads;
-
- // restricted functions
- thread_pool_implementation(thread_pool_implementation&); // copy constructor
- thread_pool_implementation& operator=(thread_pool_implementation&); // assignment operator
-
- };
-
-
-// ----------------------------------------------------------------------------------------
-
- class thread_pool
- {
- /*!
- This object is just a shell that holds a std::shared_ptr
- to the real thread_pool_implementation object. The reason for doing
- it this way is so that we can allow any mixture of destruction orders
- between thread_pool objects and futures. Whoever gets destroyed
- last cleans up the thread_pool_implementation resources.
- !*/
- typedef bound_function_pointer::kernel_1a_c bfp_type;
-
- public:
- explicit thread_pool (
- unsigned long num_threads
- )
- {
- impl.reset(new thread_pool_implementation(num_threads));
- }
-
- ~thread_pool (
- )
- {
- try
- {
- impl->shutdown_pool();
- }
- catch (std::exception& e)
- {
- std::cerr << "An unhandled exception was inside a dlib::thread_pool when it was destructed." << std::endl;
- std::cerr << "It's what string is: \n" << e.what() << std::endl;
- using namespace std;
- assert(false);
- abort();
- }
- catch (...)
- {
- std::cerr << "An unhandled exception was inside a dlib::thread_pool when it was destructed." << std::endl;
- using namespace std;
- assert(false);
- abort();
- }
- }
-
- void wait_for_task (
- uint64 task_id
- ) const { impl->wait_for_task(task_id); }
-
- unsigned long num_threads_in_pool (
- ) const { return impl->num_threads_in_pool(); }
-
- void wait_for_all_tasks (
- ) const { impl->wait_for_all_tasks(); }
-
- bool is_task_thread (
- ) const { return impl->is_task_thread(); }
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)()
- )
- {
- return impl->add_task(obj, funct);
- }
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)(long),
- long arg1
- )
- {
- return impl->add_task(obj, funct, arg1);
- }
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)(long,long),
- long arg1,
- long arg2
- )
- {
- return impl->add_task(obj, funct, arg1, arg2);
- }
-
- // --------------------
-
- template <typename F>
- uint64 add_task (
- F& function_object
- )
- {
- COMPILE_TIME_ASSERT(is_function<F>::value == false);
- COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
-
- bfp_type temp;
- temp.set(function_object);
- uint64 id = impl->add_task_internal(temp);
-
- return id;
- }
-
- template <typename F>
- uint64 add_task_by_value (
- const F& function_object
- )
- {
- thread_pool_implementation::function_object_copy_instance<F>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<F>(function_object);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
-
- bfp_type temp;
- temp.set(ptr->item);
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- return id;
- }
-
- template <typename T>
- uint64 add_task (
- const T& obj,
- void (T::*funct)() const
- )
- {
- bfp_type temp;
- temp.set(obj,funct);
- uint64 id = impl->add_task_internal(temp);
-
- return id;
- }
-
- template <typename T>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)() const
- )
- {
- thread_pool_implementation::function_object_copy_instance<const T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<const T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item,funct);
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- return id;
- }
-
- template <typename T>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)()
- )
- {
- thread_pool_implementation::function_object_copy_instance<T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item,funct);
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- return id;
- }
-
- uint64 add_task (
- void (*funct)()
- )
- {
- bfp_type temp;
- temp.set(funct);
- uint64 id = impl->add_task_internal(temp);
-
- return id;
- }
-
- // --------------------
-
- template <typename F, typename A1>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1
- )
- {
- COMPILE_TIME_ASSERT(is_function<F>::value == false);
- COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
-
- bfp_type temp;
- temp.set(function_object,arg1.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- return id;
- }
-
- template <typename F, typename A1>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1
- )
- {
- thread_pool_implementation::function_object_copy_instance<F>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<F>(function_object);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, arg1.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1),
- future<A1>& arg1
- )
- {
- bfp_type temp;
- temp.set(obj,funct,arg1.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1),
- future<A1>& arg1
- )
- {
- thread_pool_implementation::function_object_copy_instance<T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item,funct,arg1.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- return id;
- }
-
-
- template <typename T, typename T1, typename A1>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1) const,
- future<A1>& arg1
- )
- {
- bfp_type temp;
- temp.set(obj,funct,arg1.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1) const,
- future<A1>& arg1
- )
- {
- thread_pool_implementation::function_object_copy_instance<const T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<const T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item,funct,arg1.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- return id;
- }
-
- template <typename T1, typename A1>
- uint64 add_task (
- void (*funct)(T1),
- future<A1>& arg1
- )
- {
- bfp_type temp;
- temp.set(funct,arg1.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- return id;
- }
-
- // --------------------
-
- template <typename F, typename A1, typename A2>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1,
- future<A2>& arg2
- )
- {
- COMPILE_TIME_ASSERT(is_function<F>::value == false);
- COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
-
- bfp_type temp;
- temp.set(function_object, arg1.get(), arg2.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- return id;
- }
-
- template <typename F, typename A1, typename A2>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1,
- future<A2>& arg2
- )
- {
- thread_pool_implementation::function_object_copy_instance<F>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<F>(function_object);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, arg1.get(), arg2.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1,T2),
- future<A1>& arg1,
- future<A2>& arg2
- )
- {
- bfp_type temp;
- temp.set(obj, funct, arg1.get(), arg2.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2),
- future<A1>& arg1,
- future<A2>& arg2
- )
- {
- thread_pool_implementation::function_object_copy_instance<T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, funct, arg1.get(), arg2.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1,T2) const,
- future<A1>& arg1,
- future<A2>& arg2
- )
- {
- bfp_type temp;
- temp.set(obj, funct, arg1.get(), arg2.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2) const,
- future<A1>& arg1,
- future<A2>& arg2
- )
- {
- thread_pool_implementation::function_object_copy_instance<const T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<const T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, funct, arg1.get(), arg2.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- return id;
- }
-
- template <typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task (
- void (*funct)(T1,T2),
- future<A1>& arg1,
- future<A2>& arg2
- )
- {
- bfp_type temp;
- temp.set(funct, arg1.get(), arg2.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- return id;
- }
-
- // --------------------
-
- template <typename F, typename A1, typename A2, typename A3>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- )
- {
- COMPILE_TIME_ASSERT(is_function<F>::value == false);
- COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
-
- bfp_type temp;
- temp.set(function_object, arg1.get(), arg2.get(), arg3.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- return id;
- }
-
- template <typename F, typename A1, typename A2, typename A3>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- )
- {
- thread_pool_implementation::function_object_copy_instance<F>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<F>(function_object);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, arg1.get(), arg2.get(), arg3.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1,T2,T3),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- )
- {
- bfp_type temp;
- temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- )
- {
- thread_pool_implementation::function_object_copy_instance<T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, funct, arg1.get(), arg2.get(), arg3.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1,T2,T3) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- )
- {
- bfp_type temp;
- temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- )
- {
- thread_pool_implementation::function_object_copy_instance<const T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<const T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, funct, arg1.get(), arg2.get(), arg3.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- return id;
- }
-
- template <typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task (
- void (*funct)(T1,T2,T3),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- )
- {
- bfp_type temp;
- temp.set(funct, arg1.get(), arg2.get(), arg3.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- return id;
- }
-
- // --------------------
-
- template <typename F, typename A1, typename A2, typename A3, typename A4>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- )
- {
- COMPILE_TIME_ASSERT(is_function<F>::value == false);
- COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
-
- bfp_type temp;
- temp.set(function_object, arg1.get(), arg2.get(), arg3.get(), arg4.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- arg4.task_id = id;
- arg4.tp = impl;
- return id;
- }
-
- template <typename F, typename A1, typename A2, typename A3, typename A4>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- )
- {
- thread_pool_implementation::function_object_copy_instance<F>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<F>(function_object);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, arg1.get(), arg2.get(), arg3.get(), arg4.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the future to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- arg4.task_id = id;
- arg4.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1,T2,T3,T4),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- )
- {
- bfp_type temp;
- temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- arg4.task_id = id;
- arg4.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3,T4),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- )
- {
- thread_pool_implementation::function_object_copy_instance<T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- arg4.task_id = id;
- arg4.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1,T2,T3,T4) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- )
- {
- bfp_type temp;
- temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- arg4.task_id = id;
- arg4.tp = impl;
- return id;
- }
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3,T4) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- )
- {
- thread_pool_implementation::function_object_copy_instance<const T>* ptr = 0;
- ptr = new thread_pool_implementation::function_object_copy_instance<const T>(obj);
- std::shared_ptr<thread_pool_implementation::function_object_copy> function_copy(ptr);
-
- bfp_type temp;
- temp.set(ptr->item, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
- uint64 id = impl->add_task_internal(temp, function_copy);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- arg4.task_id = id;
- arg4.tp = impl;
- return id;
- }
-
- template <typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task (
- void (*funct)(T1,T2,T3,T4),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- )
- {
- bfp_type temp;
- temp.set(funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
- uint64 id = impl->add_task_internal(temp);
-
- // tie the futures to this task
- arg1.task_id = id;
- arg1.tp = impl;
- arg2.task_id = id;
- arg2.tp = impl;
- arg3.task_id = id;
- arg3.tp = impl;
- arg4.task_id = id;
- arg4.tp = impl;
- return id;
- }
-
- private:
-
- std::shared_ptr<thread_pool_implementation> impl;
-
- // restricted functions
- thread_pool(thread_pool&); // copy constructor
- thread_pool& operator=(thread_pool&); // assignment operator
-
- };
-
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- void future<T>::
- wait (
- ) const
- {
- if (tp)
- {
- tp->wait_for_task(task_id);
- tp.reset();
- task_id = 0;
- }
- }
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#ifdef NO_MAKEFILE
-#include "thread_pool_extension.cpp"
-#endif
-
-#endif // DLIB_THREAD_POOl_Hh_
-
-
diff --git a/ml/dlib/dlib/threads/thread_pool_extension_abstract.h b/ml/dlib/dlib/threads/thread_pool_extension_abstract.h
deleted file mode 100644
index ba54a7546..000000000
--- a/ml/dlib/dlib/threads/thread_pool_extension_abstract.h
+++ /dev/null
@@ -1,842 +0,0 @@
-// Copyright (C) 2008 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_THREAD_POOl_ABSTRACT_Hh_
-#ifdef DLIB_THREAD_POOl_ABSTRACT_Hh_
-
-#include "threads_kernel_abstract.h"
-#include "../uintn.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- class future
- {
- /*!
- INITIAL VALUE
- - is_ready() == true
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a container that allows you to safely pass objects
- into the tasks performed by the thread_pool object defined below. An
- example will make it clear:
-
- // Suppose you have a global function defined as follows
- void add (int a, int b, int& result) { result = a + b; }
-
- // Also suppose you have a thread_pool named tp defined somewhere.
- // Then you could do the following.
- future<int> a, b, result;
- a = 3;
- b = 4;
- // this function call causes another thread to execute a call to the add() function
- // and passes in the int objects contained in a, b, and result
- tp.add_task(add,a,b,result);
- // This line will wait for the task in the thread pool to finish and then print the
- // value in the result integer. So it will print a 7.
- cout << result << endl;
- !*/
-
- public:
- future (
- );
- /*!
- ensures
- - The object of type T contained in this future has
- an initial value for its type.
- - #is_ready() == true
- !*/
-
- future (
- const T& item
- );
- /*!
- ensures
- - #get() == item
- - #is_ready() == true
- !*/
-
- future (
- const future& item
- );
- /*!
- ensures
- - if (item.is_ready() == false) then
- - the call to this function blocks until the thread processing the task related
- to the item future has finished.
- - #is_ready() == true
- - #item.is_ready() == true
- - #get() == item.get()
- !*/
-
- ~future (
- );
- /*!
- ensures
- - if (is_ready() == false) then
- - the call to this function blocks until the thread processing the task related
- to this future has finished.
- !*/
-
- bool is_ready (
- ) const;
- /*!
- ensures
- - if (the value of this future may not yet be ready to be accessed because it
- is in use by a task in a thread_pool) then
- - returns false
- - else
- - returns true
- !*/
-
- future& operator=(
- const T& item
- );
- /*!
- ensures
- - if (is_ready() == false) then
- - the call to this function blocks until the thread processing the task related
- to this future has finished.
- - #is_ready() == true
- - #get() == item
- - returns *this
- !*/
-
- future& operator=(
- const future& item
- );
- /*!
- ensures
- - if (is_ready() == false || item.is_ready() == false) then
- - the call to this function blocks until the threads processing the tasks related
- to this future and the item future have finished.
- - #is_ready() == true
- - #item.is_ready() == true
- - #get() == item.get()
- - returns *this
- !*/
-
- operator T& (
- );
- /*!
- ensures
- - if (is_ready() == false) then
- - the call to this function blocks until the thread processing the task related
- to this future has finished.
- - #is_ready() == true
- - returns get()
- !*/
-
- operator const T& (
- ) const;
- /*!
- ensures
- - if (is_ready() == false) then
- - the call to this function blocks until the thread processing the task related
- to this future has finished.
- - #is_ready() == true
- - returns get()
- !*/
-
- T& get (
- );
- /*!
- ensures
- - if (is_ready() == false) then
- - the call to this function blocks until the thread processing the task related
- to this future has finished.
- - #is_ready() == true
- - returns a non-const reference to the object of type T contained inside this future
- !*/
-
- const T& get (
- ) const;
- /*!
- ensures
- - if (is_ready() == false) then
- - the call to this function blocks until the thread processing the task related
- to this future has finished.
- - #is_ready() == true
- - returns a const reference to the object of type T contained inside this future
- !*/
-
- };
-
-// ----------------------------------------------------------------------------------------
-
- template <typename T>
- inline void swap (
- future<T>& a,
- future<T>& b
- ) { std::swap(a.get(), b.get()); }
- /*!
- provides a global swap function
- !*/
-
-// ----------------------------------------------------------------------------------------
-
-
-// The future object comes with overloads for all the usual comparison operators.
-
- template <typename T> bool operator== (const future<T>& a, const future<T>& b) { return a.get() == b.get(); }
- template <typename T> bool operator!= (const future<T>& a, const future<T>& b) { return a.get() != b.get(); }
- template <typename T> bool operator<= (const future<T>& a, const future<T>& b) { return a.get() <= b.get(); }
- template <typename T> bool operator>= (const future<T>& a, const future<T>& b) { return a.get() >= b.get(); }
- template <typename T> bool operator< (const future<T>& a, const future<T>& b) { return a.get() < b.get(); }
- template <typename T> bool operator> (const future<T>& a, const future<T>& b) { return a.get() > b.get(); }
-
- template <typename T> bool operator== (const future<T>& a, const T& b) { return a.get() == b; }
- template <typename T> bool operator== (const T& a, const future<T>& b) { return a == b.get(); }
- template <typename T> bool operator!= (const future<T>& a, const T& b) { return a.get() != b; }
- template <typename T> bool operator!= (const T& a, const future<T>& b) { return a != b.get(); }
- template <typename T> bool operator<= (const future<T>& a, const T& b) { return a.get() <= b; }
- template <typename T> bool operator<= (const T& a, const future<T>& b) { return a <= b.get(); }
- template <typename T> bool operator>= (const future<T>& a, const T& b) { return a.get() >= b; }
- template <typename T> bool operator>= (const T& a, const future<T>& b) { return a >= b.get(); }
- template <typename T> bool operator< (const future<T>& a, const T& b) { return a.get() < b; }
- template <typename T> bool operator< (const T& a, const future<T>& b) { return a < b.get(); }
- template <typename T> bool operator> (const future<T>& a, const T& b) { return a.get() > b; }
- template <typename T> bool operator> (const T& a, const future<T>& b) { return a > b.get(); }
-
-// ----------------------------------------------------------------------------------------
-
- class thread_pool
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a fixed size group of threads which you can
- submit tasks to and then wait for those tasks to be completed.
-
- Note that setting the number of threads to 0 is a valid way to
- use this object. It causes it to not contain any threads
- at all. When tasks are submitted to the object in this mode
- the tasks are processed within the calling thread. So in this
- mode any thread that calls add_task() is considered to be
- a thread_pool thread capable of executing tasks.
-
- This object is also implemented such that no memory allocations occur
- after the thread_pool has been constructed so long as the user doesn't
- call any of the add_task_by_value() routines. The future object also
- doesn't perform any memory allocations or contain any system resources
- such as mutex objects.
-
- EXCEPTIONS
- Note that if an exception is thrown inside a task thread and is not caught
- then the exception will be trapped inside the thread pool and rethrown at a
- later time when someone calls one of the add task or wait member functions
- of the thread pool. This allows exceptions to propagate out of task threads
- and into the calling code where they can be handled.
- !*/
-
- public:
- explicit thread_pool (
- unsigned long num_threads
- );
- /*!
- ensures
- - #num_threads_in_pool() == num_threads
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- ~thread_pool(
- );
- /*!
- ensures
- - blocks until all tasks in the pool have finished.
- - If one of the threads has generated an exception but it hasn't yet been
- rethrown to the caller (e.g. by calling wait_for_all_tasks()) then the
- program will be terminated. So make sure you handle all the possible
- exceptions from your tasks.
- !*/
-
- bool is_task_thread (
- ) const;
- /*!
- ensures
- - if (the thread calling this function is one of the threads in this
- thread pool or num_threads_in_pool() == 0) then
- - returns true
- - else
- - returns false
- !*/
-
- unsigned long num_threads_in_pool (
- ) const;
- /*!
- ensures
- - returns the number of threads contained in this thread pool. That is, returns
- the maximum number of tasks that this object will process concurrently.
- !*/
-
- template <typename F>
- uint64 add_task_by_value (
- const F& function_object
- );
- /*!
- requires
- - function_object() is a valid expression
- ensures
- - makes a copy of function_object, call it FCOPY.
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls FCOPY() within the calling thread and returns when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls FCOPY().
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)()
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- - obj will not go out of scope until after the task has completed (i.e.
- this function passes obj to the task by reference. If you want to avoid
- this restriction then use add_task_by_value())
- ensures
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (obj.*funct)() within the calling thread and returns
- when it finishes.
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (obj.*funct)()
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)()
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- ensures
- - makes a copy of obj, call it OBJ_COPY.
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (OBJ_COPY.*funct)() within the calling thread and returns
- when it finishes.
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (OBJ_COPY.*funct)().
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)(long),
- long arg1
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- - obj will not go out of scope until after the task has completed (i.e.
- this function passes obj to the task by reference. If you want to avoid
- this restriction then use add_task_by_value())
- ensures
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (obj.*funct)(arg1) within the calling thread and returns
- when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (obj.*funct)(arg1)
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T>
- uint64 add_task (
- T& obj,
- void (T::*funct)(long,long),
- long arg1,
- long arg2
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- - obj will not go out of scope until after the task has completed (i.e.
- this function passes obj to the task by reference. If you want to avoid
- this restriction then use add_task_by_value())
- ensures
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (obj.*funct)(arg1,arg2) within the calling thread and returns
- when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (obj.*funct)(arg1,arg2)
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- void wait_for_task (
- uint64 task_id
- ) const;
- /*!
- ensures
- - if (there is currently a task with the given id being executed in the thread pool) then
- - the call to this function blocks until the task with the given id is complete
- - else
- - the call to this function returns immediately
- !*/
-
- void wait_for_all_tasks (
- ) const;
- /*!
- ensures
- - the call to this function blocks until all tasks which were submitted
- to the thread pool by the thread that is calling this function have
- finished.
- !*/
-
- // --------------------
-
- template <typename F, typename A1>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1
- );
- /*!
- requires
- - function_object(arg1.get()) is a valid expression
- (i.e. The A1 type stored in the future must be a type that can be passed into the given function object)
- - function_object will not go out of scope until after the task has completed (i.e.
- this function passes function_object to the task by reference. If you want to avoid
- this restriction then use add_task_by_value())
- ensures
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls function_object(arg1.get()) within the calling thread and returns
- when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls function_object(arg1.get()).
- - #arg1.is_ready() == false
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename F, typename A1>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1
- );
- /*!
- requires
- - function_object(arg1.get()) is a valid expression
- (i.e. The A1 type stored in the future must be a type that can be passed into the given function object)
- ensures
- - makes a copy of function_object, call it FCOPY.
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls FCOPY(arg1.get()) within the calling thread and returns when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls FCOPY(arg1.get()).
- - #arg1.is_ready() == false
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T, typename T1, typename A1>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1),
- future<A1>& arg1
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- - (obj.*funct)(arg1.get()) must be a valid expression.
- (i.e. The A1 type stored in the future must be a type that can be passed into the given function)
- - obj will not go out of scope until after the task has completed (i.e.
- this function passes obj to the task by reference. If you want to avoid
- this restriction then use add_task_by_value())
- ensures
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (obj.*funct)(arg1.get()) within the calling thread and returns
- when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (obj.*funct)(arg1.get()).
- - #arg1.is_ready() == false
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T, typename T1, typename A1>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1),
- future<A1>& arg1
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- - (obj.*funct)(arg1.get()) must be a valid expression.
- (i.e. The A1 type stored in the future must be a type that can be passed into the given function)
- ensures
- - makes a copy of obj, call it OBJ_COPY.
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (OBJ_COPY.*funct)(arg1.get()) within the calling thread and returns
- when it finishes.
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (OBJ_COPY.*funct)(arg1.get()).
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T, typename T1, typename A1>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1) const,
- future<A1>& arg1
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- - (obj.*funct)(arg1.get()) must be a valid expression.
- (i.e. The A1 type stored in the future must be a type that can be passed into the given function)
- - obj will not go out of scope until after the task has completed (i.e.
- this function passes obj to the task by reference. If you want to avoid
- this restriction then use add_task_by_value())
- ensures
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (obj.*funct)(arg1.get()) within the calling thread and returns
- when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (obj.*funct)(arg1.get()).
- - #arg1.is_ready() == false
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T, typename T1, typename A1>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1) const,
- future<A1>& arg1
- );
- /*!
- requires
- - funct == a valid member function pointer for class T
- - (obj.*funct)(arg1.get()) must be a valid expression.
- (i.e. The A1 type stored in the future must be a type that can be passed into the given function)
- ensures
- - makes a copy of obj, call it OBJ_COPY.
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls (OBJ_COPY.*funct)(arg1.get()) within the calling thread and returns
- when it finishes.
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls (OBJ_COPY.*funct)(arg1.get()).
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- template <typename T1, typename A1>
- uint64 add_task (
- void (*funct)(T1),
- future<A1>& arg1
- );
- /*!
- requires
- - funct == a valid function pointer
- - (funct)(arg1.get()) must be a valid expression.
- (i.e. The A1 type stored in the future must be a type that can be passed into the given function)
- ensures
- - if (is_task_thread() == true and there aren't any free threads available) then
- - calls funct(arg1.get()) within the calling thread and returns
- when it finishes
- - else
- - the call to this function blocks until there is a free thread in the pool
- to process this new task. Once a free thread is available the task
- is handed off to that thread which then calls funct(arg1.get()).
- - #arg1.is_ready() == false
- - returns a task id that can be used by this->wait_for_task() to wait
- for the submitted task to finish.
- !*/
-
- // --------------------------------------------------------------------------------
- // The remainder of this class just contains overloads for add_task() and add_task_by_value()
- // that take up to 4 futures (as well as 0 futures). Their behavior is identical to the above
- // add_task() and add_task_by_value() functions.
- // --------------------------------------------------------------------------------
-
- template <typename F, typename A1, typename A2>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1,
- future<A2>& arg2
- );
-
- template <typename F, typename A1, typename A2>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1,
- future<A2>& arg2
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1,T2),
- future<A1>& arg1,
- future<A2>& arg2
- );
-
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2),
- future<A1>& arg1,
- future<A2>& arg2
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1,T2) const,
- future<A1>& arg1,
- future<A2>& arg2
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2) const,
- future<A1>& arg1,
- future<A2>& arg2
- );
-
- template <typename T1, typename A1,
- typename T2, typename A2>
- uint64 add_task (
- void (*funct)(T1,T2),
- future<A1>& arg1,
- future<A2>& arg2
- );
-
- // --------------------
-
- template <typename F, typename A1, typename A2, typename A3>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- );
-
- template <typename F, typename A1, typename A2, typename A3>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1,T2,T3),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1,T2,T3) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- );
-
- template <typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3>
- uint64 add_task (
- void (*funct)(T1,T2,T3),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3
- );
-
- // --------------------
-
- template <typename F, typename A1, typename A2, typename A3, typename A4>
- uint64 add_task (
- F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- );
-
- template <typename F, typename A1, typename A2, typename A3, typename A4>
- uint64 add_task_by_value (
- const F& function_object,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task (
- T& obj,
- void (T::*funct)(T1,T2,T3,T4),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3,T4),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task (
- const T& obj,
- void (T::*funct)(T1,T2,T3,T4) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- );
-
- template <typename T, typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)(T1,T2,T3,T4) const,
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- );
-
- template <typename T1, typename A1,
- typename T2, typename A2,
- typename T3, typename A3,
- typename T4, typename A4>
- uint64 add_task (
- void (*funct)(T1,T2,T3,T4),
- future<A1>& arg1,
- future<A2>& arg2,
- future<A3>& arg3,
- future<A4>& arg4
- );
-
- // --------------------
-
- template <typename F>
- uint64 add_task (
- F& function_object
- );
-
- template <typename T>
- uint64 add_task (
- const T& obj,
- void (T::*funct)() const,
- );
-
- template <typename T>
- uint64 add_task_by_value (
- const T& obj,
- void (T::*funct)() const
- );
-
- uint64 add_task (
- void (*funct)()
- );
-
- // --------------------
-
- private:
-
- // restricted functions
- thread_pool(thread_pool&); // copy constructor
- thread_pool& operator=(thread_pool&); // assignment operator
- };
-
-}
-
-// ----------------------------------------------------------------------------------------
-
-#endif // DLIB_THREAD_POOl_ABSTRACT_Hh_
-
-
-
diff --git a/ml/dlib/dlib/threads/thread_specific_data_extension.h b/ml/dlib/dlib/threads/thread_specific_data_extension.h
deleted file mode 100644
index 0b5339200..000000000
--- a/ml/dlib/dlib/threads/thread_specific_data_extension.h
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREAD_SPECIFIC_DATA_EXTENSIOn_
-#define DLIB_THREAD_SPECIFIC_DATA_EXTENSIOn_
-
-#include "thread_specific_data_extension_abstract.h"
-#include "threads_kernel_abstract.h"
-#include "../binary_search_tree.h"
-#include "auto_mutex_extension.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- class thread_specific_data
- {
- /*!
- CONVENTION
- - for all valid ID:
- (*items[ID]) == pointer to the data for thread with id ID
- !*/
- public:
-
- thread_specific_data (
- )
- {
- thread_end_handler_calls_left = 0;
- }
-
- ~thread_specific_data (
- )
- {
- // We should only call the unregister_thread_end_handler function if there are
- // some outstanding callbacks we expect to get. Otherwise lets avoid calling it
- // since the dlib state that maintains the registered thread end handlers may have
- // been destructed already (since the program might be in the process of terminating).
- bool call_unregister = false;
- m.lock();
- if (thread_end_handler_calls_left > 0)
- call_unregister = true;
- m.unlock();
-
- if (call_unregister)
- unregister_thread_end_handler(const_cast<thread_specific_data&>(*this),&thread_specific_data::thread_end_handler);
-
- auto_mutex M(m);
- items.reset();
- while (items.move_next())
- {
- delete items.element().value();
- }
- }
-
- inline T& data (
- ) { return get_data(); }
-
- inline const T& data (
- ) const { return get_data(); }
-
- private:
-
- T& get_data (
- ) const
- {
- thread_id_type id = get_thread_id();
- auto_mutex M(m);
-
- T** item = items[id];
- if (item)
- {
- return **item;
- }
- else
- {
- // register an end handler for this thread so long as it is a dlib created thread.
- T* new_item = new T;
-
- bool in_tree = false;
- try
- {
- T* temp_item = new_item;
- thread_id_type temp_id = id;
- items.add(temp_id,temp_item);
- in_tree = true;
-
- if (is_dlib_thread(id))
- {
- register_thread_end_handler(const_cast<thread_specific_data&>(*this),&thread_specific_data::thread_end_handler);
- ++thread_end_handler_calls_left;
- }
- }
- catch (...)
- {
- if (in_tree)
- {
- items.destroy(id);
- }
- delete new_item;
- throw;
- }
-
- return *new_item;
- }
- }
-
- void thread_end_handler (
- )
- {
- const thread_id_type id = get_thread_id();
- thread_id_type junk = 0;
- T* item = 0;
- auto_mutex M(m);
- --thread_end_handler_calls_left;
- if (items[id])
- {
- items.remove(id,junk,item);
- delete item;
- }
- }
-
- mutable typename binary_search_tree<thread_id_type,T*>::kernel_2a items;
- mutex m;
- mutable long thread_end_handler_calls_left;
-
- // restricted functions
- thread_specific_data(thread_specific_data&); // copy constructor
- thread_specific_data& operator=(thread_specific_data&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREAD_SPECIFIC_DATA_EXTENSIOn_
-
-
-
diff --git a/ml/dlib/dlib/threads/thread_specific_data_extension_abstract.h b/ml/dlib/dlib/threads/thread_specific_data_extension_abstract.h
deleted file mode 100644
index 03fb9ddaa..000000000
--- a/ml/dlib/dlib/threads/thread_specific_data_extension_abstract.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_THREAD_SPECIFIC_DATA_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_THREAD_SPECIFIC_DATA_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- class thread_specific_data
- {
- /*!
- WHAT THIS OBJECT REPRESENTS
- This object represents a container of thread specific data. When
- a thread calls the data() member function it gets a reference to a T object
- that is specific to its own thread. Each subsequent call to data() from that
- thread returns the same instance. Also note that when a thread ends
- the instance of its data() object gets destroyed and freed (if the thread
- was created by the dlib library). So any pointers or references to the object
- will be invalid after the thread has ended.
- !*/
- public:
-
- thread_specific_data (
- );
- /*!
- ensures
- - #*this is properly initialized
- !*/
-
- ~thread_specific_data (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed. This includes
- all the thread specific data returned by the data() functions.
- !*/
-
- T& data (
- );
- /*!
- ensures
- - if (the calling thread has NOT called this->data() before) then
- - constructs an instance of T that is specific to the calling
- thread.
- - returns a reference to the T instance that was constructed for
- the calling thread.
- throws
- - std::bad_alloc or any exception thrown by T's constructor
- If an exception is thrown then the call to data() will have
- no effect on *this.
- !*/
-
- const T& data (
- ) const;
- /*!
- ensures
- - if (the calling thread has NOT called this->data() before) then
- - constructs an instance of T that is specific to the calling
- thread.
- - returns a const reference to the T instance that was constructed for
- the calling thread.
- throws
- - std::bad_alloc or any exception thrown by T's constructor
- If an exception is thrown then the call to data() will have
- no effect on *this.
- !*/
-
- private:
- // restricted functions
- thread_specific_data(thread_specific_data&); // copy constructor
- thread_specific_data& operator=(thread_specific_data&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREAD_SPECIFIC_DATA_EXTENSIOn_ABSTRACT_
-
-
diff --git a/ml/dlib/dlib/threads/threaded_object_extension.cpp b/ml/dlib/dlib/threads/threaded_object_extension.cpp
deleted file mode 100644
index a7326c11d..000000000
--- a/ml/dlib/dlib/threads/threaded_object_extension.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADED_OBJECT_EXTENSIOn_CPP
-#define DLIB_THREADED_OBJECT_EXTENSIOn_CPP
-
-#include "threaded_object_extension.h"
-#include "create_new_thread_extension.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- threaded_object::
- threaded_object (
- ):
- s(m_),
- id1(0),
- is_running_(false),
- is_alive_(false),
- should_stop_(false),
- id_valid(false)
- {
- }
-
-// ----------------------------------------------------------------------------------------
-
- threaded_object::
- ~threaded_object (
- )
- {
- try
- {
- DLIB_ASSERT(is_alive() == false,
- "\tthreaded_object::~threaded_object()"
- << "\n\tYou have let a threaded object destruct itself before terminating its thread"
- << "\n\tthis: " << this
- );
- }
- catch (std::exception& e)
- {
- std::cerr << e.what() << std::endl;
- assert(false);
- abort();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool threaded_object::
- is_running (
- ) const
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tbool threaded_object::is_running()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- return is_running_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool threaded_object::
- is_alive (
- ) const
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tbool threaded_object::is_alive()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- return is_alive_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threaded_object::
- wait (
- ) const
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tvoid threaded_object::wait()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- while (is_alive_)
- s.wait();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threaded_object::
- start (
- )
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tvoid threaded_object::start()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- if (is_alive_ == false)
- {
- if (create_new_thread<threaded_object,&threaded_object::thread_helper>(*this) == false)
- {
- is_running_ = false;
- throw thread_error();
- }
- }
- is_alive_ = true;
- is_running_ = true;
- should_stop_ = false;
- s.broadcast();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threaded_object::
- restart (
- )
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tvoid threaded_object::restart()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- if (is_alive_ == false)
- {
- if (create_new_thread<threaded_object,&threaded_object::thread_helper>(*this) == false)
- {
- is_running_ = false;
- throw thread_error();
- }
- should_respawn_ = false;
- }
- else
- {
- should_respawn_ = true;
- }
- is_alive_ = true;
- is_running_ = true;
- should_stop_ = false;
- s.broadcast();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threaded_object::
- set_respawn (
- )
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tvoid threaded_object::set_respawn()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- should_respawn_ = true;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool threaded_object::
- should_respawn (
- ) const
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tbool threaded_object::should_respawn()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- return should_respawn_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threaded_object::
- pause (
- )
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tvoid threaded_object::pause()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- is_running_ = false;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threaded_object::
- stop (
- )
- {
- auto_mutex M(m_);
-
- DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
- "\tvoid threaded_object::stop()"
- << "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
-
- should_stop_ = true;
- is_running_ = false;
- should_respawn_ = false;
- s.broadcast();
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool threaded_object::
- should_stop (
- ) const
- {
- auto_mutex M(m_);
- DLIB_ASSERT(is_alive_ && id1 == get_thread_id() && id_valid == true,
- "\tbool threaded_object::should_stop()"
- << "\n\tYou can only call this function from the thread that executes threaded_object::thread"
- << "\n\tthis: " << this
- );
- while (is_running_ == false && should_stop_ == false)
- s.wait();
- return should_stop_;
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threaded_object::
- thread_helper(
- )
- {
-#ifdef ENABLE_ASSERTS
- id1 = get_thread_id();
- id_valid = true;
-#endif
- while (true)
- {
- m_.lock();
- should_respawn_ = false;
- m_.unlock();
-
- thread();
-
- auto_mutex M(m_);
-
- if (should_respawn_)
- continue;
-
-#ifdef ENABLE_ASSERTS
- id_valid = false;
-#endif
-
- is_alive_ = false;
- is_running_ = false;
- should_stop_ = false;
- s.broadcast();
-
- return;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREADED_OBJECT_EXTENSIOn_CPP
-
diff --git a/ml/dlib/dlib/threads/threaded_object_extension.h b/ml/dlib/dlib/threads/threaded_object_extension.h
deleted file mode 100644
index dcf00daea..000000000
--- a/ml/dlib/dlib/threads/threaded_object_extension.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADED_OBJECT_EXTENSIOn_
-#define DLIB_THREADED_OBJECT_EXTENSIOn_
-
-#include "threaded_object_extension_abstract.h"
-#include "threads_kernel.h"
-#include "auto_mutex_extension.h"
-#include "../algs.h"
-#include "../assert.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class threaded_object
- {
- /*!
- INITIAL VALUE
- - is_running_ == false
- - is_alive_ == false
- - should_stop_ == false
- - should_respawn_ == false
-
-#ifdef ENABLE_ASSERTS
- - id_valid == false
- - id1 == get_main_thread_id()
-#endif
-
- CONVENTION
- - is_running() == is_running_
- - is_alive() == is_alive_
- - should_stop() == should_stop_
- - should_respawn() == should_respawn_
-
-
-#ifdef ENABLE_ASSERTS
- - if (when thread() is executing) then
- - id1 == the id of the running thread
- - id_valid == true
- - else
- - id1 == an undefined value
- - id_valid == false
-#endif
-
- - m_ == the mutex used to protect all our variables
- - s == the signaler for m_
- !*/
-
- public:
-
- threaded_object (
- );
-
- virtual ~threaded_object (
- );
-
- bool is_running (
- ) const;
-
- bool is_alive (
- ) const;
-
- void wait (
- ) const;
-
- void start (
- );
-
- void restart (
- );
-
- void set_respawn (
- );
-
- bool should_respawn (
- ) const;
-
- void pause (
- );
-
- void stop (
- );
-
- protected:
-
- bool should_stop (
- ) const;
-
- private:
-
- void thread_helper(
- );
-
- virtual void thread (
- ) = 0;
-
- mutex m_;
- signaler s;
- thread_id_type id1;
- bool is_running_;
- bool is_alive_;
- bool should_stop_;
- bool should_respawn_;
- bool id_valid;
-
- // restricted functions
- threaded_object(threaded_object&); // copy constructor
- threaded_object& operator=(threaded_object&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "threaded_object_extension.cpp"
-#endif
-
-#endif // DLIB_THREADED_OBJECT_EXTENSIOn_
-
-
diff --git a/ml/dlib/dlib/threads/threaded_object_extension_abstract.h b/ml/dlib/dlib/threads/threaded_object_extension_abstract.h
deleted file mode 100644
index 32a8fbc31..000000000
--- a/ml/dlib/dlib/threads/threaded_object_extension_abstract.h
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (C) 2007 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_THREADED_OBJECT_EXTENSIOn_ABSTRACT_
-#ifdef DLIB_THREADED_OBJECT_EXTENSIOn_ABSTRACT_
-
-#include "threads_kernel_abstract.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- class threaded_object
- {
- /*!
- INITIAL VALUE
- - is_running() == false
- - is_alive() == false
- - should_respawn() == false
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a simple threaded object. To use it you inherit
- from it and define the thread() function. Then when you call start()
- it will spawn a thread that calls this->thread().
- !*/
- public:
-
- threaded_object (
- );
- /*!
- ensures
- - #*this is properly initialized
- throws
- - std::bad_alloc
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create threading objects.
- !*/
-
- virtual ~threaded_object (
- );
- /*!
- requires
- - is_alive() == false
- (i.e. in the destructor for the object you derive from this one you
- must wait for this->thread() to end.)
- ensures
- - all resources allocated by *this have been freed.
- !*/
-
- bool is_running (
- ) const;
- /*!
- requires
- - is not called from this->thread()
- ensures
- - if (is_alive() && this->thread() is currently supposed to be executing) then
- - returns true
- - else
- - returns false
- !*/
-
- bool is_alive (
- ) const;
- /*!
- requires
- - is not called from this->thread()
- ensures
- - if (this->thread() has been called by some thread and has yet to terminate) then
- - returns true
- - else
- - returns false
- !*/
-
- void wait (
- ) const;
- /*!
- requires
- - is not called from this->thread()
- ensures
- - if (is_alive() == true) then
- - blocks until this->thread() terminates
- !*/
-
- void start (
- );
- /*!
- requires
- - is not called from this->thread()
- ensures
- - #is_alive() == true
- - #is_running() == true
- - #should_stop() == false
- throws
- - std::bad_alloc or dlib::thread_error
- If either of these exceptions are thrown then
- #is_alive() == false and #is_running() == false
- !*/
-
- void set_respawn (
- );
- /*!
- requires
- - is not called from this->thread()
- ensures
- - #should_respawn() == true
- !*/
-
- bool should_respawn (
- ) const;
- /*!
- requires
- - is not called from this->thread()
- ensures
- - returns true if the thread will automatically restart upon termination and
- false otherwise. Note that every time a thread starts it sets should_respawn()
- back to false. Therefore, a single call to set_respawn() can cause at most
- one respawn to occur.
- !*/
-
- void restart (
- );
- /*!
- requires
- - is not called from this->thread()
- ensures
- - This function atomically executes set_respawn() and start(). The precise meaning of this
- is defined below.
- - if (is_alive()) then
- - #should_respawn() == true
- - else
- - #should_respawn() == false
- - #is_alive() == true
- - #is_running() == true
- - #should_stop() == false
- throws
- - std::bad_alloc or dlib::thread_error
- If either of these exceptions are thrown then
- #is_alive() == false and #is_running() == false
- !*/
-
- void pause (
- );
- /*!
- requires
- - is not called from this->thread()
- ensures
- - #is_running() == false
- !*/
-
- void stop (
- );
- /*!
- requires
- - is not called from this->thread()
- ensures
- - #should_stop() == true
- - #is_running() == false
- - #should_respawn() == false
- !*/
-
- protected:
-
- bool should_stop (
- ) const;
- /*!
- requires
- - is only called from the thread that executes this->thread()
- ensures
- - calls to this function block until (#is_running() == true || #should_stop() == true)
- - if (this thread is supposed to terminate) then
- - returns true
- - else
- - returns false
- !*/
-
- private:
-
- virtual void thread (
- ) = 0;
- /*!
- requires
- - is executed in its own thread
- - is only executed in one thread at a time
- throws
- - does not throw any exceptions
- !*/
-
- // restricted functions
- threaded_object(threaded_object&); // copy constructor
- threaded_object& operator=(threaded_object&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREADED_OBJECT_EXTENSIOn_ABSTRACT_
-
diff --git a/ml/dlib/dlib/threads/threads_kernel.h b/ml/dlib/dlib/threads/threads_kernel.h
deleted file mode 100644
index 77cb16d92..000000000
--- a/ml/dlib/dlib/threads/threads_kernel.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (C) 2006 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADs_KERNEL_
-#define DLIB_THREADs_KERNEL_
-
-#include "../platform.h"
-
-#ifdef WIN32
-#include "windows.h"
-#endif
-
-#ifndef WIN32
-#include "posix.h"
-#endif
-
-#endif // DLIB_THREADs_KERNEL_
-
-
diff --git a/ml/dlib/dlib/threads/threads_kernel_1.cpp b/ml/dlib/dlib/threads/threads_kernel_1.cpp
deleted file mode 100644
index cb36b8d3f..000000000
--- a/ml/dlib/dlib/threads/threads_kernel_1.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEL_1_CPp_
-#define DLIB_THREADS_KERNEL_1_CPp_
-
-#include "../platform.h"
-
-#ifdef WIN32
-
-#include "threads_kernel_1.h"
-
-#include <process.h>
-
-
-namespace dlib
-{
- namespace threads_kernel_shared_helpers
- {
-
- // -----------------------------------------------------------------------------------
-
- struct info
- {
- void* param;
- void (*funct)(void*);
- };
-
- // -----------------------------------------------------------------------------------
-
- unsigned int __stdcall thread_starter (
- void* param
- )
- {
- info* alloc_p = static_cast<info*>(param);
- info p = *alloc_p;
- delete alloc_p;
-
- p.funct(p.param);
- return 0;
- }
-
- // -----------------------------------------------------------------------------------
-
- bool spawn_thread (
- void (*funct)(void*),
- void* param
- )
- {
- info* p;
- try { p = new info; }
- catch (...) { return false; }
-
- p->funct = funct;
- p->param = param;
-
-
- unsigned int garbage;
-
- HANDLE thandle = (HANDLE)_beginthreadex (NULL,0,thread_starter,p,0,&garbage);
- // make thread and add it to the pool
-
- // return false if _beginthreadex didn't work
- if ( thandle == 0)
- {
- delete p;
- return false;
- }
-
- // throw away the thread handle
- CloseHandle(thandle);
- return true;
- }
-
- // -----------------------------------------------------------------------------------
-
- }
-
-}
-
-#endif // WIN32
-
-#endif // DLIB_THREADS_KERNEL_1_CPp_
-
diff --git a/ml/dlib/dlib/threads/threads_kernel_1.h b/ml/dlib/dlib/threads/threads_kernel_1.h
deleted file mode 100644
index 586a21b7e..000000000
--- a/ml/dlib/dlib/threads/threads_kernel_1.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEl_1_
-#define DLIB_THREADS_KERNEl_1_
-
-#ifdef DLIB_ISO_CPP_ONLY
-#error "DLIB_ISO_CPP_ONLY is defined so you can't use this OS dependent code. Turn DLIB_ISO_CPP_ONLY off if you want to use it."
-#endif
-
-#include "threads_kernel_abstract.h"
-
-#include "../windows_magic.h"
-#include <windows.h>
-#include "../algs.h"
-#include <condition_variable>
-#include <mutex>
-#include <chrono>
-
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- typedef DWORD thread_id_type;
-
- inline thread_id_type get_thread_id (
- )
- {
- return GetCurrentThreadId();
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // mutex object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- // forward declaration of signaler
- class signaler;
-
- class mutex
- {
- public:
-
- mutex (
- )
- {
- }
-
- ~mutex (
- ) { }
-
- void lock (
- ) const { cs.lock(); }
-
- void unlock (
- ) const { cs.unlock(); }
-
- private:
-
- friend class signaler;
-
- mutable std::mutex cs;
-
- // restricted functions
- mutex(mutex&); // copy constructor
- mutex& operator=(mutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // signaler object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class signaler
- {
-
- public:
- signaler (
- const mutex& associated_mutex
- ) :
- m(associated_mutex)
- {
-
- }
-
- ~signaler (
- ) { }
-
- void wait (
- ) const
- {
- std::unique_lock<std::mutex> cs(m.cs, std::defer_lock);
- cv.wait(cs);
- }
-
- bool wait_or_timeout (
- unsigned long milliseconds
- ) const
- {
- std::unique_lock<std::mutex> cs(m.cs, std::defer_lock);
- auto status = cv.wait_until(cs, std::chrono::system_clock::now() + std::chrono::milliseconds(milliseconds));
- return status == std::cv_status::no_timeout;
- }
-
- void signal (
- ) const
- {
- cv.notify_one();
- }
-
- void broadcast (
- ) const
- {
- cv.notify_all();
- }
-
- const mutex& get_mutex (
- ) const { return m; }
-
- private:
-
- mutable std::condition_variable cv;
-
- const mutex& m;
-
- // restricted functions
- signaler(signaler&); // copy constructor
- signaler& operator=(signaler&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
- namespace threads_kernel_shared_helpers
- {
- bool spawn_thread (
- void (*funct)(void*),
- void* param
- );
- /*!
- is identical to create_new_thread() but just doesn't use any thread pooling.
- !*/
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#include "threads_kernel_shared.h"
-
-#ifdef NO_MAKEFILE
-#include "threads_kernel_1.cpp"
-#endif
-
-#endif // DLIB_THREADS_KERNEl_1_
-
diff --git a/ml/dlib/dlib/threads/threads_kernel_2.cpp b/ml/dlib/dlib/threads/threads_kernel_2.cpp
deleted file mode 100644
index 06fb80d00..000000000
--- a/ml/dlib/dlib/threads/threads_kernel_2.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEL_2_CPp_
-#define DLIB_THREADS_KERNEL_2_CPp_
-
-#include "../platform.h"
-
-#ifdef POSIX
-
-#include "threads_kernel_2.h"
-
-
-namespace dlib
-{
- namespace threads_kernel_shared_helpers
- {
-
- // -----------------------------------------------------------------------------------
-
- struct info
- {
- void* param;
- void (*funct)(void*);
- };
-
- // -----------------------------------------------------------------------------------
-
- void* thread_starter (
- void* param
- )
- {
- info* alloc_p = static_cast<info*>(param);
- info p = *alloc_p;
- delete alloc_p;
-
- // detach self
- pthread_detach(pthread_self());
-
- p.funct(p.param);
- return 0;
- }
-
- // -----------------------------------------------------------------------------------
-
- bool spawn_thread (
- void (*funct)(void*),
- void* param
- )
- {
- info* p;
- try { p = new info; }
- catch (...) { return false; }
-
- p->funct = funct;
- p->param = param;
-
- pthread_t thread_id;
- if ( pthread_create (&thread_id, 0, thread_starter, p) )
- {
- delete p;
- return false;
- }
- return true;
- }
-
- // -----------------------------------------------------------------------------------
-
- }
-
-}
-
-#endif // POSIX
-
-#endif // DLIB_THREADS_KERNEL_2_CPp_
-
diff --git a/ml/dlib/dlib/threads/threads_kernel_2.h b/ml/dlib/dlib/threads/threads_kernel_2.h
deleted file mode 100644
index 209142131..000000000
--- a/ml/dlib/dlib/threads/threads_kernel_2.h
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEl_2_
-#define DLIB_THREADS_KERNEl_2_
-
-#ifdef DLIB_ISO_CPP_ONLY
-#error "DLIB_ISO_CPP_ONLY is defined so you can't use this OS dependent code. Turn DLIB_ISO_CPP_ONLY off if you want to use it."
-#endif
-
-#include "threads_kernel_abstract.h"
-#include <pthread.h>
-#include <errno.h>
-#include <sys/time.h>
-#include "../algs.h"
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- typedef pthread_t thread_id_type;
-
- inline thread_id_type get_thread_id (
- )
- {
- return pthread_self();
- }
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // mutex object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- // forward declaration of signaler
- class signaler;
-
- class mutex
- {
- // give signaler access to hMutex
- friend class signaler;
- public:
-
- mutex (
- )
- {
- if (pthread_mutex_init(&myMutex,0))
- {
- throw dlib::thread_error(ECREATE_MUTEX,
- "in function mutex::mutex() an error occurred making the mutex"
- );
- }
- }
-
- ~mutex (
- ) { pthread_mutex_destroy(&myMutex); }
-
- void lock (
- ) const { pthread_mutex_lock(&myMutex); }
-
- void unlock (
- ) const { pthread_mutex_unlock(&myMutex); }
-
- private:
-
- mutable pthread_mutex_t myMutex;
-
- // restricted functions
- mutex(mutex&); // copy constructor
- mutex& operator=(mutex&); // assignement opertor
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // signaler object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class signaler
- {
-
- public:
-
-
- signaler (
- const mutex& assoc_mutex
- ) :
- associated_mutex(&assoc_mutex.myMutex),
- m(assoc_mutex)
- {
- if (pthread_cond_init(&cond,0))
- {
- throw dlib::thread_error(ECREATE_SIGNALER,
- "in function signaler::signaler() an error occurred making the signaler"
- );
- }
- }
-
- ~signaler (
- ) { pthread_cond_destroy(&cond); }
-
- void wait (
- ) const
- {
- pthread_cond_wait(&cond,associated_mutex);
- }
-
- bool wait_or_timeout (
- unsigned long milliseconds
- ) const
- {
- timespec time_to_wait;
-
- timeval curtime;
- gettimeofday(&curtime,0);
-
- // get the time and adjust the timespec object by the appropriate amount
- time_to_wait.tv_sec = milliseconds/1000 + curtime.tv_sec;
- time_to_wait.tv_nsec = curtime.tv_usec;
- time_to_wait.tv_nsec *= 1000;
- time_to_wait.tv_nsec += (milliseconds%1000)*1000000;
-
- time_to_wait.tv_sec += time_to_wait.tv_nsec/1000000000;
- time_to_wait.tv_nsec = time_to_wait.tv_nsec%1000000000;
-
- if ( pthread_cond_timedwait(&cond,associated_mutex,&time_to_wait) == ETIMEDOUT)
- {
- return false;
- }
- else
- {
- return true;
- }
- }
-
- void signal (
- ) const { pthread_cond_signal(&cond); }
-
- void broadcast (
- ) const { pthread_cond_broadcast(&cond); }
-
- const mutex& get_mutex (
- ) const { return m; }
-
- private:
-
- pthread_mutex_t* const associated_mutex;
- mutable pthread_cond_t cond;
- const mutex& m;
-
- // restricted functions
- signaler(signaler&); // copy constructor
- signaler& operator=(signaler&); // assignement opertor
- };
-
-// ----------------------------------------------------------------------------------------
-
- namespace threads_kernel_shared_helpers
- {
- bool spawn_thread (
- void (*funct)(void*),
- void* param
- );
- /*!
- is identical to create_new_thread() but just doesn't use any thread pooling.
- !*/
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#include "threads_kernel_shared.h"
-
-#ifdef NO_MAKEFILE
-#include "threads_kernel_2.cpp"
-#endif
-
-#endif // DLIB_THREADS_KERNEl_2_
-
diff --git a/ml/dlib/dlib/threads/threads_kernel_abstract.h b/ml/dlib/dlib/threads/threads_kernel_abstract.h
deleted file mode 100644
index d88d37dad..000000000
--- a/ml/dlib/dlib/threads/threads_kernel_abstract.h
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#undef DLIB_THREADS_KERNEl_ABSTRACT_
-#ifdef DLIB_THREADS_KERNEl_ABSTRACT_
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-
- /*!
- THREAD POOLING
- When threads end they go into a global thread pool and each waits there
- for 30 seconds before timing out and having its resources returned to the
- operating system. When create_new_thread() is called it first looks in the
- thread pool to see if there are any threads it can snatch from the pool, if
- not then it makes a new one.
-
- Note that whenever I say something happens when a thread "terminates" or "ends"
- I mean "when it returns to the thread pool." From the client programmer point
- of view a thread terminates/ends when it returns to the dlib thread pool and you
- shouldn't and indeed don't need to know when it actually gets its resources
- reclaimed by the operating system.
-
- If you want to change the timeout to a different value you can #define
- DLIB_THREAD_POOL_TIMEOUT to whatever value (in milliseconds) that you like.
-
- EXCEPTIONS
- Unless specified otherwise, nothing in this file throws exceptions.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- thread_id_type get_thread_id (
- );
- /*!
- ensures
- - returns a unique id for the calling thread. Note that while the id is unique
- among all currently existing threads it may have been used by a previous
- thread that has terminated.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- bool is_dlib_thread (
- thread_id_type id = get_thread_id()
- );
- /*!
- ensures
- - if (the thread with the given id was spawned by a call to
- dlib::create_new_thread) then
- - returns true
- - else
- - returns false
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- void register_thread_end_handler (
- T& obj,
- void (T::*handler)()
- );
- /*!
- requires
- - handler == a valid member function pointer for class T
- - handler does not throw
- - handler does not call register_thread_end_handler()
- - handler does not block
- - is_dlib_thread() == true (i.e. the calling thread was spawned by dlib::create_new_thread())
- ensures
- - let ID == the thread id for the thread calling register_thread_end_handler()
- - (obj.*handler)() will be called when the thread with thread id ID is
- terminating and it will be called from within that terminating thread.
- (i.e. inside the handler function get_thread_id() == ID == the id of the
- thread that is terminating. )
- - each call to this function adds another handler that will be called when
- the given thread terminates. This means that if you call it a bunch of
- times then you will end up registering multiple handlers (or single
- handlers multiple times) that will be called when the thread ends.
- throws
- - std::bad_alloc
- If this exception is thrown then the call to this function had no effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- void unregister_thread_end_handler (
- T& obj,
- void (T::*handler)()
- );
- /*!
- requires
- - handler == a valid member function pointer for class T
- ensures
- - Undoes all previous calls to register_thread_end_handler(obj,handler).
- So the given handler won't be called when any threads end.
- throws
- - std::bad_alloc
- If this exception is thrown then the call to this function had no effect.
- !*/
-
-// ----------------------------------------------------------------------------------------
-
- bool create_new_thread (
- void (*funct)(void*),
- void* param
- );
- /*!
- ensures
- - creates a new thread for the function pointed to by funct
- - passes it param as its parameter. (i.e. calls funct(param) from the new thread)
- - returns true upon success and false upon failure to create the new thread
- !*/
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // mutex object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class mutex
- {
- /*!
- INITIAL VALUE
- mutex is in the unlocked state
-
- WHAT THIS OBJECT REPRESENTS
- This object represents a mutex intended to be used for synchronous
- thread control of shared data. When a thread wants to access some
- shared data it locks out other threads by calling lock() and calls
- unlock() when it is finished.
- !*/
- public:
-
- mutex (
- );
- /*!
- ensures
- - #*this is properly initialized
- throws
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create the mutex.
- !*/
-
- ~mutex (
- );
- /*!
- requires
- - *this is not locked
- ensures
- - all resources allocated by *this have been freed
- !*/
-
- void lock (
- ) const;
- /*!
- requires
- - the thread calling lock() does not already have a lock on *this
- ensures
- - if (*this is currently locked by another thread) then
- - the thread that called lock() on *this is put to sleep until
- it becomes available
- - if (*this is currently unlocked) then
- - #*this becomes locked and the current thread is NOT put to sleep
- but now "owns" #*this
- !*/
-
- void unlock (
- ) const;
- /*!
- requires
- - the thread calling unlock() already has a lock on *this
- ensures
- - #*this is unlocked (i.e. other threads may now lock this object)
- !*/
-
-
- private:
- // restricted functions
- mutex(mutex&); // copy constructor
- mutex& operator=(mutex&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
- // signaler object
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- class signaler
- {
- /*!
-
- WHAT THIS OBJECT REPRESENTS
- This object represents an event signaling system for threads. It gives
- a thread the ability to wake up other threads that are waiting for a
- particular signal.
-
- Each signaler object is associated with one and only one mutex object.
- More than one signaler object may be associated with a single mutex
- but a signaler object may only be associated with a single mutex.
-
- NOTE:
- You must guard against spurious wakeups. This means that a thread
- might return from a call to wait even if no other thread called
- signal. This is rare but must be guarded against.
- !*/
- public:
-
- signaler (
- const mutex& associated_mutex
- );
- /*!
- ensures
- - #*this is properly initialized
- - #get_mutex() == associated_mutex
- throws
- - dlib::thread_error
- the constructor may throw this exception if there is a problem
- gathering resources to create the signaler.
- !*/
-
-
- ~signaler (
- );
- /*!
- ensures
- - all resources allocated by *this have been freed
- !*/
-
- void wait (
- ) const;
- /*!
- requires
- - get_mutex() is locked and owned by the calling thread
- ensures
- - atomically unlocks get_mutex() and blocks the calling thread
- - calling thread may wake if another thread calls signal() or broadcast()
- on *this
- - when wait() returns the calling thread again has a lock on get_mutex()
- !*/
-
- bool wait_or_timeout (
- unsigned long milliseconds
- ) const;
- /*!
- requires
- - get_mutex() is locked and owned by the calling thread
- ensures
- - atomically unlocks get_mutex() and blocks the calling thread
- - calling thread may wake if another thread calls signal() or broadcast()
- on *this
- - after the specified number of milliseconds has elapsed the calling thread
- will wake once get_mutex() is free
- - when wait returns the calling thread again has a lock on get_mutex()
-
- - returns false if the call to wait_or_timeout timed out
- - returns true if the call did not time out
- !*/
-
-
- void signal (
- ) const;
- /*!
- ensures
- - if (at least one thread is waiting on *this) then
- - at least one of the waiting threads will wake
- !*/
-
- void broadcast (
- ) const;
- /*!
- ensures
- - any and all threads waiting on *this will wake
- !*/
-
- const mutex& get_mutex (
- ) const;
- /*!
- ensures
- - returns a const reference to the mutex associated with *this
- !*/
-
- private:
- // restricted functions
- signaler(signaler&); // copy constructor
- signaler& operator=(signaler&); // assignment operator
- };
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREADS_KERNEl_ABSTRACT_
-
diff --git a/ml/dlib/dlib/threads/threads_kernel_shared.cpp b/ml/dlib/dlib/threads/threads_kernel_shared.cpp
deleted file mode 100644
index 8e81193e9..000000000
--- a/ml/dlib/dlib/threads/threads_kernel_shared.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEL_SHARED_CPp_
-#define DLIB_THREADS_KERNEL_SHARED_CPp_
-
-#include "threads_kernel_shared.h"
-#include "../assert.h"
-#include "../platform.h"
-#include <iostream>
-
-
-#ifndef DLIB_THREAD_POOL_TIMEOUT
-// default to 30000 milliseconds
-#define DLIB_THREAD_POOL_TIMEOUT 30000
-#endif
-
-namespace dlib
-{
-
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-// threader functions
-// ----------------------------------------------------------------------------------------
-// ----------------------------------------------------------------------------------------
-
- namespace threads_kernel_shared
- {
-
- bool thread_pool_has_been_destroyed = false;
-
-// ----------------------------------------------------------------------------------------
-
- struct threader_destruct_helper
- {
- // cause the thread pool to begin its destruction process when
- // global objects start to be destroyed
- ~threader_destruct_helper()
- {
- thread_pool().destruct_if_ready();
- }
- };
-
-// ----------------------------------------------------------------------------------------
-
- threader& thread_pool (
- )
- {
- static threader* thread_pool = new threader;
- static threader_destruct_helper a;
- return *thread_pool;
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool threader::
- is_dlib_thread (
- thread_id_type id
- )
- {
- auto_mutex M(data_mutex);
- return thread_ids.is_member(id);
- }
-
-// ----------------------------------------------------------------------------------------
-
- threader::
- threader (
- ) :
- total_count(0),
- function_pointer(0),
- pool_count(0),
- data_ready(data_mutex),
- data_empty(data_mutex),
- destruct(false),
- destructed(data_mutex),
- do_not_ever_destruct(false)
- {
-#ifdef WIN32
- // Trying to destroy the global thread pool when we are part of a DLL and the
- // DLL is being unloaded can sometimes lead to weird behavior. For example, in
- // the python interpreter you will get the interpreter to hang. Or if we are
- // part of a MATLAB mex file and the file is being unloaded there can also be
- // similar weird issues. So when we are using dlib on windows we just disable
- // the destruction of the global thread pool since it doesn't matter anyway.
- // It's resources will just get freed by the OS. This is even the recommended
- // thing to do by Microsoft (http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx).
- //
- // As an aside, it's worth pointing out that the reason we try and free
- // resources on program shutdown on other operating systems is so we can have
- // clean reports from tools like valgrind which check for memory leaks. But
- // trying to do this on windows is a lost cause so we give up in this case and
- // follow the Microsoft recommendation.
- do_not_ever_destruct = true;
-#endif // WIN32
- }
-
-// ----------------------------------------------------------------------------------------
-
- threader::
- ~threader (
- )
- {
- data_mutex.lock();
- destruct = true;
- data_ready.broadcast();
-
- // wait for all the threads to end
- while (total_count > 0)
- destructed.wait();
-
- thread_pool_has_been_destroyed = true;
- data_mutex.unlock();
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threader::
- destruct_if_ready (
- )
- {
- if (do_not_ever_destruct)
- return;
-
- data_mutex.lock();
-
- // if there aren't any active threads, just maybe some sitting around
- // in the pool then just destroy the threader
- if (total_count == pool_count)
- {
- destruct = true;
- data_ready.broadcast();
- data_mutex.unlock();
- delete this;
- }
- else
- {
- // There are still some user threads running so there isn't
- // much we can really do. Just let the program end without
- // cleaning up threading resources.
- data_mutex.unlock();
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- void threader::
- call_end_handlers (
- )
- {
- reg.m.lock();
- const thread_id_type id = get_thread_id();
- thread_id_type id_copy;
- member_function_pointer<> mfp;
-
- // Remove all the member function pointers for this thread from the tree
- // and call them.
- while (reg.reg[id] != 0)
- {
- reg.reg.remove(id,id_copy,mfp);
- reg.m.unlock();
- mfp();
- reg.m.lock();
- }
- reg.m.unlock();
- }
-
- // ------------------------------------------------------------------------------------
-
- bool threader::
- create_new_thread (
- void (*funct)(void*),
- void* param
- )
- {
-
- // get a lock on the data mutex
- auto_mutex M(data_mutex);
-
- // loop to ensure that the new function pointer is in the data
- while (true)
- {
- // if the data is empty then add new data and quit loop
- if (function_pointer == 0)
- {
- parameter = param;
- function_pointer = funct;
- break;
- }
- else
- {
- // wait for data to become empty
- data_empty.wait();
- }
- }
-
-
- // get a thread for this new data
- // if a new thread must be created
- if (pool_count == 0)
- {
- // make thread and add it to the pool
- if ( threads_kernel_shared_helpers::spawn_thread(thread_starter, this) == false )
- {
- function_pointer = 0;
- parameter = 0;
- data_empty.signal();
- return false;
- }
- ++total_count;
- }
- // wake up a thread from the pool
- else
- {
- data_ready.signal();
- }
-
- return true;
- }
-
- // ------------------------------------------------------------------------------------
-
- void thread_starter (
- void* object
- )
- {
- // get a reference to the calling threader object
- threader& self = *static_cast<threader*>(object);
-
-
- {
- auto_mutex M(self.data_mutex);
-
- // add this thread id
- thread_id_type thread_id = get_thread_id();
- self.thread_ids.add(thread_id);
-
- // indicate that this thread is now in the thread pool
- ++self.pool_count;
-
- while (self.destruct == false)
- {
- // if data is ready then process it and launch the thread
- // if its not ready then go back into the pool
- while (self.function_pointer != 0)
- {
- // indicate that this thread is now out of the thread pool
- --self.pool_count;
-
- // get the data for the function call
- void (*funct)(void*) = self.function_pointer;
- void* param = self.parameter;
- self.function_pointer = 0;
-
- // signal that the data is now empty
- self.data_empty.signal();
-
- self.data_mutex.unlock();
- // Call funct with its intended parameter. If this function throws then
- // we intentionally let the exception escape the thread and result in whatever
- // happens when it gets caught by the OS (generally the program is terminated).
- funct(param);
- self.call_end_handlers();
-
- self.data_mutex.lock();
-
- // indicate that this thread is now back in the thread pool
- ++self.pool_count;
- }
-
- if (self.destruct == true)
- break;
-
- // if we timed out and there isn't any work to do then
- // this thread will quit this loop and end.
- if (self.data_ready.wait_or_timeout(DLIB_THREAD_POOL_TIMEOUT) == false &&
- self.function_pointer == 0)
- break;
-
- }
-
- // remove this thread id from thread_ids
- thread_id = get_thread_id();
- self.thread_ids.destroy(thread_id);
-
- // indicate that this thread is now out of the thread pool
- --self.pool_count;
- --self.total_count;
-
- self.destructed.signal();
-
- } // end of auto_mutex M(self.data_mutex) block
- }
-
- // ------------------------------------------------------------------------------------
-
- }
-
-// ----------------------------------------------------------------------------------------
-
- bool is_dlib_thread (
- thread_id_type id
- )
- {
- return threads_kernel_shared::thread_pool().is_dlib_thread(id);
- }
-
- bool is_dlib_thread (
- )
- {
- return is_dlib_thread(get_thread_id());
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#endif // DLIB_THREADS_KERNEL_SHARED_CPp_
-
diff --git a/ml/dlib/dlib/threads/threads_kernel_shared.h b/ml/dlib/dlib/threads/threads_kernel_shared.h
deleted file mode 100644
index b4526e8db..000000000
--- a/ml/dlib/dlib/threads/threads_kernel_shared.h
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEl_SHARED_
-#define DLIB_THREADS_KERNEl_SHARED_
-
-// this file should be included at the bottom of one of the thread kernel headers for a
-// specific platform.
-//#include "../threads.h"
-#include "auto_mutex_extension.h"
-#include "../binary_search_tree.h"
-#include "../member_function_pointer.h"
-#include "../memory_manager.h"
-#include "../queue.h"
-#include "../set.h"
-#include "../test_for_odr_violations.h"
-
-
-
-
-
-namespace dlib
-{
-
-
-// ----------------------------------------------------------------------------------------
-
- namespace threads_kernel_shared
- {
- void thread_starter (
- void*
- );
-
- class threader
- {
- /*!
- INITIAL VALUE
- - pool_count == 0 and
- - data_ready is associated with the mutex data_mutex
- - data_empty is associated with the mutex data_mutex
- - destructed is associated with the mutex data_mutex
- - destruct == false
- - total_count == 0
- - function_pointer == 0
- - do_not_ever_destruct == false
-
- CONVENTION
- - data_ready is associated with the mutex data_mutex
- - data_empty is associated with the mutex data_mutex
- - data_ready == a signaler used signal when there is new data waiting
- to start a thread with.
- - data_empty == a signaler used to signal when the data is now empty
- - pool_count == the number of suspended threads in the thread pool
- - total_count == the number of threads that are executing anywhere. i.e.
- pool_count + the ones that are currently running some user function.
- - if (function_pointer != 0) then
- - parameter == a void pointer pointing to the parameter which
- should be used to start the next thread
- - function_pointer == a pointer to the next function to make a
- new thread with
-
- - if (the destructor is running) then
- - destruct == true
- - else
- - destruct == false
-
- - thread_ids is locked by the data_mutex
- - thread_ids == a set that contains the thread id for each thread spawned by this
- object.
- !*/
-
-
- public:
- threader (
- );
-
- ~threader (
- );
-
- void destruct_if_ready (
- );
- /*!
- ensures
- - if (there are no threads currently running and we haven't set do_not_ever_destruct) then
- - calls delete this
- - else
- - does nothing
- !*/
-
- bool create_new_thread (
- void (*funct)(void*),
- void* param
- );
-
- template <
- typename T
- >
- void unregister_thread_end_handler (
- T& obj,
- void (T::*handler)()
- )
- {
- member_function_pointer<> mfp, junk_mfp;
- mfp.set(obj,handler);
-
- thread_id_type junk_id;
-
- // find any member function pointers in the registry that point to the same
- // thing as mfp and remove them
- auto_mutex M(reg.m);
- reg.reg.reset();
- while (reg.reg.move_next())
- {
- while (reg.reg.current_element_valid() && reg.reg.element().value() == mfp)
- {
- reg.reg.remove_current_element(junk_id, junk_mfp);
- }
- }
- }
-
- template <
- typename T
- >
- void register_thread_end_handler (
- T& obj,
- void (T::*handler)()
- )
- {
- thread_id_type id = get_thread_id();
- member_function_pointer<> mfp;
- mfp.set(obj,handler);
-
- auto_mutex M(reg.m);
- reg.reg.add(id,mfp);
- }
-
- bool is_dlib_thread (
- thread_id_type id
- );
-
- private:
-
- friend void thread_starter (
- void*
- );
-
- void call_end_handlers (
- );
- /*!
- ensures
- - calls the registered end handlers for the calling thread and
- then removes them from reg.reg
- !*/
-
-
- // private data
- set<thread_id_type,memory_manager<char>::kernel_2b>::kernel_1b_c thread_ids;
- unsigned long total_count;
- void* parameter;
- void (*function_pointer)(void*);
- unsigned long pool_count;
- mutex data_mutex; // mutex to protect the above data
- signaler data_ready; // signaler to signal when there is new data
- signaler data_empty; // signaler to signal when the data is empty
- bool destruct;
- signaler destructed; // signaler to signal when a thread has ended
- bool do_not_ever_destruct;
-
- struct registry_type
- {
- mutex m;
- binary_search_tree<
- thread_id_type,
- member_function_pointer<>,
- memory_manager<char>::kernel_2a
- >::kernel_2a_c reg;
- };
-
- // stuff for the register_thread_end_handler
- registry_type reg;
-
-
- // restricted functions
- threader(threader&); // copy constructor
- threader& operator=(threader&); // assignement opertor
-
- };
-
- // ------------------------------------------------------------------------------------
-
- threader& thread_pool (
- );
- /*!
- ensures
- - returns a reference to the global threader object
- !*/
-
- // ------------------------------------------------------------------------------------
-
- extern bool thread_pool_has_been_destroyed;
- }
-
- bool is_dlib_thread (
- thread_id_type id
- );
-
- bool is_dlib_thread (
- );
-
-// ----------------------------------------------------------------------------------------
-
- inline bool create_new_thread (
- void (*funct)(void*),
- void* param
- )
- {
- try
- {
- // now make this thread
- return threads_kernel_shared::thread_pool().create_new_thread(funct,param);
- }
- catch (std::bad_alloc&)
- {
- return false;
- }
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- inline void register_thread_end_handler (
- T& obj,
- void (T::*handler)()
- )
- {
- DLIB_ASSERT(is_dlib_thread(),
- "\tvoid register_thread_end_handler"
- << "\n\tYou can't register a thread end handler for a thread dlib didn't spawn."
- );
-
- threads_kernel_shared::thread_pool().register_thread_end_handler(obj,handler);
- }
-
-// ----------------------------------------------------------------------------------------
-
- template <
- typename T
- >
- inline void unregister_thread_end_handler (
- T& obj,
- void (T::*handler)()
- )
- {
- // Check if the thread pool has been destroyed and if it has then don't do anything.
- // This bool here is always true except when the program has started to terminate and
- // the thread pool object has been destroyed. This if is here to catch other global
- // objects that have destructors that try to call unregister_thread_end_handler().
- // Without this check we get into trouble if the thread pool is destroyed before these
- // objects.
- if (threads_kernel_shared::thread_pool_has_been_destroyed == false)
- threads_kernel_shared::thread_pool().unregister_thread_end_handler(obj,handler);
- }
-
-// ----------------------------------------------------------------------------------------
-
-}
-
-#ifdef NO_MAKEFILE
-#include "threads_kernel_shared.cpp"
-#endif
-
-#endif // DLIB_THREADS_KERNEl_SHARED_
-
diff --git a/ml/dlib/dlib/threads/windows.h b/ml/dlib/dlib/threads/windows.h
deleted file mode 100644
index f7c775950..000000000
--- a/ml/dlib/dlib/threads/windows.h
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright (C) 2003 Davis E. King (davis@dlib.net)
-// License: Boost Software License See LICENSE.txt for the full license.
-#ifndef DLIB_THREADS_KERNEl_2_
-#include "threads_kernel_1.h"
-#endif
-