Commit c1bcd2e0 by FritzFlorian

First draft of thread class using c++11 standard.

The first draft of the internal threading component is currently only implemented using the c++11 std::thread, pthread support will be added next.
parent 3e1aa956
...@@ -36,4 +36,7 @@ As this project contains a lot concurrent code we use ...@@ -36,4 +36,7 @@ As this project contains a lot concurrent code we use
in our CI process and optional in other builds. To setup CMake builds in our CI process and optional in other builds. To setup CMake builds
with sanitizer enabled add the cmake option `-DTHREAD_SANITIZER=ON`. with sanitizer enabled add the cmake option `-DTHREAD_SANITIZER=ON`.
Please regularly test with thread sanitizer enabled and make sure to not Please regularly test with thread sanitizer enabled and make sure to not
keep the repository in a state where the sanitizer reports errors. keep the repository in a state where the sanitizer reports errors.
\ No newline at end of file
Consider reading [the section on common data races](https://github.com/google/sanitizers/wiki/ThreadSanitizerPopularDataRaces)
to get an idea of what we try to avoid in our code.
\ No newline at end of file
# List all required files here (cmake best practice to NOT automate this step!) # List all required files here (cmake best practice to NOT automate this step!)
add_library(pls STATIC add_library(pls STATIC
src/library.cpp include/pls/library.h) src/library.cpp include/pls/library.h
src/internal/base/thread.cpp include/pls/internal/base/thread.h)
# Settings for our project...
# ...pthreads or C++ 11 threads
option(USING_PTHREADS "Build the tests" ON)
if(USING_PTHREADS)
target_compile_definitions(pls PUBLIC USING_PTHREADS)
else()
target_compile_definitions(pls PUBLIC USING_CPP_THREADS)
endif()
# Add everything in `./include` to be in the include path of this project # Add everything in `./include` to be in the include path of this project
target_include_directories(pls target_include_directories(pls
......
/**
* Abstraction for threading to allow porting.
* Currently using either pthread or C++ 11 threads.
*/
#ifndef PLS_THREAD_H
#define PLS_THREAD_H
// platform specific includes
#ifdef USING_PTHREADS
#include <pthread.h>
#elif USING_CPP_THREADS
#include <thread>
#else
#error "Please configure exactly one threading library!"
#endif
namespace pls {
namespace internal {
namespace base {
using thread_entrypoint = void();
// Thread local storage support
#ifdef USING_PTHREADS
pthread_key_t thr_id_key;
bool thr_id_key_created = false;
// forward declaration
int start_pthread_internal(void*);
#endif
#ifdef USING_CPP_THREADS
thread_local void* local_thread;
#endif
template<typename T>
class thread {
private:
// Handle to the native thread used
#ifdef USING_PTHREADS
friend int start_pthread_internal(void*);
pthread_t pthread_thread_;
thread_entrypoint entry_function_;
thread(thread_entrypoint entry_function, T local_object):
pthread_thread_(),
entry_function_(entry_function),
local_object_(local_object) {
if (!thr_id_key_created) {
pthread_key_create(&thr_id_key, nullptr);
thr_id_key_created = true;
}
pthread_create(&pthread_thread_, nullptr, start_pthread_internal, (void *)(this));
}
#endif
#ifdef USING_CPP_THREADS
std::thread std_thread_;
thread(thread_entrypoint entry_function, T local_object):
local_object_(local_object),
std_thread_([=](){
local_thread = this;
entry_function();
}) {};
#endif
public:
T local_object_;
/**
* Creates and starts a thread.
* NOT thread safe, best only use from one main thread managing the runtime!
*
* @param entry_function The entry function to run on the thread
* @param T local_object
*
* @return a handle to the newly created thread
*/
static thread start(thread_entrypoint entry_function, T local_object) {
return thread(entry_function, local_object);
}
void join() {
#ifdef USING_PTHREADS
// TODO
#endif
#ifdef USING_CPP_THREADS
std_thread_.join();
#endif
}
static void yield() {
#ifdef USING_PTHREADS
// TODO
#endif
#ifdef USING_CPP_THREADS
std::this_thread::yield();
#endif
}
static thread* get_current() {
#ifdef USING_PTHREADS
// TODO
#endif
#ifdef USING_CPP_THREADS
return (thread*) local_thread;
#endif
}
// make object move only
thread(thread&&) = default;
thread& operator=(thread&&) = default;
thread(const thread&) = delete;
thread& operator=(const thread&) = delete;
};
#ifdef USING_PTHREADS
int start_pthread_internal(void* thread_pointer) {
thread* my_thread = (thread*)thread_pointer;
pthread_setspecific(thr_id_key, thread_pointer);
my_thread->entry_function_();
pthread_exit(NULL);
}
#endif
}
}
}
#endif //PLS_THREAD_H
#include "pls/internal/base/thread.h"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment