248
249 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
250 return localtime_r(clock, res);
251 }
252
253 void os::Solaris::try_enable_extended_io() {
254 typedef int (*enable_extended_FILE_stdio_t)(int, int);
255
256 if (!UseExtendedFileIO) {
257 return;
258 }
259
260 enable_extended_FILE_stdio_t enabler =
261 (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT,
262 "enable_extended_FILE_stdio");
263 if (enabler) {
264 enabler(-1, -1);
265 }
266 }
267
268 static int _processors_online = 0;
269
270 jint os::Solaris::_os_thread_limit = 0;
271 volatile jint os::Solaris::_os_thread_count = 0;
272
273 julong os::available_memory() {
274 return Solaris::available_memory();
275 }
276
277 julong os::Solaris::available_memory() {
278 return (julong)sysconf(_SC_AVPHYS_PAGES) * os::vm_page_size();
279 }
280
281 julong os::Solaris::_physical_memory = 0;
282
283 julong os::physical_memory() {
284 return Solaris::physical_memory();
285 }
286
287 static hrtime_t first_hrtime = 0;
288 static const hrtime_t hrtime_hz = 1000*1000*1000;
289 static volatile hrtime_t max_hrtime = 0;
290
291
292 void os::Solaris::initialize_system_info() {
293 set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
294 _processors_online = sysconf(_SC_NPROCESSORS_ONLN);
295 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) *
296 (julong)sysconf(_SC_PAGESIZE);
297 }
298
299 uint os::processor_id() {
300 const processorid_t id = ::getcpuid();
301 assert(id >= 0 && id < _processor_count, "Invalid processor id");
302 return (uint)id;
303 }
304
305 int os::active_processor_count() {
306 // User has overridden the number of active processors
307 if (ActiveProcessorCount > 0) {
308 log_trace(os)("active_processor_count: "
309 "active processor count set by user : %d",
310 ActiveProcessorCount);
311 return ActiveProcessorCount;
312 }
313
314 int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
315 pid_t pid = getpid();
316 psetid_t pset = PS_NONE;
317 // Are we running in a processor set or is there any processor set around?
318 if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) {
319 uint_t pset_cpus;
320 // Query the number of cpus available to us.
321 if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
322 assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
323 _processors_online = pset_cpus;
324 return pset_cpus;
325 }
326 }
327 // Otherwise return number of online cpus
328 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 }
460
461 void os::set_native_thread_name(const char *name) {
462 if (Solaris::_pthread_setname_np != NULL) {
463 // Only the first 31 bytes of 'name' are processed by pthread_setname_np
464 // but we explicitly copy into a size-limited buffer to avoid any
465 // possible overflow.
466 char buf[32];
467 snprintf(buf, sizeof(buf), "%s", name);
468 buf[sizeof(buf) - 1] = '\0';
469 Solaris::_pthread_setname_np(pthread_self(), buf);
470 }
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 }
497
498 bool os::bind_to_processor(uint processor_id) {
499 // We assume that a processorid_t can be stored in a uint.
500 assert(sizeof(uint) == sizeof(processorid_t),
501 "can't convert uint to processorid_t");
502 int bind_result =
503 processor_bind(P_LWPID, // bind LWP.
504 P_MYID, // bind current LWP.
505 (processorid_t) processor_id, // id.
506 NULL); // don't return old binding.
507 return (bind_result == 0);
508 }
509
510 // Return true if user is running as root.
511
512 bool os::have_special_privileges() {
513 static bool init = false;
514 static bool privileges = false;
515 if (!init) {
516 privileges = (getuid() != geteuid()) || (getgid() != getegid());
517 init = true;
1220 double* process_user_time,
1221 double* process_system_time) {
1222 struct tms ticks;
1223 clock_t real_ticks = times(&ticks);
1224
1225 if (real_ticks == (clock_t) (-1)) {
1226 return false;
1227 } else {
1228 double ticks_per_second = (double) clock_tics_per_sec;
1229 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
1230 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
1231 // For consistency return the real time from getTimeNanos()
1232 // converted to seconds.
1233 *process_real_time = ((double) getTimeNanos()) / ((double) NANOUNITS);
1234
1235 return true;
1236 }
1237 }
1238
1239 bool os::supports_vtime() { return true; }
1240 bool os::enable_vtime() { return false; }
1241 bool os::vtime_enabled() { return false; }
1242
1243 double os::elapsedVTime() {
1244 return (double)gethrvtime() / (double)hrtime_hz;
1245 }
1246
1247 // Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
1248 jlong os::javaTimeMillis() {
1249 timeval t;
1250 if (gettimeofday(&t, NULL) == -1) {
1251 fatal("os::javaTimeMillis: gettimeofday (%s)", os::strerror(errno));
1252 }
1253 return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
1254 }
1255
1256 // Must return seconds+nanos since Jan 1 1970. This must use the same
1257 // time source as javaTimeMillis and can't use get_nsec_fromepoch as
1258 // we need better than 1ms accuracy
1259 void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
1260 timeval t;
1261 if (gettimeofday(&t, NULL) == -1) {
|
248
249 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
250 return localtime_r(clock, res);
251 }
252
253 void os::Solaris::try_enable_extended_io() {
254 typedef int (*enable_extended_FILE_stdio_t)(int, int);
255
256 if (!UseExtendedFileIO) {
257 return;
258 }
259
260 enable_extended_FILE_stdio_t enabler =
261 (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT,
262 "enable_extended_FILE_stdio");
263 if (enabler) {
264 enabler(-1, -1);
265 }
266 }
267
268 jint os::Solaris::_os_thread_limit = 0;
269 volatile jint os::Solaris::_os_thread_count = 0;
270
271 julong os::available_memory() {
272 return Solaris::available_memory();
273 }
274
275 julong os::Solaris::available_memory() {
276 return (julong)sysconf(_SC_AVPHYS_PAGES) * os::vm_page_size();
277 }
278
279 julong os::Solaris::_physical_memory = 0;
280
281 julong os::physical_memory() {
282 return Solaris::physical_memory();
283 }
284
285 static hrtime_t first_hrtime = 0;
286 static const hrtime_t hrtime_hz = 1000*1000*1000;
287 static volatile hrtime_t max_hrtime = 0;
288
289
290 void os::Solaris::initialize_system_info() {
291 set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
292 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) *
293 (julong)sysconf(_SC_PAGESIZE);
294 }
295
296 uint os::processor_id() {
297 const processorid_t id = ::getcpuid();
298 assert(id >= 0 && id < _processor_count, "Invalid processor id");
299 return (uint)id;
300 }
301
302 int os::active_processor_count() {
303 // User has overridden the number of active processors
304 if (ActiveProcessorCount > 0) {
305 log_trace(os)("active_processor_count: "
306 "active processor count set by user : %d",
307 ActiveProcessorCount);
308 return ActiveProcessorCount;
309 }
310
311 int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
312 pid_t pid = getpid();
313 psetid_t pset = PS_NONE;
314 // Are we running in a processor set or is there any processor set around?
315 if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) {
316 uint_t pset_cpus;
317 // Query the number of cpus available to us.
318 if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
319 assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
320 return pset_cpus;
321 }
322 }
323 // Otherwise return number of online cpus
324 return online_cpus;
325 }
326
327 void os::set_native_thread_name(const char *name) {
328 if (Solaris::_pthread_setname_np != NULL) {
329 // Only the first 31 bytes of 'name' are processed by pthread_setname_np
330 // but we explicitly copy into a size-limited buffer to avoid any
331 // possible overflow.
332 char buf[32];
333 snprintf(buf, sizeof(buf), "%s", name);
334 buf[sizeof(buf) - 1] = '\0';
335 Solaris::_pthread_setname_np(pthread_self(), buf);
336 }
337 }
338
339 bool os::bind_to_processor(uint processor_id) {
340 // We assume that a processorid_t can be stored in a uint.
341 assert(sizeof(uint) == sizeof(processorid_t),
342 "can't convert uint to processorid_t");
343 int bind_result =
344 processor_bind(P_LWPID, // bind LWP.
345 P_MYID, // bind current LWP.
346 (processorid_t) processor_id, // id.
347 NULL); // don't return old binding.
348 return (bind_result == 0);
349 }
350
351 // Return true if user is running as root.
352
353 bool os::have_special_privileges() {
354 static bool init = false;
355 static bool privileges = false;
356 if (!init) {
357 privileges = (getuid() != geteuid()) || (getgid() != getegid());
358 init = true;
1061 double* process_user_time,
1062 double* process_system_time) {
1063 struct tms ticks;
1064 clock_t real_ticks = times(&ticks);
1065
1066 if (real_ticks == (clock_t) (-1)) {
1067 return false;
1068 } else {
1069 double ticks_per_second = (double) clock_tics_per_sec;
1070 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
1071 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
1072 // For consistency return the real time from getTimeNanos()
1073 // converted to seconds.
1074 *process_real_time = ((double) getTimeNanos()) / ((double) NANOUNITS);
1075
1076 return true;
1077 }
1078 }
1079
1080 bool os::supports_vtime() { return true; }
1081
1082 double os::elapsedVTime() {
1083 return (double)gethrvtime() / (double)hrtime_hz;
1084 }
1085
1086 // Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
1087 jlong os::javaTimeMillis() {
1088 timeval t;
1089 if (gettimeofday(&t, NULL) == -1) {
1090 fatal("os::javaTimeMillis: gettimeofday (%s)", os::strerror(errno));
1091 }
1092 return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
1093 }
1094
1095 // Must return seconds+nanos since Jan 1 1970. This must use the same
1096 // time source as javaTimeMillis and can't use get_nsec_fromepoch as
1097 // we need better than 1ms accuracy
1098 void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
1099 timeval t;
1100 if (gettimeofday(&t, NULL) == -1) {
|