diff options
Diffstat (limited to 'ml/dlib/dlib/threads/threads_kernel_shared.cpp')
-rw-r--r-- | ml/dlib/dlib/threads/threads_kernel_shared.cpp | 318 |
1 files changed, 0 insertions, 318 deletions
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_ - |