Mercurial > hg > nginx
diff src/os/unix/ngx_freebsd_rfork_thread.c @ 84:fab4cb00fe5b
nginx-0.0.1-2003-05-06-21:03:16 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 06 May 2003 17:03:16 +0000 |
parents | src/os/unix/freebsd/ngx_rfork_thread.c@34a521b1a148 |
children | 3549c2bf9eaf |
line wrap: on
line diff
copy from src/os/unix/freebsd/ngx_rfork_thread.c copy to src/os/unix/ngx_freebsd_rfork_thread.c --- a/src/os/unix/freebsd/ngx_rfork_thread.c +++ b/src/os/unix/ngx_freebsd_rfork_thread.c @@ -1,64 +1,158 @@ -#include <ngx_os_thread.h> +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_process.h> +#include <ngx_log.h> +#include <ngx_alloc.h> + -char *ngx_stacks_start; -char *ngx_stacks_end; -size_t ngx_stack_size; +extern int __isthreaded; + + +typedef int ngx_tid_t; + + +static inline int ngx_gettid(); -/* handle thread-safe errno */ -static int errno0; /* errno for main thread */ +static char *stacks_start; +static char *stacks_end; +static size_t stack_size; +static char *last_stack; +static int last_thread; + +static ngx_log_t *log; + +static ngx_tid_t *tids; + +static int red_zone = 4096; + + +/* the thread-safe errno */ + +static int errno0; /* the main thread's errno */ static int *errnos; int *__error() { - ngx_tid_t tid = ngx_gettid(); - return tid ? &(errnos[ngx_gettid()]) : &errno0; + int tid; + + tid = ngx_gettid(); + return tid ? &errnos[tid] : &errno0; } -int ngx_create_thread(ngx_os_tid_t *tid, void *stack, - int (*func)(void *arg), void *arg, ngx_log_t log) +int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg) { - int id, err; + int id, err; + char *stack_top; + + last_stack += stack_size; + stack_top = last_stack - red_zone; + + if (stack_top > stacks_end) { + ngx_log_error(NGX_LOG_CRIT, log, 0, "no more threads allocated"); + return NGX_ERROR; + } - id = rfork_thread(RFPROC|RFMEM, stack, func, arg); - err = ngx_errno; +#if 0 + id = rfork_thread(RFPROC|RFMEM|RFFDG|RFCFDG, stack_top, func, arg); +#elif 1 + id = rfork_thread(RFPROC|RFMEM, stack_top, func, arg); +#else + id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg); +#endif + err = errno; - if (id == -1) - ngx_log_error(NGX_LOG_ERR, log, err, - "ngx_create_os_thread: rfork failed"); - else + if (id == -1) { + ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed"); + + } else { *tid = id; + tids[last_thread++] = id; + + /* allow the spinlock in libc malloc() */ + __isthreaded = 1; + } return err; } -int ngx_create_thread_env(int n, size_t size, ngx_log_t log) +int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg) { - char *addr; + int len, i; + char *usrstack, *zone; + + log = lg; - /* create thread stacks */ - addr = mmap(NULL, n * size, PROT_READ|PROT_WRITE, MAP_ANON, -1, NULL); - if (addr == MAP_FAILED) { - ngx_log_error(NGX_LOG_ERR, log, ngx_errno, - "ngx_create_os_thread_stacks: mmap failed"); - return -1; + /* create the thread stacks */ + + len = 4; + if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "sysctlbyname(kern.usrstack) failed"); + return NGX_ERROR; } - nxg_stacks_start = addr; - nxg_stacks_end = addr + n * size; - nxg_stack_size = size; +printf("usrstack: %08X\n", usrstack); +printf("red zone: %08X\n", usrstack - (size + red_zone)); - /* create thread errno array */ - ngx_test_null(errnos, ngx_calloc(n * sizeof(int)), -1); +#if 1 + /* red zone */ + zone = mmap(usrstack - (size + red_zone), red_zone, + PROT_NONE, MAP_ANON, -1, 0); + if (zone == MAP_FAILED) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "mmap(%d, PROT_NONE, MAP_ANON) failed", red_zone); + return NGX_ERROR; + } +#else + zone = usrstack - (size + red_zone); +#endif + + last_stack = zone + red_zone; + + for (i = 0; i < n; i++) { + last_stack -= size + red_zone; +printf("stack: %08X\n", last_stack); + last_stack = mmap(last_stack, size, PROT_READ|PROT_WRITE, + MAP_STACK, -1, 0); + if (last_stack == MAP_FAILED) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "mmap(%d, MAP_STACK) failed", size); + return NGX_ERROR; + } + } - /* create thread tid array */ - ngx_test_null(ngx_os_tids, ngx_calloc(n * sizeof(ngx_os_tid_t)), -1); + stacks_start = last_stack; + stack_size = size + red_zone; + stacks_end = stacks_start + n * stack_size; + + /* create the thread errno array */ + ngx_test_null(errnos, ngx_calloc(n * sizeof(int), log), NGX_ERROR); + + /* create the thread tid array */ + ngx_test_null(tids, ngx_calloc(n * sizeof(ngx_tid_t), log), NGX_ERROR); + + tids[0] = ngx_getpid(); + last_thread = 1; + + return NGX_OK; +} - /* allow spinlock in malloc() */ - __isthreaded = 1; + +ngx_tid_t ngx_thread_self() +{ + return tids[ngx_gettid()]; +} + - return 0; +static inline int ngx_gettid() +{ + char *sp; + + __asm__ ("mov %%esp, %0" : "=q" (sp)); + + return (sp > stacks_end) ? 0: ((sp - stacks_start) / stack_size + 1); }