Add new threadwrapper

This commit is contained in:
Mikko Pitkänen 2019-06-18 17:13:26 +03:00
parent 081d16fc33
commit 3dd606ce2e
9 changed files with 303 additions and 9 deletions

View file

@ -13,7 +13,7 @@
<AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput> <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PreprocessorDefinitions>KVZ_DLL_EXPORTS;KVZ_COMPILE_ASM;WIN32_LEAN_AND_MEAN;WIN32;WIN64;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>KVZ_DLL_EXPORTS;KVZ_COMPILE_ASM;WIN32_LEAN_AND_MEAN;WIN32;WIN64;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\pthreads.2\include;$(SolutionDir)..\src;$(SolutionDir)..\src\extras;$(SolutionDir)..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)..\src\threadwrapper\include;$(SolutionDir)..\src;$(SolutionDir)..\src\extras;$(SolutionDir)..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4244;4204;4206;4028;4152;4996;4018;4456;4389;4100;4131;4459;4706;4214;4127;4201</DisableSpecificWarnings> <DisableSpecificWarnings>4244;4204;4206;4028;4152;4996;4018;4456;4389;4100;4131;4459;4706;4214;4127;4201</DisableSpecificWarnings>
<OpenMPSupport>false</OpenMPSupport> <OpenMPSupport>false</OpenMPSupport>
<TreatSpecificWarningsAsErrors>4013;4029;4047;4716;4700;4020;4021;4133</TreatSpecificWarningsAsErrors> <TreatSpecificWarningsAsErrors>4013;4029;4047;4716;4700;4020;4021;4133</TreatSpecificWarningsAsErrors>

View file

