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)) {
|