-
Notifications
You must be signed in to change notification settings - Fork 409
Save and propagate si_pid for async signals, update omrsig_info() #7963
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
base: master
Are you sure you want to change the base?
Conversation
@keithc-ca can you pls do an initial review. |
include_core/omrport.h
Outdated
#define OMRPORT_SIG_SIGNAL_PID -63 | ||
#define OMRPORT_SIG_SIGNAL_PID_NAME -64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps "sender" is a better than "signal":
#define OMRPORT_SIG_SENDER_PID -63
#define OMRPORT_SIG_SENDER_NAME -64
port/aix/omrsignal_context.c
Outdated
if ((NULL != info) && (NULL != info->sigInfo)) { | ||
*name = "Sending Process"; | ||
*value = &info->sigInfo->si_pid; | ||
return OMRPORT_SIG_VALUE_32; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps things like this should be conditional:
return (sizeof(info->sigInfo->si_pid) == sizeof(uint32_t))
? OMRPORT_SIG_VALUE_32
: OMRPORT_SIG_VALUE_64;
port/aix/omrsignal_context.c
Outdated
case OMRPORT_SIG_SIGNAL_PID: | ||
case 6: | ||
if ((NULL != info) && (NULL != info->sigInfo)) { | ||
*name = "Sending Process"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No other names have spaces; suggest:
*name = "Sending_Process";
port/linux386/omrsignal_context.c
Outdated
if ((NULL != info) && (NULL != info->sigInfo)) { | ||
char exebuf[32]; | ||
char linkbuf[PATH_MAX]; | ||
snprintf(exebuf, sizeof(exebuf), "/proc/%d/exe", info->sigInfo->si_pid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think %d
should be %u
.
if ((NULL != info) && (NULL != info->sigInfo)) { | ||
char exebuf[32]; | ||
char linkbuf[PATH_MAX]; | ||
snprintf(exebuf, sizeof(exebuf), "/proc/%d/exe", info->sigInfo->si_pid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case process ids are wider than int
, this should cast to 64 bits:
snprintf(exebuf, sizeof(exebuf), "/proc/%" OMR_PRIu64 "/exe", (uint64_t)info->sigInfo->si_pid);
static volatile pid_t signalPids[ARRAY_SIZE_SIGNALS][NUM_SIGNAL_PIDS] = {0}; | ||
static volatile uintptr_t signalPidHeads[ARRAY_SIZE_SIGNALS] = {0}; | ||
static volatile uintptr_t signalPidTails[ARRAY_SIZE_SIGNALS] = {0}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't create two or more consecutive blank lines.
port/unix/omrsignal.c
Outdated
} | ||
cursor = cursor->next; | ||
} | ||
portLibrary->mem_free_memory(portLibrary, sigInfo); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the caller should do this?
port/unix/omrsignal.c
Outdated
* | ||
* @return void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing @param sigInfo
; unwanted @return void
.
port/unix/omrsignal.c
Outdated
/* Ensure the -1 is written before updating the head. */ | ||
issueWriteBarrier(); | ||
signalPidHeads[unixSignal] = nextHead; | ||
fprintf(stderr, "si_pid %d head %" PRIuPTR " tail %" PRIuPTR "\n", siPid, head, tail); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is temporary.
port/unix/omrsignal.c
Outdated
uintptr_t head = signalPidHeads[signal]; | ||
/* Check if there is room. */ | ||
if (nextTail != head) { | ||
if ((pid_t)-1 == compareAndSwapU32((uint32_t *)&signalPids[signal][tail], (pid_t)-1, sigInfo->si_pid)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's safe to assume sizeof(pid_t) == sizeof(uint32_t)
.
1cc3395
to
0c589af
Compare
Addressed the comments. |
include_core/omrport.h
Outdated
#define OMRPORT_SIG_GPR_ARM_R9 -61 | ||
#define OMRPORT_SIG_GPR_ARM_R10 -62 | ||
#define OMRPORT_SIG_SENDER_PID -63 | ||
#define OMRPORT_SIG_SENDER_PID_NAME -64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't a "PID" name that's returned; if you don't like just OMRPORT_SIG_SENDER_NAME
, perhaps OMRPORT_SIG_SENDER_IMAGE_NAME
?
port/linux386/omrsignal_context.c
Outdated
if ((NULL != info) && (NULL != info->sigInfo)) { | ||
char exebuf[32]; | ||
char linkbuf[PATH_MAX]; | ||
snprintf(exebuf, sizeof(exebuf), "/proc/%u/exe", (uint64_t)info->sigInfo->si_pid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is for 32-bit Linux; it's hard to imagine PIDs are 64 bits, but if you want to be consistent with other platforms the matching format (OMR_PRIu64
) must be used.
port/unix/omrsignal.c
Outdated
if (sizeof(sigInfo->si_pid) == sizeof(uint32_t)) { | ||
if ((uint32_t)-1 == compareAndSwapU32((uint32_t *)&signalPids[signal][tail], (uint32_t)-1, sigInfo->si_pid)) { | ||
/* The pid is written before the tail is incremented. */ | ||
signalPidTails[signal] = nextTail; | ||
break; | ||
} | ||
} else { | ||
if ((uint64_t)-1 == compareAndSwapUDATA((uint64_t *)&signalPids[signal][tail], (uint64_t)-1, sigInfo->si_pid)) { | ||
/* The pid is written before the tail is incremented. */ | ||
signalPidTails[signal] = nextTail; | ||
break; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UDATA
and uint64_t
aren't necessarily the same size without a check; suggest inverting this:
if (sizeof(sigInfo->si_pid) == sizeof(uintptr_t)) {
if ((uintptr_t)-1 == compareAndSwapUDATA((uintptr_t *)&signalPids[signal][tail], (uintptr_t)-1, sigInfo->si_pid)) {
/* The pid is written before the tail is incremented. */
signalPidTails[signal] = nextTail;
break;
}
} else {
if ((uint32_t)-1 == compareAndSwapU32((uint32_t *)&signalPids[signal][tail], (uint32_t)-1, sigInfo->si_pid)) {
/* The pid is written before the tail is incremented. */
signalPidTails[signal] = nextTail;
break;
}
}
The if
on line 1261 could also be inverted to reduce the indentation here.
Updated. |
include_core/omrport.h
Outdated
#define OMRPORT_SIG_GPR_ARM_R9 -61 | ||
#define OMRPORT_SIG_GPR_ARM_R10 -62 | ||
#define OMRPORT_SIG_SENDER_PID -63 | ||
#define OMRPORT_SIG_SENDER_NAME -64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An extra space so the values line up would be welcome.
port/unix/omrsignal.c
Outdated
uintptr_t nextTail = (tail + 1) % NUM_SIGNAL_PIDS; | ||
uintptr_t head = signalPidHeads[signal]; | ||
if (nextTail == head) { | ||
/* Stop if there is no room. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "if" is not appropriate here, if we reach this line, there is no room:
if (nextTail == head) {
/* Stop: there is no room. */
break;
}
Updated. What do you think about the algorithm to keep the pids. There can be multiple signals/threads adding, but only one thread removing. |
I haven't looked at that part closely enough to comment yet: I take a closer look tomorrow. |
efff2c6
to
2514074
Compare
I see |
include_core/omrport.h
Outdated
/** see @ref omrsysinfo.c::omrsysinfo_get_processes "omrsysinfo_get_processes" */ | ||
uintptr_t (*sysinfo_get_processes)(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData); | ||
/** see @ref omrsysinfo.c::omrsysinfo_get_process_id_name "omrsysinfo_get_process_id_name"*/ | ||
const char *(*sysinfo_get_process_id_name)(struct OMRPortLibrary *portLibrary, uintptr_t pid) ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type should be char *
because the caller is expected to free that memory.
Please remove the space before ;
.
As before, I don't think _id_
makes sense here processes run programs, but IDs don't have names.
include_core/omrport.h
Outdated
intptr_t (*sysinfo_get_CPU_load)(struct OMRPortLibrary *portLibrary, double *load) ; | ||
/** see @ref omrsysinfo.c::omrsysinfo_get_processes "omrsysinfo_get_processes" */ | ||
uintptr_t (*sysinfo_get_processes)(struct OMRPortLibrary *portLibrary, OMRProcessInfoCallback callback, void *userData); | ||
/** see @ref omrsysinfo.c::omrsysinfo_get_process_id_name "omrsysinfo_get_process_id_name"*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space before */
, please.
port/common/omrsysinfo.c
Outdated
* Get the name of the specified process. | ||
* @param[in] portLibrary The port library. | ||
* @param[in] pid The process ID. | ||
* @return The process name string (NULL terminated) on success, which must be freed, NULL on error or not supported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"or not" -> "or if not"
I moved the code to omrsysinfo_get_process_id_name(). For one thing the code doesn't need to be duplicated a number of times, and the sysinfo function can be used outside of signals. To handle SIGABRT, for which the handler is in openj9, it doesn't work to call omrsig_info() because it takes a private omr OMRUnixSignalInfo structure. |
I assume it is replaced by |
port/unix/omrsysinfo.c
Outdated
char exebuf[32]; | ||
char linkbuf[PATH_MAX]; | ||
snprintf(exebuf, sizeof(exebuf), "/proc/%" OMR_PRIuPTR "/exe", pid); | ||
ssize_t rc = readlink(exebuf, linkbuf, sizeof(linkbuf)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not legal C code (rc
must be declared before line 7905).
port/unix/omrsysinfo.c
Outdated
char linkbuf[PATH_MAX]; | ||
snprintf(exebuf, sizeof(exebuf), "/proc/%" OMR_PRIuPTR "/exe", pid); | ||
ssize_t rc = readlink(exebuf, linkbuf, sizeof(linkbuf)); | ||
if ((-1 != rc) && rc < sizeof(linkbuf)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing parentheses:
if ((-1 != rc) && (rc < sizeof(linkbuf))) {
Updated. |
port/common/omrsysinfo.c
Outdated
* Get the name of the specified process. | ||
* @param[in] portLibrary The port library. | ||
* @param[in] pid The process ID. | ||
* @return The process name string (NULL terminated) on success, which must be freed, NULL on error or if not supported. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line is a little long.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
9d5aef1
to
f2fe8d0
Compare
Signed-off-by: Peter Shipton <[email protected]>
I think there's a real danger of dropping signals. Maybe we can just drop the sending pid rather than drop the signal entirely? |
That's how it already works, I didn't change anything to do with counting signals and waking up asynchSignalReporter to process them. |
Ok, you're right; we just might not have the sending PID for some signals when a queue overflows. The PIDs can also be "wrong" in that they may be consumed by a signal occurrence that wasn't queued in the same order (I don't think this is a serious issue). |
@babsingh pls review when you get a chance. |
jenkins build all |
Related to eclipse-openj9/openj9#21609