diff --git a/include/uv.h b/include/uv.h index f8c422dfe3b5052f1fcabfe2af220395e0bb464e..cbd5ce46c1247e38f256003098f8a76295c2fd6f 100644 --- a/include/uv.h +++ b/include/uv.h @@ -208,7 +208,8 @@ typedef enum { UV_REQ_TYPE_MAX } uv_req_type; - +#define UV_EVENT_MAGIC_OFFSET 0x12345ULL +#define UV_EVENT_MAGIC_OFFSETBITS 44 /* Handle types. */ typedef struct uv_loop_s uv_loop_t; typedef struct uv_handle_s uv_handle_t; @@ -1829,6 +1830,19 @@ union uv_any_req { }; #undef XX +enum TaskPriority { + TASK_HIGH, + TASK_NORMAL, + TASK_LOW, +}; + +typedef void (*uv_io_cb)(void* data, int status); +typedef void (*uv_post_task)(void* handler, uv_io_cb func, void* data, int prio); + +struct uv_loop_data { + void* event_handler; + uv_post_task post_task_func; +}; struct uv_loop_s { /* User data - use this for whatever. */ @@ -1849,6 +1863,8 @@ struct uv_loop_s { UV_EXTERN void* uv_loop_get_data(const uv_loop_t*); UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data); +UV_EXTERN void uv_register_task_to_event(struct uv_loop_s* loop, uv_post_task func, void* handler); +UV_EXTERN void uv_unregister_task_to_event(struct uv_loop_s* loop); /* Don't export the private CPP symbols. */ #undef UV_HANDLE_TYPE_PRIVATE diff --git a/src/threadpool.c b/src/threadpool.c index 6b19893b69206061c787caaf9f78c864f6bab68e..1317a8743a4911d3a42439f94cde6d29edf4e0fe 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -37,7 +37,7 @@ #include #define MAX_THREADPOOL_SIZE 1024 - +#define TASK_NUMBER_WARNING 50 static uv_rwlock_t g_closed_uv_loop_rwlock; static uv_cond_t cond; @@ -51,6 +51,25 @@ static QUEUE wq; static QUEUE run_slow_work_message; static QUEUE slow_io_pending_wq; +#ifdef USE_FFRT +static int check_data_valid(struct uv_loop_data* data) { +#if defined(__aarch64__) + if (data == NULL || ((uint64_t)data >> UV_EVENT_MAGIC_OFFSETBITS) != (uint64_t)(UV_EVENT_MAGIC_OFFSET)) { + return -1; + } + struct uv_loop_data* addr = (struct uv_loop_data*)((uint64_t)loop->data - + (UV_EVENT_MAGIC_OFFSET << UV_EVENT_MAGIC_OFFSETBITS)); + if (addr->post_task_func == NULL) { + UV_LOGE("post_task_func is NULL"); + return -1; + } + return 0; +#else + return -1; +#endif +} +#endif + #ifdef ASYNC_STACKTRACE #include "async_stack.h" #endif @@ -608,12 +627,20 @@ static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) { uv_mutex_lock(&loop->wq_mutex); #ifndef USE_FFRT QUEUE_INSERT_TAIL(&loop->wq, &w->wq); + uv_async_send(&loop->wq_async); #else uv__loop_internal_fields_t* lfields = uv__get_internal_fields(w->loop); int qos = (ffrt_qos_t)(intptr_t)req->reserved[0]; - QUEUE_INSERT_TAIL(&(lfields->wq_sub[qos]), &w->wq); + + if (check_data_valid((struct uv_loop_data*)(w->loop->data)) == 0) { + struct uv_loop_data* addr = (struct uv_loop_data*)((uint64_t)w->loop->data - + (UV_EVENT_MAGIC_OFFSET << UV_EVENT_MAGIC_OFFSETBITS)); + addr->post_task_func(addr->event_handler, w->done, w, qos); + } else { + QUEUE_INSERT_TAIL(&(lfields->wq_sub[qos]), &w->wq); + uv_async_send(&loop->wq_async); + } #endif - uv_async_send(&loop->wq_async); uv_mutex_unlock(&loop->wq_mutex); rdunlock_closed_uv_loop_rwlock(); @@ -627,9 +654,8 @@ void uv__work_done(uv_async_t* handle) { QUEUE* q; QUEUE wq; int err; - char traceName[25] = "TaskNumber_"; + char trac_name[25] = "TaskNumber_"; char str[10]; - int cnt = 0; loop = container_of(handle, uv_loop_t, wq_async); rdlock_closed_uv_loop_rwlock(); @@ -651,14 +677,13 @@ void uv__work_done(uv_async_t* handle) { } #endif uv_mutex_unlock(&loop->wq_mutex); - cnt = loop->active_reqs.count; - if (cnt > 50) { - UV_LOGW("The number of task is too much, task number is %{public}d", cnt); + if (loop->active_reqs.count > TASK_NUMBER_WARNING) { + UV_LOGW("The number of task is too much, task number is %{public}d", loop->active_reqs.count); } - snprintf(str, sizeof(str), "%d", cnt); - strcat(traceName, str); + snprintf(str, sizeof(str), "%d", loop->active_reqs.count); + strcat(trac_name, str); - uv_start_trace(UV_TRACE_TAG, traceName); + uv_start_trace(UV_TRACE_TAG, trac_name); while (!QUEUE_EMPTY(&wq)) { q = QUEUE_HEAD(&wq); QUEUE_REMOVE(q); @@ -744,8 +769,15 @@ void uv__ffrt_work(ffrt_executor_task_t* data, ffrt_qos_t qos) uv_mutex_lock(&w->loop->wq_mutex); w->work = NULL; /* Signal uv_cancel() that the work req is done executing. */ - QUEUE_INSERT_TAIL(&(lfields->wq_sub[qos]), &w->wq); - uv_async_send(&w->loop->wq_async); + + if (check_data_valid((struct uv_loop_data*)(w->loop->data)) == 0) { + struct uv_loop_data* addr = (struct uv_loop_data*)((uint64_t)w->loop->data - + (UV_EVENT_MAGIC_OFFSET << UV_EVENT_MAGIC_OFFSETBITS)); + addr->post_task_func(addr->event_handler, w->done, w, qos); + } else { + QUEUE_INSERT_TAIL(&(lfields->wq_sub[qos]), &w->wq); + uv_async_send(&w->loop->wq_async); + } uv_mutex_unlock(&w->loop->wq_mutex); rdunlock_closed_uv_loop_rwlock(); } diff --git a/src/unix/core.c b/src/unix/core.c index 8067ea1290ee8052164de05417a4e8b35070b8db..e7f73a0c24c3741fa4092b3617111ead13da6d82 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -19,6 +19,7 @@ */ #include "uv.h" +#include "uv_log.h" #include "internal.h" #include "strtok.h" @@ -1676,3 +1677,39 @@ unsigned int uv_available_parallelism(void) { return (unsigned) rc; #endif /* __linux__ */ } + +void uv_register_task_to_event(struct uv_loop_s* loop, uv_post_task func, void* handler) +{ +#if defined(__aarch64__) + if (loop == NULL) + return; + + struct uv_loop_data* data = (struct uv_loop_data*)malloc(sizeof(struct uv_loop_data)); + if (data == NULL) + return; + if ((uint64_t)data >> UV_EVENT_MAGIC_OFFSETBITS != 0x0) { + UV_LOGE("malloc address error!"); + free(data); + return; + } + + (void)memset(data, 0, sizeof(struct uv_loop_data)); + data->post_task_func = func; + data->event_handler = handler; + data = (struct uv_loop_data*)((uint64_t)data | (UV_EVENT_MAGIC_OFFSET << UV_EVENT_MAGIC_OFFSETBITS)); + loop->data = (void *)data; +#endif +} + +void uv_unregister_task_to_event(struct uv_loop_s* loop) +{ +#if defined(__aarch64__) + if (loop == NULL || loop->data == NULL || + ((uint64_t)loop->data >> UV_EVENT_MAGIC_OFFSETBITS) != (uint64_t)(UV_EVENT_MAGIC_OFFSET)) + return; + loop->data = (struct uv_loop_data*)((uint64_t)loop->data - + (UV_EVENT_MAGIC_OFFSET << UV_EVENT_MAGIC_OFFSETBITS)); + free(loop->data); + loop->data = NULL; +#endif +} \ No newline at end of file