Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only unblock an asynchronous signal if it is used #4554

Merged
merged 1 commit into from
Nov 22, 2019

Conversation

babsingh
Copy link
Contributor

@babsingh babsingh commented Nov 12, 2019

Currently, all supported asynchronous signals are unblocked during
startup. A signal is unblocked even when a signal handler is not
installed for it. This conflicts with an OMR consumer, who wants to
block a set of signals. The OMR consumer blocks a set of signals but the
OMR signal library unblocks those signals at startup. OMR signal library
should only unblock a signal if a signal handler is registered for it.
In other words, a signal should not be unblocked if it is not used i.e.
a signal handler is not registered for it.

Related:

  1. Customer Issue (IntelliJ IDE doesn't receive signals; 28th Oct. 2018)
  2. OMR Fix (Handle signals blocked by a parent process; 23rd Nov. 2018)
  3. Add support for new signals (SIGUSR1, SIGUSR2, ...; 15th April 2019)

Signed-off-by: Babneet Singh sbabneet@ca.ibm.com

@babsingh
Copy link
Contributor Author

Performance Results

Compile the micro-benchmark

gcc -pthread -O3 benchmark_pthread_sigmask.c -o benchmark_pthread_sigmask

Run the micro-benchmark

/usr/bin/time -v ./benchmark_pthread_sigmask <ITERATIONS>

Elapsed time

Number of ITERATIONS Elapsed time (m:ss)
1 0:00.00
10 0:00.00
100 0:00.00
1000 0:00.01
1000 0:00.14

Currently, pthread_sigmask is invoked once at startup for all the supported signals. With this fix, pthread_sigmask will be invoked everytime a signal handler is installed for a signal. Generally, a master handler is only installed once for a signal. Before this fix, pthread_sigmask is invoked once. After this fix, pthread_sigmask will be invoked ~32 times (== number of signals).

Each iteration of the micro-benchmark invokes pthread_sigmask 32 times. The above results for the elapsed time suggest that this fix will have negligible impact on performance.

Micro-benchmark (benchmark_pthread_sigmask.c):

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

static int
unblockSignal(int signal)
{
	int rc = 0;
	sigset_t signalSet;

	rc = sigemptyset(&signalSet);
	if (0 != rc) {
		goto exit;
	}

	rc = sigaddset(&signalSet, signal);
	if (0 != rc) {
		goto exit;
	}

	/* Unblock the signal. */
	rc = pthread_sigmask(SIG_UNBLOCK, &signalSet, NULL);
exit:
	return rc;
}

int main(int argc,char* argv[]) 
{
	int i = 0;
	int j = 0;
	int rc = 0;
	int iterations = 0;
	int signals[] = {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGSTKFLT, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGPWR, SIGSYS};
	int numSignals = (int)sizeof(signals)/sizeof(signals[0]);
	if (argc !=2) {
		printf("Error: Number of iterations not provided.\n");
		exit(-1);
	}
	
	iterations = atoi(argv[1]);
	if (iterations <= 0) {
		printf("Error: Number of iterations is not a valid positive integer\n");
		exit(-1);
	}

	for (i = 0; i < iterations; i++) {
		for (j = 0; j < numSignals; j++) {
			rc = unblockSignal(signals[j]);
			if (0 != rc) {
				printf("Error: Unable to unblock signal=%d j=%d\n", signals[j], j);
				exit(-1);
			}
		}
	}

	return rc;
}

@babsingh babsingh marked this pull request as ready for review November 12, 2019 15:54
@babsingh
Copy link
Contributor Author

Initial testing looks good. Awaiting for test results from customer's nightly build. Code is ready-to-be-reviewed. But it should not be merged until test results from customer's nightly build are received.

@babsingh
Copy link
Contributor Author

The failures have been resolved in the customer's nightly build. So, this pull request can be merged after the code-review.

@rwy7
Copy link
Contributor

rwy7 commented Nov 18, 2019

@genie-omr build all

1 similar comment
@rwy7
Copy link
Contributor

rwy7 commented Nov 20, 2019

@genie-omr build all

@Leonardo2718
Copy link
Contributor

Leonardo2718 commented Nov 21, 2019

FYI: I'm manually stopping some tests for this PR that look like they're hanging.

@babsingh
Copy link
Contributor Author

babsingh commented Nov 21, 2019

@rwy0717 Unrelated errors were happening in the CI build jobs. I have rebased my branch. Can you please retry the builds?

@rwy7
Copy link
Contributor

rwy7 commented Nov 21, 2019

@genie-omr build all

@rwy7 rwy7 self-assigned this Nov 21, 2019
Currently, all supported asynchronous signals are unblocked during
startup. A signal is unblocked even when a signal handler is not
installed for it. This conflicts with an OMR consumer, who wants to
block a set of signals. The OMR consumer blocks a set of signals but the
OMR signal library unblocks those signals at startup. OMR signal library
should only unblock a signal if a signal handler is registered for it.
In other words, a signal should not be unblocked if it is not used i.e.
a signal handler is not registered for it. 

Fixes: eclipse-openj9/openj9#7749

Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
@babsingh babsingh changed the title Only unblock a signal if it is used Only unblock an asynchronous signal if it is used Nov 21, 2019
@rwy7
Copy link
Contributor

rwy7 commented Nov 21, 2019

@genie-omr build all

@youngar
Copy link
Contributor

youngar commented Nov 21, 2019

@genie-omr build x32linux
Relaunching build due to machine issues

@youngar youngar self-assigned this Nov 21, 2019
@youngar youngar merged commit f0489cc into eclipse-omr:master Nov 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants