< prev index next >

src/os/linux/vm/os_linux.cpp

Print this page




  43 #include "prims/jvm_misc.hpp"
  44 #include "runtime/arguments.hpp"
  45 #include "runtime/atomic.inline.hpp"
  46 #include "runtime/extendedPC.hpp"
  47 #include "runtime/globals.hpp"
  48 #include "runtime/interfaceSupport.hpp"
  49 #include "runtime/init.hpp"
  50 #include "runtime/java.hpp"
  51 #include "runtime/javaCalls.hpp"
  52 #include "runtime/mutexLocker.hpp"
  53 #include "runtime/objectMonitor.hpp"
  54 #include "runtime/orderAccess.inline.hpp"
  55 #include "runtime/osThread.hpp"
  56 #include "runtime/perfMemory.hpp"
  57 #include "runtime/sharedRuntime.hpp"
  58 #include "runtime/statSampler.hpp"
  59 #include "runtime/stubRoutines.hpp"
  60 #include "runtime/thread.inline.hpp"
  61 #include "runtime/threadCritical.hpp"
  62 #include "runtime/timer.hpp"

  63 #include "services/attachListener.hpp"
  64 #include "services/memTracker.hpp"
  65 #include "services/runtimeService.hpp"
  66 #include "utilities/decoder.hpp"
  67 #include "utilities/defaultStream.hpp"
  68 #include "utilities/events.hpp"
  69 #include "utilities/elfFile.hpp"
  70 #include "utilities/growableArray.hpp"
  71 #include "utilities/macros.hpp"
  72 #include "utilities/vmError.hpp"
  73 
  74 // put OS-includes here
  75 # include <sys/types.h>
  76 # include <sys/mman.h>
  77 # include <sys/stat.h>
  78 # include <sys/select.h>
  79 # include <pthread.h>
  80 # include <signal.h>
  81 # include <errno.h>
  82 # include <dlfcn.h>


