From 914b10c17eac8d7d5a76c4eda2b8ac82a61bbf69 Mon Sep 17 00:00:00 2001 From: Jessica Hamilton Date: Fri, 11 Mar 2022 23:49:53 +0000 Subject: [PATCH] wait_for_thread_etc: expose as syscall/make public. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * This will be needed for the following commit that implements `pthread_tryjoin_np` and `pthread_timedjoin_np`. Change-Id: Idccb1aa588d6d10825294d14925d9bd046b65f19 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5098 Tested-by: Commit checker robot Reviewed-by: Jérôme Duval Reviewed-by: Adrien Destugues --- headers/os/kernel/OS.h | 2 ++ headers/private/kernel/thread.h | 4 ++-- headers/private/system/syscalls.h | 2 ++ src/system/kernel/thread.cpp | 22 +++++++++++++++++++ src/system/libroot/os/thread.c | 7 ++++++ src/system/libroot/stubbed/libroot_stubs.c | 1 + .../libroot/stubbed/libroot_stubs_legacy.c | 1 + 7 files changed, 37 insertions(+), 2 deletions(-) diff --git a/headers/os/kernel/OS.h b/headers/os/kernel/OS.h index 6d3a34c5db..cfae3581b4 100644 --- a/headers/os/kernel/OS.h +++ b/headers/os/kernel/OS.h @@ -341,6 +341,8 @@ extern status_t rename_thread(thread_id thread, const char *newName); extern status_t set_thread_priority(thread_id thread, int32 newPriority); extern void exit_thread(status_t status); extern status_t wait_for_thread(thread_id thread, status_t *returnValue); +extern status_t wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, + status_t *_returnCode); extern status_t on_exit_thread(void (*callback)(void *), void *data); extern thread_id find_thread(const char *name); diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h index a352f2eae0..771d650d1c 100644 --- a/headers/private/kernel/thread.h +++ b/headers/private/kernel/thread.h @@ -127,8 +127,6 @@ thread_id thread_create_thread(const ThreadCreationAttributes& attributes, thread_id spawn_kernel_thread_etc(thread_func, const char *name, int32 priority, void *args, team_id team); -status_t wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, - status_t *_returnCode); status_t select_thread(int32 object, struct select_info *info, bool kernel); status_t deselect_thread(int32 object, struct select_info *info, bool kernel); @@ -147,6 +145,8 @@ status_t _user_resume_thread(thread_id thread); status_t _user_rename_thread(thread_id thread, const char *name); thread_id _user_spawn_thread(struct thread_creation_attributes* attributes); status_t _user_wait_for_thread(thread_id id, status_t *_returnCode); +status_t _user_wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, + status_t *_returnCode); status_t _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags, bigtime_t* _remainingTime); status_t _user_kill_thread(thread_id thread); diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 94e95cbd42..16ad7a2fe1 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -167,6 +167,8 @@ extern status_t _kern_cancel_thread(thread_id threadID, extern void _kern_thread_yield(void); extern status_t _kern_wait_for_thread(thread_id thread, status_t *_returnCode); +extern status_t _kern_wait_for_thread_etc(thread_id thread, uint32 flags, + bigtime_t timeout, status_t *_returnCode); extern bool _kern_has_data(thread_id thread); extern status_t _kern_send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize); diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index bea34448da..db6f4fe3c3 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -3676,6 +3676,28 @@ _user_wait_for_thread(thread_id id, status_t *userReturnCode) } +status_t +_user_wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, status_t *userReturnCode) +{ + status_t returnCode; + status_t status; + + if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode)) + return B_BAD_ADDRESS; + + syscall_restart_handle_timeout_pre(flags, timeout); + + status = wait_for_thread_etc(id, flags | B_CAN_INTERRUPT, timeout, &returnCode); + + if (status == B_OK && userReturnCode != NULL + && user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) { + return B_BAD_ADDRESS; + } + + return syscall_restart_handle_timeout_post(status, timeout); +} + + bool _user_has_data(thread_id thread) { diff --git a/src/system/libroot/os/thread.c b/src/system/libroot/os/thread.c index c278e660f1..9c1cfa0ee8 100644 --- a/src/system/libroot/os/thread.c +++ b/src/system/libroot/os/thread.c @@ -183,6 +183,13 @@ wait_for_thread(thread_id thread, status_t *_returnCode) } +status_t +wait_for_thread_etc(thread_id thread, uint32 flags, bigtime_t timeout, status_t *_returnCode) +{ + return _kern_wait_for_thread_etc(thread, flags, timeout, _returnCode); +} + + status_t on_exit_thread(void (*callback)(void *), void *data) { diff --git a/src/system/libroot/stubbed/libroot_stubs.c b/src/system/libroot/stubbed/libroot_stubs.c index 6fcce6135c..5cd88a1b25 100644 --- a/src/system/libroot/stubbed/libroot_stubs.c +++ b/src/system/libroot/stubbed/libroot_stubs.c @@ -2894,6 +2894,7 @@ void wait_for_debugger() {} void wait_for_objects() {} void wait_for_objects_etc() {} void wait_for_thread() {} +void wait_for_thread_etc() {} void waitid() {} void waitpid() {} void wcpcpy() {} diff --git a/src/system/libroot/stubbed/libroot_stubs_legacy.c b/src/system/libroot/stubbed/libroot_stubs_legacy.c index 4c8cd83e95..ec0ad5d566 100644 --- a/src/system/libroot/stubbed/libroot_stubs_legacy.c +++ b/src/system/libroot/stubbed/libroot_stubs_legacy.c @@ -2841,6 +2841,7 @@ void wait_for_debugger() {} void wait_for_objects() {} void wait_for_objects_etc() {} void wait_for_thread() {} +void wait_for_thread_etc() {} void waitid() {} void waitpid() {} void wcpcpy() {}