From 7a6df03715c17d62e72d32e178d2838b56a47647 Mon Sep 17 00:00:00 2001 From: jcoomes Date: Mon, 11 Jul 2011 14:15:43 -0700 Subject: [PATCH] 7061212: use o/s low memory notification in embedded builds Reviewed-by: dholmes, never, jwilhelm, kvn --- src/os/linux/vm/os_linux.cpp | 116 ++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) diff --git a/src/os/linux/vm/os_linux.cpp b/src/os/linux/vm/os_linux.cpp index 5ba903504..09285a39a 100644 --- a/src/os/linux/vm/os_linux.cpp +++ b/src/os/linux/vm/os_linux.cpp @@ -169,7 +169,35 @@ sigset_t SR_sigset; /* Used to protect dlsym() calls */ static pthread_mutex_t dl_mutex; -//////////////////////////////////////////////////////////////////////////////// +#ifdef JAVASE_EMBEDDED +class MemNotifyThread: public Thread { + friend class VMStructs; + public: + virtual void run(); + + private: + static MemNotifyThread* _memnotify_thread; + int _fd; + + public: + + // Constructor + MemNotifyThread(int fd); + + // Tester + bool is_memnotify_thread() const { return true; } + + // Printing + char* name() const { return (char*)"Linux MemNotify Thread"; } + + // Returns the single instance of the MemNotifyThread + static MemNotifyThread* memnotify_thread() { return _memnotify_thread; } + + // Create and start the single instance of MemNotifyThread + static void start(); +}; +#endif // JAVASE_EMBEDDED + // utility functions static int SR_initialize(); @@ -4245,7 +4273,16 @@ jint os::init_2(void) } // this is called at the end of vm_initialization -void os::init_3(void) { } +void os::init_3(void) +{ +#ifdef JAVASE_EMBEDDED + // Start the MemNotifyThread + if (LowMemoryProtection) { + MemNotifyThread::start(); + } + return; +#endif +} // Mark the polling page as unreadable void os::make_polling_page_unreadable(void) { @@ -5368,3 +5405,78 @@ bool os::is_headless_jre() { return true; } + +#ifdef JAVASE_EMBEDDED +// +// A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory. +// +MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL; + +// ctor +// +MemNotifyThread::MemNotifyThread(int fd): Thread() { + assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread"); + _fd = fd; + + if (os::create_thread(this, os::os_thread)) { + _memnotify_thread = this; + os::set_priority(this, NearMaxPriority); + os::start_thread(this); + } +} + +// Where all the work gets done +// +void MemNotifyThread::run() { + assert(this == memnotify_thread(), "expected the singleton MemNotifyThread"); + + // Set up the select arguments + fd_set rfds; + if (_fd != -1) { + FD_ZERO(&rfds); + FD_SET(_fd, &rfds); + } + + // Now wait for the mem_notify device to wake up + while (1) { + // Wait for the mem_notify device to signal us.. + int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL); + if (rc == -1) { + perror("select!\n"); + break; + } else if (rc) { + //ssize_t free_before = os::available_memory(); + //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024); + + // The kernel is telling us there is not much memory left... + // try to do something about that + + // If we are not already in a GC, try one. + if (!Universe::heap()->is_gc_active()) { + Universe::heap()->collect(GCCause::_allocation_failure); + + //ssize_t free_after = os::available_memory(); + //tty->print ("Post-Notify: Free: %dK\n",free_after/1024); + //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024); + } + // We might want to do something like the following if we find the GC's are not helping... + // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true); + } + } +} + +// +// See if the /dev/mem_notify device exists, and if so, start a thread to monitor it. +// +void MemNotifyThread::start() { + int fd; + fd = open ("/dev/mem_notify", O_RDONLY, 0); + if (fd < 0) { + return; + } + + if (memnotify_thread() == NULL) { + new MemNotifyThread(fd); + } +} +#endif // JAVASE_EMBEDDED -- GitLab