comparison src/core/nginx.c @ 6402:7296b38f6416

Core: added support for more than 64 CPUs in worker_cpu_affinity.
author Vladimir Homutov <vl@nginx.com>
date Thu, 18 Feb 2016 13:58:49 +0300
parents 50fb3fd79f76
children 0ff7eff48c7e
comparison
equal deleted inserted replaced
6401:6812ca9a8002 6402:7296b38f6416
1268 ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 1268 ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1269 { 1269 {
1270 #if (NGX_HAVE_CPU_AFFINITY) 1270 #if (NGX_HAVE_CPU_AFFINITY)
1271 ngx_core_conf_t *ccf = conf; 1271 ngx_core_conf_t *ccf = conf;
1272 1272
1273 u_char ch; 1273 u_char ch, *p;
1274 uint64_t *mask;
1275 ngx_str_t *value; 1274 ngx_str_t *value;
1276 ngx_uint_t i, n; 1275 ngx_uint_t i, n;
1276 ngx_cpuset_t *mask;
1277 1277
1278 if (ccf->cpu_affinity) { 1278 if (ccf->cpu_affinity) {
1279 return "is duplicate"; 1279 return "is duplicate";
1280 } 1280 }
1281 1281
1282 mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t)); 1282 mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(ngx_cpuset_t));
1283 if (mask == NULL) { 1283 if (mask == NULL) {
1284 return NGX_CONF_ERROR; 1284 return NGX_CONF_ERROR;
1285 } 1285 }
1286 1286
1287 ccf->cpu_affinity_n = cf->args->nelts - 1; 1287 ccf->cpu_affinity_n = cf->args->nelts - 1;
1297 "\"worker_cpu_affinity\" directive"); 1297 "\"worker_cpu_affinity\" directive");
1298 return NGX_CONF_ERROR; 1298 return NGX_CONF_ERROR;
1299 } 1299 }
1300 1300
1301 ccf->cpu_affinity_auto = 1; 1301 ccf->cpu_affinity_auto = 1;
1302 mask[0] = (uint64_t) -1 >> (64 - ngx_min(64, ngx_ncpu)); 1302
1303 CPU_ZERO(&mask[0]);
1304 for (i = 0; i < (ngx_uint_t) ngx_min(ngx_ncpu, CPU_SETSIZE); i++) {
1305 CPU_SET(i, &mask[0]);
1306 }
1307
1303 n = 2; 1308 n = 2;
1304 1309
1305 } else { 1310 } else {
1306 n = 1; 1311 n = 1;
1307 } 1312 }
1308 1313
1309 for ( /* void */ ; n < cf->args->nelts; n++) { 1314 for ( /* void */ ; n < cf->args->nelts; n++) {
1310 1315
1311 if (value[n].len > 64) { 1316 if (value[n].len > CPU_SETSIZE) {
1312 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 1317 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1313 "\"worker_cpu_affinity\" supports up to 64 CPUs only"); 1318 "\"worker_cpu_affinity\" supports up to %d CPUs only",
1319 CPU_SETSIZE);
1314 return NGX_CONF_ERROR; 1320 return NGX_CONF_ERROR;
1315 } 1321 }
1316 1322
1317 mask[n - 1] = 0; 1323 i = 0;
1318 1324 CPU_ZERO(&mask[n - 1]);
1319 for (i = 0; i < value[n].len; i++) { 1325
1320 1326 for (p = value[n].data + value[n].len - 1;
1321 ch = value[n].data[i]; 1327 p >= value[n].data;
1328 p--)
1329 {
1330 ch = *p;
1322 1331
1323 if (ch == ' ') { 1332 if (ch == ' ') {
1324 continue; 1333 continue;
1325 } 1334 }
1326 1335
1327 mask[n - 1] <<= 1; 1336 i++;
1328 1337
1329 if (ch == '0') { 1338 if (ch == '0') {
1330 continue; 1339 continue;
1331 } 1340 }
1332 1341
1333 if (ch == '1') { 1342 if (ch == '1') {
1334 mask[n - 1] |= 1; 1343 CPU_SET(i - 1, &mask[n - 1]);
1335 continue; 1344 continue;
1336 } 1345 }
1337 1346
1338 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 1347 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1339 "invalid character \"%c\" in \"worker_cpu_affinity\"", 1348 "invalid character \"%c\" in \"worker_cpu_affinity\"",
1351 1360
1352 return NGX_CONF_OK; 1361 return NGX_CONF_OK;
1353 } 1362 }
1354 1363
1355 1364
1356 uint64_t 1365 ngx_cpuset_t *
1357 ngx_get_cpu_affinity(ngx_uint_t n) 1366 ngx_get_cpu_affinity(ngx_uint_t n)
1358 { 1367 {
1359 uint64_t mask; 1368 #if (NGX_HAVE_CPU_AFFINITY)
1360 ngx_uint_t i; 1369 ngx_uint_t i, j;
1370 ngx_cpuset_t *mask;
1361 ngx_core_conf_t *ccf; 1371 ngx_core_conf_t *ccf;
1372
1373 static ngx_cpuset_t result;
1362 1374
1363 ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, 1375 ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
1364 ngx_core_module); 1376 ngx_core_module);
1365 1377
1366 if (ccf->cpu_affinity == NULL) { 1378 if (ccf->cpu_affinity == NULL) {
1367 return 0; 1379 return NULL;
1368 } 1380 }
1369 1381
1370 if (ccf->cpu_affinity_auto) { 1382 if (ccf->cpu_affinity_auto) {
1371 mask = ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; 1383 mask = &ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
1372 1384
1373 if (mask == 0) { 1385 for (i = 0, j = n; /* void */ ; i++) {
1374 return 0; 1386
1375 } 1387 if (CPU_ISSET(i % CPU_SETSIZE, mask) && j-- == 0) {
1376
1377 for (i = 0; /* void */ ; i++) {
1378 if ((mask & ((uint64_t) 1 << (i % 64))) && n-- == 0) {
1379 break; 1388 break;
1380 } 1389 }
1381 1390
1391 if (i == CPU_SETSIZE && j == n) {
1392 /* empty mask */
1393 return NULL;
1394 }
1395
1382 /* void */ 1396 /* void */
1383 } 1397 }
1384 1398
1385 return (uint64_t) 1 << (i % 64); 1399 CPU_ZERO(&result);
1400 CPU_SET(i % CPU_SETSIZE, &result);
1401
1402 return &result;
1386 } 1403 }
1387 1404
1388 if (ccf->cpu_affinity_n > n) { 1405 if (ccf->cpu_affinity_n > n) {
1389 return ccf->cpu_affinity[n]; 1406 return &ccf->cpu_affinity[n];
1390 } 1407 }
1391 1408
1392 return ccf->cpu_affinity[ccf->cpu_affinity_n - 1]; 1409 return &ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
1410
1411 #else
1412
1413 return NULL;
1414
1415 #endif
1393 } 1416 }
1394 1417
1395 1418
1396 static char * 1419 static char *
1397 ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 1420 ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)