pthread: alternative for dynamic_cast in 'pthread_self()'

Fixes #2077
This commit is contained in:
Christian Prochaska 2016-08-25 16:05:25 +02:00 committed by Christian Helmuth
parent b3c877a8bf
commit 8a93e3e20a
2 changed files with 85 additions and 3 deletions

View File

@ -57,6 +57,53 @@ static __attribute__((constructor)) Thread * main_thread()
}
void Pthread_registry::insert(pthread_t thread)
{
/* prevent multiple insertions at the same location */
static Genode::Lock insert_lock;
Genode::Lock::Guard insert_lock_guard(insert_lock);
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++) {
if (_array[i] == 0) {
_array[i] = thread;
return;
}
}
Genode::error("pthread registry overflow, pthread_self() might fail");
}
void Pthread_registry::remove(pthread_t thread)
{
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++) {
if (_array[i] == thread) {
_array[i] = 0;
return;
}
}
Genode::error("could not remove unknown pthread from registry");
}
bool Pthread_registry::contains(pthread_t thread)
{
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++)
if (_array[i] == thread)
return true;
return false;
}
Pthread_registry &pthread_registry()
{
static Pthread_registry instance;
return instance;
}
extern "C" {
/* Thread */
@ -129,9 +176,10 @@ extern "C" {
{
Thread *myself = Thread::myself();
pthread_t pthread = dynamic_cast<pthread_t>(myself);
if (pthread)
return pthread;
pthread_t pthread_myself = static_cast<pthread_t>(myself);
if (pthread_registry().contains(pthread_myself))
return pthread_myself;
/*
* We pass here if the main thread or an alien thread calls

View File

@ -18,6 +18,31 @@
#include <pthread.h>
/*
* Used by 'pthread_self()' to find out if the current thread is an alien
* thread.
*/
class Pthread_registry
{
private:
enum { MAX_NUM_PTHREADS = 128 };
pthread_t _array[MAX_NUM_PTHREADS] = { 0 };
public:
void insert(pthread_t thread);
void remove(pthread_t thread);
bool contains(pthread_t thread);
};
Pthread_registry &pthread_registry();
extern "C" {
struct pthread_attr
@ -50,6 +75,8 @@ extern "C" {
{
if (_attr)
_attr->pthread = this;
pthread_registry().insert(this);
}
/**
@ -62,6 +89,13 @@ extern "C" {
{
if (_attr)
_attr->pthread = this;
pthread_registry().insert(this);
}
virtual ~pthread()
{
pthread_registry().remove(this);
}
void entry()