comparison 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
comparison
equal deleted inserted replaced
83:a7e45c45a95c 84:fab4cb00fe5b
1
2 #include <ngx_config.h>
3 #include <ngx_core.h>
4 #include <ngx_process.h>
5 #include <ngx_log.h>
6 #include <ngx_alloc.h>
7
8
9 extern int __isthreaded;
10
11
12 typedef int ngx_tid_t;
13
14
15 static inline int ngx_gettid();
16
17
18 static char *stacks_start;
19 static char *stacks_end;
20 static size_t stack_size;
21 static char *last_stack;
22 static int last_thread;
23
24 static ngx_log_t *log;
25
26 static ngx_tid_t *tids;
27
28 static int red_zone = 4096;
29
30
31 /* the thread-safe errno */
32
33 static int errno0; /* the main thread's errno */
34 static int *errnos;
35
36 int *__error()
37 {
38 int tid;
39
40 tid = ngx_gettid();
41 return tid ? &errnos[tid] : &errno0;
42 }
43
44
45 int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg)
46 {
47 int id, err;
48 char *stack_top;
49
50 last_stack += stack_size;
51 stack_top = last_stack - red_zone;
52
53 if (stack_top > stacks_end) {
54 ngx_log_error(NGX_LOG_CRIT, log, 0, "no more threads allocated");
55 return NGX_ERROR;
56 }
57
58 #if 0
59 id = rfork_thread(RFPROC|RFMEM|RFFDG|RFCFDG, stack_top, func, arg);
60 #elif 1
61 id = rfork_thread(RFPROC|RFMEM, stack_top, func, arg);
62 #else
63 id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg);
64 #endif
65 err = errno;
66
67 if (id == -1) {
68 ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed");
69
70 } else {
71 *tid = id;
72 tids[last_thread++] = id;
73
74 /* allow the spinlock in libc malloc() */
75 __isthreaded = 1;
76 }
77
78 return err;
79 }
80
81
82 int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg)
83 {
84 int len, i;
85 char *usrstack, *zone;
86
87 log = lg;
88
89 /* create the thread stacks */
90
91 len = 4;
92 if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) {
93 ngx_log_error(NGX_LOG_ALERT, log, errno,
94 "sysctlbyname(kern.usrstack) failed");
95 return NGX_ERROR;
96 }
97
98 printf("usrstack: %08X\n", usrstack);
99 printf("red zone: %08X\n", usrstack - (size + red_zone));
100
101 #if 1
102 /* red zone */
103 zone = mmap(usrstack - (size + red_zone), red_zone,
104 PROT_NONE, MAP_ANON, -1, 0);
105 if (zone == MAP_FAILED) {
106 ngx_log_error(NGX_LOG_ALERT, log, errno,
107 "mmap(%d, PROT_NONE, MAP_ANON) failed", red_zone);
108 return NGX_ERROR;
109 }
110 #else
111 zone = usrstack - (size + red_zone);
112 #endif
113
114 last_stack = zone + red_zone;
115
116 for (i = 0; i < n; i++) {
117 last_stack -= size + red_zone;
118 printf("stack: %08X\n", last_stack);
119 last_stack = mmap(last_stack, size, PROT_READ|PROT_WRITE,
120 MAP_STACK, -1, 0);
121 if (last_stack == MAP_FAILED) {
122 ngx_log_error(NGX_LOG_ALERT, log, errno,
123 "mmap(%d, MAP_STACK) failed", size);
124 return NGX_ERROR;
125 }
126 }
127
128 stacks_start = last_stack;
129 stack_size = size + red_zone;
130 stacks_end = stacks_start + n * stack_size;
131
132 /* create the thread errno array */
133 ngx_test_null(errnos, ngx_calloc(n * sizeof(int), log), NGX_ERROR);
134
135 /* create the thread tid array */
136 ngx_test_null(tids, ngx_calloc(n * sizeof(ngx_tid_t), log), NGX_ERROR);
137
138 tids[0] = ngx_getpid();
139 last_thread = 1;
140
141 return NGX_OK;
142 }
143
144
145 ngx_tid_t ngx_thread_self()
146 {
147 return tids[ngx_gettid()];
148 }
149
150
151 static inline int ngx_gettid()
152 {
153 char *sp;
154
155 __asm__ ("mov %%esp, %0" : "=q" (sp));
156
157 return (sp > stacks_end) ? 0: ((sp - stacks_start) / stack_size + 1);
158 }