summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/threads/threads_kernel_shared.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/threads/threads_kernel_shared.cpp')
-rw-r--r--ml/dlib/dlib/threads/threads_kernel_shared.cpp318
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_
-