From 1883330bbac65047e0a84918b94eeb3caa42d946 Mon Sep 17 00:00:00 2001 From: lxsang Date: Sat, 30 Jan 2021 22:16:11 +0100 Subject: [PATCH] Reduce CPU usage on idle in proxy mode: - Scheduler timeout event now support millisecond granulity - Use only READABLE event on proxy socket which reduce tasks CPU time --- http_server.c | 43 ++++++++++++++++++++++--------------------- httpd.c | 9 ++++----- lib/scheduler.c | 9 ++++++++- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/http_server.c b/http_server.c index 58c5cb5..07db283 100644 --- a/http_server.c +++ b/http_server.c @@ -762,31 +762,36 @@ static void *proxy_monitor(void *data) rq->client->state = ANTD_CLIENT_PROXY_MONITOR; antd_client_t *proxy = (antd_client_t *)dvalue(rq->request, "PROXY_HANDLE"); antd_task_t *task = antd_create_task(NULL, data, NULL, rq->client->last_io); - int ret, sz1, sz2; + int ret, sz1 = 0, sz2 = 0; char *buf = NULL; buf = (char *)malloc(BUFFLEN); struct pollfd pfd[1]; memset(pfd, 0, sizeof(pfd)); pfd[0].fd = proxy->sock; pfd[0].events = POLLIN; - ret = 1; - sz1 = antd_recv_upto(rq->client, buf, BUFFLEN); - - if ((sz1 < 0) || (sz1 > 0 && antd_send(proxy, buf, sz1) != sz1)) - { - ret = 0; - } if (poll(pfd, 1, 0) < 0) { - ret = 0; + (void)close(proxy->sock); + return task; } - sz2 = antd_recv_upto(proxy, buf, BUFFLEN); - if (sz2 < 0 || (sz2 > 0 && antd_send(rq->client, buf, sz2) != sz2)) + do { - ret = 0; - } + sz1 = antd_recv_upto(rq->client, buf, BUFFLEN); + + if ((sz1 < 0) || (sz1 > 0 && antd_send(proxy, buf, sz1) != sz1)) + { + ret = 0; + break; + } + sz2 = read_buf(proxy, buf, BUFFLEN); + if (sz2 < 0 || (sz2 > 0 && antd_send(rq->client, buf, sz2) != sz2)) + { + ret = 0; + break; + } + } while (sz1 > 0 || sz2 > 0); free(buf); if (ret == 0) @@ -794,27 +799,23 @@ static void *proxy_monitor(void *data) (void)close(proxy->sock); return task; } - if (sz2 == 0) { if ( pfd[0].revents & POLLERR || pfd[0].revents & POLLRDHUP || pfd[0].revents & POLLHUP || - pfd[0].revents & POLLNVAL || - pfd[0].revents & POLLIN) + pfd[0].revents & POLLNVAL) //|| + //pfd[0].revents & POLLIN) { (void)close(proxy->sock); return task; } - usleep(10000); } - task->handle = proxy_monitor; task->access_time = rq->client->last_io; - + antd_task_bind_event(task, proxy->sock, 0, TASK_EVT_ON_READABLE); antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_READABLE); - antd_task_bind_event(task, proxy->sock, 0, TASK_EVT_ON_READABLE | TASK_EVT_ON_WRITABLE); return task; } @@ -1115,7 +1116,7 @@ void *decode_request(void *data) task->handle = resolve_request; return task; } - else if(EQU(method, "HEAD") || EQU(method, "OPTIONS") || EQU(method, "DELETE") ) + else if (EQU(method, "HEAD") || EQU(method, "OPTIONS") || EQU(method, "DELETE")) { task->handle = resolve_request; return task; diff --git a/httpd.c b/httpd.c index 1684026..0e36283 100644 --- a/httpd.c +++ b/httpd.c @@ -301,7 +301,6 @@ void antd_scheduler_destroy_data(void *data) antd_client_t *proxy = (antd_client_t *)dvalue(rq->request, "PROXY_HANDLE"); if(proxy) { - printf("closing proxy \n"); close(proxy->sock); } finish_request(data); @@ -309,12 +308,12 @@ void antd_scheduler_destroy_data(void *data) int antd_task_data_id(void *data) { - antd_request_t *rq = (antd_request_t *)data; + /*antd_request_t *rq = (antd_request_t *)data; if(!rq) return 0; - return antd_scheduler_next_id(scheduler,rq->client->sock); - //UNUSED(data); - //return antd_scheduler_next_id(scheduler,0); + return antd_scheduler_next_id(scheduler,rq->client->sock);*/ + UNUSED(data); + return antd_scheduler_next_id(scheduler,0); } int main(int argc, char *argv[]) diff --git a/lib/scheduler.c b/lib/scheduler.c index 2c4d516..e23738c 100644 --- a/lib/scheduler.c +++ b/lib/scheduler.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "scheduler.h" #include "utils.h" @@ -24,6 +25,7 @@ typedef struct { int flags; int fd; + struct timeval stamp; int timeout; // seconds antd_task_t *task; } antd_task_evt_item_t; @@ -655,6 +657,7 @@ static void task_event_collect(bst_node_t* node, void** argv, int argc) antd_task_t* task = (antd_task_t*) node->data; bst_node_t** exec_list = (bst_node_t**) argv[0]; bst_node_t** poll_list = (bst_node_t**) argv[1]; + struct timeval now; int* pollsize = (int*) argv[2]; if(!task->events) { @@ -671,7 +674,10 @@ static void task_event_collect(bst_node_t* node, void** argv, int argc) else if(it->evt->flags & TASK_EVT_ON_TIMEOUT) { // check if timeout - if(difftime(time(NULL),task->stamp) > it->evt->timeout ) + gettimeofday(&now, NULL); + //do stuff + int diff = (int)(((now.tv_sec - it->evt->stamp.tv_sec) * 1000000 + now.tv_usec - it->evt->stamp.tv_usec) / 1000); + if( diff >= it->evt->timeout ) { *exec_list = bst_insert(*exec_list,task->id, task); } @@ -692,6 +698,7 @@ void antd_task_bind_event(antd_task_t *task, int fd, int timeout, int flags) eit->timeout = timeout; eit->flags = flags; eit->task = task; + gettimeofday(&eit->stamp, NULL); enqueue(&task->events, eit); }