< prev index next >

src/os/bsd/vm/os_bsd.cpp

Print this page




  42 #include "prims/jvm.h"
  43 #include "prims/jvm_misc.hpp"
  44 #include "runtime/arguments.hpp"
  45 #include "runtime/atomic.inline.hpp"
  46 #include "runtime/extendedPC.hpp"
  47 #include "runtime/globals.hpp"
  48 #include "runtime/interfaceSupport.hpp"
  49 #include "runtime/java.hpp"
  50 #include "runtime/javaCalls.hpp"
  51 #include "runtime/mutexLocker.hpp"
  52 #include "runtime/objectMonitor.hpp"
  53 #include "runtime/orderAccess.inline.hpp"
  54 #include "runtime/osThread.hpp"
  55 #include "runtime/perfMemory.hpp"
  56 #include "runtime/sharedRuntime.hpp"
  57 #include "runtime/statSampler.hpp"
  58 #include "runtime/stubRoutines.hpp"
  59 #include "runtime/thread.inline.hpp"
  60 #include "runtime/threadCritical.hpp"
  61 #include "runtime/timer.hpp"

  62 #include "services/attachListener.hpp"
  63 #include "services/memTracker.hpp"
  64 #include "services/runtimeService.hpp"
  65 #include "utilities/decoder.hpp"
  66 #include "utilities/defaultStream.hpp"
  67 #include "utilities/events.hpp"
  68 #include "utilities/growableArray.hpp"
  69 #include "utilities/vmError.hpp"
  70 
  71 // put OS-includes here
  72 # include <sys/types.h>
  73 # include <sys/mman.h>
  74 # include <sys/stat.h>
  75 # include <sys/select.h>
  76 # include <pthread.h>
  77 # include <signal.h>
  78 # include <errno.h>
  79 # include <dlfcn.h>
  80 # include <stdio.h>
  81 # include <unistd.h>


1939 // a counter for each possible signal value
1940 static volatile jint pending_signals[NSIG+1] = { 0 };
1941 
1942 // Bsd(POSIX) specific hand shaking semaphore.
1943 #ifdef __APPLE__
1944 typedef semaphore_t os_semaphore_t;
1945 
1946   #define SEM_INIT(sem, value)    semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value)
1947   #define SEM_WAIT(sem)           semaphore_wait(sem)
1948   #define SEM_POST(sem)           semaphore_signal(sem)
1949   #define SEM_DESTROY(sem)        semaphore_destroy(mach_task_self(), sem)
1950 #else
1951 typedef sem_t os_semaphore_t;
1952 
1953   #define SEM_INIT(sem, value)    sem_init(&sem, 0, value)
1954   #define SEM_WAIT(sem)           sem_wait(&sem)
1955   #define SEM_POST(sem)           sem_post(&sem)
1956   #define SEM_DESTROY(sem)        sem_destroy(&sem)
1957 #endif
1958 
1959 class Semaphore : public StackObj {
1960  public:
1961   Semaphore();
1962   ~Semaphore();
1963   void signal();
1964   void wait();
1965   bool trywait();
1966   bool timedwait(unsigned int sec, int nsec);
1967  private:
1968   jlong currenttime() const;
1969   os_semaphore_t _semaphore;
1970 };

1971 
1972 Semaphore::Semaphore() : _semaphore(0) {
1973   SEM_INIT(_semaphore, 0);
1974 }
1975 
1976 Semaphore::~Semaphore() {
1977   SEM_DESTROY(_semaphore);
1978 }
1979 
1980 void Semaphore::signal() {
1981   SEM_POST(_semaphore);




1982 }
1983 
1984 void Semaphore::wait() {
1985   SEM_WAIT(_semaphore);




1986 }
1987 
1988 jlong Semaphore::currenttime() const {
1989   struct timeval tv;
1990   gettimeofday(&tv, NULL);
1991   return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
1992 }
1993 
1994 #ifdef __APPLE__
1995 bool Semaphore::trywait() {
1996   return timedwait(0, 0);
1997 }
1998 
1999 bool Semaphore::timedwait(unsigned int sec, int nsec) {
2000   kern_return_t kr = KERN_ABORTED;
2001   mach_timespec_t waitspec;
2002   waitspec.tv_sec = sec;
2003   waitspec.tv_nsec = nsec;
2004 
2005   jlong starttime = currenttime();
2006 
2007   kr = semaphore_timedwait(_semaphore, waitspec);
2008   while (kr == KERN_ABORTED) {
2009     jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec;
2010 
2011     jlong current = currenttime();
2012     jlong passedtime = current - starttime;
2013 
2014     if (passedtime >= totalwait) {
2015       waitspec.tv_sec = 0;
2016       waitspec.tv_nsec = 0;
2017     } else {
2018       jlong waittime = totalwait - (current - starttime);
2019       waitspec.tv_sec = waittime / NANOSECS_PER_SEC;
2020       waitspec.tv_nsec = waittime % NANOSECS_PER_SEC;
2021     }
2022 
2023     kr = semaphore_timedwait(_semaphore, waitspec);
2024   }
2025 
2026   return kr == KERN_SUCCESS;
2027 }
2028 
2029 #else

