* Made i386_get_current_iframe() static again, since it wasn't what was
needed to get the topmost user iframe. Added i386_get_user_iframe() for exactly that purpose. * Added reinitialization of user debugging for the new thread when switching the context. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11523 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c8d7534e5d
commit
98b14f8a6a
@ -17,7 +17,7 @@ extern "C" {
|
||||
|
||||
void i386_push_iframe(struct thread *t, struct iframe *frame);
|
||||
void i386_pop_iframe(struct thread *t);
|
||||
struct iframe *i386_get_current_iframe(void);
|
||||
struct iframe *i386_get_user_iframe(void);
|
||||
|
||||
void i386_return_from_signal();
|
||||
void i386_end_return_from_signal();
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <thread.h>
|
||||
#include <arch/thread.h>
|
||||
#include <arch/user_debugger.h>
|
||||
#include <arch_cpu.h>
|
||||
#include <kernel.h>
|
||||
#include <debug.h>
|
||||
@ -78,7 +79,7 @@ i386_pop_iframe(struct thread *thread)
|
||||
* from standard kernel threads.
|
||||
*/
|
||||
|
||||
struct iframe *
|
||||
static struct iframe *
|
||||
i386_get_current_iframe(void)
|
||||
{
|
||||
struct thread *thread = thread_get_current_thread();
|
||||
@ -88,6 +89,28 @@ i386_get_current_iframe(void)
|
||||
}
|
||||
|
||||
|
||||
/** \brief Returns the current thread's topmost (i.e. most recent)
|
||||
* userland->kernel transition iframe (usually the first one, save for
|
||||
* interrupts in signal handlers).
|
||||
* \return The iframe, or \c NULL, if there is no such iframe (e.g. when
|
||||
* the thread is a kernel thread).
|
||||
*/
|
||||
struct iframe *
|
||||
i386_get_user_iframe(void)
|
||||
{
|
||||
struct thread *thread = thread_get_current_thread();
|
||||
int i;
|
||||
|
||||
for (i = thread->arch_info.iframe_ptr - 1; i >= 0; i--) {
|
||||
struct iframe *frame = thread->arch_info.iframes[i];
|
||||
if (frame->cs == USER_CODE_SEG)
|
||||
return frame;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
set_fs_register(uint32 segment)
|
||||
{
|
||||
@ -247,6 +270,11 @@ arch_thread_context_switch(struct thread *t_from, struct thread *t_to)
|
||||
if (((uint32)new_pgdir % B_PAGE_SIZE) != 0)
|
||||
panic("arch_thread_context_switch: bad pgdir 0x%lx\n", new_pgdir);
|
||||
|
||||
// reinit debugging; necessary, if the thread was preempted after
|
||||
// initializing debugging before returning to userland
|
||||
if (t_to->team->aspace != NULL)
|
||||
i386_reinit_user_debug_after_context_switch(t_to);
|
||||
|
||||
i386_fsave_swap(t_from->arch_info.fpu_state, t_to->arch_info.fpu_state);
|
||||
i386_context_switch(&t_from->arch_info, &t_to->arch_info, (addr_t)new_pgdir);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user