Skip to content

Commit

Permalink
add debug code for timer_posix
Browse files Browse the repository at this point in the history
timer_posix mode is managed by timer_posix.state. This patch
adds some debug code for the transition of the state.
  • Loading branch information
ko1 committed Feb 2, 2021
1 parent f92b7b7 commit be14865
Showing 1 changed file with 47 additions and 8 deletions.
55 changes: 47 additions & 8 deletions thread_pthread.c
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

0 comments on commit be14865

Please sign in to comment.