2003-05-07 01:03:16 +08:00
|
|
|
|
|
|
|
#include <ngx_config.h>
|
|
|
|
#include <ngx_core.h>
|
|
|
|
#include <ngx_process.h>
|
|
|
|
#include <ngx_log.h>
|
|
|
|
#include <ngx_alloc.h>
|
|
|
|
|
|
|
|
|
|
|
|
extern int __isthreaded;
|
|
|
|
|
|
|
|
|
|
|
|
typedef int ngx_tid_t;
|
|
|
|
|
2003-05-08 01:32:45 +08:00
|
|
|
#define NGX_MAX_THREADS 10
|
|
|
|
|
2003-05-07 01:03:16 +08:00
|
|
|
|
|
|
|
static inline int ngx_gettid();
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2003-05-08 01:32:45 +08:00
|
|
|
static ngx_tid_t tids[NGX_MAX_THREADS];
|
2003-05-07 01:03:16 +08:00
|
|
|
|
|
|
|
static int red_zone = 4096;
|
|
|
|
|
|
|
|
|
|
|
|
/* the thread-safe errno */
|
|
|
|
|
2003-05-08 01:32:45 +08:00
|
|
|
static int errnos[NGX_MAX_THREADS];
|
2003-05-07 01:03:16 +08:00
|
|
|
|
|
|
|
int *__error()
|
|
|
|
{
|
2003-05-08 01:32:45 +08:00
|
|
|
return &errnos[ngx_gettid()];
|
2003-05-07 01:03:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ngx_create_thread(ngx_tid_t *tid, int (*func)(void *arg), void *arg)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
2003-05-08 01:32:45 +08:00
|
|
|
id = rfork(RFFDG|RFCFDG);
|
|
|
|
#elif 0
|
|
|
|
id = rfork_thread(RFFDG|RFCFDG, stack_top, func, arg);
|
|
|
|
#elif 0
|
2003-05-07 01:03:16 +08:00
|
|
|
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_ALERT, log, err, "rfork() failed");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
*tid = id;
|
|
|
|
tids[last_thread++] = id;
|
|
|
|
|
|
|
|
/* allow the spinlock in libc malloc() */
|
|
|
|
__isthreaded = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ngx_init_thread_env(int n, size_t size, ngx_log_t *lg)
|
|
|
|
{
|
|
|
|
int len, i;
|
|
|
|
char *usrstack, *zone;
|
|
|
|
|
|
|
|
log = lg;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("usrstack: %08X\n", usrstack);
|
|
|
|
printf("red zone: %08X\n", usrstack - (size + red_zone));
|
|
|
|
|
|
|
|
#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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stacks_start = last_stack;
|
|
|
|
stack_size = size + red_zone;
|
|
|
|
stacks_end = stacks_start + n * stack_size;
|
|
|
|
|
|
|
|
tids[0] = ngx_getpid();
|
|
|
|
last_thread = 1;
|
|
|
|
|
|
|
|
return NGX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ngx_tid_t ngx_thread_self()
|
|
|
|
{
|
|
|
|
return tids[ngx_gettid()];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline int ngx_gettid()
|
|
|
|
{
|
|
|
|
char *sp;
|
|
|
|
|
|
|
|
__asm__ ("mov %%esp, %0" : "=q" (sp));
|
|
|
|
|
2003-05-08 01:32:45 +08:00
|
|
|
return (sp > stacks_end) ? 0 : ((sp - stacks_start) / stack_size + 1);
|
2003-05-07 01:03:16 +08:00
|
|
|
}
|