Mercurial > hg > graal-jvmci-8
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 |