From 030a9fb454f53b8a94567fe56eb524b735a04a4a Mon Sep 17 00:00:00 2001 From: "nfullagar@chromium.org" Date: Sat, 8 Jun 2013 00:46:05 +0000 Subject: Move thread_pool.h into utils so it can be shared by more than one example. BUG=none TEST=voronoi demo R=binji@chromium.org, noelallen@chromium.org Review URL: https://codereview.chromium.org/16325024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204998 0039d316-1c4b-4281-b951-d872f2087c98 --- native_client_sdk/src/build_tools/sdk_files.list | 32 ++++- .../src/examples/demo/voronoi/example.dsc | 6 +- .../src/examples/demo/voronoi/threadpool.cc | 144 --------------------- .../src/examples/demo/voronoi/threadpool.h | 45 ------- .../src/examples/demo/voronoi/voronoi.cc | 2 +- .../src/libraries/error_handling/error_handling.h | 5 +- .../src/libraries/nacl_io/inode_pool.h | 2 +- .../src/libraries/nacl_io/kernel_handle.h | 4 +- .../src/libraries/nacl_io/kernel_intercept.h | 2 +- .../src/libraries/nacl_io/kernel_object.cc | 2 +- .../src/libraries/nacl_io/kernel_proxy.cc | 4 +- .../src/libraries/nacl_io/kernel_wrap.h | 2 +- .../src/libraries/nacl_io/kernel_wrap_real.h | 2 +- .../src/libraries/nacl_io/library.dsc | 12 +- native_client_sdk/src/libraries/nacl_io/mount.cc | 7 +- native_client_sdk/src/libraries/nacl_io/mount.h | 4 +- .../src/libraries/nacl_io/mount_dev.cc | 2 +- .../src/libraries/nacl_io/mount_html5fs.cc | 2 +- .../src/libraries/nacl_io/mount_http.cc | 2 +- .../src/libraries/nacl_io/mount_mem.cc | 4 +- .../src/libraries/nacl_io/mount_node.cc | 2 +- .../src/libraries/nacl_io/mount_node.h | 2 +- .../src/libraries/nacl_io/mount_node_dir.cc | 4 +- .../src/libraries/nacl_io/mount_node_html5fs.cc | 2 +- .../src/libraries/nacl_io/mount_node_mem.cc | 2 +- native_client_sdk/src/libraries/nacl_io/nacl_io.h | 2 +- .../src/libraries/nacl_io/nacl_mounts.vcproj | 2 +- native_client_sdk/src/libraries/nacl_io/osdirent.h | 2 +- native_client_sdk/src/libraries/nacl_io/path.h | 2 +- .../src/libraries/nacl_io/pepper_interface.h | 2 +- native_client_sdk/src/libraries/ppapi_simple/ps.h | 2 +- .../src/libraries/ppapi_simple/ps_event.h | 2 +- .../src/libraries/ppapi_simple/ps_instance.h | 2 +- .../src/libraries/sdk_util/auto_lock.h | 31 +++++ .../src/libraries/sdk_util/library.dsc | 29 +++++ native_client_sdk/src/libraries/sdk_util/macros.h | 50 +++++++ .../src/libraries/sdk_util/ref_object.h | 49 +++++++ .../src/libraries/sdk_util/thread_pool.cc | 144 +++++++++++++++++++++ .../src/libraries/sdk_util/thread_pool.h | 45 +++++++ .../src/libraries/sdk_util/thread_safe_queue.h | 63 +++++++++ native_client_sdk/src/libraries/utils/auto_lock.h | 30 ----- native_client_sdk/src/libraries/utils/macros.h | 49 ------- native_client_sdk/src/libraries/utils/ref_object.h | 48 ------- .../src/libraries/utils/thread_safe_queue.h | 62 --------- 44 files changed, 478 insertions(+), 435 deletions(-) delete mode 100644 native_client_sdk/src/examples/demo/voronoi/threadpool.cc delete mode 100644 native_client_sdk/src/examples/demo/voronoi/threadpool.h create mode 100644 native_client_sdk/src/libraries/sdk_util/auto_lock.h create mode 100644 native_client_sdk/src/libraries/sdk_util/library.dsc create mode 100644 native_client_sdk/src/libraries/sdk_util/macros.h create mode 100644 native_client_sdk/src/libraries/sdk_util/ref_object.h create mode 100644 native_client_sdk/src/libraries/sdk_util/thread_pool.cc create mode 100644 native_client_sdk/src/libraries/sdk_util/thread_pool.h create mode 100644 native_client_sdk/src/libraries/sdk_util/thread_safe_queue.h delete mode 100644 native_client_sdk/src/libraries/utils/auto_lock.h delete mode 100644 native_client_sdk/src/libraries/utils/macros.h delete mode 100644 native_client_sdk/src/libraries/utils/ref_object.h delete mode 100644 native_client_sdk/src/libraries/utils/thread_safe_queue.h diff --git a/native_client_sdk/src/build_tools/sdk_files.list b/native_client_sdk/src/build_tools/sdk_files.list index 61deb99..c733c9d 100644 --- a/native_client_sdk/src/build_tools/sdk_files.list +++ b/native_client_sdk/src/build_tools/sdk_files.list @@ -153,8 +153,6 @@ examples/demo/voronoi/index.html examples/demo/voronoi/Makefile [win]examples/demo/voronoi/make.bat examples/demo/voronoi/manifest.json -examples/demo/voronoi/threadpool.cc -examples/demo/voronoi/threadpool.h examples/demo/voronoi/voronoi.cc examples/favicon.ico [win]examples/getting_started/hello_world/make.bat @@ -480,10 +478,11 @@ include/ppapi/utility/websocket/websocket_api.h [win]include/win/pthread.h [win]include/win/sched.h [win]include/win/semaphore.h -include/utils/auto_lock.h -include/utils/macros.h -include/utils/ref_object.h -include/utils/thread_safe_queue.h +include/sdk_util/auto_lock.h +include/sdk_util/macros.h +include/sdk_util/ref_object.h +include/sdk_util/thread_safe_queue.h +include/sdk_util/thread_pool.h lib/glibc_x86_32/Debug/libjsoncpp.a lib/glibc_x86_32/Debug/libjsoncpp.so lib/glibc_x86_32/Debug/libnacl_io.a @@ -496,6 +495,8 @@ lib/glibc_x86_32/Debug/libppapi_gles2.a lib/glibc_x86_32/Debug/libppapi_gles2.so lib/glibc_x86_32/Debug/libppapi_simple.a lib/glibc_x86_32/Debug/libppapi_simple.so +lib/glibc_x86_32/Debug/libsdk_util.a +lib/glibc_x86_32/Debug/libsdk_util.so lib/glibc_x86_32/Release/libjsoncpp.a lib/glibc_x86_32/Release/libjsoncpp.so lib/glibc_x86_32/Release/libnacl_io.a @@ -508,6 +509,8 @@ lib/glibc_x86_32/Release/libppapi_gles2.a lib/glibc_x86_32/Release/libppapi_gles2.so lib/glibc_x86_32/Release/libppapi_simple.a lib/glibc_x86_32/Release/libppapi_simple.so +lib/glibc_x86_32/Release/libsdk_util.a +lib/glibc_x86_32/Release/libsdk_util.so lib/glibc_x86_64/Debug/libjsoncpp.a lib/glibc_x86_64/Debug/libjsoncpp.so lib/glibc_x86_64/Debug/libnacl_io.a @@ -520,6 +523,8 @@ lib/glibc_x86_64/Debug/libppapi_gles2.a lib/glibc_x86_64/Debug/libppapi_gles2.so lib/glibc_x86_64/Debug/libppapi_simple.a lib/glibc_x86_64/Debug/libppapi_simple.so +lib/glibc_x86_64/Debug/libsdk_util.a +lib/glibc_x86_64/Debug/libsdk_util.so lib/glibc_x86_64/Release/libjsoncpp.a lib/glibc_x86_64/Release/libjsoncpp.so lib/glibc_x86_64/Release/libnacl_io.a @@ -532,6 +537,8 @@ lib/glibc_x86_64/Release/libppapi_gles2.a lib/glibc_x86_64/Release/libppapi_gles2.so lib/glibc_x86_64/Release/libppapi_simple.a lib/glibc_x86_64/Release/libppapi_simple.so +lib/glibc_x86_64/Release/libsdk_util.a +lib/glibc_x86_64/Release/libsdk_util.so [linux]lib/${PLATFORM}_host/Debug/libjsoncpp.a [linux]lib/${PLATFORM}_host/Debug/libppapi.a [linux]lib/${PLATFORM}_host/Debug/libppapi_cpp.a @@ -556,6 +563,8 @@ lib/glibc_x86_64/Release/libppapi_simple.so [win]lib/${PLATFORM}_x86_32_host/Release/ppapi_gles2.lib [win]lib/${PLATFORM}_x86_32_host/Release/ppapi.lib [win]lib/${PLATFORM}_x86_32_host/Release/pthread.lib +[win]lib/${PLATFORM}_x86_32_host/Debug/sdk_util.lib +[win]lib/${PLATFORM}_x86_32_host/Release/sdk_util.lib lib/newlib_arm/Debug/liberror_handling.a lib/newlib_arm/Debug/libjsoncpp.a lib/newlib_arm/Debug/libnacl_io.a @@ -563,6 +572,7 @@ lib/newlib_arm/Debug/libppapi_cpp.a lib/newlib_arm/Debug/libppapi_cpp_private.a lib/newlib_arm/Debug/libppapi_gles2.a lib/newlib_arm/Debug/libppapi_simple.a +lib/newlib_arm/Debug/libsdk_util.a lib/newlib_arm/Release/liberror_handling.a lib/newlib_arm/Release/libjsoncpp.a lib/newlib_arm/Release/libnacl_io.a @@ -570,6 +580,7 @@ lib/newlib_arm/Release/libppapi_cpp.a lib/newlib_arm/Release/libppapi_cpp_private.a lib/newlib_arm/Release/libppapi_gles2.a lib/newlib_arm/Release/libppapi_simple.a +lib/newlib_arm/Release/libsdk_util.a lib/newlib_x86_32/Debug/liberror_handling.a lib/newlib_x86_32/Debug/libjsoncpp.a lib/newlib_x86_32/Debug/libnacl_io.a @@ -577,6 +588,7 @@ lib/newlib_x86_32/Debug/libppapi_cpp.a lib/newlib_x86_32/Debug/libppapi_cpp_private.a lib/newlib_x86_32/Debug/libppapi_gles2.a lib/newlib_x86_32/Debug/libppapi_simple.a +lib/newlib_x86_32/Debug/libsdk_util.a lib/newlib_x86_32/Release/liberror_handling.a lib/newlib_x86_32/Release/libjsoncpp.a lib/newlib_x86_32/Release/libnacl_io.a @@ -584,6 +596,7 @@ lib/newlib_x86_32/Release/libppapi_cpp.a lib/newlib_x86_32/Release/libppapi_cpp_private.a lib/newlib_x86_32/Release/libppapi_gles2.a lib/newlib_x86_32/Release/libppapi_simple.a +lib/newlib_x86_32/Release/libsdk_util.a lib/newlib_x86_64/Debug/liberror_handling.a lib/newlib_x86_64/Debug/libjsoncpp.a lib/newlib_x86_64/Debug/libnacl_io.a @@ -591,6 +604,7 @@ lib/newlib_x86_64/Debug/libppapi_cpp.a lib/newlib_x86_64/Debug/libppapi_cpp_private.a lib/newlib_x86_64/Debug/libppapi_gles2.a lib/newlib_x86_64/Debug/libppapi_simple.a +lib/newlib_x86_64/Debug/libsdk_util.a lib/newlib_x86_64/Release/liberror_handling.a lib/newlib_x86_64/Release/libjsoncpp.a lib/newlib_x86_64/Release/libnacl_io.a @@ -598,18 +612,21 @@ lib/newlib_x86_64/Release/libppapi_cpp.a lib/newlib_x86_64/Release/libppapi_cpp_private.a lib/newlib_x86_64/Release/libppapi_gles2.a lib/newlib_x86_64/Release/libppapi_simple.a +lib/newlib_x86_64/Release/libsdk_util.a lib/pnacl/Debug/libjsoncpp.a lib/pnacl/Debug/libnacl_io.a lib/pnacl/Debug/libppapi_cpp.a lib/pnacl/Debug/libppapi_cpp_private.a lib/pnacl/Debug/libppapi_gles2.a lib/pnacl/Debug/libppapi_simple.a +lib/pnacl/Debug/libsdk_util.a lib/pnacl/Release/libjsoncpp.a lib/pnacl/Release/libnacl_io.a lib/pnacl/Release/libppapi_cpp.a lib/pnacl/Release/libppapi_cpp_private.a lib/pnacl/Release/libppapi_gles2.a lib/pnacl/Release/libppapi_simple.a +lib/pnacl/Release/libsdk_util.a LICENSE NOTICE README @@ -859,6 +876,9 @@ src/ppapi_cpp_private/x509_certificate_private.cc [win]src/ppapi/make.bat [win,linux]src/ppapi/Makefile [win,linux]src/ppapi/ppapi_externs.c +src/sdk_util/Makefile +[win]src/sdk_util/make.bat +src/sdk_util/thread_pool.cc toolchain/${PLATFORM}_arm_newlib/arm-nacl/include/irt.h toolchain/${PLATFORM}_arm_newlib/arm-nacl/include/irt_ppapi.h toolchain/${PLATFORM}_arm_newlib/arm-nacl/include/nacl/dynamic_annotations.h diff --git a/native_client_sdk/src/examples/demo/voronoi/example.dsc b/native_client_sdk/src/examples/demo/voronoi/example.dsc index 810d4f9..d9fabce 100644 --- a/native_client_sdk/src/examples/demo/voronoi/example.dsc +++ b/native_client_sdk/src/examples/demo/voronoi/example.dsc @@ -5,12 +5,10 @@ 'NAME' : 'voronoi', 'TYPE' : 'main', 'SOURCES' : [ - 'voronoi.cc', - 'threadpool.cc', - 'threadpool.h' + 'voronoi.cc' ], - 'LIBS': ['ppapi_cpp', 'ppapi', 'pthread'] + 'LIBS': ['sdk_util', 'ppapi_cpp', 'ppapi', 'pthread'] } ], 'DATA': [ diff --git a/native_client_sdk/src/examples/demo/voronoi/threadpool.cc b/native_client_sdk/src/examples/demo/voronoi/threadpool.cc deleted file mode 100644 index 4c403f3..0000000 --- a/native_client_sdk/src/examples/demo/voronoi/threadpool.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "threadpool.h" - -#include -#include -#include -#include - -#include "utils/auto_lock.h" - -// Initializes mutex, semaphores and a pool of threads. If 0 is passed for -// num_threads, all work will be performed on the dispatch thread. -ThreadPool::ThreadPool(int num_threads) - : threads_(NULL), counter_(0), num_threads_(num_threads), exiting_(false), - user_data_(NULL), user_work_function_(NULL) { - if (num_threads_ > 0) { - int status; - status = sem_init(&work_sem_, 0, 0); - if (-1 == status) { - fprintf(stderr, "Failed to initialize semaphore!\n"); - exit(-1); - } - status = sem_init(&done_sem_, 0, 0); - if (-1 == status) { - fprintf(stderr, "Failed to initialize semaphore!\n"); - exit(-1); - } - threads_ = new pthread_t[num_threads_]; - for (int i = 0; i < num_threads_; i++) { - status = pthread_create(&threads_[i], NULL, WorkerThreadEntry, this); - if (0 != status) { - fprintf(stderr, "Failed to create thread!\n"); - exit(-1); - } - } - } -} - -// Post exit request, wait for all threads to join, and cleanup. -ThreadPool::~ThreadPool() { - if (num_threads_ > 0) { - PostExitAndJoinAll(); - delete[] threads_; - sem_destroy(&done_sem_); - sem_destroy(&work_sem_); - } -} - -// Setup work parameters. This function is called from the dispatch thread, -// when all worker threads are sleeping. -void ThreadPool::Setup(int counter, WorkFunction work, void *data) { - counter_ = counter; - user_work_function_ = work; - user_data_ = data; -} - -// Return decremented task counter. This function -// can be called from multiple threads at any given time. -int ThreadPool::DecCounter() { -#if defined(__native_client__) - // Use fast atomic sub & fetch. - return __sync_sub_and_fetch(&counter_, 1); -#else - // Fallback to a more platform independent pthread mutex via AutoLock. - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - AutoLock lock(&mutex); - return --counter_; -#endif -} - -// Set exit flag, post and join all the threads in the pool. This function is -// called only from the dispatch thread, and only when all worker threads are -// sleeping. -void ThreadPool::PostExitAndJoinAll() { - exiting_ = true; - // Wake up all the sleeping worker threads. - for (int i = 0; i < num_threads_; ++i) - sem_post(&work_sem_); - void* retval; - for (int i = 0; i < num_threads_; ++i) - pthread_join(threads_[i], &retval); -} - -// Main work loop - one for each worker thread. -void ThreadPool::WorkLoop() { - while (true) { - // Wait for work. If no work is availble, this thread will sleep here. - sem_wait(&work_sem_); - if (exiting_) break; - while (true) { - // Grab a task index to work on from the counter. - int task_index = DecCounter(); - if (task_index < 0) - break; - user_work_function_(task_index, user_data_); - } - // Post to dispatch thread work is done. - sem_post(&done_sem_); - } -} - -// pthread entry point for a worker thread. -void* ThreadPool::WorkerThreadEntry(void* thiz) { - static_cast(thiz)->WorkLoop(); - return NULL; -} - -// DispatchMany() will dispatch a set of tasks across worker threads. -// Note: This function will block until all work has completed. -void ThreadPool::DispatchMany(int num_tasks, WorkFunction work, void* data) { - // On entry, all worker threads are sleeping. - Setup(num_tasks, work, data); - - // Wake up the worker threads & have them process tasks. - for (int i = 0; i < num_threads_; i++) - sem_post(&work_sem_); - - // Worker threads are now awake and busy. - - // This dispatch thread will now sleep-wait for the worker threads to finish. - for (int i = 0; i < num_threads_; i++) - sem_wait(&done_sem_); - // On exit, all tasks are done and all worker threads are sleeping again. -} - -// DispatchHere will dispatch all tasks on this thread. -void ThreadPool::DispatchHere(int num_tasks, WorkFunction work, void* data) { - for (int i = 0; i < num_tasks; i++) - work(i, data); -} - -// Dispatch() will invoke the user supplied work function across -// one or more threads for each task. -// Note: This function will block until all work has completed. -void ThreadPool::Dispatch(int num_tasks, WorkFunction work, void* data) { - if (num_threads_ > 0) - DispatchMany(num_tasks, work, data); - else - DispatchHere(num_tasks, work, data); -} - diff --git a/native_client_sdk/src/examples/demo/voronoi/threadpool.h b/native_client_sdk/src/examples/demo/voronoi/threadpool.h deleted file mode 100644 index d459120..0000000 --- a/native_client_sdk/src/examples/demo/voronoi/threadpool.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Simple thread pool class - -#ifndef EXAMPLES_DEMO_VORONOI_THREADPOOL_H_ -#define EXAMPLES_DEMO_VORONOI_THREADPOOL_H_ - -#include -#include - -// typdef helper for work function -typedef void (*WorkFunction)(int task_index, void* data); - -// ThreadPool is a class to manage num_threads and assign -// them num_tasks of work at a time. Each call -// to Dispatch(..) will block until all tasks complete. -// If 0 is passed in for num_threads, all tasks will be -// issued on the dispatch thread. - -class ThreadPool { - public: - void Dispatch(int num_tasks, WorkFunction work, void* data); - explicit ThreadPool(int num_threads); - ~ThreadPool(); - private: - int DecCounter(); - void Setup(int counter, WorkFunction work, void* data); - void DispatchMany(int num_tasks, WorkFunction work, void* data); - void DispatchHere(int num_tasks, WorkFunction work, void* data); - void WorkLoop(); - static void* WorkerThreadEntry(void* data); - void PostExitAndJoinAll(); - pthread_t* threads_; - int counter_; - const int num_threads_; - bool exiting_; - void* user_data_; - WorkFunction user_work_function_; - sem_t work_sem_; - sem_t done_sem_; -}; -#endif // EXAMPLES_DEMO_VORONOI_THREADPOOL_H_ - diff --git a/native_client_sdk/src/examples/demo/voronoi/voronoi.cc b/native_client_sdk/src/examples/demo/voronoi/voronoi.cc index 23e6d3e..d4e1025 100644 --- a/native_client_sdk/src/examples/demo/voronoi/voronoi.cc +++ b/native_client_sdk/src/examples/demo/voronoi/voronoi.cc @@ -23,7 +23,7 @@ #include #include -#include "threadpool.h" +#include "sdk_util/thread_pool.h" // Global properties used to setup Voronoi demo. namespace { diff --git a/native_client_sdk/src/libraries/error_handling/error_handling.h b/native_client_sdk/src/libraries/error_handling/error_handling.h index 29b4aca..add76ce 100644 --- a/native_client_sdk/src/libraries/error_handling/error_handling.h +++ b/native_client_sdk/src/libraries/error_handling/error_handling.h @@ -8,7 +8,7 @@ #define ERROR_HANDLING_ERROR_HANDLING_H_ #include "error_handling/string_stream.h" -#include "utils/macros.h" +#include "sdk_util/macros.h" EXTERN_C_BEGIN @@ -82,4 +82,5 @@ int EHUnwindFrame(EHFrame* frame); EXTERN_C_END -#endif // ERROR_HANDLING_ERROR_HANDLING_H_ \ No newline at end of file +#endif // ERROR_HANDLING_ERROR_HANDLING_H_ + diff --git a/native_client_sdk/src/libraries/nacl_io/inode_pool.h b/native_client_sdk/src/libraries/nacl_io/inode_pool.h index 5624b1d..4c3f44b 100644 --- a/native_client_sdk/src/libraries/nacl_io/inode_pool.h +++ b/native_client_sdk/src/libraries/nacl_io/inode_pool.h @@ -11,7 +11,7 @@ #include "nacl_io/osstat.h" #include "pthread.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" class INodePool { diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_handle.h b/native_client_sdk/src/libraries/nacl_io/kernel_handle.h index a047125..4695be3 100644 --- a/native_client_sdk/src/libraries/nacl_io/kernel_handle.h +++ b/native_client_sdk/src/libraries/nacl_io/kernel_handle.h @@ -8,8 +8,8 @@ #include #include "nacl_io/ostypes.h" -#include "utils/macros.h" -#include "utils/ref_object.h" +#include "sdk_util/macros.h" +#include "sdk_util/ref_object.h" class Mount; class MountNode; diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h index b1bcf90d..c4b658d 100644 --- a/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h +++ b/native_client_sdk/src/libraries/nacl_io/kernel_intercept.h @@ -8,7 +8,7 @@ #include #include #include "nacl_io/ostypes.h" -#include "utils/macros.h" +#include "sdk_util/macros.h" EXTERN_C_BEGIN diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_object.cc b/native_client_sdk/src/libraries/nacl_io/kernel_object.cc index 5c26530..4841864 100644 --- a/native_client_sdk/src/libraries/nacl_io/kernel_object.cc +++ b/native_client_sdk/src/libraries/nacl_io/kernel_object.cc @@ -17,7 +17,7 @@ #include "nacl_io/kernel_handle.h" #include "nacl_io/mount.h" #include "nacl_io/mount_node.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" KernelObject::KernelObject() { pthread_mutex_init(&kernel_lock_, NULL); diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc index 6d996d3..b0c449f 100644 --- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc +++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc @@ -25,8 +25,8 @@ #include "nacl_io/osstat.h" #include "nacl_io/path.h" #include "nacl_io/pepper_interface.h" -#include "utils/auto_lock.h" -#include "utils/ref_object.h" +#include "sdk_util/auto_lock.h" +#include "sdk_util/ref_object.h" #ifndef MAXPATHLEN #define MAXPATHLEN 256 diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h b/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h index 87dca82..322fe72 100644 --- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h +++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap.h @@ -7,7 +7,7 @@ #include #include -#include "utils/macros.h" +#include "sdk_util/macros.h" #if defined(__GLIBC__) #include diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h index 7d7dd41..c4ff5e0 100644 --- a/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h +++ b/native_client_sdk/src/libraries/nacl_io/kernel_wrap_real.h @@ -6,7 +6,7 @@ #define LIBRARIES_NACL_IO_KERNEL_WRAP_REAL_H_ #include "nacl_io/ostypes.h" -#include "utils/macros.h" +#include "sdk_util/macros.h" EXTERN_C_BEGIN diff --git a/native_client_sdk/src/libraries/nacl_io/library.dsc b/native_client_sdk/src/libraries/nacl_io/library.dsc index 3e6b074..612af7d 100644 --- a/native_client_sdk/src/libraries/nacl_io/library.dsc +++ b/native_client_sdk/src/libraries/nacl_io/library.dsc @@ -2,8 +2,7 @@ 'TOOLS': ['newlib', 'glibc', 'pnacl', 'win'], 'SEARCH': [ '.', - 'pepper', - '../utils' + 'pepper' ], 'TARGETS': [ { @@ -73,15 +72,6 @@ "undef_macros.h", ], 'DEST': 'include/nacl_io/pepper', - }, - { - 'FILES': [ - "auto_lock.h", - "macros.h", - "ref_object.h", - "thread_safe_queue.h" - ], - 'DEST': 'include/utils', } ], 'DEST': 'src', diff --git a/native_client_sdk/src/libraries/nacl_io/mount.cc b/native_client_sdk/src/libraries/nacl_io/mount.cc index 8b583db..f099aa8 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount.cc @@ -13,8 +13,8 @@ #include "nacl_io/mount_node_mem.h" #include "nacl_io/osstat.h" #include "nacl_io/path.h" -#include "utils/auto_lock.h" -#include "utils/ref_object.h" +#include "sdk_util/auto_lock.h" +#include "sdk_util/ref_object.h" #if defined(WIN32) #include @@ -62,4 +62,5 @@ void Mount::OnNodeCreated(MountNode* node) { void Mount::OnNodeDestroyed(MountNode* node) { if (node->stat_.st_ino) inode_pool_.Release(node->stat_.st_ino); -} \ No newline at end of file +} + diff --git a/native_client_sdk/src/libraries/nacl_io/mount.h b/native_client_sdk/src/libraries/nacl_io/mount.h index 622dae0..abfe68f 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount.h +++ b/native_client_sdk/src/libraries/nacl_io/mount.h @@ -11,8 +11,8 @@ #include "nacl_io/inode_pool.h" #include "nacl_io/mount_node.h" #include "nacl_io/path.h" -#include "utils/macros.h" -#include "utils/ref_object.h" +#include "sdk_util/macros.h" +#include "sdk_util/ref_object.h" class MountNode; class PepperInterface; diff --git a/native_client_sdk/src/libraries/nacl_io/mount_dev.cc b/native_client_sdk/src/libraries/nacl_io/mount_dev.cc index 83d2e55..9190a92 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_dev.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_dev.cc @@ -14,7 +14,7 @@ #include "nacl_io/mount_node.h" #include "nacl_io/mount_node_dir.h" #include "nacl_io/pepper_interface.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" #if defined(__native_client__) # include diff --git a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc index 9b995359..c49acae 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_html5fs.cc @@ -12,7 +12,7 @@ #include #include #include "nacl_io/mount_node_html5fs.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" namespace { diff --git a/native_client_sdk/src/libraries/nacl_io/mount_http.cc b/native_client_sdk/src/libraries/nacl_io/mount_http.cc index 9a6579e..9e6155f 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_http.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_http.cc @@ -16,7 +16,7 @@ #include #include "nacl_io/mount_node_dir.h" #include "nacl_io/osinttypes.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" #if defined(WIN32) #define snprintf _snprintf diff --git a/native_client_sdk/src/libraries/nacl_io/mount_mem.cc b/native_client_sdk/src/libraries/nacl_io/mount_mem.cc index fa3035c..541f58c 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_mem.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_mem.cc @@ -14,8 +14,8 @@ #include "nacl_io/mount_node_mem.h" #include "nacl_io/osstat.h" #include "nacl_io/path.h" -#include "utils/auto_lock.h" -#include "utils/ref_object.h" +#include "sdk_util/auto_lock.h" +#include "sdk_util/ref_object.h" // TODO(noelallen) : Grab/Redefine these in the kernel object once available. #define USR_ID 1002 diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node.cc b/native_client_sdk/src/libraries/nacl_io/mount_node.cc index ff722b4..97dc799 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_node.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_node.cc @@ -13,7 +13,7 @@ #include "nacl_io/kernel_wrap_real.h" #include "nacl_io/mount.h" #include "nacl_io/osmman.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" static const int USR_ID = 1001; static const int GRP_ID = 1002; diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node.h b/native_client_sdk/src/libraries/nacl_io/mount_node.h index 36a937e..6837548 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_node.h +++ b/native_client_sdk/src/libraries/nacl_io/mount_node.h @@ -8,7 +8,7 @@ #include #include "nacl_io/osstat.h" -#include "utils/ref_object.h" +#include "sdk_util/ref_object.h" struct dirent; struct stat; diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc index 7a33bfd..aa4b019 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_node_dir.cc @@ -9,8 +9,8 @@ #include "nacl_io/osdirent.h" #include "nacl_io/osstat.h" -#include "utils/macros.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" +#include "sdk_util/macros.h" MountNodeDir::MountNodeDir(Mount* mount) : MountNode(mount), diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc index ce32e08..63c6ab8 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc @@ -17,7 +17,7 @@ #include "nacl_io/mount.h" #include "nacl_io/osdirent.h" #include "nacl_io/pepper_interface.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" namespace { diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc index 0fa82ba..13f0d21 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_node_mem.cc @@ -8,7 +8,7 @@ #include #include "nacl_io/osstat.h" -#include "utils/auto_lock.h" +#include "sdk_util/auto_lock.h" #define BLOCK_SIZE (1 << 16) #define BLOCK_MASK (BLOCK_SIZE - 1) diff --git a/native_client_sdk/src/libraries/nacl_io/nacl_io.h b/native_client_sdk/src/libraries/nacl_io/nacl_io.h index f934353..b408bb9 100644 --- a/native_client_sdk/src/libraries/nacl_io/nacl_io.h +++ b/native_client_sdk/src/libraries/nacl_io/nacl_io.h @@ -9,7 +9,7 @@ #include #include "nacl_io/kernel_wrap.h" -#include "utils/macros.h" +#include "sdk_util/macros.h" EXTERN_C_BEGIN diff --git a/native_client_sdk/src/libraries/nacl_io/nacl_mounts.vcproj b/native_client_sdk/src/libraries/nacl_io/nacl_mounts.vcproj index 875a16f..d57c84f 100644 --- a/native_client_sdk/src/libraries/nacl_io/nacl_mounts.vcproj +++ b/native_client_sdk/src/libraries/nacl_io/nacl_mounts.vcproj @@ -41,7 +41,7 @@ -#include "utils/macros.h" +#include "sdk_util/macros.h" struct dirent { _ino_t d_ino; diff --git a/native_client_sdk/src/libraries/nacl_io/path.h b/native_client_sdk/src/libraries/nacl_io/path.h index 7ac41f2..fcbaa33 100644 --- a/native_client_sdk/src/libraries/nacl_io/path.h +++ b/native_client_sdk/src/libraries/nacl_io/path.h @@ -8,7 +8,7 @@ #include #include -#include "utils/macros.h" +#include "sdk_util/macros.h" typedef std::vector StringArray_t; diff --git a/native_client_sdk/src/libraries/nacl_io/pepper_interface.h b/native_client_sdk/src/libraries/nacl_io/pepper_interface.h index 512fd6f..31915a4 100644 --- a/native_client_sdk/src/libraries/nacl_io/pepper_interface.h +++ b/native_client_sdk/src/libraries/nacl_io/pepper_interface.h @@ -21,7 +21,7 @@ #include #include -#include +#include // Note: To add a new interface: // diff --git a/native_client_sdk/src/libraries/ppapi_simple/ps.h b/native_client_sdk/src/libraries/ppapi_simple/ps.h index 92655d0..1d7b254 100644 --- a/native_client_sdk/src/libraries/ppapi_simple/ps.h +++ b/native_client_sdk/src/libraries/ppapi_simple/ps.h @@ -6,7 +6,7 @@ #define PPAPI_SIMPLE_PS_H_ #include "ppapi/c/pp_instance.h" -#include "utils/macros.h" +#include "sdk_util/macros.h" EXTERN_C_BEGIN diff --git a/native_client_sdk/src/libraries/ppapi_simple/ps_event.h b/native_client_sdk/src/libraries/ppapi_simple/ps_event.h index 536ba87..563832c 100644 --- a/native_client_sdk/src/libraries/ppapi_simple/ps_event.h +++ b/native_client_sdk/src/libraries/ppapi_simple/ps_event.h @@ -10,7 +10,7 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" -#include "utils/macros.h" +#include "sdk_util/macros.h" EXTERN_C_BEGIN diff --git a/native_client_sdk/src/libraries/ppapi_simple/ps_instance.h b/native_client_sdk/src/libraries/ppapi_simple/ps_instance.h index 246e8bc..d888dd7 100644 --- a/native_client_sdk/src/libraries/ppapi_simple/ps_instance.h +++ b/native_client_sdk/src/libraries/ppapi_simple/ps_instance.h @@ -23,7 +23,7 @@ #include "ppapi_simple/ps_event.h" #include "ppapi_simple/ps_main.h" -#include "utils/thread_safe_queue.h" +#include "sdk_util/thread_safe_queue.h" typedef std::map PropertyMap_t; diff --git a/native_client_sdk/src/libraries/sdk_util/auto_lock.h b/native_client_sdk/src/libraries/sdk_util/auto_lock.h new file mode 100644 index 0000000..88215d0 --- /dev/null +++ b/native_client_sdk/src/libraries/sdk_util/auto_lock.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef LIBRARIES_SDK_UTIL_AUTO_LOCK_H_ +#define LIBRARIES_SDK_UTIL_AUTO_LOCK_H_ + +#include + +class AutoLock { + public: + explicit AutoLock(pthread_mutex_t* lock) { + lock_ = lock; + pthread_mutex_lock(lock_); + } + ~AutoLock() { + if (lock_) pthread_mutex_unlock(lock_); + } + + void Unlock() { + if (lock_) pthread_mutex_unlock(lock_); + lock_ = NULL; + } + + private: + pthread_mutex_t* lock_; +}; + +#endif // LIBRARIES_SDK_UTIL_AUTO_LOCK_H_ + diff --git a/native_client_sdk/src/libraries/sdk_util/library.dsc b/native_client_sdk/src/libraries/sdk_util/library.dsc new file mode 100644 index 0000000..0491d98 --- /dev/null +++ b/native_client_sdk/src/libraries/sdk_util/library.dsc @@ -0,0 +1,29 @@ +{ + 'TOOLS': ['newlib', 'glibc', 'pnacl', 'win'], + 'SEARCH': [ + '.' + ], + 'TARGETS': [ + { + 'NAME' : 'sdk_util', + 'TYPE' : 'lib', + 'SOURCES' : [ + 'thread_pool.cc' + ] + } + ], + 'HEADERS': [ + { + 'FILES': [ + 'auto_lock.h', + 'macros.h', + 'ref_object.h', + 'thread_pool.h', + 'thread_safe_queue.h' + ], + 'DEST': 'include/sdk_util', + } + ], + 'DEST': 'src', + 'NAME': 'sdk_util', +} diff --git a/native_client_sdk/src/libraries/sdk_util/macros.h b/native_client_sdk/src/libraries/sdk_util/macros.h new file mode 100644 index 0000000..fd15dc3 --- /dev/null +++ b/native_client_sdk/src/libraries/sdk_util/macros.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef LIBRARIES_SDK_UTIL_MACROS_H_ +#define LIBRARIES_SDK_UTIL_MACROS_H_ + +/** + * A macro to disallow the evil copy constructor and operator= functions + * This should be used in the private: declarations for a class. + */ +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +/** returns the size of a member of a struct. */ +#define MEMBER_SIZE(struct_name, member) sizeof(((struct_name*)0)->member) + +/** + * Macros to prevent name mangling of definitions, allowing them to be + * referenced from C. + */ +#ifdef __cplusplus +# define EXTERN_C_BEGIN extern "C" { +# define EXTERN_C_END } +#else +# define EXTERN_C_BEGIN +# define EXTERN_C_END +#endif /* __cplusplus */ + +/** + * Macros to help force linkage of symbols that otherwise would not be + * included. + * + * // In a source file that you want to force linkage (file scope): + * FORCE_LINK_THIS(myfilename); + * + * // In a source file that you are sure will be linked (file scope): + * FORCE_LINK_THAT(myfilename) + * + */ +#define FORCE_LINK_THIS(x) int force_link_##x = 0; +#define FORCE_LINK_THAT(x) \ + void force_link_function_##x() { \ + extern int force_link_##x; \ + force_link_##x = 1; \ + } + +#endif /* LIBRARIES_SDK_UTIL_MACROS_H_ */ + diff --git a/native_client_sdk/src/libraries/sdk_util/ref_object.h b/native_client_sdk/src/libraries/sdk_util/ref_object.h new file mode 100644 index 0000000..4e81f32 --- /dev/null +++ b/native_client_sdk/src/libraries/sdk_util/ref_object.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef LIBRARIES_SDK_UTIL_REF_OBJECT +#define LIBRARIES_SDK_UTIL_REF_OBJECT + +#include +#include "pthread.h" + +class RefObject { + public: + RefObject() { + ref_count_ = 1; + pthread_mutex_init(&lock_, NULL); + } + + int RefCount() const { return ref_count_; } + + void Acquire() { + ref_count_++; + } + + bool Release() { + if (--ref_count_ == 0) { + Destroy(); + delete this; + return false; + } + return true; + } + + protected: + virtual ~RefObject() { + pthread_mutex_destroy(&lock_); + } + + // Override to clean up object when last reference is released. + virtual void Destroy() {} + + pthread_mutex_t lock_; + + private: + int ref_count_; +}; + +#endif // LIBRARIES_SDK_UTIL_REF_OBJECT + diff --git a/native_client_sdk/src/libraries/sdk_util/thread_pool.cc b/native_client_sdk/src/libraries/sdk_util/thread_pool.cc new file mode 100644 index 0000000..e7d2e5c --- /dev/null +++ b/native_client_sdk/src/libraries/sdk_util/thread_pool.cc @@ -0,0 +1,144 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sdk_util/thread_pool.h" + +#include +#include +#include +#include + +#include "sdk_util/auto_lock.h" + +// Initializes mutex, semaphores and a pool of threads. If 0 is passed for +// num_threads, all work will be performed on the dispatch thread. +ThreadPool::ThreadPool(int num_threads) + : threads_(NULL), counter_(0), num_threads_(num_threads), exiting_(false), + user_data_(NULL), user_work_function_(NULL) { + if (num_threads_ > 0) { + int status; + status = sem_init(&work_sem_, 0, 0); + if (-1 == status) { + fprintf(stderr, "Failed to initialize semaphore!\n"); + exit(-1); + } + status = sem_init(&done_sem_, 0, 0); + if (-1 == status) { + fprintf(stderr, "Failed to initialize semaphore!\n"); + exit(-1); + } + threads_ = new pthread_t[num_threads_]; + for (int i = 0; i < num_threads_; i++) { + status = pthread_create(&threads_[i], NULL, WorkerThreadEntry, this); + if (0 != status) { + fprintf(stderr, "Failed to create thread!\n"); + exit(-1); + } + } + } +} + +// Post exit request, wait for all threads to join, and cleanup. +ThreadPool::~ThreadPool() { + if (num_threads_ > 0) { + PostExitAndJoinAll(); + delete[] threads_; + sem_destroy(&done_sem_); + sem_destroy(&work_sem_); + } +} + +// Setup work parameters. This function is called from the dispatch thread, +// when all worker threads are sleeping. +void ThreadPool::Setup(int counter, WorkFunction work, void *data) { + counter_ = counter; + user_work_function_ = work; + user_data_ = data; +} + +// Return decremented task counter. This function +// can be called from multiple threads at any given time. +int ThreadPool::DecCounter() { +#if defined(__native_client__) + // Use fast atomic sub & fetch. + return __sync_sub_and_fetch(&counter_, 1); +#else + // Fallback to a more platform independent pthread mutex via AutoLock. + static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + AutoLock lock(&mutex); + return --counter_; +#endif +} + +// Set exit flag, post and join all the threads in the pool. This function is +// called only from the dispatch thread, and only when all worker threads are +// sleeping. +void ThreadPool::PostExitAndJoinAll() { + exiting_ = true; + // Wake up all the sleeping worker threads. + for (int i = 0; i < num_threads_; ++i) + sem_post(&work_sem_); + void* retval; + for (int i = 0; i < num_threads_; ++i) + pthread_join(threads_[i], &retval); +} + +// Main work loop - one for each worker thread. +void ThreadPool::WorkLoop() { + while (true) { + // Wait for work. If no work is availble, this thread will sleep here. + sem_wait(&work_sem_); + if (exiting_) break; + while (true) { + // Grab a task index to work on from the counter. + int task_index = DecCounter(); + if (task_index < 0) + break; + user_work_function_(task_index, user_data_); + } + // Post to dispatch thread work is done. + sem_post(&done_sem_); + } +} + +// pthread entry point for a worker thread. +void* ThreadPool::WorkerThreadEntry(void* thiz) { + static_cast(thiz)->WorkLoop(); + return NULL; +} + +// DispatchMany() will dispatch a set of tasks across worker threads. +// Note: This function will block until all work has completed. +void ThreadPool::DispatchMany(int num_tasks, WorkFunction work, void* data) { + // On entry, all worker threads are sleeping. + Setup(num_tasks, work, data); + + // Wake up the worker threads & have them process tasks. + for (int i = 0; i < num_threads_; i++) + sem_post(&work_sem_); + + // Worker threads are now awake and busy. + + // This dispatch thread will now sleep-wait for the worker threads to finish. + for (int i = 0; i < num_threads_; i++) + sem_wait(&done_sem_); + // On exit, all tasks are done and all worker threads are sleeping again. +} + +// DispatchHere will dispatch all tasks on this thread. +void ThreadPool::DispatchHere(int num_tasks, WorkFunction work, void* data) { + for (int i = 0; i < num_tasks; i++) + work(i, data); +} + +// Dispatch() will invoke the user supplied work function across +// one or more threads for each task. +// Note: This function will block until all work has completed. +void ThreadPool::Dispatch(int num_tasks, WorkFunction work, void* data) { + if (num_threads_ > 0) + DispatchMany(num_tasks, work, data); + else + DispatchHere(num_tasks, work, data); +} + diff --git a/native_client_sdk/src/libraries/sdk_util/thread_pool.h b/native_client_sdk/src/libraries/sdk_util/thread_pool.h new file mode 100644 index 0000000..760b3f7 --- /dev/null +++ b/native_client_sdk/src/libraries/sdk_util/thread_pool.h @@ -0,0 +1,45 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Simple thread pool class + +#ifndef LIBRARIES_SDK_UTIL_THREAD_POOL_H_ +#define LIBRARIES_SDK_UTIL_THREAD_POOL_H_ + +#include +#include + +// typdef helper for work function +typedef void (*WorkFunction)(int task_index, void* data); + +// ThreadPool is a class to manage num_threads and assign +// them num_tasks of work at a time. Each call +// to Dispatch(..) will block until all tasks complete. +// If 0 is passed in for num_threads, all tasks will be +// issued on the dispatch thread. + +class ThreadPool { + public: + void Dispatch(int num_tasks, WorkFunction work, void* data); + explicit ThreadPool(int num_threads); + ~ThreadPool(); + private: + int DecCounter(); + void Setup(int counter, WorkFunction work, void* data); + void DispatchMany(int num_tasks, WorkFunction work, void* data); + void DispatchHere(int num_tasks, WorkFunction work, void* data); + void WorkLoop(); + static void* WorkerThreadEntry(void* data); + void PostExitAndJoinAll(); + pthread_t* threads_; + int counter_; + const int num_threads_; + bool exiting_; + void* user_data_; + WorkFunction user_work_function_; + sem_t work_sem_; + sem_t done_sem_; +}; +#endif // LIBRARIES_SDK_UTIL_THREAD_POOL_H_ + diff --git a/native_client_sdk/src/libraries/sdk_util/thread_safe_queue.h b/native_client_sdk/src/libraries/sdk_util/thread_safe_queue.h new file mode 100644 index 0000000..545b7c4 --- /dev/null +++ b/native_client_sdk/src/libraries/sdk_util/thread_safe_queue.h @@ -0,0 +1,63 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef LIBRARIES_SDK_UTIL_THREAD_SAFE_QUEUE_H_ +#define LIBRARIES_SDK_UTIL_THREAD_SAFE_QUEUE_H_ + +#include + +#include + +#include "sdk_util/auto_lock.h" +#include "sdk_util/macros.h" + + +// ThreadSafeQueue +// +// A simple template to support multithreaded and optionally blocking access +// to a Queue of object pointers. +// +template class ThreadSafeQueue { + public: + ThreadSafeQueue() { + pthread_mutex_init(&mutex_, NULL); + pthread_cond_init(&cond_, NULL); + } + + ~ThreadSafeQueue() { + pthread_mutex_destroy(&mutex_); + pthread_cond_destroy(&cond_); + } + + void Enqueue(T* item) { + AutoLock lock(&mutex_); + list_.push_back(item); + + pthread_cond_signal(&cond_); + } + + T* Dequeue(bool block) { + AutoLock lock(&mutex_); + + // If blocking enabled, wait until we queue is non-empty + if (block) { + while (list_.empty()) pthread_cond_wait(&cond_, &mutex_); + } + + if (list_.empty()) return NULL; + + T* item = list_.front(); + list_.pop_front(); + return item; + } + + private: + std::list list_; + pthread_cond_t cond_; + pthread_mutex_t mutex_; + DISALLOW_COPY_AND_ASSIGN(ThreadSafeQueue); +}; + +#endif // LIBRARIES_SDK_UTIL_THREAD_SAFE_QUEUE_H_ + diff --git a/native_client_sdk/src/libraries/utils/auto_lock.h b/native_client_sdk/src/libraries/utils/auto_lock.h deleted file mode 100644 index 19dd66f..0000000 --- a/native_client_sdk/src/libraries/utils/auto_lock.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef LIBRARIES_UTILS_AUTO_LOCK_H_ -#define LIBRARIES_UTILS_AUTO_LOCK_H_ - -#include - -class AutoLock { - public: - explicit AutoLock(pthread_mutex_t* lock) { - lock_ = lock; - pthread_mutex_lock(lock_); - } - ~AutoLock() { - if (lock_) pthread_mutex_unlock(lock_); - } - - void Unlock() { - if (lock_) pthread_mutex_unlock(lock_); - lock_ = NULL; - } - - private: - pthread_mutex_t* lock_; -}; - -#endif // LIBRARIES_UTILS_AUTO_LOCK_H_ diff --git a/native_client_sdk/src/libraries/utils/macros.h b/native_client_sdk/src/libraries/utils/macros.h deleted file mode 100644 index 718d83f..0000000 --- a/native_client_sdk/src/libraries/utils/macros.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef LIBRARIES_UTILS_MACROS_H_ -#define LIBRARIES_UTILS_MACROS_H_ - -/** - * A macro to disallow the evil copy constructor and operator= functions - * This should be used in the private: declarations for a class. - */ -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -/** returns the size of a member of a struct. */ -#define MEMBER_SIZE(struct_name, member) sizeof(((struct_name*)0)->member) - -/** - * Macros to prevent name mangling of definitions, allowing them to be - * referenced from C. - */ -#ifdef __cplusplus -# define EXTERN_C_BEGIN extern "C" { -# define EXTERN_C_END } -#else -# define EXTERN_C_BEGIN -# define EXTERN_C_END -#endif /* __cplusplus */ - -/** - * Macros to help force linkage of symbols that otherwise would not be - * included. - * - * // In a source file that you want to force linkage (file scope): - * FORCE_LINK_THIS(myfilename); - * - * // In a source file that you are sure will be linked (file scope): - * FORCE_LINK_THAT(myfilename) - * - */ -#define FORCE_LINK_THIS(x) int force_link_##x = 0; -#define FORCE_LINK_THAT(x) \ - void force_link_function_##x() { \ - extern int force_link_##x; \ - force_link_##x = 1; \ - } - -#endif /* LIBRARIES_UTILS_MACROS_H_ */ diff --git a/native_client_sdk/src/libraries/utils/ref_object.h b/native_client_sdk/src/libraries/utils/ref_object.h deleted file mode 100644 index d3eb9f8..0000000 --- a/native_client_sdk/src/libraries/utils/ref_object.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef LIBRARIES_UTILS_REF_OBJECT -#define LIBRARIES_UTILS_REF_OBJECT - -#include -#include "pthread.h" - -class RefObject { - public: - RefObject() { - ref_count_ = 1; - pthread_mutex_init(&lock_, NULL); - } - - int RefCount() const { return ref_count_; } - - void Acquire() { - ref_count_++; - } - - bool Release() { - if (--ref_count_ == 0) { - Destroy(); - delete this; - return false; - } - return true; - } - - protected: - virtual ~RefObject() { - pthread_mutex_destroy(&lock_); - } - - // Override to clean up object when last reference is released. - virtual void Destroy() {} - - pthread_mutex_t lock_; - - private: - int ref_count_; -}; - -#endif // LIBRARIES_UTILS_REF_OBJECT diff --git a/native_client_sdk/src/libraries/utils/thread_safe_queue.h b/native_client_sdk/src/libraries/utils/thread_safe_queue.h deleted file mode 100644 index d35d504..0000000 --- a/native_client_sdk/src/libraries/utils/thread_safe_queue.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef LIBRARIES_UTILS_THREAD_SAFE_QUEUE_H_ -#define LIBRARIES_UTILS_THREAD_SAFE_QUEUE_H_ - -#include - -#include - -#include "utils/auto_lock.h" -#include "utils/macros.h" - - -// ThreadSafeQueue -// -// A simple template to support multithreaded and optionally blocking access -// to a Queue of object pointers. -// -template class ThreadSafeQueue { - public: - ThreadSafeQueue() { - pthread_mutex_init(&mutex_, NULL); - pthread_cond_init(&cond_, NULL); - } - - ~ThreadSafeQueue() { - pthread_mutex_destroy(&mutex_); - pthread_cond_destroy(&cond_); - } - - void Enqueue(T* item) { - AutoLock lock(&mutex_); - list_.push_back(item); - - pthread_cond_signal(&cond_); - } - - T* Dequeue(bool block) { - AutoLock lock(&mutex_); - - // If blocking enabled, wait until we queue is non-empty - if (block) { - while (list_.empty()) pthread_cond_wait(&cond_, &mutex_); - } - - if (list_.empty()) return NULL; - - T* item = list_.front(); - list_.pop_front(); - return item; - } - - private: - std::list list_; - pthread_cond_t cond_; - pthread_mutex_t mutex_; - DISALLOW_COPY_AND_ASSIGN(ThreadSafeQueue); -}; - -#endif // LIBRARIES_UTILS_THREAD_SAFE_QUEUE_H_ \ No newline at end of file -- cgit v1.1