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/semaphore.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>
84 # include <stdio.h>
85 # include <unistd.h>
86 # include <sys/resource.h>
87 # include <pthread.h>
88 # include <sys/stat.h>
89 # include <sys/time.h>
90 # include <sys/times.h>
91 # include <sys/utsname.h>
92 # include <sys/socket.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 Semaphore::Semaphore(uint value, uint max) {
2398 guarantee(value <= max, "value lower than max");
2399 guarantee(max == Semaphore::NoMaxCount || max <= SEM_VALUE_MAX, "Max value set too high");
2400
2401 int ret = sem_init(&_semaphore, 0, value);
2402 guarantee(ret == 0, "Failed to initialize semaphore");
2403 }
2404
2405 Semaphore::~Semaphore() {
2406 sem_destroy(&_semaphore);
2407 }
2408
2409 void Semaphore::signal() {
2410 int ret = sem_post(&_semaphore);
2411 guarantee(ret == 0, err_msg("sem_post failed: %d", ret));
2412 }
2413
2414 void Semaphore::signal(uint count) {
2415 for (uint i = 0; i < count; i++) {
2416 signal();
2417 }
2418 }
2419
2420 void Semaphore::wait() {
2421 while (sem_wait(&_semaphore) == -1 && errno == EINTR) {
2422 // Retry if the wait was interrupted by a signal.
2423 }
2424 }
2425
2426 bool Semaphore::trywait() {
2427 return sem_trywait(&_semaphore) == 0;
2428 }
2429
2430 bool Semaphore::timedwait(unsigned int sec, int nsec) {
2431
2432 struct timespec ts;
2433 // Semaphore's are always associated with CLOCK_REALTIME
2434 os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
2435 // see unpackTime for discussion on overflow checking
2436 if (sec >= MAX_SECS) {
2437 ts.tv_sec += MAX_SECS;
2438 ts.tv_nsec = 0;
2439 } else {
2440 ts.tv_sec += sec;
2441 ts.tv_nsec += nsec;
2442 if (ts.tv_nsec >= NANOSECS_PER_SEC) {
2443 ts.tv_nsec -= NANOSECS_PER_SEC;
2444 ++ts.tv_sec; // note: this must be <= max_secs
2445 }
2446 }
2447
2448 while (1) {
2449 int result = sem_timedwait(&_semaphore, &ts);
2450 if (result == 0) {
2451 return true;
2452 } else if (errno == EINTR) {
2453 continue;
2454 } else if (errno == ETIMEDOUT) {
2455 return false;
2456 } else {
2457 return false;
2458 }
2459 }
2460 }
2461
2462 extern "C" {
2463 typedef void (*sa_handler_t)(int);
2464 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2465 }
2466
2467 void* os::signal(int signal_number, void* handler) {
2468 struct sigaction sigAct, oldSigAct;
2469
2470 sigfillset(&(sigAct.sa_mask));
2471 sigAct.sa_flags = SA_RESTART|SA_SIGINFO;
2472 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2473
2474 if (sigaction(signal_number, &sigAct, &oldSigAct)) {
2475 // -1 means registration failed
2476 return (void *)-1;
2477 }
2478
2479 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
2480 }
2481
2482 void os::signal_raise(int signal_number) {
2483 ::raise(signal_number);
2484 }
2485
2486 // The following code is moved from os.cpp for making this
2487 // code platform specific, which it is by its very nature.
2488
2489 // Will be modified when max signal is changed to be dynamic
2490 int os::sigexitnum_pd() {
2491 return NSIG;
2492 }
2493
2494 // a counter for each possible signal value
2495 static volatile jint pending_signals[NSIG+1] = { 0 };
2496
2497 // Linux(POSIX) specific hand shaking semaphore.
2498 static sem_t sig_sem;
2499 static Semaphore sr_semaphore;
2500
2501 void os::signal_init_pd() {
2502 // Initialize signal structures
2503 ::memset((void*)pending_signals, 0, sizeof(pending_signals));
2504
2505 // Initialize signal semaphore
2506 ::sem_init(&sig_sem, 0, 0);
2507 }
2508
2509 void os::signal_notify(int sig) {
2510 Atomic::inc(&pending_signals[sig]);
2511 ::sem_post(&sig_sem);
2512 }
2513
2514 static int check_pending_signals(bool wait) {
2515 Atomic::store(0, &sigint_count);
2516 for (;;) {
2517 for (int i = 0; i < NSIG + 1; i++) {
2518 jint n = pending_signals[i];
2519 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
|
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>
83 # include <stdio.h>
84 # include <unistd.h>
85 # include <sys/resource.h>
86 # include <pthread.h>
87 # include <sys/stat.h>
88 # include <sys/time.h>
89 # include <sys/times.h>
90 # include <sys/utsname.h>
91 # include <sys/socket.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 LinuxSemaphore : public os::PosixSemaphore {
2397 public:
2398 LinuxSemaphore(uint value = 0) : os::PosixSemaphore(value) {}
2399
2400 bool timedwait(unsigned int sec, int nsec) {
2401 struct timespec ts;
2402 // Semaphore's are always associated with CLOCK_REALTIME
2403 os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
2404 // see unpackTime for discussion on overflow checking
2405 if (sec >= MAX_SECS) {
2406 ts.tv_sec += MAX_SECS;
2407 ts.tv_nsec = 0;
2408 } else {
2409 ts.tv_sec += sec;
2410 ts.tv_nsec += nsec;
2411 if (ts.tv_nsec >= NANOSECS_PER_SEC) {
2412 ts.tv_nsec -= NANOSECS_PER_SEC;
2413 ++ts.tv_sec; // note: this must be <= max_secs
2414 }
2415 }
2416
2417 return os::PosixSemaphore::timedwait(ts);
2418 }
2419 };
2420
2421 extern "C" {
2422 typedef void (*sa_handler_t)(int);
2423 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
2424 }
2425
2426 void* os::signal(int signal_number, void* handler) {
2427 struct sigaction sigAct, oldSigAct;
2428
2429 sigfillset(&(sigAct.sa_mask));
2430 sigAct.sa_flags = SA_RESTART|SA_SIGINFO;
2431 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2432
2433 if (sigaction(signal_number, &sigAct, &oldSigAct)) {
2434 // -1 means registration failed
2435 return (void *)-1;
2436 }
2437
2438 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
2439 }
2440
2441 void os::signal_raise(int signal_number) {
2442 ::raise(signal_number);
2443 }
2444
2445 // The following code is moved from os.cpp for making this
2446 // code platform specific, which it is by its very nature.
2447
2448 // Will be modified when max signal is changed to be dynamic
2449 int os::sigexitnum_pd() {
2450 return NSIG;
2451 }
2452
2453 // a counter for each possible signal value
2454 static volatile jint pending_signals[NSIG+1] = { 0 };
2455
2456 // Linux(POSIX) specific hand shaking semaphore.
2457 static sem_t sig_sem;
2458 static LinuxSemaphore sr_semaphore;
2459
2460 void os::signal_init_pd() {
2461 // Initialize signal structures
2462 ::memset((void*)pending_signals, 0, sizeof(pending_signals));
2463
2464 // Initialize signal semaphore
2465 ::sem_init(&sig_sem, 0, 0);
2466 }
2467
2468 void os::signal_notify(int sig) {
2469 Atomic::inc(&pending_signals[sig]);
2470 ::sem_post(&sig_sem);
2471 }
2472
2473 static int check_pending_signals(bool wait) {
2474 Atomic::store(0, &sigint_count);
2475 for (;;) {
2476 for (int i = 0; i < NSIG + 1; i++) {
2477 jint n = pending_signals[i];
2478 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
|