From 779661154d2bc02c0be395a193951f12294a0093 Mon Sep 17 00:00:00 2001 From: yongyuan Date: Sun, 29 Sep 2024 22:37:13 +0800 Subject: [PATCH] multi-thread check Signed-off-by: yongyuan --- include/uv.h | 3 +++ src/threadpool.c | 11 ++++++++--- src/timer.c | 17 ++++++++++++++++- src/unix/async.c | 6 +++++- src/unix/core.c | 5 +++++ src/unix/loop.c | 3 +++ src/uv-common.c | 19 ++++++++++++++++++- src/uv-common.h | 13 +++++++++++++ 8 files changed, 71 insertions(+), 6 deletions(-) diff --git a/include/uv.h b/include/uv.h index 945c34e..41217cd 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1937,6 +1937,9 @@ struct uv_loop_s { void* data; /* Loop reference counting. */ unsigned int active_handles; +#if defined(USE_OHOS_DFX) && defined(__LP64__) + unsigned int thread_id; +#endif struct uv__queue handle_queue; union { void* unused; diff --git a/src/threadpool.c b/src/threadpool.c index edd724f..0e8c03b 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -678,6 +678,10 @@ void uv__work_done(uv_async_t* handle) { uv__queue_append(&lfields->wq_sub[i], &wq); } } + + if (loop->active_reqs > 1000) { + UV_LOGW("there are %{public}u tasks in loop thread", loop->active_reqs); + } #endif uv_mutex_unlock(&loop->wq_mutex); @@ -762,8 +766,9 @@ void uv__ffrt_work(ffrt_executor_task_t* data, ffrt_qos_t qos) #ifdef UV_STATISTIC uv__post_statistic_work(w, WORK_EXECUTING); #endif - uv_work_t* req = container_of(w, uv_work_t, work_req); + #ifdef ASYNC_STACKTRACE + uv_work_t* req = container_of(w, uv_work_t, work_req); LibuvSetStackId((uint64_t)req->reserved[3]); #endif w->work(w); @@ -778,8 +783,8 @@ void uv__ffrt_work(ffrt_executor_task_t* data, ffrt_qos_t qos) || !lfields->wq_sub[qos].next || !lfields->wq_sub[qos].prev) { rdunlock_closed_uv_loop_rwlock(); - UV_LOGE("uv_loop(%{public}zu:%{public}#x) in task(%p:%p) is invalid", - (size_t)loop, loop->magic, req->work_cb, req->after_work_cb); + UV_LOGE("uv_loop(%{public}zu:%{public}#x), task is invalid", + (size_t)loop, loop->magic); return; } diff --git a/src/timer.c b/src/timer.c index 35548b4..9ac00f9 100644 --- a/src/timer.c +++ b/src/timer.c @@ -59,6 +59,11 @@ static int timer_less_than(const struct heap_node* ha, int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { +#if defined(USE_OHOS_DFX) && defined(__LP64__) + if (uv__multithread_check(loop) != 0) { + uv__print_caller(__FUNCTION__); + } +#endif uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER); handle->timer_cb = NULL; handle->timeout = 0; @@ -72,7 +77,11 @@ int uv_timer_start(uv_timer_t* handle, uint64_t timeout, uint64_t repeat) { uint64_t clamped_timeout; - +#if defined(USE_OHOS_DFX) && defined(__LP64__) + if (uv__multithread_check(loop) != 0) { + uv__print_caller(__FUNCTION__); + } +#endif if (uv__is_closing(handle) || cb == NULL) return UV_EINVAL; @@ -107,6 +116,12 @@ int uv_timer_start(uv_timer_t* handle, int uv_timer_stop(uv_timer_t* handle) { +#if defined(USE_OHOS_DFX) && defined(__LP64__) + if (uv__multithread_check(loop) != 0) { + uv__print_caller(__FUNCTION__); + } +#endif + if (!uv__is_active(handle)) return 0; diff --git a/src/unix/async.c b/src/unix/async.c index dbc66d6..4a8e250 100644 --- a/src/unix/async.c +++ b/src/unix/async.c @@ -50,7 +50,11 @@ static int uv__async_start(uv_loop_t* loop); int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { int err; - +#if defined(USE_OHOS_DFX) && defined(__LP64__) + if (uv__multithread_check(loop) != 0) { + uv__print_caller(__FUNCTION__); + } +#endif err = uv__async_start(loop); if (err) return err; diff --git a/src/unix/core.c b/src/unix/core.c index ba7c8ce..215c407 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -146,6 +146,11 @@ uint64_t uv_hrtime(void) { void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { +#if defined(USE_OHOS_DFX) && defined(__LP64__) + if (uv__multithread_check(loop) != 0) { + uv__print_caller(__FUNCTION__); + } +#endif assert(!uv__is_closing(handle)); handle->flags |= UV_HANDLE_CLOSING; diff --git a/src/unix/loop.c b/src/unix/loop.c index 2cb896a..c898f54 100644 --- a/src/unix/loop.c +++ b/src/unix/loop.c @@ -66,6 +66,9 @@ int uv_loop_init(uv_loop_t* loop) { uv__queue_init(&loop->prepare_handles); uv__queue_init(&loop->handle_queue); +#if defined(USE_OHOS_DFX) && defined(__LP64__) + loop->thread_id = (unsigned int)gettid(); +#endif loop->active_handles = 0; loop->active_reqs.count = 0; loop->nfds = 0; diff --git a/src/uv-common.c b/src/uv-common.c index c766d09..405f60e 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -31,6 +31,11 @@ #include /* malloc */ #include /* memset */ +#if defined(USE_OHOS_DFX) && defined(__LP64__) +#include +#include +#endif + #if defined(_WIN32) # include /* malloc */ #else @@ -1052,4 +1057,16 @@ uint64_t uv__get_addr_tag(void* addr) { } #endif return tag; -} \ No newline at end of file +} + +#if defined(USE_OHOS_DFX) && defined(__LP64__) +int uv__multithread_check(uv_loop_t* loop, const char* str) { + if (ffrt_get_cur_task() != NULL) { + return 0; + } + + if (loop->thread_id != (unsigned int)gettid()) { + return -1; + } +} +#endif \ No newline at end of file diff --git a/src/uv-common.h b/src/uv-common.h index bc2e300..6c2c7e6 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -454,4 +454,17 @@ struct uv__loop_internal_fields_s { uint64_t uv__get_addr_tag(void* addr); +#if defined(USE_OHOS_DFX) && defined(__LP64__) +int uv__multithread_check(uv_loop_t* loop, const char* str); + +# define uv__print_caller(string) \ + do{ \ + void *caller_address = __builtin_return_address(0); \ + Dl_info info; \ + if (dladdr(caller_address, &info)) { \ + UV_LOGW("multi-thread occuered in %{public}s! file_name: %{public}s, offset: %{public}lx", \ + string, info.dli_fname, ((uintptr_t)caller_address - (uintptr_t)info.dli_fbase)); \ + } \ + }while(0) \ +#endif #endif /* UV_COMMON_H_ */ -- Gitee