From 3dd606ce2e150542843122abc336506a024bd646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20Pitk=C3=A4nen?= Date: Tue, 18 Jun 2019 17:13:26 +0300 Subject: [PATCH] Add new threadwrapper --- build/C_Properties.props | 2 +- build/kvazaar_lib/kvazaar_lib.vcxproj | 38 ++++++-- build/kvazaar_lib/kvazaar_lib.vcxproj.filters | 15 ++++ src/threadwrapper/LICENSE | 5 ++ src/threadwrapper/README.md | 6 ++ src/threadwrapper/include/pthread.h | 53 +++++++++++ src/threadwrapper/include/semaphore.h | 33 +++++++ src/threadwrapper/src/pthread.cpp | 88 +++++++++++++++++++ src/threadwrapper/src/semaphore.cpp | 72 +++++++++++++++ 9 files changed, 303 insertions(+), 9 deletions(-) create mode 100644 src/threadwrapper/LICENSE create mode 100644 src/threadwrapper/README.md create mode 100644 src/threadwrapper/include/pthread.h create mode 100644 src/threadwrapper/include/semaphore.h create mode 100644 src/threadwrapper/src/pthread.cpp create mode 100644 src/threadwrapper/src/semaphore.cpp diff --git a/build/C_Properties.props b/build/C_Properties.props index 8d300ca7..e623c441 100644 --- a/build/C_Properties.props +++ b/build/C_Properties.props @@ -13,7 +13,7 @@ AssemblyAndSourceCode MultiThreadedDebugDLL KVZ_DLL_EXPORTS;KVZ_COMPILE_ASM;WIN32_LEAN_AND_MEAN;WIN32;WIN64;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(SolutionDir)..\..\pthreads.2\include;$(SolutionDir)..\src;$(SolutionDir)..\src\extras;$(SolutionDir)..\;%(AdditionalIncludeDirectories) + $(SolutionDir)..\src\threadwrapper\include;$(SolutionDir)..\src;$(SolutionDir)..\src\extras;$(SolutionDir)..\;%(AdditionalIncludeDirectories) 4244;4204;4206;4028;4152;4996;4018;4456;4389;4100;4131;4459;4706;4214;4127;4201 false 4013;4029;4047;4716;4700;4020;4021;4133 diff --git a/build/kvazaar_lib/kvazaar_lib.vcxproj b/build/kvazaar_lib/kvazaar_lib.vcxproj index 1869aad2..4fc454da 100644 --- a/build/kvazaar_lib/kvazaar_lib.vcxproj +++ b/build/kvazaar_lib/kvazaar_lib.vcxproj @@ -78,8 +78,10 @@ - $(SolutionDir)..\..\pthreads.2\lib\x64 - pthreadVC2.lib + + + + ARCH_X86_64=1;%(Defines) @@ -92,8 +94,10 @@ $(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm; - $(SolutionDir)..\..\pthreads.2\lib\x86 - pthreadVC2.lib + + + + @@ -106,8 +110,10 @@ $(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm; - $(SolutionDir)..\..\pthreads.2\lib\x86 - pthreadVC2.lib + + + + @@ -120,8 +126,10 @@ $(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm; - $(SolutionDir)..\..\pthreads.2\lib\x64 - pthreadVC2.lib + + + + @@ -226,6 +234,18 @@ + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + @@ -297,6 +317,8 @@ + + diff --git a/build/kvazaar_lib/kvazaar_lib.vcxproj.filters b/build/kvazaar_lib/kvazaar_lib.vcxproj.filters index c562119d..b8d487ea 100644 --- a/build/kvazaar_lib/kvazaar_lib.vcxproj.filters +++ b/build/kvazaar_lib/kvazaar_lib.vcxproj.filters @@ -49,6 +49,9 @@ {63c21cb2-b379-4d38-bcb8-173786c2466d} + + {f4abece9-e209-4817-a57e-c64ca7c5e05c} + @@ -230,6 +233,12 @@ Optimization\strategies + + Threadwrapper + + + Threadwrapper + @@ -438,6 +447,12 @@ Optimization\strategies\sse41 + + Threadwrapper + + + Threadwrapper + diff --git a/src/threadwrapper/LICENSE b/src/threadwrapper/LICENSE new file mode 100644 index 00000000..2fcf2196 --- /dev/null +++ b/src/threadwrapper/LICENSE @@ -0,0 +1,5 @@ +Copyright 2019 Tampere University + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/src/threadwrapper/README.md b/src/threadwrapper/README.md new file mode 100644 index 00000000..d393f0ed --- /dev/null +++ b/src/threadwrapper/README.md @@ -0,0 +1,6 @@ +ThreadWrapper +======= +Wraps pthread functions so that they actually call C++ standard functions. + +Only functions used by Kvazaar, an open-source HEVC encoder, are implemented. +People are free to contribute if they implement other functions. diff --git a/src/threadwrapper/include/pthread.h b/src/threadwrapper/include/pthread.h new file mode 100644 index 00000000..eeef31d5 --- /dev/null +++ b/src/threadwrapper/include/pthread.h @@ -0,0 +1,53 @@ +/* +Copyright 2019 Tampere University + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* pthread_cond_t; +typedef void* pthread_cond_t; +typedef void* pthread_mutex_t; +typedef void* pthread_t; +typedef void*(voidp_voidp_func)(void*); + +typedef void pthread_attr_t; +typedef void pthread_condattr_t; +typedef void pthread_mutexattr_t; + +// Parameter names that have been commented away do nothing, +// as they are always null when the functions are used in Kvazaar. + +int pthread_cond_broadcast(pthread_cond_t* cond); +int pthread_cond_destroy(pthread_cond_t* cond); +int pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* /*attr*/); +int pthread_cond_signal(pthread_cond_t* cond); +int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex); + +int pthread_create(pthread_t* thread, const pthread_attr_t* /*attr*/, voidp_voidp_func executee, void* arg); +void pthread_exit(void* /*value_ptr*/); +int pthread_join(pthread_t thread, void** /*value_ptr*/); + +int pthread_mutex_destroy(pthread_mutex_t* mutex); +int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* /*attr*/); +int pthread_mutex_lock(pthread_mutex_t* mutex); +int pthread_mutex_unlock(pthread_mutex_t* mutex); + +#ifdef __cplusplus +} +#endif diff --git a/src/threadwrapper/include/semaphore.h b/src/threadwrapper/include/semaphore.h new file mode 100644 index 00000000..f1a87345 --- /dev/null +++ b/src/threadwrapper/include/semaphore.h @@ -0,0 +1,33 @@ +/* +Copyright 2019 Tampere University + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* sem_t; + +int sem_destroy(sem_t* sem); +// pshared is always 0 in Kvazaar on w32. +int sem_init(sem_t* sem, int /*pshared*/, unsigned int value); +int sem_post(sem_t* sem); +int sem_wait(sem_t* sem); + +#ifdef __cplusplus +} +#endif diff --git a/src/threadwrapper/src/pthread.cpp b/src/threadwrapper/src/pthread.cpp new file mode 100644 index 00000000..7e094b9e --- /dev/null +++ b/src/threadwrapper/src/pthread.cpp @@ -0,0 +1,88 @@ +/* +Copyright 2019 Tampere University + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "pthread.h" +#include +#include +#include + + +int pthread_cond_broadcast(pthread_cond_t* cond) { + static_cast(*cond)->notify_all(); + return 0; +} + +int pthread_cond_destroy(pthread_cond_t* cond) { + delete static_cast(*cond); + *cond = nullptr; + return 0; +} + +int pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t*) { + *cond = new std::condition_variable(); + return 0; +} + +int pthread_cond_signal(pthread_cond_t* cond) { + static_cast(*cond)->notify_one(); + return 0; +} + +int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) { + std::mutex* real_mutex = static_cast(*mutex); + std::unique_lock lock(*real_mutex, std::adopt_lock); + static_cast(*cond)->wait(lock); + lock.release(); + return 0; +} + +int pthread_create(pthread_t* thread, const pthread_attr_t*, voidp_voidp_func executee, void* arg) { + *thread = new std::thread(executee, arg); + return 0; +} + +void pthread_exit(void*) { + // It might be enough to do nothing here + // considering Kvazaar's current use of pthread_exit +} + +int pthread_join(pthread_t thread, void**) { + std::thread* real_thread = static_cast(thread); + real_thread->join(); + delete real_thread; + return 0; +} + +int pthread_mutex_destroy(pthread_mutex_t* mutex) { + delete static_cast(*mutex); + *mutex = nullptr; + return 0; +} + +int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t*) { + *mutex = new std::mutex(); + return 0; +} + +int pthread_mutex_lock(pthread_mutex_t* mutex) { + static_cast(*mutex)->lock(); + return 0; +} + +int pthread_mutex_unlock(pthread_mutex_t* mutex) { + static_cast(*mutex)->unlock(); + return 0; +} diff --git a/src/threadwrapper/src/semaphore.cpp b/src/threadwrapper/src/semaphore.cpp new file mode 100644 index 00000000..b4fe0170 --- /dev/null +++ b/src/threadwrapper/src/semaphore.cpp @@ -0,0 +1,72 @@ +/* +Copyright 2019 Tampere University + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "semaphore.h" +#include +#include + + +class Semaphore { +public: + + Semaphore(int value): + val_(value) { + } + + void post() { + std::unique_lock lck(mtx_); + if (++val_ <= 0) { + cvar_.notify_one(); + } + } + + void wait() { + std::unique_lock lck(mtx_); + if (--val_ < 0) { + cvar_.wait(lck); + } + } + + +private: + + int val_; + std::condition_variable cvar_; + std::mutex mtx_; + +}; // class Semaphore + + +int sem_destroy(sem_t* sem) { + delete static_cast(*sem); + *sem = nullptr; + return 0; +} + +int sem_init(sem_t* sem, int, unsigned int value) { + *sem = new Semaphore(value); + return 0; +} + +int sem_post(sem_t* sem) { + static_cast(*sem)->post(); + return 0; +} + +int sem_wait(sem_t* sem) { + static_cast(*sem)->wait(); + return 0; +}