src/os/bsd/vm/os_bsd.cpp

changeset 6782
f73af4455d7d
parent 6779
364b73402247
parent 6680
78bbf4d43a14
child 6876
710a3c8b516e
child 6918
d22136881b85
equal deleted inserted replaced
6781:da65bbf6f89e 6782:f73af4455d7d
121 121
122 // for timer info max values which include all bits 122 // for timer info max values which include all bits
123 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) 123 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
124 124
125 #define LARGEPAGES_BIT (1 << 6) 125 #define LARGEPAGES_BIT (1 << 6)
126
127 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
128
126 //////////////////////////////////////////////////////////////////////////////// 129 ////////////////////////////////////////////////////////////////////////////////
127 // global variables 130 // global variables
128 julong os::Bsd::_physical_memory = 0; 131 julong os::Bsd::_physical_memory = 0;
129 132
130 133 #ifdef __APPLE__
134 mach_timebase_info_data_t os::Bsd::_timebase_info = {0, 0};
135 volatile uint64_t os::Bsd::_max_abstime = 0;
136 #else
131 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL; 137 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
138 #endif
132 pthread_t os::Bsd::_main_thread; 139 pthread_t os::Bsd::_main_thread;
133 int os::Bsd::_page_size = -1; 140 int os::Bsd::_page_size = -1;
134 141
135 static jlong initial_time_count=0; 142 static jlong initial_time_count=0;
136 143
984 int status = gettimeofday(&time, NULL); 991 int status = gettimeofday(&time, NULL);
985 assert(status != -1, "bsd error"); 992 assert(status != -1, "bsd error");
986 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); 993 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
987 } 994 }
988 995
996 #ifndef __APPLE__
989 #ifndef CLOCK_MONOTONIC 997 #ifndef CLOCK_MONOTONIC
990 #define CLOCK_MONOTONIC (1) 998 #define CLOCK_MONOTONIC (1)
991 #endif 999 #endif
1000 #endif
992 1001
993 #ifdef __APPLE__ 1002 #ifdef __APPLE__
994 void os::Bsd::clock_init() { 1003 void os::Bsd::clock_init() {
995 // XXXDARWIN: Investigate replacement monotonic clock 1004 mach_timebase_info(&_timebase_info);
996 } 1005 }
997 #else 1006 #else
998 void os::Bsd::clock_init() { 1007 void os::Bsd::clock_init() {
999 struct timespec res; 1008 struct timespec res;
1000 struct timespec tp; 1009 struct timespec tp;
1005 } 1014 }
1006 } 1015 }
1007 #endif 1016 #endif
1008 1017
1009 1018
1019 #ifdef __APPLE__
1020
1021 jlong os::javaTimeNanos() {
1022 const uint64_t tm = mach_absolute_time();
1023 const uint64_t now = (tm * Bsd::_timebase_info.numer) / Bsd::_timebase_info.denom;
1024 const uint64_t prev = Bsd::_max_abstime;
1025 if (now <= prev) {
1026 return prev; // same or retrograde time;
1027 }
1028 const uint64_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&Bsd::_max_abstime, prev);
1029 assert(obsv >= prev, "invariant"); // Monotonicity
1030 // If the CAS succeeded then we're done and return "now".
1031 // If the CAS failed and the observed value "obsv" is >= now then
1032 // we should return "obsv". If the CAS failed and now > obsv > prv then
1033 // some other thread raced this thread and installed a new value, in which case
1034 // we could either (a) retry the entire operation, (b) retry trying to install now
1035 // or (c) just return obsv. We use (c). No loop is required although in some cases
1036 // we might discard a higher "now" value in deference to a slightly lower but freshly
1037 // installed obsv value. That's entirely benign -- it admits no new orderings compared
1038 // to (a) or (b) -- and greatly reduces coherence traffic.
1039 // We might also condition (c) on the magnitude of the delta between obsv and now.
1040 // Avoiding excessive CAS operations to hot RW locations is critical.
1041 // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
1042 return (prev == obsv) ? now : obsv;
1043 }
1044
1045 #else // __APPLE__
1046
1010 jlong os::javaTimeNanos() { 1047 jlong os::javaTimeNanos() {
1011 if (Bsd::supports_monotonic_clock()) { 1048 if (Bsd::supports_monotonic_clock()) {
1012 struct timespec tp; 1049 struct timespec tp;
1013 int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp); 1050 int status = Bsd::_clock_gettime(CLOCK_MONOTONIC, &tp);
1014 assert(status == 0, "gettime error"); 1051 assert(status == 0, "gettime error");
1015 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); 1052 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
1016 return result; 1053 return result;
1017 } else { 1054 } else {
1018 timeval time; 1055 timeval time;
1020 assert(status != -1, "bsd error"); 1057 assert(status != -1, "bsd error");
1021 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); 1058 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
1022 return 1000 * usecs; 1059 return 1000 * usecs;
1023 } 1060 }
1024 } 1061 }
1062
1063 #endif // __APPLE__
1025 1064
1026 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { 1065 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
1027 if (Bsd::supports_monotonic_clock()) { 1066 if (Bsd::supports_monotonic_clock()) {
1028 info_ptr->max_value = ALL_64_BITS; 1067 info_ptr->max_value = ALL_64_BITS;
1029 1068
2349 2388
2350 bool warn_on_failure = UseLargePages && 2389 bool warn_on_failure = UseLargePages &&
2351 (!FLAG_IS_DEFAULT(UseLargePages) || 2390 (!FLAG_IS_DEFAULT(UseLargePages) ||
2352 !FLAG_IS_DEFAULT(LargePageSizeInBytes) 2391 !FLAG_IS_DEFAULT(LargePageSizeInBytes)
2353 ); 2392 );
2354 char msg[128];
2355 2393
2356 // Create a large shared memory region to attach to based on size. 2394 // Create a large shared memory region to attach to based on size.
2357 // Currently, size is the total size of the heap 2395 // Currently, size is the total size of the heap
2358 int shmid = shmget(key, bytes, IPC_CREAT|SHM_R|SHM_W); 2396 int shmid = shmget(key, bytes, IPC_CREAT|SHM_R|SHM_W);
2359 if (shmid == -1) { 2397 if (shmid == -1) {
2370 // Note 2: it's possible there's enough physical memory available but 2408 // Note 2: it's possible there's enough physical memory available but
2371 // they are so fragmented after a long run that they can't 2409 // they are so fragmented after a long run that they can't
2372 // coalesce into large pages. Try to reserve large pages when 2410 // coalesce into large pages. Try to reserve large pages when
2373 // the system is still "fresh". 2411 // the system is still "fresh".
2374 if (warn_on_failure) { 2412 if (warn_on_failure) {
2375 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); 2413 warning("Failed to reserve shared memory (errno = %d).", errno);
2376 warning(msg);
2377 } 2414 }
2378 return NULL; 2415 return NULL;
2379 } 2416 }
2380 2417
2381 // attach to the region 2418 // attach to the region
2388 // segment immediately. 2425 // segment immediately.
2389 shmctl(shmid, IPC_RMID, NULL); 2426 shmctl(shmid, IPC_RMID, NULL);
2390 2427
2391 if ((intptr_t)addr == -1) { 2428 if ((intptr_t)addr == -1) {
2392 if (warn_on_failure) { 2429 if (warn_on_failure) {
2393 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); 2430 warning("Failed to attach shared memory (errno = %d).", err);
2394 warning(msg);
2395 } 2431 }
2396 return NULL; 2432 return NULL;
2397 } 2433 }
2398 2434
2399 // The memory is committed 2435 // The memory is committed
3888 3924
3889 bool os::check_heap(bool force) { 3925 bool os::check_heap(bool force) {
3890 return true; 3926 return true;
3891 } 3927 }
3892 3928
3929 ATTRIBUTE_PRINTF(3, 0)
3893 int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) { 3930 int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
3894 return ::vsnprintf(buf, count, format, args); 3931 return ::vsnprintf(buf, count, format, args);
3895 } 3932 }
3896 3933
3897 // Is a (classpath) directory empty? 3934 // Is a (classpath) directory empty?

mercurial