Mercurial > hg > nginx
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 } |