# HG changeset patch # User Maxim Dounin # Date 1452529397 -10800 # Node ID 96c4297375bc497e26b649a362dbffb7fd079d95 # Parent b31928ca38701a84f560194520876bb1c567fb6a Core: worker_cpu_affinity auto. If enabled, workers are bound to available CPUs, each worker to once CPU in order. If there are more workers than available CPUs, remaining are bound in a loop, starting again from the first available CPU. The optional mask parameter defines which CPUs are available for automatic binding. In collaboration with Vladimir Homutov. diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -961,6 +961,7 @@ ngx_core_module_create_conf(ngx_cycle_t * ccf->pid = NULL; * ccf->oldpid = NULL; * ccf->priority = 0; + * ccf->cpu_affinity_auto = 0; * ccf->cpu_affinity_n = 0; * ccf->cpu_affinity = NULL; */ @@ -1002,7 +1003,8 @@ ngx_core_module_init_conf(ngx_cycle_t *c #if (NGX_HAVE_CPU_AFFINITY) - if (ccf->cpu_affinity_n + if (!ccf->cpu_affinity_auto + && ccf->cpu_affinity_n && ccf->cpu_affinity_n != 1 && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes) { @@ -1273,7 +1275,24 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx value = cf->args->elts; - for (n = 1; n < cf->args->nelts; n++) { + if (ngx_strcmp(value[1].data, "auto") == 0) { + + if (cf->args->nelts > 3) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid number of arguments in " + "\"worker_cpu_affinity\" directive"); + return NGX_CONF_ERROR; + } + + ccf->cpu_affinity_auto = 1; + mask[0] = (uint64_t) -1 >> (64 - ngx_min(64, ngx_ncpu)); + n = 2; + + } else { + n = 1; + } + + for ( /* void */ ; n < cf->args->nelts; n++) { if (value[n].len > 64) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, @@ -1323,6 +1342,8 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx uint64_t ngx_get_cpu_affinity(ngx_uint_t n) { + uint64_t mask; + ngx_uint_t i; ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, @@ -1332,6 +1353,24 @@ ngx_get_cpu_affinity(ngx_uint_t n) return 0; } + if (ccf->cpu_affinity_auto) { + mask = ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; + + if (mask == 0) { + return 0; + } + + for (i = 0; /* void */ ; i++) { + if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 0) { + break; + } + + /* void */ + } + + return (uint64_t) 1 << (i % 64); + } + if (ccf->cpu_affinity_n > n) { return ccf->cpu_affinity[n]; } diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -88,6 +88,7 @@ typedef struct { int priority; + ngx_uint_t cpu_affinity_auto; ngx_uint_t cpu_affinity_n; uint64_t *cpu_affinity;