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