mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
parent
75ba52a52b
commit
e0ca250232
@ -976,6 +976,7 @@ _ZN4Libc7suspendERNS_15Suspend_functorEm T
|
||||
_Z16pthread_registryv T
|
||||
_ZN4Libc16Pthread_registry6insertERNS_7PthreadE T
|
||||
_ZN4Libc16Pthread_registry6removeERNS_7PthreadE T
|
||||
_ZN4Libc16Pthread_registry7cleanupEPNS_7PthreadE T
|
||||
_ZN4Libc16Pthread_registry8containsERNS_7PthreadE T
|
||||
_ZN4Libc14pthread_createEPP7pthreadPFPvS3_ES3_mPKcPN6Genode11Cpu_sessionENS8_8Affinity8LocationE T
|
||||
_ZN4Libc14pthread_createEPP7pthreadRN6Genode6ThreadE T
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/blockade.h>
|
||||
#include <base/sleep.h>
|
||||
#include <libc/allocator.h>
|
||||
#include <libc/component.h>
|
||||
#include <util/reconstructible.h>
|
||||
@ -51,6 +52,9 @@ class Libc::Pthread_registry
|
||||
|
||||
Pthread *_array[MAX_NUM_PTHREADS] = { 0 };
|
||||
|
||||
/* thread to be destroyed on next 'cleanup()' call */
|
||||
Pthread *_cleanup_thread { nullptr };
|
||||
|
||||
public:
|
||||
|
||||
void insert(Pthread &thread);
|
||||
@ -58,6 +62,9 @@ class Libc::Pthread_registry
|
||||
void remove(Pthread &thread);
|
||||
|
||||
bool contains(Pthread &thread);
|
||||
|
||||
/* destroy '_cleanup_thread' and register another one if given */
|
||||
void cleanup(Pthread *new_cleanup_thread = nullptr);
|
||||
};
|
||||
|
||||
|
||||
@ -68,8 +75,9 @@ extern "C" {
|
||||
|
||||
struct pthread_attr
|
||||
{
|
||||
void *stack_addr { nullptr };
|
||||
size_t stack_size { Libc::Component::stack_size() };
|
||||
void *stack_addr { nullptr };
|
||||
size_t stack_size { Libc::Component::stack_size() };
|
||||
int detach_state { PTHREAD_CREATE_JOINABLE };
|
||||
};
|
||||
|
||||
/*
|
||||
@ -160,6 +168,7 @@ struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
||||
void _associate_thread_with_pthread()
|
||||
{
|
||||
Thread::Tls::Base::tls(_thread, *this);
|
||||
pthread_registry().cleanup();
|
||||
pthread_registry().insert(*this);
|
||||
}
|
||||
|
||||
@ -174,6 +183,8 @@ struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
||||
*/
|
||||
Genode::Mutex _mutex { };
|
||||
|
||||
Genode::Blockade _detach_blockade;
|
||||
|
||||
/* return value for 'pthread_join()' */
|
||||
void *_retval = PTHREAD_CANCELED;
|
||||
|
||||
@ -243,17 +254,29 @@ struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
||||
|
||||
void join(void **retval);
|
||||
|
||||
int detach();
|
||||
|
||||
/*
|
||||
* Inform the thread calling 'pthread_join()' that this thread can be
|
||||
* destroyed.
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
void exit(void *retval)
|
||||
void exit(void *retval) __attribute__((noreturn))
|
||||
{
|
||||
while (cleanup_pop(1)) { }
|
||||
_retval = retval;
|
||||
cancel();
|
||||
|
||||
/*
|
||||
* Block until the thread is destroyed by 'pthread_join()' or
|
||||
* register the thread for destruction if it is in detached state.
|
||||
*/
|
||||
|
||||
_detach_blockade.block();
|
||||
|
||||
pthread_registry().cleanup(this);
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
void *stack_addr() const { return _stack_addr; }
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/thread.h>
|
||||
#include <util/list.h>
|
||||
#include <libc/allocator.h>
|
||||
@ -93,6 +92,13 @@ void Libc::Pthread::join(void **retval)
|
||||
}
|
||||
|
||||
|
||||
int Libc::Pthread::detach()
|
||||
{
|
||||
_detach_blockade.wakeup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Libc::Pthread::cancel()
|
||||
{
|
||||
Genode::Mutex::Guard guard(_mutex);
|
||||
@ -147,6 +153,20 @@ bool Libc::Pthread_registry::contains(Pthread &thread)
|
||||
}
|
||||
|
||||
|
||||
void Libc::Pthread_registry::cleanup(Pthread *new_cleanup_thread)
|
||||
{
|
||||
static Mutex cleanup_mutex;
|
||||
Mutex::Guard guard(cleanup_mutex);
|
||||
|
||||
if (_cleanup_thread) {
|
||||
Libc::Allocator alloc { };
|
||||
destroy(alloc, _cleanup_thread);
|
||||
}
|
||||
|
||||
_cleanup_thread = new_cleanup_thread;
|
||||
}
|
||||
|
||||
|
||||
Libc::Pthread_registry &pthread_registry()
|
||||
{
|
||||
static Libc::Pthread_registry instance;
|
||||
@ -558,7 +578,6 @@ extern "C" {
|
||||
void pthread_exit(void *value_ptr)
|
||||
{
|
||||
pthread_self()->exit(value_ptr);
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
typeof(pthread_exit) _pthread_exit
|
||||
@ -614,6 +633,34 @@ extern "C" {
|
||||
pthread_t __sys_thr_self(void);
|
||||
|
||||
|
||||
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
|
||||
{
|
||||
if (!attr || !*attr || !detachstate)
|
||||
return EINVAL;
|
||||
|
||||
*detachstate = (*attr)->detach_state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typeof(pthread_attr_getdetachstate) _pthread_attr_getdetachstate
|
||||
__attribute__((alias("pthread_attr_getdetachstate")));
|
||||
|
||||
|
||||
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
|
||||
{
|
||||
if (!attr || !*attr)
|
||||
return EINVAL;
|
||||
|
||||
(*attr)->detach_state = detachstate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typeof(pthread_attr_setdetachstate) _pthread_attr_setdetachstate
|
||||
__attribute__((alias("pthread_attr_setdetachstate")));
|
||||
|
||||
|
||||
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
|
||||
{
|
||||
if (!attr || !*attr)
|
||||
@ -692,6 +739,15 @@ extern "C" {
|
||||
__attribute__((alias("pthread_equal")));
|
||||
|
||||
|
||||
int pthread_detach(pthread_t thread)
|
||||
{
|
||||
return thread->detach();
|
||||
}
|
||||
|
||||
typeof(pthread_detach) _pthread_detach
|
||||
__attribute__((alias("pthread_detach")));
|
||||
|
||||
|
||||
void __pthread_cleanup_push_imp(void (*routine)(void*), void *arg,
|
||||
struct _pthread_cleanup_info *)
|
||||
{
|
||||
|
@ -141,9 +141,15 @@ extern "C"
|
||||
if (_verbose)
|
||||
Genode::log("create ", pthread_name, " -> cpu ", cpu);
|
||||
|
||||
return Libc::pthread_create(thread, start_routine, arg, stack_size,
|
||||
pthread_name.string(), _cpu_session,
|
||||
location);
|
||||
int result = Libc::pthread_create(thread, start_routine, arg, stack_size,
|
||||
pthread_name.string(), _cpu_session,
|
||||
location);
|
||||
|
||||
if ((result == 0) && attr && *attr &&
|
||||
((*attr)->detach_state == PTHREAD_CREATE_DETACHED))
|
||||
pthread_detach(*thread);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typeof(pthread_create) _pthread_create
|
||||
|
Loading…
Reference in New Issue
Block a user