From 919501e92cd910a6be134314902f1cc9ca0d3ecc Mon Sep 17 00:00:00 2001 From: "roberto@sirius" Date: Mon, 29 Mar 2010 10:30:03 +0200 Subject: [PATCH] uGreen little refactoring and fixes --- ugreen.c | 81 ++++++++++++++++++++++++++++---------------------- utils.c | 2 +- uwsgi.c | 12 ++++++++ uwsgi.h | 8 ++--- uwsgiconfig.py | 2 +- 5 files changed, 64 insertions(+), 41 deletions(-) diff --git a/ugreen.c b/ugreen.c index 376c9689..951fcbb1 100644 --- a/ugreen.c +++ b/ugreen.c @@ -6,7 +6,6 @@ TODO -page-guards in stack configurable stack size io and sleep management @@ -19,7 +18,7 @@ io and sleep management extern struct uwsgi_server uwsgi; -static int green_blocking(struct uwsgi_server *uwsgi) { +static int u_green_blocking(struct uwsgi_server *uwsgi) { struct wsgi_request* wsgi_req = uwsgi->wsgi_requests ; int i ; @@ -33,7 +32,7 @@ static int green_blocking(struct uwsgi_server *uwsgi) { return -1 ; } -static void u_green_schedule_to_main(struct uwsgi_server *uwsgi, int async_id) { +inline static void u_green_schedule_to_main(struct uwsgi_server *uwsgi, int async_id) { int py_current_recursion_depth; struct _frame* py_current_frame; @@ -42,14 +41,14 @@ static void u_green_schedule_to_main(struct uwsgi_server *uwsgi, int async_id) { py_current_recursion_depth = tstate->recursion_depth; py_current_frame = tstate->frame; - swapcontext(uwsgi->green_contexts[async_id], &uwsgi->greenmain); + swapcontext(uwsgi->ugreen_contexts[async_id], &uwsgi->ugreenmain); tstate = PyThreadState_GET(); tstate->recursion_depth = py_current_recursion_depth; tstate->frame = py_current_frame ; } -static void u_green_schedule_to_req(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) { +inline static void u_green_schedule_to_req(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) { int py_current_recursion_depth; struct _frame* py_current_frame; @@ -60,7 +59,7 @@ static void u_green_schedule_to_req(struct uwsgi_server *uwsgi, struct wsgi_requ uwsgi->wsgi_req = wsgi_req; wsgi_req->async_switches++; - swapcontext(&uwsgi->greenmain, uwsgi->green_contexts[wsgi_req->async_id] ); + swapcontext(&uwsgi->ugreenmain, uwsgi->ugreen_contexts[wsgi_req->async_id] ); tstate = PyThreadState_GET(); tstate->recursion_depth = py_current_recursion_depth; @@ -133,51 +132,49 @@ static void u_green_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsg } -void u_green_loop(struct uwsgi_server *uwsgi) { +void u_green_init(struct uwsgi_server *uwsgi) { struct wsgi_request *wsgi_req = uwsgi->wsgi_requests ; - int i, current = 0 ; + int i; PyMethodDef *uwsgi_function; fprintf(stderr,"initializing %d uGreen threads with stack size of %lu (%lu KB)\n", uwsgi->async, (unsigned long) GREEN_STACK_SIZE, (unsigned long) GREEN_STACK_SIZE/1024); - uwsgi->green_stacks = malloc( sizeof(char*) * uwsgi->async); - if (!uwsgi->green_stacks) { - perror("malloc()\n"); - exit(1); - } - for(i=0;iasync;i++) { - //uwsgi->green_stacks[i] = malloc( 4096 * 256 ); - uwsgi->green_stacks[i] = mmap(NULL, GREEN_STACK_SIZE , PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN, -1, 0); - if (!uwsgi->green_stacks[i]) { - perror("mmap()"); - exit(1); - } - } - - - uwsgi->green_contexts = malloc( sizeof(ucontext_t*) * uwsgi->async); - if (!uwsgi->green_contexts) { + uwsgi->ugreen_contexts = malloc( sizeof(ucontext_t*) * uwsgi->async); + if (!uwsgi->ugreen_contexts) { perror("malloc()\n"); exit(1); } for(i=0;iasync;i++) { - uwsgi->green_contexts[i] = malloc( sizeof(ucontext_t) ); - if (!uwsgi->green_contexts[i]) { + uwsgi->ugreen_contexts[i] = malloc( sizeof(ucontext_t) ); + if (!uwsgi->ugreen_contexts[i]) { perror("malloc()"); exit(1); } - getcontext(uwsgi->green_contexts[i]); - uwsgi->green_contexts[i]->uc_stack.ss_sp = uwsgi->green_stacks[i]; - uwsgi->green_contexts[i]->uc_stack.ss_size = GREEN_STACK_SIZE ; - uwsgi->green_contexts[i]->uc_link = NULL; - makecontext(uwsgi->green_contexts[i], (void (*) (void)) &u_green_request, 3, uwsgi, wsgi_req, i); + getcontext(uwsgi->ugreen_contexts[i]); + uwsgi->ugreen_contexts[i]->uc_stack.ss_sp = mmap(NULL, GREEN_STACK_SIZE + uwsgi->page_size*2 , PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0) + uwsgi->page_size; + if (!uwsgi->ugreen_contexts[i]->uc_stack.ss_sp) { + perror("mmap()"); + exit(1); + } + // set guard pages for stack + if (mprotect(uwsgi->ugreen_contexts[i]->uc_stack.ss_sp - uwsgi->page_size, uwsgi->page_size, PROT_NONE)) { + perror("mprotect()"); + exit(1); + } + if (mprotect(uwsgi->ugreen_contexts[i]->uc_stack.ss_sp + GREEN_STACK_SIZE, uwsgi->page_size, PROT_NONE)) { + perror("mprotect()"); + exit(1); + } + uwsgi->ugreen_contexts[i]->uc_stack.ss_size = GREEN_STACK_SIZE ; + uwsgi->ugreen_contexts[i]->uc_link = NULL; + makecontext(uwsgi->ugreen_contexts[i], (void (*) (void)) &u_green_request, 3, uwsgi, wsgi_req, i); wsgi_req->async_status = UWSGI_ACCEPTING; wsgi_req->async_id = i; wsgi_req = next_wsgi_req(uwsgi, wsgi_req) ; @@ -188,11 +185,18 @@ void u_green_loop(struct uwsgi_server *uwsgi) { PyDict_SetItemString(uwsgi->embedded_dict, uwsgi_function->ml_name, func); Py_DECREF(func); } +} - for(;;) { +void u_green_loop(struct uwsgi_server *uwsgi) { - uwsgi->async_running = green_blocking(uwsgi) ; + struct wsgi_request *wsgi_req = uwsgi->wsgi_requests ; + + int i, current = 0 ; + + while(uwsgi->workers[uwsgi->mywid].manage_next_request) { + + uwsgi->async_running = u_green_blocking(uwsgi) ; uwsgi->async_nevents = async_wait(uwsgi->async_queue, uwsgi->async_events, uwsgi->async, uwsgi->async_running, 0); @@ -200,7 +204,7 @@ void u_green_loop(struct uwsgi_server *uwsgi) { continue; } - if (i > 0) { + if (uwsgi->async_nevents > 0) { wsgi_req = find_first_accepting_wsgi_req(uwsgi); if (!wsgi_req) goto cycle; } @@ -223,6 +227,13 @@ cycle: } + if (uwsgi->workers[uwsgi->mywid].manage_next_request == 0) { + reload_me(); + } + else { + goodbye_cruel_world(); + } + // never here } diff --git a/utils.c b/utils.c index c6674bc9..4152ed88 100644 --- a/utils.c +++ b/utils.c @@ -289,7 +289,7 @@ int wsgi_req_accept(int fd, struct wsgi_request *wsgi_req) { return 0; } -struct wsgi_request *current_wsgi_req(struct uwsgi_server *uwsgi) { +inline struct wsgi_request *current_wsgi_req(struct uwsgi_server *uwsgi) { struct wsgi_request *wsgi_req = uwsgi->wsgi_req; diff --git a/uwsgi.c b/uwsgi.c index e97bf404..1cbe8782 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -672,6 +672,17 @@ int main(int argc, char *argv[], char *envp[]) { } #endif +#ifdef UWSGI_UGREEN + if (uwsgi.ugreen) { + if (uwsgi.has_threads) { + fprintf(stderr,"--- python threads will be disabled in uGreen mode ---\n"); + uwsgi.has_threads = 0; + } + + u_green_init(&uwsgi); + } +#endif + #ifdef UWSGI_THREADING if (uwsgi.has_threads) { PyEval_InitThreads(); @@ -1323,6 +1334,7 @@ int main(int argc, char *argv[], char *envp[]) { #ifdef UWSGI_UGREEN if (uwsgi.ugreen) { u_green_loop(&uwsgi); + // never here } #endif diff --git a/uwsgi.h b/uwsgi.h index 1c1cb0c2..b7b4285d 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -409,9 +409,8 @@ struct uwsgi_server { #ifdef UWSGI_UGREEN int ugreen; - ucontext_t greenmain; - ucontext_t **green_contexts; - char **green_stacks; + ucontext_t ugreenmain; + ucontext_t **ugreen_contexts; #endif #ifdef __linux__ @@ -772,7 +771,8 @@ int wsgi_req_recv(struct wsgi_request *); int wsgi_req_accept(int, struct wsgi_request *); #ifdef UWSGI_UGREEN +void u_green_init(struct uwsgi_server *); void u_green_loop(struct uwsgi_server *); #endif -struct wsgi_request *current_wsgi_req(struct uwsgi_server *); +inline struct wsgi_request *current_wsgi_req(struct uwsgi_server *); diff --git a/uwsgiconfig.py b/uwsgiconfig.py index fbbe3efe..c952d86a 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -8,7 +8,7 @@ SPOOLER=True EMBEDDED=True UDP=True MULTICAST=True -THREADING=False +THREADING=True SENDFILE=True PROFILER=False NAGIOS=True