@ -78,8 +78,10 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<YASM /> <YASM />
<Lib> <Lib>
<AdditionalLibraryDirectories>$(SolutionDir)..\..\pthreads.2\lib\x64</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>
<AdditionalDependencies>pthreadVC2.lib</AdditionalDependencies> </AdditionalLibraryDirectories>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib> </Lib>
<YASM> <YASM>
<Defines>ARCH_X86_64=1;%(Defines)</Defines> <Defines>ARCH_X86_64=1;%(Defines)</Defines>
@ -92,8 +94,10 @@
<IncludePaths>$(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm;</IncludePaths> <IncludePaths>$(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm;</IncludePaths>
</YASM> </YASM>
<Lib> <Lib>
<AdditionalLibraryDirectories>$(SolutionDir)..\..\pthreads.2\lib\x86</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>
<AdditionalDependencies>pthreadVC2.lib</AdditionalDependencies> </AdditionalLibraryDirectories>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib> </Lib>
<ClCompile> <ClCompile>
<UndefinePreprocessorDefinitions> <UndefinePreprocessorDefinitions>
@ -106,8 +110,10 @@
<IncludePaths>$(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm;</IncludePaths> <IncludePaths>$(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm;</IncludePaths>
</YASM> </YASM>
<Lib> <Lib>
<AdditionalLibraryDirectories>$(SolutionDir)..\..\pthreads.2\lib\x86</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>
<AdditionalDependencies>pthreadVC2.lib</AdditionalDependencies> </AdditionalLibraryDirectories>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib> </Lib>
<ClCompile> <ClCompile>
<UndefinePreprocessorDefinitions> <UndefinePreprocessorDefinitions>
@ -120,8 +126,10 @@
<IncludePaths>$(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm;</IncludePaths> <IncludePaths>$(SolutionDir)..\src\extras;%(IncludePaths);$(SolutionDir)..\src\strategies\x86-asm;</IncludePaths>
</YASM> </YASM>
<Lib> <Lib>
<AdditionalLibraryDirectories>$(SolutionDir)..\..\pthreads.2\lib\x64</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>
<AdditionalDependencies>pthreadVC2.lib</AdditionalDependencies> </AdditionalLibraryDirectories>
<AdditionalDependencies>
</AdditionalDependencies>
</Lib> </Lib>
<ClCompile> <ClCompile>
<UndefinePreprocessorDefinitions> <UndefinePreprocessorDefinitions>
@ -226,6 +234,18 @@
<ClCompile Include="..\..\src\strategies\strategies-picture.c" /> <ClCompile Include="..\..\src\strategies\strategies-picture.c" />
<ClCompile Include="..\..\src\strategies\strategies-sao.c" /> <ClCompile Include="..\..\src\strategies\strategies-sao.c" />
<ClCompile Include="..\..\src\strategies\x86_asm\picture-x86-asm.c" /> <ClCompile Include="..\..\src\strategies\x86_asm\picture-x86-asm.c" />
<ClCompile Include="..\..\src\threadwrapper\src\pthread.cpp">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\src\threadwrapper\src\semaphore.cpp">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsCpp</CompileAs>
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CompileAsCpp</CompileAs>
</ClCompile>
<ClCompile Include="..\..\src\videoframe.c" /> <ClCompile Include="..\..\src\videoframe.c" />
<ClInclude Include="..\..\src\encoder_state-bitstream.h" /> <ClInclude Include="..\..\src\encoder_state-bitstream.h" />
<ClInclude Include="..\..\src\encoder_state-ctors_dtors.h" /> <ClInclude Include="..\..\src\encoder_state-ctors_dtors.h" />
@ -297,6 +317,8 @@
<ClInclude Include="..\..\src\tables.h" /> <ClInclude Include="..\..\src\tables.h" />
<ClInclude Include="..\..\src\threadqueue.h" /> <ClInclude Include="..\..\src\threadqueue.h" />
<ClInclude Include="..\..\src\threads.h" /> <ClInclude Include="..\..\src\threads.h" />
<ClInclude Include="..\..\src\threadwrapper\include\pthread.h" />
<ClInclude Include="..\..\src\threadwrapper\include\semaphore.h" />
<ClInclude Include="..\..\src\transform.h" /> <ClInclude Include="..\..\src\transform.h" />
<ClInclude Include="..\..\src\videoframe.h" /> <ClInclude Include="..\..\src\videoframe.h" />
</ItemGroup> </ItemGroup>

View file

@ -49,6 +49,9 @@
<Filter Include="Threading"> <Filter Include="Threading">
<UniqueIdentifier>{63c21cb2-b379-4d38-bcb8-173786c2466d}</UniqueIdentifier> <UniqueIdentifier>{63c21cb2-b379-4d38-bcb8-173786c2466d}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Threadwrapper">
<UniqueIdentifier>{f4abece9-e209-4817-a57e-c64ca7c5e05c}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\strategies\strategies-nal.c"> <ClCompile Include="..\..\src\strategies\strategies-nal.c">
@ -230,6 +233,12 @@
<ClCompile Include="..\..\src\strategies\strategies-encode.c"> <ClCompile Include="..\..\src\strategies\strategies-encode.c">
<Filter>Optimization\strategies</Filter> <Filter>Optimization\strategies</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\threadwrapper\src\pthread.cpp">
<Filter>Threadwrapper</Filter>
</ClCompile>
<ClCompile Include="..\..\src\threadwrapper\src\semaphore.cpp">
<Filter>Threadwrapper</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\src\bitstream.h"> <ClInclude Include="..\..\src\bitstream.h">
@ -438,6 +447,12 @@
<ClInclude Include="..\..\src\strategies\sse41\reg_sad_pow2_widths-sse41.h"> <ClInclude Include="..\..\src\strategies\sse41\reg_sad_pow2_widths-sse41.h">
<Filter>Optimization\strategies\sse41</Filter> <Filter>Optimization\strategies\sse41</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\threadwrapper\include\pthread.h">
<Filter>Threadwrapper</Filter>
</ClInclude>
<ClInclude Include="..\..\src\threadwrapper\include\semaphore.h">
<Filter>Threadwrapper</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<YASM Include="..\..\src\extras\x86inc.asm"> <YASM Include="..\..\src\extras\x86inc.asm">

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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 <condition_variable>
#include <mutex>
#include <thread>
int pthread_cond_broadcast(pthread_cond_t* cond) {
static_cast<std::condition_variable*>(*cond)->notify_all();
return 0;
}
int pthread_cond_destroy(pthread_cond_t* cond) {
delete static_cast<std::condition_variable*>(*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<std::condition_variable*>(*cond)->notify_one();
return 0;
}
int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) {
std::mutex* real_mutex = static_cast<std::mutex*>(*mutex);
std::unique_lock<std::mutex> lock(*real_mutex, std::adopt_lock);
static_cast<std::condition_variable*>(*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<std::thread*>(thread);
real_thread->join();
delete real_thread;
return 0;
}
int pthread_mutex_destroy(pthread_mutex_t* mutex) {
delete static_cast<std::mutex*>(*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<std::mutex*>(*mutex)->lock();
return 0;
}
int pthread_mutex_unlock(pthread_mutex_t* mutex) {
static_cast<std::mutex*>(*mutex)->unlock();
return 0;
}

View file

@ -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 <condition_variable>
#include <mutex>
class Semaphore {
public:
Semaphore(int value):
val_(value) {
}
void post() {
std::unique_lock<std::mutex> lck(mtx_);
if (++val_ <= 0) {
cvar_.notify_one();
}
}
void wait() {
std::unique_lock<std::mutex> 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<Semaphore*>(*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<Semaphore*>(*sem)->post();
return 0;
}
int sem_wait(sem_t* sem) {
static_cast<Semaphore*>(*sem)->wait();
return 0;
}