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

add debug code for timer_posix #4145

Merged
merged 1 commit into from
Feb 2, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 47 additions & 8 deletions thread_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,52 @@ enum rtimer_state {
#if UBF_TIMER == UBF_TIMER_POSIX
static const struct itimerspec zero;
static struct {
rb_atomic_t state; /* rtimer_state */
rb_atomic_t state_; /* rtimer_state */
rb_pid_t owner;
timer_t timerid;
} timer_posix = {
/* .state = */ RTIMER_DEAD,
};

#define TIMER_STATE_DEBUG 0

static const char *
rtimer_state_name(enum rtimer_state state)
{
switch (state) {
case RTIMER_DISARM: return "disarm";
case RTIMER_ARMING: return "arming";
case RTIMER_ARMED: return "armed";
case RTIMER_DEAD: return "dead";
default: rb_bug("unreachable");
}
}

static enum rtimer_state
timer_state_exchange(enum rtimer_state state)
{
enum rtimer_state prev = ATOMIC_EXCHANGE(timer_posix.state_, state);
if (TIMER_STATE_DEBUG) fprintf(stderr, "state (exc): %s->%s\n", rtimer_state_name(prev), rtimer_state_name(state));
return prev;
}

static enum rtimer_state
timer_state_cas(enum rtimer_state expected_prev, enum rtimer_state state)
{
enum rtimer_state prev = ATOMIC_CAS(timer_posix.state_, expected_prev, state);

if (TIMER_STATE_DEBUG) {
if (prev == expected_prev) {
fprintf(stderr, "state (cas): %s->%s\n", rtimer_state_name(prev), rtimer_state_name(state));
}
else {
fprintf(stderr, "state (cas): %s (expected:%s)\n", rtimer_state_name(prev), rtimer_state_name(expected_prev));
}
}

return prev;
}

#elif UBF_TIMER == UBF_TIMER_PTHREAD
static void *timer_pthread_fn(void *);
static struct {
Expand Down Expand Up @@ -1423,7 +1462,7 @@ ubf_timer_arm(rb_pid_t current) /* async signal safe */
{
#if UBF_TIMER == UBF_TIMER_POSIX
if ((!current || timer_posix.owner == current) &&
!ATOMIC_CAS(timer_posix.state, RTIMER_DISARM, RTIMER_ARMING)) {
timer_state_cas(RTIMER_DISARM, RTIMER_ARMING) == RTIMER_DISARM) {
struct itimerspec it;

it.it_interval.tv_sec = it.it_value.tv_sec = 0;
Expand All @@ -1432,7 +1471,7 @@ ubf_timer_arm(rb_pid_t current) /* async signal safe */
if (timer_settime(timer_posix.timerid, 0, &it, 0))
rb_async_bug_errno("timer_settime (arm)", errno);

switch (ATOMIC_CAS(timer_posix.state, RTIMER_ARMING, RTIMER_ARMED)) {
switch (timer_state_cas(RTIMER_ARMING, RTIMER_ARMED)) {
case RTIMER_DISARM:
/* somebody requested a disarm while we were arming */
/* may race harmlessly with ubf_timer_destroy */
Expand Down Expand Up @@ -1714,7 +1753,7 @@ ubf_timer_create(rb_pid_t current)
sev.sigev_value.sival_ptr = &timer_posix;

if (!timer_create(UBF_TIMER_CLOCK, &sev, &timer_posix.timerid)) {
rb_atomic_t prev = ATOMIC_EXCHANGE(timer_posix.state, RTIMER_DISARM);
rb_atomic_t prev = timer_state_exchange(RTIMER_DISARM);

if (prev != RTIMER_DEAD) {
rb_bug("timer_posix was not dead: %u\n", (unsigned)prev);
Expand Down Expand Up @@ -1759,7 +1798,7 @@ ubf_timer_disarm(void)
#if UBF_TIMER == UBF_TIMER_POSIX
rb_atomic_t prev;

prev = ATOMIC_CAS(timer_posix.state, RTIMER_ARMED, RTIMER_DISARM);
prev = timer_state_cas(RTIMER_ARMED, RTIMER_DISARM);
switch (prev) {
case RTIMER_DISARM: return; /* likely */
case RTIMER_ARMING: return; /* ubf_timer_arm will disarm itself */
Expand All @@ -1768,7 +1807,7 @@ ubf_timer_disarm(void)
int err = errno;

if (err == EINVAL) {
prev = ATOMIC_CAS(timer_posix.state, RTIMER_DISARM, RTIMER_DISARM);
prev = timer_state_cas(RTIMER_DISARM, RTIMER_DISARM);

/* main thread may have killed the timer */
if (prev == RTIMER_DEAD) return;
Expand Down Expand Up @@ -1797,7 +1836,7 @@ ubf_timer_destroy(void)

/* prevent signal handler from arming: */
for (i = 0; i < max; i++) {
switch (ATOMIC_CAS(timer_posix.state, expect, RTIMER_DEAD)) {
switch (timer_state_cas(expect, RTIMER_DEAD)) {
case RTIMER_DISARM:
if (expect == RTIMER_DISARM) goto done;
expect = RTIMER_DISARM;
Expand All @@ -1823,7 +1862,7 @@ ubf_timer_destroy(void)
if (timer_delete(timer_posix.timerid) < 0)
rb_sys_fail("timer_delete");

VM_ASSERT(ATOMIC_EXCHANGE(timer_posix.state, RTIMER_DEAD) == RTIMER_DEAD);
VM_ASSERT(timer_state_exchange(RTIMER_DEAD) == RTIMER_DEAD);
}
#elif UBF_TIMER == UBF_TIMER_PTHREAD
int err;
Expand Down