2376   // 4511530 - sem_post is serialized and handled by the manager thread. When
2377   // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
2378   // don't want to flood the manager thread with sem_post requests.
2379   if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) {
2380     return;
2381   }
2382 
2383   // Ctrl-C is pressed during error reporting, likely because the error
2384   // handler fails to abort. Let VM die immediately.
2385   if (sig == SIGINT && is_error_reported()) {
2386     os::die();
2387   }
2388 
2389   os::signal_notify(sig);
2390 }
2391 
2392 void* os::user_handler() {
2393   return CAST_FROM_FN_PTR(void*, UserHandler);
2394 }
2395 
2396 class Semaphore : public StackObj {
2397  public:
2398   Semaphore();
2399   ~Semaphore();
2400   void signal();
2401   void wait();
2402   bool trywait();
2403   bool timedwait(unsigned int sec, int nsec);
2404  private:
2405   sem_t _semaphore;
2406 };
2407 
2408 Semaphore::Semaphore() {
2409   sem_init(&_semaphore, 0, 0);
2410 }
2411 
2412 Semaphore::~Semaphore() {
2413   sem_destroy(&_semaphore);
2414 }
2415 
2416 void Semaphore::signal() {
2417   sem_post(&_semaphore);
2418 }
2419 
2420 void Semaphore::wait() {
2421   sem_wait(&_semaphore);
2422 }
2423 
2424 bool Semaphore::trywait() {
2425   return sem_trywait(&_semaphore) == 0;
2426 }
2427 
2428 bool Semaphore::timedwait(unsigned int sec, int nsec) {
2429 
2430   struct timespec ts;
2431   // Semaphore's are always associated with CLOCK_REALTIME
2432   os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
2433   // see unpackTime for discussion on overflow checking
2434   if (sec >= MAX_SECS) {
2435     ts.tv_sec += MAX_SECS;
2436     ts.tv_nsec = 0;
2437   } else {
2438     ts.tv_sec += sec;
2439     ts.tv_nsec += nsec;
2440     if (ts.tv_nsec >= NANOSECS_PER_SEC) {
2441       ts.tv_nsec -= NANOSECS_PER_SEC;
2442       ++ts.tv_sec; // note: this must be <= max_secs
2443     }
2444   }
2445 
2446   while (1) {
2447     int result = sem_timedwait(&_semaphore, &ts);
2448     if (result == 0) {
2449       return true;
2450     } else if (errno == EINTR) {
2451       continue;
2452     } else if (errno == ETIMEDOUT) {
2453       return false;
2454     } else {
2455       return false;
2456     }
2457   }
2458 }
2459 
2460 extern "C" {
2461   typedef void (*sa_handler_t)(int);
2462   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2463 }
2464 
2465 void* os::signal(int signal_number, void* handler) {
2466   struct sigaction sigAct, oldSigAct;
2467 
2468   sigfillset(&(sigAct.sa_mask));
2469   sigAct.sa_flags   = SA_RESTART|SA_SIGINFO;
2470   sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2471 
2472   if (sigaction(signal_number, &sigAct, &oldSigAct)) {
2473     // -1 means registration failed
2474     return (void *)-1;
2475   }
2476 
2477   return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
2478 }
2479 
2480 void os::signal_raise(int signal_number) {
2481   ::raise(signal_number);
2482 }
2483 
2484 // The following code is moved from os.cpp for making this
2485 // code platform specific, which it is by its very nature.
2486 
2487 // Will be modified when max signal is changed to be dynamic
2488 int os::sigexitnum_pd() {
2489   return NSIG;
2490 }
2491 
2492 // a counter for each possible signal value
2493 static volatile jint pending_signals[NSIG+1] = { 0 };
2494 
2495 // Linux(POSIX) specific hand shaking semaphore.
2496 static sem_t sig_sem;
2497 static Semaphore sr_semaphore;
2498 
2499 void os::signal_init_pd() {
2500   // Initialize signal structures
2501   ::memset((void*)pending_signals, 0, sizeof(pending_signals));
2502 
2503   // Initialize signal semaphore
2504   ::sem_init(&sig_sem, 0, 0);
2505 }
2506 
2507 void os::signal_notify(int sig) {
2508   Atomic::inc(&pending_signals[sig]);
2509   ::sem_post(&sig_sem);
2510 }
2511 
2512 static int check_pending_signals(bool wait) {
2513   Atomic::store(0, &sigint_count);
2514   for (;;) {
2515     for (int i = 0; i < NSIG + 1; i++) {
2516       jint n = pending_signals[i];
2517       if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {




  43 #include "prims/jvm_misc.hpp"
  44 #include "runtime/arguments.hpp"
  45 #include "runtime/atomic.inline.hpp"
  46 #include "runtime/extendedPC.hpp"
  47 #include "runtime/globals.hpp"
  48 #include "runtime/interfaceSupport.hpp"
  49 #include "runtime/init.hpp"
  50 #include "runtime/java.hpp"
  51 #include "runtime/javaCalls.hpp"
  52 #include "runtime/mutexLocker.hpp"
  53 #include "runtime/objectMonitor.hpp"
  54 #include "runtime/orderAccess.inline.hpp"
  55 #include "runtime/osThread.hpp"
  56 #include "runtime/perfMemory.hpp"
  57 #include "runtime/sharedRuntime.hpp"
  58 #include "runtime/statSampler.hpp"
  59 #include "runtime/stubRoutines.hpp"
  60 #include "runtime/thread.inline.hpp"
  61 #include "runtime/threadCritical.hpp"
  62 #include "runtime/timer.hpp"
  63 #include "semaphore_posix.hpp"
  64 #include "services/attachListener.hpp"
  65 #include "services/memTracker.hpp"
  66 #include "services/runtimeService.hpp"
  67 #include "utilities/decoder.hpp"
  68 #include "utilities/defaultStream.hpp"
  69 #include "utilities/events.hpp"
  70 #include "utilities/elfFile.hpp"
  71 #include "utilities/growableArray.hpp"
  72 #include "utilities/macros.hpp"
  73 #include "utilities/vmError.hpp"
  74 
  75 // put OS-includes here
  76 # include <sys/types.h>
  77 # include <sys/mman.h>
  78 # include <sys/stat.h>
  79 # include <sys/select.h>
  80 # include <pthread.h>
  81 # include <signal.h>
  82 # include <errno.h>
  83 # include <dlfcn.h>


2377   // 4511530 - sem_post is serialized and handled by the manager thread. When
2378   // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
2379   // don't want to flood the manager thread with sem_post requests.
2380   if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) {
2381     return;
2382   }
2383 
2384   // Ctrl-C is pressed during error reporting, likely because the error
2385   // handler fails to abort. Let VM die immediately.
2386   if (sig == SIGINT && is_error_reported()) {
2387     os::die();
2388   }
2389 
2390   os::signal_notify(sig);
2391 }
2392 
2393 void* os::user_handler() {
2394   return CAST_FROM_FN_PTR(void*, UserHandler);
2395 }
2396 
2397 struct timespec PosixSemaphore::create_timespec(unsigned int sec, int nsec) {

































2398   struct timespec ts;
2399   // Semaphore's are always associated with CLOCK_REALTIME
2400   os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
2401   // see unpackTime for discussion on overflow checking
2402   if (sec >= MAX_SECS) {
2403     ts.tv_sec += MAX_SECS;
2404     ts.tv_nsec = 0;
2405   } else {
2406     ts.tv_sec += sec;
2407     ts.tv_nsec += nsec;
2408     if (ts.tv_nsec >= NANOSECS_PER_SEC) {
2409       ts.tv_nsec -= NANOSECS_PER_SEC;
2410       ++ts.tv_sec; // note: this must be <= max_secs
2411     }
2412   }
2413 
2414   return ts;











2415 }
2416 
2417 extern "C" {
2418   typedef void (*sa_handler_t)(int);
2419   typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2420 }
2421 
2422 void* os::signal(int signal_number, void* handler) {
2423   struct sigaction sigAct, oldSigAct;
2424 
2425   sigfillset(&(sigAct.sa_mask));
2426   sigAct.sa_flags   = SA_RESTART|SA_SIGINFO;
2427   sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2428 
2429   if (sigaction(signal_number, &sigAct, &oldSigAct)) {
2430     // -1 means registration failed
2431     return (void *)-1;
2432   }
2433 
2434   return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
2435 }
2436 
2437 void os::signal_raise(int signal_number) {
2438   ::raise(signal_number);
2439 }
2440 
2441 // The following code is moved from os.cpp for making this
2442 // code platform specific, which it is by its very nature.
2443 
2444 // Will be modified when max signal is changed to be dynamic
2445 int os::sigexitnum_pd() {
2446   return NSIG;
2447 }
2448 
2449 // a counter for each possible signal value
2450 static volatile jint pending_signals[NSIG+1] = { 0 };
2451 
2452 // Linux(POSIX) specific hand shaking semaphore.
2453 static sem_t sig_sem;
2454 static PosixSemaphore sr_semaphore;
2455 
2456 void os::signal_init_pd() {
2457   // Initialize signal structures
2458   ::memset((void*)pending_signals, 0, sizeof(pending_signals));
2459 
2460   // Initialize signal semaphore
2461   ::sem_init(&sig_sem, 0, 0);
2462 }
2463 
2464 void os::signal_notify(int sig) {
2465   Atomic::inc(&pending_signals[sig]);
2466   ::sem_post(&sig_sem);
2467 }
2468 
2469 static int check_pending_signals(bool wait) {
2470   Atomic::store(0, &sigint_count);
2471   for (;;) {
2472     for (int i = 0; i < NSIG + 1; i++) {
2473       jint n = pending_signals[i];
2474       if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {


< prev index next >