comparison src/os/unix/ngx_freebsd_rfork_thread.c @ 86:3973260705cc

nginx-0.0.1-2003-05-12-19:52:24 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 12 May 2003 15:52:24 +0000
parents 3549c2bf9eaf
children 738fe44c70d5
comparison
equal deleted inserted replaced
85:3549c2bf9eaf 86:3973260705cc
9 extern int __isthreaded; 9 extern int __isthreaded;
10 10
11 11
12 typedef int ngx_tid_t; 12 typedef int ngx_tid_t;
13 13
14 #define NGX_MAX_THREADS 10
15
16 14
17 static inline int ngx_gettid(); 15 static inline int ngx_gettid();
18 16
19 17
20 static char *stacks_start; 18 static char *usrstack;
21 static char *stacks_end;
22 static size_t stack_size;
23 static char *last_stack;
24 static int last_thread;
25
26 static ngx_log_t *log;
27
28 static ngx_tid_t tids[NGX_MAX_THREADS];
29
30 static int red_zone = 4096; 19 static int red_zone = 4096;
31 20
21 static size_t stack_size;
22 static size_t usable_stack_size;
23 static char *last_stack;
24
25 static int threads;
26 static int nthreads;
27 static ngx_tid_t *tids;
32 28
33 /* the thread-safe errno */ 29 /* the thread-safe errno */
34 30
35 static int errnos[NGX_MAX_THREADS]; 31 static int errno0; /* the main thread's errno */
32 static int *errnos;
36 33
37 int *__error() 34 int *__error()
38 { 35 {
39 return &errnos[ngx_gettid()]; 36 int tid;
37
38 tid = ngx_gettid();
39
40 return tid ? &errnos[tid - 1] : &errno0;
40 } 41 }
41 42
42 43
43 int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg) 44 int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg,
45 ngx_log_t *log)
44 { 46 {
45 int id, err; 47 int id, err;
46 char *stack_top; 48 char *stack, *stack_top;
47 49
48 last_stack += stack_size; 50 if (threads >= nthreads) {
49 stack_top = last_stack - red_zone; 51 ngx_log_error(NGX_LOG_CRIT, log, 0,
50 52 "no more than %d threads can be created", nthreads);
51 if (stack_top > stacks_end) {
52 ngx_log_error(NGX_LOG_CRIT, log, 0, "no more threads allocated");
53 return NGX_ERROR; 53 return NGX_ERROR;
54 } 54 }
55 55
56 #if 0 56 last_stack -= stack_size;
57 stack = mmap(last_stack, usable_stack_size, PROT_READ|PROT_WRITE,
58 MAP_STACK, -1, 0);
59 if (stack == MAP_FAILED) {
60 ngx_log_error(NGX_LOG_ALERT, log, errno,
61 "mmap(%08X:%d, MAP_STACK) thread stack failed",
62 last_stack, usable_stack_size);
63 return NGX_ERROR;
64 }
65
66 if (stack != last_stack) {
67 ngx_log_error(NGX_LOG_ALERT, log, 0, "stack address was changed");
68 }
69
70 stack_top = stack + usable_stack_size;
71
72 printf("stack: %08X-%08X\n", stack, stack_top);
73
74 #if 1
75 id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top, func, arg);
76 #elif 1
77 id = rfork_thread(RFPROC|RFMEM, stack_top, func, arg);
78 #elif 1
79 id = rfork_thread(RFFDG|RFCFDG, stack_top, func, arg);
80 #else
57 id = rfork(RFFDG|RFCFDG); 81 id = rfork(RFFDG|RFCFDG);
58 #elif 0
59 id = rfork_thread(RFFDG|RFCFDG, stack_top, func, arg);
60 #elif 0
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 82 #endif
83
65 err = errno; 84 err = errno;
66 85
67 if (id == -1) { 86 if (id == -1) {
68 ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed"); 87 ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed");
69 88
70 } else { 89 } else {
71 *tid = id; 90 *tid = id;
72 tids[last_thread++] = id; 91 threads = (usrstack - stack_top) / stack_size;
92 tids[threads] = id;
73 93
74 /* allow the spinlock in libc malloc() */ 94 /* allow the spinlock in libc malloc() */
75 __isthreaded = 1; 95 __isthreaded = 1;
76 } 96 }
77 97
78 return err; 98 return err;
79 } 99 }
80 100
81 101
82 int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg) 102 int ngx_init_thread_env(int n, size_t size, ngx_log_t *log)
83 { 103 {
84 int len, i; 104 int len;
85 char *usrstack, *zone; 105 char *rz, *zone;
86 106
87 log = lg; 107 nthreads = n;
88
89 /* create the thread stacks */
90 108
91 len = 4; 109 len = 4;
92 if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) { 110 if (sysctlbyname("kern.usrstack", &usrstack, &len, NULL, 0) == -1) {
93 ngx_log_error(NGX_LOG_ALERT, log, errno, 111 ngx_log_error(NGX_LOG_ALERT, log, errno,
94 "sysctlbyname(kern.usrstack) failed"); 112 "sysctlbyname(kern.usrstack) failed");
95 return NGX_ERROR; 113 return NGX_ERROR;
96 } 114 }
97 115
98 printf("usrstack: %08X\n", usrstack); 116 printf("usrstack: %08X\n", usrstack);
99 printf("red zone: %08X\n", usrstack - (size + red_zone));
100 117
101 #if 1
102 /* red zone */ 118 /* red zone */
103 zone = mmap(usrstack - (size + red_zone), red_zone, 119 rz = usrstack - (size + red_zone);
104 PROT_NONE, MAP_ANON, -1, 0); 120
121 printf("red zone: %08X\n", rz);
122
123 zone = mmap(rz, red_zone, PROT_NONE, MAP_ANON, -1, 0);
105 if (zone == MAP_FAILED) { 124 if (zone == MAP_FAILED) {
106 ngx_log_error(NGX_LOG_ALERT, log, errno, 125 ngx_log_error(NGX_LOG_ALERT, log, errno,
107 "mmap(%d, PROT_NONE, MAP_ANON) failed", red_zone); 126 "mmap(%08X:%d, PROT_NONE, MAP_ANON) red zone failed",
127 rz, red_zone);
108 return NGX_ERROR; 128 return NGX_ERROR;
109 } 129 }
110 #else 130
111 zone = usrstack - (size + red_zone); 131 if (zone != rz) {
112 #endif 132 ngx_log_error(NGX_LOG_ALERT, log, 0, "red zone address was changed");
133 }
134
135 /* create the thread errno array */
136 ngx_test_null(errnos, ngx_calloc(n * sizeof(int), log), NGX_ERROR);
137
138 /* create the thread tid array */
139 ngx_test_null(tids, ngx_calloc((n + 1) * sizeof(ngx_tid_t), log),
140 NGX_ERROR);
141
142 tids[0] = ngx_getpid();
143 threads = 1;
113 144
114 last_stack = zone + red_zone; 145 last_stack = zone + red_zone;
115 146 usable_stack_size = size;
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; 147 stack_size = size + red_zone;
130 stacks_end = stacks_start + n * stack_size;
131
132 tids[0] = ngx_getpid();
133 last_thread = 1;
134 148
135 return NGX_OK; 149 return NGX_OK;
136 } 150 }
137 151
138 152
139 ngx_tid_t ngx_thread_self() 153 ngx_tid_t ngx_thread_self()
140 { 154 {
141 return tids[ngx_gettid()]; 155 int tid;
156 ngx_tid_t pid;
157
158 tid = ngx_gettid();
159
160 if (tids[tid] == 0) {
161 pid = ngx_getpid();
162 tids[tid] = pid;
163 return pid;
164 }
165
166 return tids[tid];
142 } 167 }
143 168
144 169
145 static inline int ngx_gettid() 170 static inline int ngx_gettid()
146 { 171 {
147 char *sp; 172 char *sp;
148 173
174 if (stack_size == 0) {
175 return 0;
176 }
177
149 __asm__ ("mov %%esp, %0" : "=q" (sp)); 178 __asm__ ("mov %%esp, %0" : "=q" (sp));
150 179
151 return (sp > stacks_end) ? 0 : ((sp - stacks_start) / stack_size + 1); 180 return (usrstack - sp) / stack_size;
152 } 181 }