Enable 'signal' test on 'base_hw'.

This commit is contained in:
Martin Stein 2012-10-09 15:41:40 +02:00 committed by Norman Feske
parent 97dd1d57cf
commit 9dba710989
7 changed files with 109 additions and 30 deletions

View File

@ -35,6 +35,7 @@ namespace Kernel
/* execution control */
NEW_THREAD = 1,
DELETE_THREAD = 24,
START_THREAD = 2,
PAUSE_THREAD = 3,
RESUME_THREAD = 4,
@ -134,12 +135,23 @@ namespace Kernel
* \retval >0 ID of the new thread
* \retval 0 if no new thread was created
*
* Restricted to core threads. Regaining of the supplied memory is not
* supported by now.
* Restricted to core threads. Regaining of the supplied memory can be done
* through 'delete_thread'.
*/
inline int new_thread(void * const dst, Genode::Platform_thread * const pt)
{ return syscall(NEW_THREAD, (Syscall_arg)dst, (Syscall_arg)pt); }
/**
* Delete an existing thread
*
* \param id kernel name of the targeted thread
*
* Restricted to core threads. After calling this, the memory that was
* granted beforehand by 'new_thread' to kernel for managing this thread
* is freed again.
*/
inline void delete_thread(unsigned thread_id) {
syscall(DELETE_THREAD, (Syscall_arg)thread_id); }
/**
* Start thread with a given context and let it participate in CPU scheduling

View File

@ -50,7 +50,17 @@ void Thread_base::_init_platform_thread() { }
void Thread_base::_deinit_platform_thread()
{ env()->cpu_session()->kill_thread(_thread_cap); }
{
/* detach UTCB */
size_t const size = sizeof(_context->utcb);
addr_t utcb = Context_allocator::addr_to_base(_context) +
Native_config::context_virtual_size() - size -
Native_config::context_area_virtual_base();
env_context_area_rm_session()->detach(utcb);
/* destroy object at the CPU session */
env()->cpu_session()->kill_thread(_thread_cap);
}
void Thread_base::start()

View File

@ -31,8 +31,6 @@ namespace Genode {
class Rm_client;
class Platform_thread;
size_t kernel_thread_size();
/**
* Userland interface for the management of kernel thread-objects
*/
@ -51,12 +49,18 @@ namespace Genode {
Software_tlb * _software_tlb;
Ram_dataspace_capability _utcb;
char _name[NAME_MAX_LEN];
void * _kernel_thread;
/**
* Common construction part
*/
void _init();
/*
* Check if this thread will attach its UTCB by itself
*/
bool _attaches_utcb_by_itself();
public:
/**
@ -73,6 +77,11 @@ namespace Genode {
Platform_thread(const char * name, unsigned int priority,
addr_t utcb);
/**
* Destructor
*/
~Platform_thread();
/**
* Join PD identified by 'pd_id'
*
@ -124,15 +133,6 @@ namespace Genode {
return -1;
};
/**
* Destructor
*/
~Platform_thread()
{
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
while (1) ;
}
/**
* Return unique identification of this thread as faulter
*/

View File

@ -697,8 +697,17 @@ namespace Kernel
* Ensures that we have a unique ID and
* can be found through the static object pool.
*/
Object() : Pool::Entry(_id_alloc()->alloc())
{ pool()->insert(static_cast<T *>(this)); }
Object() : Pool::Entry(_id_alloc()->alloc()) {
pool()->insert(static_cast<T *>(this)); }
/**
* Destructor
*/
~Object()
{
pool()->remove(static_cast<T *>(this));
_id_alloc()->free(Pool::Entry::id());
}
};
/**
@ -1539,6 +1548,23 @@ namespace Kernel
user->user_arg_0((Syscall_ret)t->id());
}
/**
* Do specific syscall for 'user', for details see 'syscall.h'
*/
void do_delete_thread(Thread * const user)
{
/* check permissions */
assert(user->pd_id() == core_id());
/* get targeted thread */
unsigned thread_id = (unsigned)user->user_arg_1();
Thread * const thread = Thread::pool()->object(thread_id);
assert(thread);
/* destroy thread */
thread->~Thread();
}
/**
* Do specific syscall for 'user', for details see 'syscall.h'
@ -1901,6 +1927,7 @@ namespace Kernel
/* 21 */ do_new_signal_context,
/* 22 */ do_await_signal,
/* 23 */ do_submit_signal,
/* 24 */ do_delete_thread,
};
enum { MAX_SYSCALL = sizeof(handle_sysc)/sizeof(handle_sysc[0]) - 1 };

View File

@ -21,6 +21,44 @@ using namespace Genode;
namespace Kernel { unsigned core_id(); }
bool Platform_thread::_attaches_utcb_by_itself()
{
/*
* If this is a main thread outside of core it'll not manage its
* virtual context area by itself, as it is done for other threads
* through a sub RM-session.
*/
return _pd_id == Kernel::core_id() || !_main_thread;
}
Platform_thread::~Platform_thread()
{
/* detach UTCB if main thread outside core */
if (!_attaches_utcb_by_itself()) {
assert(_rm_client);
Rm_session_component * const rm = _rm_client->member_rm_session();
rm->detach(_virt_utcb);
}
/* free UTCB */
if (_pd_id == Kernel::core_id()) {
Range_allocator * const ram = platform()->ram_alloc();
ram->free((void *)_phys_utcb, sizeof(Native_utcb));
} else {
Ram_session_component * const ram =
dynamic_cast<Ram_session_component *>(core_env()->ram_session());
assert(ram);
ram->free(_utcb);
}
/* destroy object at the kernel */
Kernel::delete_thread(_id);
/* free kernel object space */
Range_allocator * ram = platform()->ram_alloc();
ram->free(&_kernel_thread, Kernel::thread_size());
}
Platform_thread::Platform_thread(const char * name,
Thread_base * const thread_base,
unsigned long const stack_size,
@ -85,10 +123,9 @@ int Platform_thread::join_pd(unsigned long const pd_id,
void Platform_thread::_init()
{
/* create kernel object */
void * kernel_thread;
Range_allocator * ram = platform()->ram_alloc();
assert(ram->alloc(Kernel::thread_size(), &kernel_thread));
_id = Kernel::new_thread(kernel_thread, this);
assert(ram->alloc(Kernel::thread_size(), &_kernel_thread));
_id = Kernel::new_thread(_kernel_thread, this);
assert(_id);
}
@ -98,13 +135,8 @@ int Platform_thread::start(void * ip, void * sp, unsigned int cpu_no)
/* check thread attributes */
assert(_pd_id);
/*
* If this is a main thread outside of core it'll not manage its
* virtual context area by itself, as it is done for other threads
* through a sub RM-session. Therefore we attach the UTCB to its
* address space before it gets started.
*/
if (_pd_id != Kernel::core_id() && _main_thread)
/* attach UTCB if the thread can't do this by itself */
if (!_attaches_utcb_by_itself())
{
/*
* Declare page aligned virtual UTCB outside the context area.

View File

@ -13,6 +13,7 @@ install_config {
<service name="PD"/>
<service name="IRQ"/>
<service name="IO_PORT"/>
<service name="IO_MEM"/>
<service name="SIGNAL"/>
<service name="LOG"/>
</parent-provides>

View File

@ -149,10 +149,7 @@ namespace Timer {
_session_cap(_entrypoint.manage(this)),
_barrier(Genode::Cancelable_lock::LOCKED),
_wake_up_alarm(&_barrier)
{
PDBG("created new session component, _session_cap.valid=%d",
_session_cap.valid());
}
{ }
/**
* Destructor