2030 
2031 bool Semaphore::trywait() {
2032   return sem_trywait(&_semaphore) == 0;
2033 }
2034 
2035 bool Semaphore::timedwait(unsigned int sec, int nsec) {
2036   struct timespec ts;
2037   unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
2038 
2039   while (1) {
2040     int result = sem_timedwait(&_semaphore, &ts);
2041     if (result == 0) {
2042       return true;
2043     } else if (errno == EINTR) {
2044       continue;
2045     } else if (errno == ETIMEDOUT) {
2046       return false;
2047     } else {
2048       return false;
2049     }
2050   }
2051 }
2052 
2053 #endif // __APPLE__
2054 
2055 static os_semaphore_t sig_sem;
2056 static Semaphore sr_semaphore;





2057 
2058 void os::signal_init_pd() {
2059   // Initialize signal structures
2060   ::memset((void*)pending_signals, 0, sizeof(pending_signals));
2061 
2062   // Initialize signal semaphore
2063   ::SEM_INIT(sig_sem, 0);
2064 }
2065 
2066 void os::signal_notify(int sig) {
2067   Atomic::inc(&pending_signals[sig]);
2068   ::SEM_POST(sig_sem);
2069 }
2070 
2071 static int check_pending_signals(bool wait) {
2072   Atomic::store(0, &sigint_count);
2073   for (;;) {
2074     for (int i = 0; i < NSIG + 1; i++) {
2075       jint n = pending_signals[i];
2076       if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {




  42 #include "prims/jvm.h"
  43 #include "prims/jvm_misc.hpp"
  44 #include "runtime/arguments.hpp"
  45 #include "runtime/atomic.inline.hpp"
  46 #include "runtime/extendedPC.hpp"
  47 #include "runtime/globals.hpp"
  48 #include "runtime/interfaceSupport.hpp"
  49 #include "runtime/java.hpp"
  50 #include "runtime/javaCalls.hpp"
  51 #include "runtime/mutexLocker.hpp"
  52 #include "runtime/objectMonitor.hpp"
  53 #include "runtime/orderAccess.inline.hpp"
  54 #include "runtime/osThread.hpp"
  55 #include "runtime/perfMemory.hpp"
  56 #include "runtime/sharedRuntime.hpp"
  57 #include "runtime/statSampler.hpp"
  58 #include "runtime/stubRoutines.hpp"
  59 #include "runtime/thread.inline.hpp"
  60 #include "runtime/threadCritical.hpp"
  61 #include "runtime/timer.hpp"
  62 #include "semaphore_bsd.hpp"
  63 #include "services/attachListener.hpp"
  64 #include "services/memTracker.hpp"
  65 #include "services/runtimeService.hpp"
  66 #include "utilities/decoder.hpp"
  67 #include "utilities/defaultStream.hpp"
  68 #include "utilities/events.hpp"
  69 #include "utilities/growableArray.hpp"
  70 #include "utilities/vmError.hpp"
  71 
  72 // put OS-includes here
  73 # include <sys/types.h>
  74 # include <sys/mman.h>
  75 # include <sys/stat.h>
  76 # include <sys/select.h>
  77 # include <pthread.h>
  78 # include <signal.h>
  79 # include <errno.h>
  80 # include <dlfcn.h>
  81 # include <stdio.h>
  82 # include <unistd.h>


1940 // a counter for each possible signal value
1941 static volatile jint pending_signals[NSIG+1] = { 0 };
1942 
1943 // Bsd(POSIX) specific hand shaking semaphore.
1944 #ifdef __APPLE__
1945 typedef semaphore_t os_semaphore_t;
1946 
1947   #define SEM_INIT(sem, value)    semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value)
1948   #define SEM_WAIT(sem)           semaphore_wait(sem)
1949   #define SEM_POST(sem)           semaphore_signal(sem)
1950   #define SEM_DESTROY(sem)        semaphore_destroy(mach_task_self(), sem)
1951 #else
1952 typedef sem_t os_semaphore_t;
1953 
1954   #define SEM_INIT(sem, value)    sem_init(&sem, 0, value)
1955   #define SEM_WAIT(sem)           sem_wait(&sem)
1956   #define SEM_POST(sem)           sem_post(&sem)
1957   #define SEM_DESTROY(sem)        sem_destroy(&sem)
1958 #endif
1959 
1960 #ifdef __APPLE__
1961 // OS X doesn't support unamed POSIX semaphores, so the implementation in os_posix.cpp can't be used.
1962 
1963 static const char* sem_init_strerror(kern_return_t value) {
1964   switch (value) {
1965     case KERN_INVALID_ARGUMENT:  return "Invalid argument";
1966     case KERN_RESOURCE_SHORTAGE: return "Resource shortage";
1967     default:                     return "Unknown";
1968   }
1969 }
1970 
1971 OSXSemaphore::OSXSemaphore(uint value) : _semaphore(0) {
1972   kern_return_t ret = SEM_INIT(_semaphore, value);
1973 
1974   guarantee(ret == KERN_SUCCESS, err_msg("Failed to create semaphore: %s", sem_init_strerror(ret)));

1975 }
1976 
1977 OSXSemaphore::~OSXSemaphore() {
1978   SEM_DESTROY(_semaphore);
1979 }
1980 
1981 void OSXSemaphore::signal(uint count) {
1982   for (uint i = 0; i < count; i++) {
1983     kern_return_t ret = SEM_POST(_semaphore);
1984 
1985     assert(ret == KERN_SUCCESS, "Failed to signal semaphore");
1986   }
1987 }
1988 
1989 void OSXSemaphore::wait() {
1990   kern_return_t ret;
1991   while ((ret = SEM_WAIT(_semaphore)) == KERN_ABORTED) {
1992     // Semaphore was interrupted. Retry.
1993   }
1994   assert(ret == KERN_SUCCESS, "Failed to wait on semaphore");
1995 }
1996 
1997 jlong OSXSemaphore::currenttime() {
1998   struct timeval tv;
1999   gettimeofday(&tv, NULL);
2000   return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
2001 }
2002 
2003 bool OSXSemaphore::trywait() {

2004   return timedwait(0, 0);
2005 }
2006 
2007 bool OSXSemaphore::timedwait(unsigned int sec, int nsec) {
2008   kern_return_t kr = KERN_ABORTED;
2009   mach_timespec_t waitspec;
2010   waitspec.tv_sec = sec;
2011   waitspec.tv_nsec = nsec;
2012 
2013   jlong starttime = currenttime();
2014 
2015   kr = semaphore_timedwait(_semaphore, waitspec);
2016   while (kr == KERN_ABORTED) {
2017     jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec;
2018 
2019     jlong current = currenttime();
2020     jlong passedtime = current - starttime;
2021 
2022     if (passedtime >= totalwait) {
2023       waitspec.tv_sec = 0;
2024       waitspec.tv_nsec = 0;
2025     } else {
2026       jlong waittime = totalwait - (current - starttime);
2027       waitspec.tv_sec = waittime / NANOSECS_PER_SEC;
2028       waitspec.tv_nsec = waittime % NANOSECS_PER_SEC;
2029     }
2030 
2031     kr = semaphore_timedwait(_semaphore, waitspec);
2032   }
2033 
2034   return kr == KERN_SUCCESS;
2035 }
2036 
2037 #else
2038 // Use POSIX implementation of semaphores.
2039 
2040 struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {




2041   struct timespec ts;
2042   unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
2043 
2044   return ts;











2045 }
2046 
2047 #endif // __APPLE__
2048 
2049 static os_semaphore_t sig_sem;
2050 
2051 #ifdef __APPLE__
2052 static OSXSemaphore sr_semaphore;
2053 #else
2054 static PosixSemaphore sr_semaphore;
2055 #endif
2056 
2057 void os::signal_init_pd() {
2058   // Initialize signal structures
2059   ::memset((void*)pending_signals, 0, sizeof(pending_signals));
2060 
2061   // Initialize signal semaphore
2062   ::SEM_INIT(sig_sem, 0);
2063 }
2064 
2065 void os::signal_notify(int sig) {
2066   Atomic::inc(&pending_signals[sig]);
2067   ::SEM_POST(sig_sem);
2068 }
2069 
2070 static int check_pending_signals(bool wait) {
2071   Atomic::store(0, &sigint_count);
2072   for (;;) {
2073     for (int i = 0; i < NSIG + 1; i++) {
2074       jint n = pending_signals[i];
2075       if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {


< prev index next >