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);
 }