src/os/linux/vm/os_linux.cpp

Print this page
rev 6079 : 8037340: Linux semaphores to use CLOCK_REALTIME
Reviewed-by:


  92 # include <fcntl.h>
  93 # include <string.h>
  94 # include <syscall.h>
  95 # include <sys/sysinfo.h>
  96 # include <gnu/libc-version.h>
  97 # include <sys/ipc.h>
  98 # include <sys/shm.h>
  99 # include <link.h>
 100 # include <stdint.h>
 101 # include <inttypes.h>
 102 # include <sys/ioctl.h>
 103 
 104 // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
 105 // getrusage() is prepared to handle the associated failure.
 106 #ifndef RUSAGE_THREAD
 107 #define RUSAGE_THREAD   (1)               /* only the calling thread */
 108 #endif
 109 
 110 #define MAX_PATH    (2 * K)
 111 


 112 // for timer info max values which include all bits
 113 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 114 
 115 #define LARGEPAGES_BIT (1 << 6)
 116 ////////////////////////////////////////////////////////////////////////////////
 117 // global variables
 118 julong os::Linux::_physical_memory = 0;
 119 
 120 address   os::Linux::_initial_thread_stack_bottom = NULL;
 121 uintptr_t os::Linux::_initial_thread_stack_size   = 0;
 122 
 123 int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL;
 124 int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
 125 Mutex* os::Linux::_createThread_lock = NULL;
 126 pthread_t os::Linux::_main_thread;
 127 int os::Linux::_page_size = -1;
 128 const int os::Linux::_vm_default_page_size = (8 * K);
 129 bool os::Linux::_is_floating_stack = false;
 130 bool os::Linux::_is_NPTL = false;
 131 bool os::Linux::_supports_fast_thread_cpu_time = false;


2417 
2418   os::signal_notify(sig);
2419 }
2420 
2421 void* os::user_handler() {
2422   return CAST_FROM_FN_PTR(void*, UserHandler);
2423 }
2424 
2425 class Semaphore : public StackObj {
2426   public:
2427     Semaphore();
2428     ~Semaphore();
2429     void signal();
2430     void wait();
2431     bool trywait();
2432     bool timedwait(unsigned int sec, int nsec);
2433   private:
2434     sem_t _semaphore;
2435 };
2436 
2437 
2438 Semaphore::Semaphore() {
2439   sem_init(&_semaphore, 0, 0);
2440 }
2441 
2442 Semaphore::~Semaphore() {
2443   sem_destroy(&_semaphore);
2444 }
2445 
2446 void Semaphore::signal() {
2447   sem_post(&_semaphore);
2448 }
2449 
2450 void Semaphore::wait() {
2451   sem_wait(&_semaphore);
2452 }
2453 
2454 bool Semaphore::trywait() {
2455   return sem_trywait(&_semaphore) == 0;
2456 }
2457 
2458 bool Semaphore::timedwait(unsigned int sec, int nsec) {

2459   struct timespec ts;
2460   unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);













2461 
2462   while (1) {
2463     int result = sem_timedwait(&_semaphore, &ts);
2464     if (result == 0) {
2465       return true;
2466     } else if (errno == EINTR) {
2467       continue;
2468     } else if (errno == ETIMEDOUT) {
2469       return false;
2470     } else {
2471       return false;
2472     }
2473   }
2474 }
2475 
2476 extern "C" {
2477   typedef void (*sa_handler_t)(int);
2478   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2479 }
2480 


5639   // circumstances this can cause a thread to return prematurely from
5640   // cond_{timed}wait() but the spurious wakeup is benign and the victim will
5641   // simply re-test the condition and re-park itself.
5642 }
5643 
5644 
5645 // JSR166
5646 // -------------------------------------------------------
5647 
5648 /*
5649  * The solaris and linux implementations of park/unpark are fairly
5650  * conservative for now, but can be improved. They currently use a
5651  * mutex/condvar pair, plus a a count.
5652  * Park decrements count if > 0, else does a condvar wait.  Unpark
5653  * sets count to 1 and signals condvar.  Only one thread ever waits
5654  * on the condvar. Contention seen when trying to park implies that someone
5655  * is unparking you, so don't wait. And spurious returns are fine, so there
5656  * is no need to track notifications.
5657  */
5658 
5659 #define MAX_SECS 100000000
5660 /*
5661  * This code is common to linux and solaris and will be moved to a
5662  * common place in dolphin.
5663  *
5664  * The passed in time value is either a relative time in nanoseconds
5665  * or an absolute time in milliseconds. Either way it has to be unpacked
5666  * into suitable seconds and nanoseconds components and stored in the
5667  * given timespec structure.
5668  * Given time is a 64-bit value and the time_t used in the timespec is only
5669  * a signed-32-bit value (except on 64-bit Linux) we have to watch for
5670  * overflow if times way in the future are given. Further on Solaris versions
5671  * prior to 10 there is a restriction (see cond_timedwait) that the specified
5672  * number of seconds, in abstime, is less than current_time  + 100,000,000.
5673  * As it will be 28 years before "now + 100000000" will overflow we can
5674  * ignore overflow and just impose a hard-limit on seconds using the value
5675  * of "now + 100,000,000". This places a limit on the timeout of about 3.17
5676  * years from "now".
5677  */
5678 
5679 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {




  92 # include <fcntl.h>
  93 # include <string.h>
  94 # include <syscall.h>
  95 # include <sys/sysinfo.h>
  96 # include <gnu/libc-version.h>
  97 # include <sys/ipc.h>
  98 # include <sys/shm.h>
  99 # include <link.h>
 100 # include <stdint.h>
 101 # include <inttypes.h>
 102 # include <sys/ioctl.h>
 103 
 104 // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
 105 // getrusage() is prepared to handle the associated failure.
 106 #ifndef RUSAGE_THREAD
 107 #define RUSAGE_THREAD   (1)               /* only the calling thread */
 108 #endif
 109 
 110 #define MAX_PATH    (2 * K)
 111 
 112 #define MAX_SECS 100000000
 113 
 114 // for timer info max values which include all bits
 115 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 116 
 117 #define LARGEPAGES_BIT (1 << 6)
 118 ////////////////////////////////////////////////////////////////////////////////
 119 // global variables
 120 julong os::Linux::_physical_memory = 0;
 121 
 122 address   os::Linux::_initial_thread_stack_bottom = NULL;
 123 uintptr_t os::Linux::_initial_thread_stack_size   = 0;
 124 
 125 int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL;
 126 int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
 127 Mutex* os::Linux::_createThread_lock = NULL;
 128 pthread_t os::Linux::_main_thread;
 129 int os::Linux::_page_size = -1;
 130 const int os::Linux::_vm_default_page_size = (8 * K);
 131 bool os::Linux::_is_floating_stack = false;
 132 bool os::Linux::_is_NPTL = false;
 133 bool os::Linux::_supports_fast_thread_cpu_time = false;


2419 
2420   os::signal_notify(sig);
2421 }
2422 
2423 void* os::user_handler() {
2424   return CAST_FROM_FN_PTR(void*, UserHandler);
2425 }
2426 
2427 class Semaphore : public StackObj {
2428   public:
2429     Semaphore();
2430     ~Semaphore();
2431     void signal();
2432     void wait();
2433     bool trywait();
2434     bool timedwait(unsigned int sec, int nsec);
2435   private:
2436     sem_t _semaphore;
2437 };
2438 

