diff options
author | anton <anton@cvs.openbsd.org> | 2018-12-27 10:04:17 +0000 |
---|---|---|
committer | anton <anton@cvs.openbsd.org> | 2018-12-27 10:04:17 +0000 |
commit | 9b4628aba211dfc09d5e2395dcb8d85a0fd10b19 (patch) | |
tree | 3f9533ac6145da45c89448f257a45e00052a421a /sys/dev/kcov.c | |
parent | cf1b10cb877c693dbe5f50eb6bdcc1f7116f0c33 (diff) |
Separate kcov descriptor state and trace mode as a first step towards supporting
different trace modes.
ok mpi@
Diffstat (limited to 'sys/dev/kcov.c')
-rw-r--r-- | sys/dev/kcov.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/sys/dev/kcov.c b/sys/dev/kcov.c index ea28ba8f326..08657418e7c 100644 --- a/sys/dev/kcov.c +++ b/sys/dev/kcov.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kcov.c,v 1.6 2018/12/25 21:56:53 anton Exp $ */ +/* $OpenBSD: kcov.c,v 1.7 2018/12/27 10:04:16 anton Exp $ */ /* * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org> @@ -35,11 +35,12 @@ struct kcov_dev { enum { - KCOV_MODE_DISABLED, - KCOV_MODE_INIT, - KCOV_MODE_TRACE_PC, - KCOV_MODE_DYING, - } kd_mode; + KCOV_STATE_NONE, + KCOV_STATE_READY, + KCOV_STATE_TRACE, + KCOV_STATE_DYING, + } kd_state; + int kd_mode; int kd_unit; /* device minor */ uintptr_t *kd_buf; /* traced coverage */ size_t kd_nmemb; @@ -137,12 +138,15 @@ kcovclose(dev_t dev, int flag, int mode, struct proc *p) if (kd == NULL) return (EINVAL); - DPRINTF("%s: unit=%d\n", __func__, minor(dev)); + DPRINTF("%s: unit=%d, state=%d, mode=%d\n", + __func__, kd->kd_unit, kd->kd_state, kd->kd_mode); - if (kd->kd_mode == KCOV_MODE_TRACE_PC) - kd->kd_mode = KCOV_MODE_DYING; - else + if (kd->kd_state == KCOV_STATE_TRACE) { + kd->kd_state = KCOV_STATE_DYING; + kd->kd_mode = KCOV_MODE_NONE; + } else { kd_free(kd); + } return (0); } @@ -163,20 +167,22 @@ kcovioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; case KIOENABLE: /* Only one kcov descriptor can be enabled per thread. */ - if (p->p_kd != NULL || kd->kd_mode != KCOV_MODE_INIT) { + if (p->p_kd != NULL || kd->kd_state != KCOV_STATE_READY) { error = EBUSY; break; } + kd->kd_state = KCOV_STATE_TRACE; kd->kd_mode = KCOV_MODE_TRACE_PC; p->p_kd = kd; break; case KIODISABLE: /* Only the enabled thread may disable itself. */ - if (p->p_kd != kd || kd->kd_mode != KCOV_MODE_TRACE_PC) { + if (p->p_kd != kd || kd->kd_state != KCOV_STATE_TRACE) { error = EBUSY; break; } - kd->kd_mode = KCOV_MODE_INIT; + kd->kd_state = KCOV_STATE_READY; + kd->kd_mode = KCOV_MODE_NONE; p->p_kd = NULL; break; default: @@ -184,8 +190,8 @@ kcovioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) DPRINTF("%s: %lu: unknown command\n", __func__, cmd); } - DPRINTF("%s: unit=%d, mode=%d, error=%d\n", - __func__, kd->kd_unit, kd->kd_mode, error); + DPRINTF("%s: unit=%d, state=%d, mode=%d, error=%d\n", + __func__, kd->kd_unit, kd->kd_state, kd->kd_mode, error); return (error); } @@ -219,12 +225,15 @@ kcov_exit(struct proc *p) if (kd == NULL) return; - DPRINTF("%s: unit=%d\n", __func__, kd->kd_unit); + DPRINTF("%s: unit=%d, state=%d, mode=%d\n", + __func__, kd->kd_unit, kd->kd_state, kd->kd_mode); - if (kd->kd_mode == KCOV_MODE_DYING) + if (kd->kd_state == KCOV_STATE_DYING) { kd_free(kd); - else - kd->kd_mode = KCOV_MODE_INIT; + } else { + kd->kd_state = KCOV_STATE_READY; + kd->kd_mode = KCOV_MODE_NONE; + } p->p_kd = NULL; } @@ -248,7 +257,7 @@ kd_init(struct kcov_dev *kd, unsigned long nmemb) KASSERT(kd->kd_buf == NULL); - if (kd->kd_mode != KCOV_MODE_DISABLED) + if (kd->kd_state != KCOV_STATE_NONE) return (EBUSY); if (nmemb == 0 || nmemb > KCOV_BUF_MAX_NMEMB) @@ -257,7 +266,7 @@ kd_init(struct kcov_dev *kd, unsigned long nmemb) size = roundup(nmemb * sizeof(uintptr_t), PAGE_SIZE); buf = malloc(size, M_SUBPROC, M_WAITOK | M_ZERO); /* malloc() can sleep, ensure the race was won. */ - if (kd->kd_mode != KCOV_MODE_DISABLED) { + if (kd->kd_state != KCOV_STATE_NONE) { free(buf, M_SUBPROC, size); return (EBUSY); } @@ -265,14 +274,15 @@ kd_init(struct kcov_dev *kd, unsigned long nmemb) /* The first element is reserved to hold the number of used elements. */ kd->kd_nmemb = nmemb - 1; kd->kd_size = size; - kd->kd_mode = KCOV_MODE_INIT; + kd->kd_state = KCOV_STATE_READY; return (0); } void kd_free(struct kcov_dev *kd) { - DPRINTF("%s: unit=%d mode=%d\n", __func__, kd->kd_unit, kd->kd_mode); + DPRINTF("%s: unit=%d, state=%d, mode=%d\n", + __func__, kd->kd_unit, kd->kd_state, kd->kd_mode); TAILQ_REMOVE(&kd_list, kd, kd_entry); free(kd->kd_buf, M_SUBPROC, kd->kd_size); |