mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-06 18:48:35 +00:00
parent
d6f89b285d
commit
a891b3832c
@ -112,7 +112,7 @@ namespace Libc {
|
|||||||
/**
|
/**
|
||||||
* Pthread/semaphore support
|
* Pthread/semaphore support
|
||||||
*/
|
*/
|
||||||
void init_pthread_support(Suspend &, Resume &, Timer_accessor &);
|
void init_pthread_support(Monitor &, Timer_accessor &);
|
||||||
void init_pthread_support(Genode::Cpu_session &, Xml_node);
|
void init_pthread_support(Genode::Cpu_session &, Xml_node);
|
||||||
void init_semaphore_support(Timer_accessor &);
|
void init_semaphore_support(Timer_accessor &);
|
||||||
|
|
||||||
|
@ -165,17 +165,7 @@ struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
|||||||
|
|
||||||
bool _exiting = false;
|
bool _exiting = false;
|
||||||
|
|
||||||
/*
|
Genode::Mutex _mutex { };
|
||||||
* The join blockade is needed because 'Libc::resume_all()' uses a
|
|
||||||
* 'Signal_transmitter' which holds a reference to a signal context
|
|
||||||
* capability, which needs to be released before the thread can be
|
|
||||||
* destroyed.
|
|
||||||
*
|
|
||||||
* Also, we cannot use 'Thread::join()', because it only
|
|
||||||
* returns when the thread entry function returns, which does not
|
|
||||||
* happen with 'pthread_cancel()'.
|
|
||||||
*/
|
|
||||||
Genode::Blockade _join_blockade;
|
|
||||||
|
|
||||||
/* return value for 'pthread_join()' */
|
/* return value for 'pthread_join()' */
|
||||||
void *_retval = PTHREAD_CANCELED;
|
void *_retval = PTHREAD_CANCELED;
|
||||||
@ -189,10 +179,12 @@ struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
|||||||
class Cleanup_handler : public List<Cleanup_handler>::Element
|
class Cleanup_handler : public List<Cleanup_handler>::Element
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void (*_routine)(void*);
|
void (*_routine)(void*);
|
||||||
void *_arg;
|
void *_arg;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Cleanup_handler(void (*routine)(void*), void *arg)
|
Cleanup_handler(void (*routine)(void*), void *arg)
|
||||||
: _routine(routine), _arg(arg) { }
|
: _routine(routine), _arg(arg) { }
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
|
|||||||
atexit(close_file_descriptors_on_exit);
|
atexit(close_file_descriptors_on_exit);
|
||||||
|
|
||||||
init_semaphore_support(_timer_accessor);
|
init_semaphore_support(_timer_accessor);
|
||||||
init_pthread_support(*this, *this, _timer_accessor);
|
init_pthread_support(*this, _timer_accessor);
|
||||||
init_pthread_support(env.cpu(), _pthread_config());
|
init_pthread_support(env.cpu(), _pthread_config());
|
||||||
|
|
||||||
_env.ep().register_io_progress_handler(*this);
|
_env.ep().register_io_progress_handler(*this);
|
||||||
|
@ -32,8 +32,7 @@
|
|||||||
#include <internal/init.h>
|
#include <internal/init.h>
|
||||||
#include <internal/kernel.h>
|
#include <internal/kernel.h>
|
||||||
#include <internal/pthread.h>
|
#include <internal/pthread.h>
|
||||||
#include <internal/resume.h>
|
#include <internal/monitor.h>
|
||||||
#include <internal/suspend.h>
|
|
||||||
#include <internal/time.h>
|
#include <internal/time.h>
|
||||||
#include <internal/timer.h>
|
#include <internal/timer.h>
|
||||||
|
|
||||||
@ -42,21 +41,28 @@ using namespace Libc;
|
|||||||
|
|
||||||
|
|
||||||
static Thread *_main_thread_ptr;
|
static Thread *_main_thread_ptr;
|
||||||
static Resume *_resume_ptr;
|
static Monitor *_monitor_ptr;
|
||||||
static Suspend *_suspend_ptr;
|
|
||||||
static Timer_accessor *_timer_accessor_ptr;
|
static Timer_accessor *_timer_accessor_ptr;
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_pthread_support(Suspend &suspend, Resume &resume,
|
void Libc::init_pthread_support(Monitor &monitor, Timer_accessor &timer_accessor)
|
||||||
Timer_accessor &timer_accessor)
|
|
||||||
{
|
{
|
||||||
_main_thread_ptr = Thread::myself();
|
_main_thread_ptr = Thread::myself();
|
||||||
_suspend_ptr = &suspend;
|
_monitor_ptr = &monitor;
|
||||||
_resume_ptr = &resume;
|
|
||||||
_timer_accessor_ptr = &timer_accessor;
|
_timer_accessor_ptr = &timer_accessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Libc::Monitor & monitor()
|
||||||
|
{
|
||||||
|
struct Missing_call_of_init_pthread_support : Genode::Exception { };
|
||||||
|
if (!_monitor_ptr)
|
||||||
|
throw Missing_call_of_init_pthread_support();
|
||||||
|
return *_monitor_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace { using Fn = Libc::Monitor::Function_result; }
|
||||||
|
|
||||||
/*************
|
/*************
|
||||||
** Pthread **
|
** Pthread **
|
||||||
*************/
|
*************/
|
||||||
@ -74,47 +80,26 @@ void Libc::Pthread::Thread_object::entry()
|
|||||||
|
|
||||||
void Libc::Pthread::join(void **retval)
|
void Libc::Pthread::join(void **retval)
|
||||||
{
|
{
|
||||||
struct Check : Suspend_functor
|
Genode::Mutex::Guard guard(_mutex);
|
||||||
{
|
|
||||||
bool retry { false };
|
|
||||||
|
|
||||||
Pthread &_thread;
|
monitor().monitor(_mutex, [&] {
|
||||||
|
if (!_exiting)
|
||||||
Check(Pthread &thread) : _thread(thread) { }
|
return Fn::INCOMPLETE;
|
||||||
|
|
||||||
bool suspend() override
|
|
||||||
{
|
|
||||||
retry = !_thread._exiting;
|
|
||||||
return retry;
|
|
||||||
}
|
|
||||||
} check(*this);
|
|
||||||
|
|
||||||
struct Missing_call_of_init_pthread_support : Exception { };
|
|
||||||
if (!_suspend_ptr)
|
|
||||||
throw Missing_call_of_init_pthread_support();
|
|
||||||
|
|
||||||
do {
|
|
||||||
_suspend_ptr->suspend(check);
|
|
||||||
} while (check.retry);
|
|
||||||
|
|
||||||
_join_blockade.block();
|
|
||||||
|
|
||||||
if (retval)
|
if (retval)
|
||||||
*retval = _retval;
|
*retval = _retval;
|
||||||
|
return Fn::COMPLETE;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Libc::Pthread::cancel()
|
void Libc::Pthread::cancel()
|
||||||
{
|
{
|
||||||
|
Genode::Mutex::Guard guard(_mutex);
|
||||||
|
|
||||||
_exiting = true;
|
_exiting = true;
|
||||||
|
|
||||||
struct Missing_call_of_init_pthread_support : Exception { };
|
monitor().trigger_monitor_examination();
|
||||||
if (!_resume_ptr)
|
|
||||||
throw Missing_call_of_init_pthread_support();
|
|
||||||
|
|
||||||
_resume_ptr->resume_all();
|
|
||||||
|
|
||||||
_join_blockade.wakeup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -278,7 +263,7 @@ class pthread_mutex : Genode::Noncopyable
|
|||||||
/**
|
/**
|
||||||
* Enqueue current context as applicant for mutex
|
* Enqueue current context as applicant for mutex
|
||||||
*
|
*
|
||||||
* Return true if mutex was aquired, false on timeout expiration.
|
* Return true if mutex was acquired, false on timeout expiration.
|
||||||
*/
|
*/
|
||||||
bool _apply_for_mutex(pthread_t thread, Libc::uint64_t timeout_ms)
|
bool _apply_for_mutex(pthread_t thread, Libc::uint64_t timeout_ms)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user