pthread: improve stack attribute handling

- initialize the stack size attribute with `Libc::Component::stack_size()`
  as default value
- remove the possibly uninitialized `pthread` member from the attribute
  structure and obtain current attribute values in the
 `pthread_attr_get_np()` function, where the `pthread` object reference
  is given as argument
- let each thread obtain its stack address and actual stack size at thread
  start to have the information available for other threads

Fixes #2865
This commit is contained in:
Christian Prochaska 2018-06-12 15:21:08 +02:00 committed by Norman Feske
parent b630bd8d6a
commit 6616b0efe7
3 changed files with 36 additions and 25 deletions

View File

@ -67,6 +67,11 @@ static __attribute__((constructor)) Thread * main_thread()
*/
void pthread::Thread_object::entry()
{
/* obtain stack attributes of new thread */
Thread::Stack_info info = Thread::mystack();
_stack_addr = (void *)info.base;
_stack_size = info.top - info.base;
void *exit_status = _start_routine(_arg);
_exiting = true;
Libc::resume_all();
@ -276,18 +281,8 @@ extern "C" {
if (!attr || !*attr || !stackaddr || !stacksize)
return EINVAL;
pthread_t pthread = (*attr)->pthread;
if (pthread != pthread_self()) {
error("pthread_attr_getstack() called, where pthread != phtread_self");
*stackaddr = nullptr;
*stacksize = 0;
return EINVAL;
}
Thread::Stack_info info = Thread::mystack();
*stackaddr = (void *)info.base;
*stacksize = info.top - info.base;
*stackaddr = (*attr)->stack_addr;
*stacksize = (*attr)->stack_size;
return 0;
}
@ -312,7 +307,9 @@ extern "C" {
if (!attr)
return EINVAL;
(*attr)->pthread = pthread;
(*attr)->stack_addr = pthread->stack_addr();
(*attr)->stack_size = pthread->stack_size();
return 0;
}

View File

@ -17,6 +17,7 @@
#define _INCLUDE__SRC_LIB_PTHREAD_THREAD_H_
/* Genode includes */
#include <libc/component.h>
#include <util/reconstructible.h>
#include <pthread.h>
@ -50,10 +51,8 @@ extern "C" {
struct pthread_attr
{
pthread_t pthread;
size_t stack_size;
pthread_attr() : pthread(0), stack_size(0) { }
void *stack_addr { nullptr };
size_t stack_size { Libc::Component::stack_size() };
};
/*
@ -107,15 +106,21 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
void *_arg;
bool _exiting = false;
void *&_stack_addr;
size_t &_stack_size;
enum { WEIGHT = Genode::Cpu_session::Weight::DEFAULT_WEIGHT };
/* 'stack_addr_out' and 'stack_size_out' are written when the thread starts */
Thread_object(char const *name, size_t stack_size,
Genode::Cpu_session *cpu,
Genode::Affinity::Location location,
start_routine_t start_routine, void *arg)
start_routine_t start_routine, void *arg,
void *&stack_addr_out, size_t &stack_size_out)
:
Genode::Thread(WEIGHT, name, stack_size, Type::NORMAL, cpu, location),
_start_routine(start_routine), _arg(arg)
_start_routine(start_routine), _arg(arg),
_stack_addr(stack_addr_out), _stack_size(stack_size_out)
{ }
void entry() override;
@ -144,6 +149,10 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
pthread_registry().insert(this);
}
/* attributes for 'pthread_attr_get_np()' */
void *_stack_addr = nullptr;
size_t _stack_size = 0;
public:
/**
@ -154,7 +163,8 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
Genode::Cpu_session * cpu, Genode::Affinity::Location location)
:
_thread(_construct_thread_object(name, stack_size, cpu, location,
start_routine, arg))
start_routine, arg,
_stack_addr, _stack_size))
{
_associate_thread_with_pthread();
}
@ -167,6 +177,11 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
:
_thread(existing_thread)
{
/* obtain stack attributes of main thread */
Genode::Thread::Stack_info info = Genode::Thread::mystack();
_stack_addr = (void *)info.base;
_stack_size = info.top - info.base;
_associate_thread_with_pthread();
}
@ -183,8 +198,8 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
void join() { _thread.join(); }
void *stack_top() const { return _thread.stack_top(); }
void *stack_base() const { return _thread.stack_base(); }
void *stack_addr() const { return _stack_addr; }
size_t stack_size() const { return _stack_size; }
};
#endif /* _INCLUDE__SRC_LIB_PTHREAD_THREAD_H_ */

View File

@ -22,8 +22,6 @@
extern "C"
{
enum { STACK_SIZE=64*1024 };
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg)
{
@ -31,7 +29,8 @@ extern "C"
pthread_cleanup();
size_t const stack_size = (attr && *attr && (*attr)->stack_size)
? (*attr)->stack_size : STACK_SIZE;
? (*attr)->stack_size
: Libc::Component::stack_size();
pthread_t thread_obj = new pthread(start_routine, arg, stack_size,
"pthread", nullptr,