|
31 | 31 | #include <sys/resource.h>
|
32 | 32 | #if KMP_OS_AIX
|
33 | 33 | #include <sys/ldr.h>
|
| 34 | +#include <libperfstat.h> |
34 | 35 | #else
|
35 | 36 | #include <sys/syscall.h>
|
36 | 37 | #endif
|
@@ -2427,6 +2428,79 @@ int __kmp_get_load_balance(int max) {
|
2427 | 2428 | return ret_avg;
|
2428 | 2429 | }
|
2429 | 2430 |
|
| 2431 | +#elif KMP_OS_AIX |
| 2432 | + |
| 2433 | +// The function returns number of running (not sleeping) threads, or -1 in case |
| 2434 | +// of error. |
| 2435 | +int __kmp_get_load_balance(int max) { |
| 2436 | + |
| 2437 | + static int glb_running_threads = 0; // Saved count of the running threads for |
| 2438 | + // the thread balance algorithm. |
| 2439 | + static double glb_call_time = 0; // Thread balance algorithm call time. |
| 2440 | + int running_threads = 0; // Number of running threads in the system. |
| 2441 | + |
| 2442 | + double call_time = 0.0; |
| 2443 | + |
| 2444 | + __kmp_elapsed(&call_time); |
| 2445 | + |
| 2446 | + if (glb_call_time && |
| 2447 | + (call_time - glb_call_time < __kmp_load_balance_interval)) |
| 2448 | + return glb_running_threads; |
| 2449 | + |
| 2450 | + glb_call_time = call_time; |
| 2451 | + |
| 2452 | + if (max <= 0) { |
| 2453 | + max = INT_MAX; |
| 2454 | + } |
| 2455 | + |
| 2456 | + // Check how many perfstat_cpu_t structures are available. |
| 2457 | + int logical_cpus = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); |
| 2458 | + if (logical_cpus <= 0) { |
| 2459 | + glb_call_time = -1; |
| 2460 | + return -1; |
| 2461 | + } |
| 2462 | + |
| 2463 | + perfstat_cpu_t *cpu_stat = (perfstat_cpu_t *)KMP_INTERNAL_MALLOC( |
| 2464 | + logical_cpus * sizeof(perfstat_cpu_t)); |
| 2465 | + if (cpu_stat == NULL) { |
| 2466 | + glb_call_time = -1; |
| 2467 | + return -1; |
| 2468 | + } |
| 2469 | + |
| 2470 | + // Set first CPU as the name of the first logical CPU for which the info is |
| 2471 | + // desired. |
| 2472 | + perfstat_id_t first_cpu_name; |
| 2473 | + strcpy(first_cpu_name.name, FIRST_CPU); |
| 2474 | + |
| 2475 | + // Get the stat info of logical CPUs. |
| 2476 | + int rc = perfstat_cpu(&first_cpu_name, cpu_stat, sizeof(perfstat_cpu_t), |
| 2477 | + logical_cpus); |
| 2478 | + KMP_DEBUG_ASSERT(rc == logical_cpus); |
| 2479 | + if (rc <= 0) { |
| 2480 | + KMP_INTERNAL_FREE(cpu_stat); |
| 2481 | + glb_call_time = -1; |
| 2482 | + return -1; |
| 2483 | + } |
| 2484 | + for (int i = 0; i < logical_cpus; ++i) { |
| 2485 | + running_threads += cpu_stat[i].runque; |
| 2486 | + if (running_threads >= max) |
| 2487 | + break; |
| 2488 | + } |
| 2489 | + |
| 2490 | + // There _might_ be a timing hole where the thread executing this |
| 2491 | + // code gets skipped in the load balance, and running_threads is 0. |
| 2492 | + // Assert in the debug builds only!!! |
| 2493 | + KMP_DEBUG_ASSERT(running_threads > 0); |
| 2494 | + if (running_threads <= 0) |
| 2495 | + running_threads = 1; |
| 2496 | + |
| 2497 | + KMP_INTERNAL_FREE(cpu_stat); |
| 2498 | + |
| 2499 | + glb_running_threads = running_threads; |
| 2500 | + |
| 2501 | + return running_threads; |
| 2502 | +} |
| 2503 | + |
2430 | 2504 | #else // Linux* OS
|
2431 | 2505 |
|
2432 | 2506 | // The function returns number of running (not sleeping) threads, or -1 in case
|
@@ -2498,14 +2572,9 @@ int __kmp_get_load_balance(int max) {
|
2498 | 2572 |
|
2499 | 2573 | proc_entry = readdir(proc_dir);
|
2500 | 2574 | while (proc_entry != NULL) {
|
2501 |
| -#if KMP_OS_AIX |
2502 |
| - // Proc entry name starts with a digit. Assume it is a process' directory. |
2503 |
| - if (isdigit(proc_entry->d_name[0])) { |
2504 |
| -#else |
2505 | 2575 | // Proc entry is a directory and name starts with a digit. Assume it is a
|
2506 | 2576 | // process' directory.
|
2507 | 2577 | if (proc_entry->d_type == DT_DIR && isdigit(proc_entry->d_name[0])) {
|
2508 |
| -#endif |
2509 | 2578 |
|
2510 | 2579 | #ifdef KMP_DEBUG
|
2511 | 2580 | ++total_processes;
|
@@ -2549,11 +2618,7 @@ int __kmp_get_load_balance(int max) {
|
2549 | 2618 | task_entry = readdir(task_dir);
|
2550 | 2619 | while (task_entry != NULL) {
|
2551 | 2620 | // It is a directory and name starts with a digit.
|
2552 |
| -#if KMP_OS_AIX |
2553 |
| - if (isdigit(task_entry->d_name[0])) { |
2554 |
| -#else |
2555 | 2621 | if (proc_entry->d_type == DT_DIR && isdigit(task_entry->d_name[0])) {
|
2556 |
| -#endif |
2557 | 2622 |
|
2558 | 2623 | // Construct complete stat file path. Easiest way would be:
|
2559 | 2624 | // __kmp_str_buf_print( & stat_path, "%s/%s/stat", task_path.str,
|
|
0 commit comments