src/os/linux/vm/os_linux.cpp
Print this page
rev 6079 : 8037340: Linux semaphores are associated with CLOCK_REALTIME and need relative to absolute time conversion utility
Reviewed-by:
*** 152,161 ****
--- 152,162 ----
/* Used to protect dlsym() calls */
static pthread_mutex_t dl_mutex;
// Declarations
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
+ static void absoluteRealTimeForRelativeTime(timespec* absTime, jlong relTime);
#ifdef JAVASE_EMBEDDED
class MemNotifyThread: public Thread {
friend class VMStructs;
public:
*** 2432,2442 ****
bool timedwait(unsigned int sec, int nsec);
private:
sem_t _semaphore;
};
-
Semaphore::Semaphore() {
sem_init(&_semaphore, 0, 0);
}
Semaphore::~Semaphore() {
--- 2433,2442 ----
*** 2455,2465 ****
return sem_trywait(&_semaphore) == 0;
}
bool Semaphore::timedwait(unsigned int sec, int nsec) {
struct timespec ts;
! unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
while (1) {
int result = sem_timedwait(&_semaphore, &ts);
if (result == 0) {
return true;
--- 2455,2466 ----
return sem_trywait(&_semaphore) == 0;
}
bool Semaphore::timedwait(unsigned int sec, int nsec) {
struct timespec ts;
! // Semaphore's are always associated with CLOCK_REALTIME
! absoluteRealTimeForRelativeTime(&ts, (sec * NANOSECS_PER_SEC) + nsec);
while (1) {
int result = sem_timedwait(&_semaphore, &ts);
if (result == 0) {
return true;
*** 5732,5741 ****
--- 5733,5799 ----
assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
}
+ /*
+ * Certain structures, for example Semaphores, are always associated
+ * with CLOCK_REALTIME derived absolute time representations.
+ * This helper will yield an absolute realtime representation for the passed
+ * in relative time. We should be able to use clock_gettime for most
+ * supported Linux's, but if that is not possible we will fallback to use
+ * gettimeofday.
+ *
+ * utility to compute the abstime argument using CLOCK_REALTIME where possible.
+ *
+ * relTime is the relative time in nanoseconds.
+ * absTime will be the absolute time in seconds and nanoseconds.
+ */
+ static void absoluteRealTimeForRelativeTime(timespec* absTime, jlong relTime) {
+ assert(absTime != NULL, "invariant");
+ assert(relTime > 0, "invariant");
+
+ time_t max_secs = 0;
+ jlong secs = relTime / NANOSECS_PER_SEC;
+
+ if (os::supports_monotonic_clock()) { // check avail of clock_gettime
+ struct timespec now;
+ int status = os::Linux::clock_gettime(CLOCK_REALTIME, &now);
+ assert_status(status == 0, status, "clock_gettime");
+ max_secs = now.tv_sec + MAX_SECS;
+ if (secs >= MAX_SECS) {
+ absTime->tv_sec = max_secs;
+ absTime->tv_nsec = 0;
+ } else {
+ absTime->tv_sec = now.tv_sec + secs;
+ absTime->tv_nsec = (relTime % NANOSECS_PER_SEC) + now.tv_nsec;
+ }
+ } else {
+ struct timeval now;
+ int status = gettimeofday(&now, NULL);
+ assert(status == 0, "gettimeofday");
+ max_secs = now.tv_sec + MAX_SECS;
+ if (secs >= MAX_SECS) {
+ absTime->tv_sec = max_secs;
+ absTime->tv_nsec = 0;
+ } else {
+ absTime->tv_sec = now.tv_sec + secs;
+ absTime->tv_nsec = (relTime % NANOSECS_PER_SEC) + now.tv_usec*1000;
+ }
+ }
+
+ if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
+ absTime->tv_nsec -= NANOSECS_PER_SEC;
+ ++absTime->tv_sec; // note: this must be <= max_secs
+ }
+
+ assert(absTime->tv_sec >= 0, "tv_sec < 0");
+ assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
+ assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
+ assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
+ }
+
void Parker::park(bool isAbsolute, jlong time) {
// Ideally we'd do something useful while spinning, such
// as calling unpackTime().
// Optional fast-path check: