318 if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) { |
315 if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) { |
319 uint_t pset_cpus; |
316 uint_t pset_cpus; |
320 // Query the number of cpus available to us. |
317 // Query the number of cpus available to us. |
321 if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) { |
318 if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) { |
322 assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check"); |
319 assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check"); |
323 _processors_online = pset_cpus; |
|
324 return pset_cpus; |
320 return pset_cpus; |
325 } |
321 } |
326 } |
322 } |
327 // Otherwise return number of online cpus |
323 // Otherwise return number of online cpus |
328 return online_cpus; |
324 return online_cpus; |
329 } |
|
330 |
|
331 static bool find_processors_in_pset(psetid_t pset, |
|
332 processorid_t** id_array, |
|
333 uint_t* id_length) { |
|
334 bool result = false; |
|
335 // Find the number of processors in the processor set. |
|
336 if (pset_info(pset, NULL, id_length, NULL) == 0) { |
|
337 // Make up an array to hold their ids. |
|
338 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal); |
|
339 // Fill in the array with their processor ids. |
|
340 if (pset_info(pset, NULL, id_length, *id_array) == 0) { |
|
341 result = true; |
|
342 } |
|
343 } |
|
344 return result; |
|
345 } |
|
346 |
|
347 // Callers of find_processors_online() must tolerate imprecise results -- |
|
348 // the system configuration can change asynchronously because of DR |
|
349 // or explicit psradm operations. |
|
350 // |
|
351 // We also need to take care that the loop (below) terminates as the |
|
352 // number of processors online can change between the _SC_NPROCESSORS_ONLN |
|
353 // request and the loop that builds the list of processor ids. Unfortunately |
|
354 // there's no reliable way to determine the maximum valid processor id, |
|
355 // so we use a manifest constant, MAX_PROCESSOR_ID, instead. See p_online |
|
356 // man pages, which claim the processor id set is "sparse, but |
|
357 // not too sparse". MAX_PROCESSOR_ID is used to ensure that we eventually |
|
358 // exit the loop. |
|
359 // |
|
360 // In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's |
|
361 // not available on S8.0. |
|
362 |
|
363 static bool find_processors_online(processorid_t** id_array, |
|
364 uint* id_length) { |
|
365 const processorid_t MAX_PROCESSOR_ID = 100000; |
|
366 // Find the number of processors online. |
|
367 *id_length = sysconf(_SC_NPROCESSORS_ONLN); |
|
368 // Make up an array to hold their ids. |
|
369 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal); |
|
370 // Processors need not be numbered consecutively. |
|
371 long found = 0; |
|
372 processorid_t next = 0; |
|
373 while (found < *id_length && next < MAX_PROCESSOR_ID) { |
|
374 processor_info_t info; |
|
375 if (processor_info(next, &info) == 0) { |
|
376 // NB, PI_NOINTR processors are effectively online ... |
|
377 if (info.pi_state == P_ONLINE || info.pi_state == P_NOINTR) { |
|
378 (*id_array)[found] = next; |
|
379 found += 1; |
|
380 } |
|
381 } |
|
382 next += 1; |
|
383 } |
|
384 if (found < *id_length) { |
|
385 // The loop above didn't identify the expected number of processors. |
|
386 // We could always retry the operation, calling sysconf(_SC_NPROCESSORS_ONLN) |
|
387 // and re-running the loop, above, but there's no guarantee of progress |
|
388 // if the system configuration is in flux. Instead, we just return what |
|
389 // we've got. Note that in the worst case find_processors_online() could |
|
390 // return an empty set. (As a fall-back in the case of the empty set we |
|
391 // could just return the ID of the current processor). |
|
392 *id_length = found; |
|
393 } |
|
394 |
|
395 return true; |
|
396 } |
|
397 |
|
398 static bool assign_distribution(processorid_t* id_array, |
|
399 uint id_length, |
|
400 uint* distribution, |
|
401 uint distribution_length) { |
|
402 // We assume we can assign processorid_t's to uint's. |
|
403 assert(sizeof(processorid_t) == sizeof(uint), |
|
404 "can't convert processorid_t to uint"); |
|
405 // Quick check to see if we won't succeed. |
|
406 if (id_length < distribution_length) { |
|
407 return false; |
|
408 } |
|
409 // Assign processor ids to the distribution. |
|
410 // Try to shuffle processors to distribute work across boards, |
|
411 // assuming 4 processors per board. |
|
412 const uint processors_per_board = ProcessDistributionStride; |
|
413 // Find the maximum processor id. |
|
414 processorid_t max_id = 0; |
|
415 for (uint m = 0; m < id_length; m += 1) { |
|
416 max_id = MAX2(max_id, id_array[m]); |
|
417 } |
|
418 // The next id, to limit loops. |
|
419 const processorid_t limit_id = max_id + 1; |
|
420 // Make up markers for available processors. |
|
421 bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id, mtInternal); |
|
422 for (uint c = 0; c < limit_id; c += 1) { |
|
423 available_id[c] = false; |
|
424 } |
|
425 for (uint a = 0; a < id_length; a += 1) { |
|
426 available_id[id_array[a]] = true; |
|
427 } |
|
428 // Step by "boards", then by "slot", copying to "assigned". |
|
429 // NEEDS_CLEANUP: The assignment of processors should be stateful, |
|
430 // remembering which processors have been assigned by |
|
431 // previous calls, etc., so as to distribute several |
|
432 // independent calls of this method. What we'd like is |
|
433 // It would be nice to have an API that let us ask |
|
434 // how many processes are bound to a processor, |
|
435 // but we don't have that, either. |
|
436 // In the short term, "board" is static so that |
|
437 // subsequent distributions don't all start at board 0. |
|
438 static uint board = 0; |
|
439 uint assigned = 0; |
|
440 // Until we've found enough processors .... |
|
441 while (assigned < distribution_length) { |
|
442 // ... find the next available processor in the board. |
|
443 for (uint slot = 0; slot < processors_per_board; slot += 1) { |
|
444 uint try_id = board * processors_per_board + slot; |
|
445 if ((try_id < limit_id) && (available_id[try_id] == true)) { |
|
446 distribution[assigned] = try_id; |
|
447 available_id[try_id] = false; |
|
448 assigned += 1; |
|
449 break; |
|
450 } |
|
451 } |
|
452 board += 1; |
|
453 if (board * processors_per_board + 0 >= limit_id) { |
|
454 board = 0; |
|
455 } |
|
456 } |
|
457 FREE_C_HEAP_ARRAY(bool, available_id); |
|
458 return true; |
|
459 } |
325 } |
460 |
326 |
461 void os::set_native_thread_name(const char *name) { |
327 void os::set_native_thread_name(const char *name) { |
462 if (Solaris::_pthread_setname_np != NULL) { |
328 if (Solaris::_pthread_setname_np != NULL) { |
463 // Only the first 31 bytes of 'name' are processed by pthread_setname_np |
329 // Only the first 31 bytes of 'name' are processed by pthread_setname_np |
466 char buf[32]; |
332 char buf[32]; |
467 snprintf(buf, sizeof(buf), "%s", name); |
333 snprintf(buf, sizeof(buf), "%s", name); |
468 buf[sizeof(buf) - 1] = '\0'; |
334 buf[sizeof(buf) - 1] = '\0'; |
469 Solaris::_pthread_setname_np(pthread_self(), buf); |
335 Solaris::_pthread_setname_np(pthread_self(), buf); |
470 } |
336 } |
471 } |
|
472 |
|
473 bool os::distribute_processes(uint length, uint* distribution) { |
|
474 bool result = false; |
|
475 // Find the processor id's of all the available CPUs. |
|
476 processorid_t* id_array = NULL; |
|
477 uint id_length = 0; |
|
478 // There are some races between querying information and using it, |
|
479 // since processor sets can change dynamically. |
|
480 psetid_t pset = PS_NONE; |
|
481 // Are we running in a processor set? |
|
482 if ((pset_bind(PS_QUERY, P_PID, P_MYID, &pset) == 0) && pset != PS_NONE) { |
|
483 result = find_processors_in_pset(pset, &id_array, &id_length); |
|
484 } else { |
|
485 result = find_processors_online(&id_array, &id_length); |
|
486 } |
|
487 if (result == true) { |
|
488 if (id_length >= length) { |
|
489 result = assign_distribution(id_array, id_length, distribution, length); |
|
490 } else { |
|
491 result = false; |
|
492 } |
|
493 } |
|
494 FREE_C_HEAP_ARRAY(processorid_t, id_array); |
|
495 return result; |
|
496 } |
337 } |
497 |
338 |
498 bool os::bind_to_processor(uint processor_id) { |
339 bool os::bind_to_processor(uint processor_id) { |
499 // We assume that a processorid_t can be stored in a uint. |
340 // We assume that a processorid_t can be stored in a uint. |
500 assert(sizeof(uint) == sizeof(processorid_t), |
341 assert(sizeof(uint) == sizeof(processorid_t), |