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:
parent
b630bd8d6a
commit
6616b0efe7
|
@ -67,6 +67,11 @@ static __attribute__((constructor)) Thread * main_thread()
|
||||||
*/
|
*/
|
||||||
void pthread::Thread_object::entry()
|
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);
|
void *exit_status = _start_routine(_arg);
|
||||||
_exiting = true;
|
_exiting = true;
|
||||||
Libc::resume_all();
|
Libc::resume_all();
|
||||||
|
@ -276,18 +281,8 @@ extern "C" {
|
||||||
if (!attr || !*attr || !stackaddr || !stacksize)
|
if (!attr || !*attr || !stackaddr || !stacksize)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
pthread_t pthread = (*attr)->pthread;
|
*stackaddr = (*attr)->stack_addr;
|
||||||
|
*stacksize = (*attr)->stack_size;
|
||||||
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;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -312,7 +307,9 @@ extern "C" {
|
||||||
if (!attr)
|
if (!attr)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
(*attr)->pthread = pthread;
|
(*attr)->stack_addr = pthread->stack_addr();
|
||||||
|
(*attr)->stack_size = pthread->stack_size();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#define _INCLUDE__SRC_LIB_PTHREAD_THREAD_H_
|
#define _INCLUDE__SRC_LIB_PTHREAD_THREAD_H_
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
|
#include <libc/component.h>
|
||||||
#include <util/reconstructible.h>
|
#include <util/reconstructible.h>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
@ -50,10 +51,8 @@ extern "C" {
|
||||||
|
|
||||||
struct pthread_attr
|
struct pthread_attr
|
||||||
{
|
{
|
||||||
pthread_t pthread;
|
void *stack_addr { nullptr };
|
||||||
size_t stack_size;
|
size_t stack_size { Libc::Component::stack_size() };
|
||||||
|
|
||||||
pthread_attr() : pthread(0), stack_size(0) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -107,15 +106,21 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
void *_arg;
|
void *_arg;
|
||||||
bool _exiting = false;
|
bool _exiting = false;
|
||||||
|
|
||||||
|
void *&_stack_addr;
|
||||||
|
size_t &_stack_size;
|
||||||
|
|
||||||
enum { WEIGHT = Genode::Cpu_session::Weight::DEFAULT_WEIGHT };
|
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,
|
Thread_object(char const *name, size_t stack_size,
|
||||||
Genode::Cpu_session *cpu,
|
Genode::Cpu_session *cpu,
|
||||||
Genode::Affinity::Location location,
|
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),
|
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;
|
void entry() override;
|
||||||
|
@ -144,6 +149,10 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
pthread_registry().insert(this);
|
pthread_registry().insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* attributes for 'pthread_attr_get_np()' */
|
||||||
|
void *_stack_addr = nullptr;
|
||||||
|
size_t _stack_size = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +163,8 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
Genode::Cpu_session * cpu, Genode::Affinity::Location location)
|
Genode::Cpu_session * cpu, Genode::Affinity::Location location)
|
||||||
:
|
:
|
||||||
_thread(_construct_thread_object(name, stack_size, cpu, location,
|
_thread(_construct_thread_object(name, stack_size, cpu, location,
|
||||||
start_routine, arg))
|
start_routine, arg,
|
||||||
|
_stack_addr, _stack_size))
|
||||||
{
|
{
|
||||||
_associate_thread_with_pthread();
|
_associate_thread_with_pthread();
|
||||||
}
|
}
|
||||||
|
@ -167,6 +177,11 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
:
|
:
|
||||||
_thread(existing_thread)
|
_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();
|
_associate_thread_with_pthread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,8 +198,8 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
|
|
||||||
void join() { _thread.join(); }
|
void join() { _thread.join(); }
|
||||||
|
|
||||||
void *stack_top() const { return _thread.stack_top(); }
|
void *stack_addr() const { return _stack_addr; }
|
||||||
void *stack_base() const { return _thread.stack_base(); }
|
size_t stack_size() const { return _stack_size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__SRC_LIB_PTHREAD_THREAD_H_ */
|
#endif /* _INCLUDE__SRC_LIB_PTHREAD_THREAD_H_ */
|
||||||
|
|
|
@ -22,8 +22,6 @@
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
enum { STACK_SIZE=64*1024 };
|
|
||||||
|
|
||||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||||
void *(*start_routine) (void *), void *arg)
|
void *(*start_routine) (void *), void *arg)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +29,8 @@ extern "C"
|
||||||
pthread_cleanup();
|
pthread_cleanup();
|
||||||
|
|
||||||
size_t const stack_size = (attr && *attr && (*attr)->stack_size)
|
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_t thread_obj = new pthread(start_routine, arg, stack_size,
|
||||||
"pthread", nullptr,
|
"pthread", nullptr,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user