2439 Semaphore::Semaphore() {
2440   sem_init(&_semaphore, 0, 0);
2441 }
2442 
2443 Semaphore::~Semaphore() {
2444   sem_destroy(&_semaphore);
2445 }
2446 
2447 void Semaphore::signal() {
2448   sem_post(&_semaphore);
2449 }
2450 
2451 void Semaphore::wait() {
2452   sem_wait(&_semaphore);
2453 }
2454 
2455 bool Semaphore::trywait() {
2456   return sem_trywait(&_semaphore) == 0;
2457 }
2458 
2459 bool Semaphore::timedwait(unsigned int sec, int nsec) {
2460 
2461   struct timespec ts;
2462   // Semaphore's are always associated with CLOCK_REALTIME
2463   os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
2464   // see unpackTime for discussion on overflow checking
2465   if (sec >= MAX_SECS) {
2466     ts.tv_sec += MAX_SECS;
2467     ts.tv_nsec = 0;
2468   } else {
2469     ts.tv_sec += sec;
2470     ts.tv_nsec += nsec;
2471     if (ts.tv_nsec >= NANOSECS_PER_SEC) {
2472       ts.tv_nsec -= NANOSECS_PER_SEC;
2473       ++ts.tv_sec; // note: this must be <= max_secs
2474     }
2475   }
2476 
2477   while (1) {
2478     int result = sem_timedwait(&_semaphore, &ts);
2479     if (result == 0) {
2480       return true;
2481     } else if (errno == EINTR) {
2482       continue;
2483     } else if (errno == ETIMEDOUT) {
2484       return false;
2485     } else {
2486       return false;
2487     }
2488   }
2489 }
2490 
2491 extern "C" {
2492   typedef void (*sa_handler_t)(int);
2493   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2494 }
2495 


5654   // circumstances this can cause a thread to return prematurely from
5655   // cond_{timed}wait() but the spurious wakeup is benign and the victim will
5656   // simply re-test the condition and re-park itself.
5657 }
5658 
5659 
5660 // JSR166
5661 // -------------------------------------------------------
5662 
5663 /*
5664  * The solaris and linux implementations of park/unpark are fairly
5665  * conservative for now, but can be improved. They currently use a
5666  * mutex/condvar pair, plus a a count.
5667  * Park decrements count if > 0, else does a condvar wait.  Unpark
5668  * sets count to 1 and signals condvar.  Only one thread ever waits
5669  * on the condvar. Contention seen when trying to park implies that someone
5670  * is unparking you, so don't wait. And spurious returns are fine, so there
5671  * is no need to track notifications.
5672  */
5673 

5674 /*
5675  * This code is common to linux and solaris and will be moved to a
5676  * common place in dolphin.
5677  *
5678  * The passed in time value is either a relative time in nanoseconds
5679  * or an absolute time in milliseconds. Either way it has to be unpacked
5680  * into suitable seconds and nanoseconds components and stored in the
5681  * given timespec structure.
5682  * Given time is a 64-bit value and the time_t used in the timespec is only
5683  * a signed-32-bit value (except on 64-bit Linux) we have to watch for
5684  * overflow if times way in the future are given. Further on Solaris versions
5685  * prior to 10 there is a restriction (see cond_timedwait) that the specified
5686  * number of seconds, in abstime, is less than current_time  + 100,000,000.
5687  * As it will be 28 years before "now + 100000000" will overflow we can
5688  * ignore overflow and just impose a hard-limit on seconds using the value
5689  * of "now + 100,000,000". This places a limit on the timeout of about 3.17
5690  * years from "now".
5691  */
5692 
5693 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {