4048494ce4
* Implemented automatic syscall restarts: - A syscall can indicate that it has been interrupted and can be restarted by setting a respective bit in thread::flags. It can store parameters it wants to be preserved for the restart in thread::syscall_restart::parameters. Another thread::flags bit indicates whether it has been restarted. - handle_signals() clears the restart flag, if the handled signal has a handler function installed and SA_RESTART is not set. Another thread flag (THREAD_FLAGS_DONT_RESTART_SYSCALL) can prevent syscalls from being restarted, even if they could be (not used yet, but we might want to use it in resume_thread(), so that we stay behaviorally compatible with BeOS). - The architecture specific syscall handler restarts the syscall, if the restart flag is set. Implemented for x86 only. - Added some support functions in the private <syscall_restart.h> to simplify the syscall restart code in the syscalls. - Adjusted all syscalls that can potentially be restarted accordingly. - _user_ioctl() sets new thread flag THREAD_FLAGS_IOCTL_SYSCALL while calling the underlying FS's/driver's hook, so that syscall restarts can also be supported there. * thread_at_kernel_exit() invokes handle_signals() in a loop now, as long as the latter indicates that the thread shall be suspended, so that after waking up signals received in the meantime will be handled before the thread returns to userland. Adjusted handle_signals() accordingly -- when encountering a suspending signal we don't check for further signals. * Fixed sigsuspend(): Suspending the thread and rescheduling doesn't result in the correct behavior. Instead we employ a temporary condition variable and interruptably wait on it. The POSIX test suite test passes, now. * Made the switch_sem[_etc]() behavior on interruption consistent. Depending on when the signal arrived (before the call or when already waiting) the first semaphore would or wouldn't be released. Now we consistently release it. * Refactored _user_{read,write}[v]() syscalls. Use a common function for either pair. The iovec version doesn't fail anymore, if anything could be read/written at all. It also checks whether a complete vector could be read/written, so that we won't skip data, if the underlying FS/driver couldn't read/write more ATM. * Some refactoring in the x86 syscall handler: The int 99 and sysenter handlers use a common subroutine to avoid code duplication. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23983 a95241bf-73f2-0310-859d-f6bbb57e9c96
59 lines
1.8 KiB
C
59 lines
1.8 KiB
C
/*
|
|
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
* Distributed under the terms of the NewOS License.
|
|
*/
|
|
#ifndef KERNEL_ARCH_THREAD_H
|
|
#define KERNEL_ARCH_THREAD_H
|
|
|
|
|
|
#include <thread_types.h>
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
status_t arch_thread_init(struct kernel_args *args);
|
|
status_t arch_team_init_team_struct(struct team *t, bool kernel);
|
|
status_t arch_thread_init_thread_struct(struct thread *t);
|
|
status_t arch_thread_init_tls(struct thread *thread);
|
|
void arch_thread_context_switch(struct thread *t_from, struct thread *t_to);
|
|
status_t arch_thread_init_kthread_stack(struct thread *t,
|
|
int (*start_func)(void), void (*entry_func)(void), void (*exit_func)(void));
|
|
void arch_thread_dump_info(void *info);
|
|
status_t arch_thread_enter_userspace(struct thread *t, addr_t entry,
|
|
void *args1, void *args2);
|
|
void arch_thread_switch_kstack_and_call(struct thread *t, addr_t new_kstack,
|
|
void (*func)(void *), void *arg);
|
|
|
|
// ToDo: doing this this way is an ugly hack - please fix me!
|
|
// (those functions are "static inline" for x86 - since
|
|
// "extern inline" doesn't work for "gcc -g"...)
|
|
#ifndef ARCH_x86
|
|
struct thread *arch_thread_get_current_thread(void);
|
|
void arch_thread_set_current_thread(struct thread *t);
|
|
#endif
|
|
|
|
bool arch_on_signal_stack(struct thread *thread);
|
|
status_t arch_setup_signal_frame(struct thread *t, struct sigaction *sa,
|
|
int signal, int signalMask);
|
|
int64 arch_restore_signal_frame(void);
|
|
|
|
void arch_store_fork_frame(struct arch_fork_arg *arg);
|
|
void arch_restore_fork_frame(struct arch_fork_arg *arg);
|
|
|
|
#define arch_syscall_64_bit_return_value()
|
|
// overridden by architectures that need special handling
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
// for any inline overrides
|
|
#include <arch_thread.h>
|
|
|
|
#endif /* KERNEL_ARCH_THREAD_H */
|