mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-11 15:33:04 +00:00
parent
75ba52a52b
commit
e0ca250232
@ -976,6 +976,7 @@ _ZN4Libc7suspendERNS_15Suspend_functorEm T
|
|||||||
_Z16pthread_registryv T
|
_Z16pthread_registryv T
|
||||||
_ZN4Libc16Pthread_registry6insertERNS_7PthreadE T
|
_ZN4Libc16Pthread_registry6insertERNS_7PthreadE T
|
||||||
_ZN4Libc16Pthread_registry6removeERNS_7PthreadE T
|
_ZN4Libc16Pthread_registry6removeERNS_7PthreadE T
|
||||||
|
_ZN4Libc16Pthread_registry7cleanupEPNS_7PthreadE T
|
||||||
_ZN4Libc16Pthread_registry8containsERNS_7PthreadE T
|
_ZN4Libc16Pthread_registry8containsERNS_7PthreadE T
|
||||||
_ZN4Libc14pthread_createEPP7pthreadPFPvS3_ES3_mPKcPN6Genode11Cpu_sessionENS8_8Affinity8LocationE T
|
_ZN4Libc14pthread_createEPP7pthreadPFPvS3_ES3_mPKcPN6Genode11Cpu_sessionENS8_8Affinity8LocationE T
|
||||||
_ZN4Libc14pthread_createEPP7pthreadRN6Genode6ThreadE T
|
_ZN4Libc14pthread_createEPP7pthreadRN6Genode6ThreadE T
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/blockade.h>
|
#include <base/blockade.h>
|
||||||
|
#include <base/sleep.h>
|
||||||
#include <libc/allocator.h>
|
#include <libc/allocator.h>
|
||||||
#include <libc/component.h>
|
#include <libc/component.h>
|
||||||
#include <util/reconstructible.h>
|
#include <util/reconstructible.h>
|
||||||
@ -51,6 +52,9 @@ class Libc::Pthread_registry
|
|||||||
|
|
||||||
Pthread *_array[MAX_NUM_PTHREADS] = { 0 };
|
Pthread *_array[MAX_NUM_PTHREADS] = { 0 };
|
||||||
|
|
||||||
|
/* thread to be destroyed on next 'cleanup()' call */
|
||||||
|
Pthread *_cleanup_thread { nullptr };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void insert(Pthread &thread);
|
void insert(Pthread &thread);
|
||||||
@ -58,6 +62,9 @@ class Libc::Pthread_registry
|
|||||||
void remove(Pthread &thread);
|
void remove(Pthread &thread);
|
||||||
|
|
||||||
bool contains(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
|
struct pthread_attr
|
||||||
{
|
{
|
||||||
void *stack_addr { nullptr };
|
void *stack_addr { nullptr };
|
||||||
size_t stack_size { Libc::Component::stack_size() };
|
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()
|
void _associate_thread_with_pthread()
|
||||||
{
|
{
|
||||||
Thread::Tls::Base::tls(_thread, *this);
|
Thread::Tls::Base::tls(_thread, *this);
|
||||||
|
pthread_registry().cleanup();
|
||||||
pthread_registry().insert(*this);
|
pthread_registry().insert(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +183,8 @@ struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
|||||||
*/
|
*/
|
||||||
Genode::Mutex _mutex { };
|
Genode::Mutex _mutex { };
|
||||||
|
|
||||||
|
Genode::Blockade _detach_blockade;
|
||||||
|
|
||||||
/* return value for 'pthread_join()' */
|
/* return value for 'pthread_join()' */
|
||||||
void *_retval = PTHREAD_CANCELED;
|
void *_retval = PTHREAD_CANCELED;
|
||||||
|
|
||||||
@ -243,17 +254,29 @@ struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
|||||||
|
|
||||||
void join(void **retval);
|
void join(void **retval);
|
||||||
|
|
||||||
|
int detach();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inform the thread calling 'pthread_join()' that this thread can be
|
* Inform the thread calling 'pthread_join()' that this thread can be
|
||||||
* destroyed.
|
* destroyed.
|
||||||
*/
|
*/
|
||||||
void cancel();
|
void cancel();
|
||||||
|
|
||||||
void exit(void *retval)
|
void exit(void *retval) __attribute__((noreturn))
|
||||||
{
|
{
|
||||||
while (cleanup_pop(1)) { }
|
while (cleanup_pop(1)) { }
|
||||||
_retval = retval;
|
_retval = retval;
|
||||||
cancel();
|
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; }
|
void *stack_addr() const { return _stack_addr; }
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
#include <base/sleep.h>
|
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
#include <libc/allocator.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()
|
void Libc::Pthread::cancel()
|
||||||
{
|
{
|
||||||
Genode::Mutex::Guard guard(_mutex);
|
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()
|
Libc::Pthread_registry &pthread_registry()
|
||||||
{
|
{
|
||||||
static Libc::Pthread_registry instance;
|
static Libc::Pthread_registry instance;
|
||||||
@ -558,7 +578,6 @@ extern "C" {
|
|||||||
void pthread_exit(void *value_ptr)
|
void pthread_exit(void *value_ptr)
|
||||||
{
|
{
|
||||||
pthread_self()->exit(value_ptr);
|
pthread_self()->exit(value_ptr);
|
||||||
sleep_forever();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typeof(pthread_exit) _pthread_exit
|
typeof(pthread_exit) _pthread_exit
|
||||||
@ -614,6 +633,34 @@ extern "C" {
|
|||||||
pthread_t __sys_thr_self(void);
|
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)
|
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
|
||||||
{
|
{
|
||||||
if (!attr || !*attr)
|
if (!attr || !*attr)
|
||||||
@ -692,6 +739,15 @@ extern "C" {
|
|||||||
__attribute__((alias("pthread_equal")));
|
__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,
|
void __pthread_cleanup_push_imp(void (*routine)(void*), void *arg,
|
||||||
struct _pthread_cleanup_info *)
|
struct _pthread_cleanup_info *)
|
||||||
{
|
{
|
||||||
|
@ -141,9 +141,15 @@ extern "C"
|
|||||||
if (_verbose)
|
if (_verbose)
|
||||||
Genode::log("create ", pthread_name, " -> cpu ", cpu);
|
Genode::log("create ", pthread_name, " -> cpu ", cpu);
|
||||||
|
|
||||||
return Libc::pthread_create(thread, start_routine, arg, stack_size,
|
int result = Libc::pthread_create(thread, start_routine, arg, stack_size,
|
||||||
pthread_name.string(), _cpu_session,
|
pthread_name.string(), _cpu_session,
|
||||||
location);
|
location);
|
||||||
|
|
||||||
|
if ((result == 0) && attr && *attr &&
|
||||||
|
((*attr)->detach_state == PTHREAD_CREATE_DETACHED))
|
||||||
|
pthread_detach(*thread);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
typeof(pthread_create) _pthread_create
|
typeof(pthread_create) _pthread_create
|
||||||
|
Loading…
Reference in New Issue
Block a user