comparison src/os/linux/vm/os_linux.cpp @ 3802:b0b8491925fe

7061212: use o/s low memory notification in embedded builds Reviewed-by: dholmes, never, jwilhelm, kvn
author jcoomes
date Mon, 11 Jul 2011 14:15:43 -0700
parents bf6481e5f96d
children a20e6e447d3d
comparison
equal deleted inserted replaced
3801:8a4fc2990229 3802:b0b8491925fe
167 sigset_t SR_sigset; 167 sigset_t SR_sigset;
168 168
169 /* Used to protect dlsym() calls */ 169 /* Used to protect dlsym() calls */
170 static pthread_mutex_t dl_mutex; 170 static pthread_mutex_t dl_mutex;
171 171
172 //////////////////////////////////////////////////////////////////////////////// 172 #ifdef JAVASE_EMBEDDED
173 class MemNotifyThread: public Thread {
174 friend class VMStructs;
175 public:
176 virtual void run();
177
178 private:
179 static MemNotifyThread* _memnotify_thread;
180 int _fd;
181
182 public:
183
184 // Constructor
185 MemNotifyThread(int fd);
186
187 // Tester
188 bool is_memnotify_thread() const { return true; }
189
190 // Printing
191 char* name() const { return (char*)"Linux MemNotify Thread"; }
192
193 // Returns the single instance of the MemNotifyThread
194 static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
195
196 // Create and start the single instance of MemNotifyThread
197 static void start();
198 };
199 #endif // JAVASE_EMBEDDED
200
173 // utility functions 201 // utility functions
174 202
175 static int SR_initialize(); 203 static int SR_initialize();
176 static int SR_finalize(); 204 static int SR_finalize();
177 205
4243 4271
4244 return JNI_OK; 4272 return JNI_OK;
4245 } 4273 }
4246 4274
4247 // this is called at the end of vm_initialization 4275 // this is called at the end of vm_initialization
4248 void os::init_3(void) { } 4276 void os::init_3(void)
4277 {
4278 #ifdef JAVASE_EMBEDDED
4279 // Start the MemNotifyThread
4280 if (LowMemoryProtection) {
4281 MemNotifyThread::start();
4282 }
4283 return;
4284 #endif
4285 }
4249 4286
4250 // Mark the polling page as unreadable 4287 // Mark the polling page as unreadable
4251 void os::make_polling_page_unreadable(void) { 4288 void os::make_polling_page_unreadable(void) {
4252 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) 4289 if( !guard_memory((char*)_polling_page, Linux::page_size()) )
4253 fatal("Could not disable polling page"); 4290 fatal("Could not disable polling page");
5366 if (::stat(libmawtpath, &statbuf) == 0) return false; 5403 if (::stat(libmawtpath, &statbuf) == 0) return false;
5367 5404
5368 return true; 5405 return true;
5369 } 5406 }
5370 5407
5408
5409 #ifdef JAVASE_EMBEDDED
5410 //
5411 // A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory.
5412 //
5413 MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
5414
5415 // ctor
5416 //
5417 MemNotifyThread::MemNotifyThread(int fd): Thread() {
5418 assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread");
5419 _fd = fd;
5420
5421 if (os::create_thread(this, os::os_thread)) {
5422 _memnotify_thread = this;
5423 os::set_priority(this, NearMaxPriority);
5424 os::start_thread(this);
5425 }
5426 }
5427
5428 // Where all the work gets done
5429 //
5430 void MemNotifyThread::run() {
5431 assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
5432
5433 // Set up the select arguments
5434 fd_set rfds;
5435 if (_fd != -1) {
5436 FD_ZERO(&rfds);
5437 FD_SET(_fd, &rfds);
5438 }
5439
5440 // Now wait for the mem_notify device to wake up
5441 while (1) {
5442 // Wait for the mem_notify device to signal us..
5443 int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL);
5444 if (rc == -1) {
5445 perror("select!\n");
5446 break;
5447 } else if (rc) {
5448 //ssize_t free_before = os::available_memory();
5449 //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024);
5450
5451 // The kernel is telling us there is not much memory left...
5452 // try to do something about that
5453
5454 // If we are not already in a GC, try one.
5455 if (!Universe::heap()->is_gc_active()) {
5456 Universe::heap()->collect(GCCause::_allocation_failure);
5457
5458 //ssize_t free_after = os::available_memory();
5459 //tty->print ("Post-Notify: Free: %dK\n",free_after/1024);
5460 //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024);
5461 }
5462 // We might want to do something like the following if we find the GC's are not helping...
5463 // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true);
5464 }
5465 }
5466 }
5467
5468 //
5469 // See if the /dev/mem_notify device exists, and if so, start a thread to monitor it.
5470 //
5471 void MemNotifyThread::start() {
5472 int fd;
5473 fd = open ("/dev/mem_notify", O_RDONLY, 0);
5474 if (fd < 0) {
5475 return;
5476 }
5477
5478 if (memnotify_thread() == NULL) {
5479 new MemNotifyThread(fd);
5480 }
5481 }
5482 #endif // JAVASE_EMBEDDED