src/os/linux/vm/os_linux.cpp

changeset 2999
b0b8491925fe
parent 2997
bf6481e5f96d
child 3023
a20e6e447d3d
     1.1 --- a/src/os/linux/vm/os_linux.cpp	Thu Jul 07 15:44:34 2011 -0700
     1.2 +++ b/src/os/linux/vm/os_linux.cpp	Mon Jul 11 14:15:43 2011 -0700
     1.3 @@ -169,7 +169,35 @@
     1.4  /* Used to protect dlsym() calls */
     1.5  static pthread_mutex_t dl_mutex;
     1.6  
     1.7 -////////////////////////////////////////////////////////////////////////////////
     1.8 +#ifdef JAVASE_EMBEDDED
     1.9 +class MemNotifyThread: public Thread {
    1.10 +  friend class VMStructs;
    1.11 + public:
    1.12 +  virtual void run();
    1.13 +
    1.14 + private:
    1.15 +  static MemNotifyThread* _memnotify_thread;
    1.16 +  int _fd;
    1.17 +
    1.18 + public:
    1.19 +
    1.20 +  // Constructor
    1.21 +  MemNotifyThread(int fd);
    1.22 +
    1.23 +  // Tester
    1.24 +  bool is_memnotify_thread() const { return true; }
    1.25 +
    1.26 +  // Printing
    1.27 +  char* name() const { return (char*)"Linux MemNotify Thread"; }
    1.28 +
    1.29 +  // Returns the single instance of the MemNotifyThread
    1.30 +  static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
    1.31 +
    1.32 +  // Create and start the single instance of MemNotifyThread
    1.33 +  static void start();
    1.34 +};
    1.35 +#endif // JAVASE_EMBEDDED
    1.36 +
    1.37  // utility functions
    1.38  
    1.39  static int SR_initialize();
    1.40 @@ -4245,7 +4273,16 @@
    1.41  }
    1.42  
    1.43  // this is called at the end of vm_initialization
    1.44 -void os::init_3(void) { }
    1.45 +void os::init_3(void)
    1.46 +{
    1.47 +#ifdef JAVASE_EMBEDDED
    1.48 +  // Start the MemNotifyThread
    1.49 +  if (LowMemoryProtection) {
    1.50 +    MemNotifyThread::start();
    1.51 +  }
    1.52 +  return;
    1.53 +#endif
    1.54 +}
    1.55  
    1.56  // Mark the polling page as unreadable
    1.57  void os::make_polling_page_unreadable(void) {
    1.58 @@ -5368,3 +5405,78 @@
    1.59      return true;
    1.60  }
    1.61  
    1.62 +
    1.63 +#ifdef JAVASE_EMBEDDED
    1.64 +//
    1.65 +// A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory.
    1.66 +//
    1.67 +MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
    1.68 +
    1.69 +// ctor
    1.70 +//
    1.71 +MemNotifyThread::MemNotifyThread(int fd): Thread() {
    1.72 +  assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread");
    1.73 +  _fd = fd;
    1.74 +
    1.75 +  if (os::create_thread(this, os::os_thread)) {
    1.76 +    _memnotify_thread = this;
    1.77 +    os::set_priority(this, NearMaxPriority);
    1.78 +    os::start_thread(this);
    1.79 +  }
    1.80 +}
    1.81 +
    1.82 +// Where all the work gets done
    1.83 +//
    1.84 +void MemNotifyThread::run() {
    1.85 +  assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
    1.86 +
    1.87 +  // Set up the select arguments
    1.88 +  fd_set rfds;
    1.89 +  if (_fd != -1) {
    1.90 +    FD_ZERO(&rfds);
    1.91 +    FD_SET(_fd, &rfds);
    1.92 +  }
    1.93 +
    1.94 +  // Now wait for the mem_notify device to wake up
    1.95 +  while (1) {
    1.96 +    // Wait for the mem_notify device to signal us..
    1.97 +    int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL);
    1.98 +    if (rc == -1) {
    1.99 +      perror("select!\n");
   1.100 +      break;
   1.101 +    } else if (rc) {
   1.102 +      //ssize_t free_before = os::available_memory();
   1.103 +      //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024);
   1.104 +
   1.105 +      // The kernel is telling us there is not much memory left...
   1.106 +      // try to do something about that
   1.107 +
   1.108 +      // If we are not already in a GC, try one.
   1.109 +      if (!Universe::heap()->is_gc_active()) {
   1.110 +        Universe::heap()->collect(GCCause::_allocation_failure);
   1.111 +
   1.112 +        //ssize_t free_after = os::available_memory();
   1.113 +        //tty->print ("Post-Notify: Free: %dK\n",free_after/1024);
   1.114 +        //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024);
   1.115 +      }
   1.116 +      // We might want to do something like the following if we find the GC's are not helping...
   1.117 +      // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true);
   1.118 +    }
   1.119 +  }
   1.120 +}
   1.121 +
   1.122 +//
   1.123 +// See if the /dev/mem_notify device exists, and if so, start a thread to monitor it.
   1.124 +//
   1.125 +void MemNotifyThread::start() {
   1.126 +  int    fd;
   1.127 +  fd = open ("/dev/mem_notify", O_RDONLY, 0);
   1.128 +  if (fd < 0) {
   1.129 +      return;
   1.130 +  }
   1.131 +
   1.132 +  if (memnotify_thread() == NULL) {
   1.133 +    new MemNotifyThread(fd);
   1.134 +  }
   1.135 +}
   1.136 +#endif // JAVASE_EMBEDDED

mercurial