Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/cddl/osnet/dist/uts/common because our xcall stuff ...
details: https://anonhg.NetBSD.org/src/rev/0765acf8fd07
branches: trunk
changeset: 770509:0765acf8fd07
user: yamt <yamt%NetBSD.org@localhost>
date: Wed Oct 19 11:02:08 2011 +0000
description:
because our xcall stuff can't be used in softint, use kernel threads
for cleaner/deadman low-level cyclic replacement. PR/44905
diffstat:
external/cddl/osnet/dist/uts/common/dtrace/dtrace.c | 180 ++++++++---------
external/cddl/osnet/dist/uts/common/sys/dtrace_impl.h | 4 +-
2 files changed, 89 insertions(+), 95 deletions(-)
diffs (250 lines):
diff -r 5cb57add1a95 -r 0765acf8fd07 external/cddl/osnet/dist/uts/common/dtrace/dtrace.c
--- a/external/cddl/osnet/dist/uts/common/dtrace/dtrace.c Wed Oct 19 10:55:50 2011 +0000
+++ b/external/cddl/osnet/dist/uts/common/dtrace/dtrace.c Wed Oct 19 11:02:08 2011 +0000
@@ -118,7 +118,6 @@
/* FreeBSD includes: */
#if !defined(sun)
-#include <sys/callout.h>
#include <sys/ctype.h>
#include <sys/limits.h>
//#include <sys/kdb.h>
@@ -250,10 +249,6 @@
#if defined(__i386__) || defined(__amd64__)
uintptr_t dtrace_in_probe_addr; /* Address of invop when already in probe */
#endif
-
-void *dtrace_deadman_wchan;
-int dtrace_deadman_alive; /* deadman thread keep alive */
-lwp_t *dtrace_deadman_proc;
#endif
/*
@@ -12836,7 +12831,6 @@
}
}
-#if defined(sun)
static void
dtrace_state_clean(dtrace_state_t *state)
{
@@ -12873,72 +12867,11 @@
dtrace_membar_producer();
state->dts_alive = now;
}
-#else
-static void
-dtrace_state_clean(void *arg)
-{
- dtrace_state_t *state = arg;
- dtrace_optval_t *opt = state->dts_options;
-
- if (state->dts_activity == DTRACE_ACTIVITY_INACTIVE)
- return;
-
- dtrace_dynvar_clean(&state->dts_vstate.dtvs_dynvars);
- dtrace_speculation_clean(state);
-
- callout_reset(&state->dts_cleaner, ((dtrace_optval_t)hz * opt[DTRACEOPT_CLEANRATE]) / NANOSEC,
- dtrace_state_clean, state);
-}
-
-static void
-dtrace_state_deadman(void *arg)
-{
- dtrace_state_t *state = arg;
- hrtime_t now;
- int res;
- kmutex_t dtrace_deadman_mutex;
-
- mutex_init(&dtrace_deadman_mutex, NULL, MUTEX_DEFAULT, NULL);
-
- while (dtrace_deadman_alive) {
- mutex_enter(&dtrace_deadman_mutex);
- res = mtsleep(&dtrace_deadman_wchan, PRI_BIO, "dtrace_deadman",
- ((dtrace_optval_t)hz * dtrace_deadman_interval) / NANOSEC,
- &dtrace_deadman_mutex);
- mutex_exit(&dtrace_deadman_mutex);
-
- if (!dtrace_deadman_alive) {
- break;
- }
-
- dtrace_sync();
-
- dtrace_debug_output();
-
- now = dtrace_gethrtime();
-
- if (state != dtrace_anon.dta_state &&
- now - state->dts_laststatus >= dtrace_deadman_user)
- continue;
-
- /*
- * We must be sure that dts_alive never appears to be less than the
- * value upon entry to dtrace_state_deadman(), and because we lack a
- * dtrace_cas64(), we cannot store to it atomically. We thus instead
- * store INT64_MAX to it, followed by a memory barrier, followed by
- * the new value. This assures that dts_alive never appears to be
- * less than its true value, regardless of the order in which the
- * stores to the underlying storage are issued.
- */
- state->dts_alive = INT64_MAX;
- dtrace_membar_producer();
- state->dts_alive = now;
- }
-
- mutex_destroy(&dtrace_deadman_mutex);
-
- kthread_exit(0);
-}
+
+#if !defined(sun)
+struct dtrace_state_worker *dtrace_state_worker_add(void (*)(dtrace_state_t *),
+ dtrace_state_t *, hrtime_t);
+void dtrace_state_worker_remove(struct dtrace_state_worker *);
#endif
static dtrace_state_t *
@@ -13015,7 +12948,8 @@
state->dts_cleaner = CYCLIC_NONE;
state->dts_deadman = CYCLIC_NONE;
#else
- callout_init(&state->dts_cleaner, CALLOUT_MPSAFE);
+ state->dts_cleaner = NULL;
+ state->dts_deadman = NULL;
#endif
state->dts_vstate.dtvs_state = state;
@@ -13503,19 +13437,10 @@
state->dts_deadman = cyclic_add(&hdlr, &when);
#else
- callout_reset(&state->dts_cleaner,
- ((dtrace_optval_t)hz * opt[DTRACEOPT_CLEANRATE]) / NANOSEC,
- dtrace_state_clean, state);
-
- dtrace_deadman_wchan = &dtrace_deadman_wchan;
- dtrace_deadman_alive = 1;
-
- if ((rval = kthread_create(PRI_BIO, KTHREAD_MPSAFE,
- NULL, dtrace_state_deadman, state,
- &dtrace_deadman_proc, "dtrace_deadman")) != 0) {
- printf("failed to create deadman thread, error=%d\n", rval);
- goto out;
- }
+ state->dts_cleaner = dtrace_state_worker_add(
+ dtrace_state_clean, state, opt[DTRACEOPT_CLEANRATE]);
+ state->dts_deadman = dtrace_state_worker_add(
+ dtrace_state_deadman, state, dtrace_deadman_interval);
#endif
state->dts_activity = DTRACE_ACTIVITY_WARMUP;
@@ -13789,13 +13714,11 @@
if (state->dts_deadman != CYCLIC_NONE)
cyclic_remove(state->dts_deadman);
#else
- callout_stop(&state->dts_cleaner);
-
- if (dtrace_deadman_alive) {
- /* tell the deadman thread to exit */
- dtrace_deadman_alive = 0;
- wakeup(dtrace_deadman_wchan);
- }
+ if (state->dts_cleaner != NULL)
+ dtrace_state_worker_remove(state->dts_cleaner);
+
+ if (state->dts_deadman != NULL)
+ dtrace_state_worker_remove(state->dts_deadman);
#endif
dtrace_dstate_fini(&vstate->dtvs_dynvars);
@@ -16691,3 +16614,74 @@
MODULE_DEPEND(dtrace, opensolaris, 1, 1, 1);
#endif
#endif
+
+#if !defined(sun)
+#undef mutex_init
+
+struct dtrace_state_worker {
+ kmutex_t lock;
+ kcondvar_t cv;
+ void (*fn)(dtrace_state_t *);
+ dtrace_state_t *state;
+ int interval;
+ lwp_t *lwp;
+ bool exiting;
+};
+
+static void
+dtrace_state_worker_thread(void *vp)
+{
+ struct dtrace_state_worker *w = vp;
+
+ mutex_enter(&w->lock);
+ while (!w->exiting) {
+ int error;
+
+ error = cv_timedwait(&w->cv, &w->lock, w->interval);
+ if (error == EWOULDBLOCK) {
+ mutex_exit(&w->lock);
+ w->fn(w->state);
+ mutex_enter(&w->lock);
+ }
+ }
+ mutex_exit(&w->lock);
+ kthread_exit(0);
+}
+
+struct dtrace_state_worker *
+dtrace_state_worker_add(void (*fn)(dtrace_state_t *), dtrace_state_t *state,
+ hrtime_t interval)
+{
+ struct dtrace_state_worker *w;
+ int error;
+
+ w = kmem_alloc(sizeof(*w), KM_SLEEP);
+ mutex_init(&w->lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&w->cv, "dtrace");
+ w->interval = ((uintmax_t)hz * interval) / NANOSEC,
+ w->fn = fn;
+ w->state = state;
+ w->exiting = false;
+ error = kthread_create(PRI_NONE, KTHREAD_MPSAFE|KTHREAD_MUSTJOIN, NULL,
+ dtrace_state_worker_thread, w, &w->lwp, "dtrace-state-worker");
+ KASSERT(error == 0); /* XXX */
+ return w;
+}
+
+void
+dtrace_state_worker_remove(struct dtrace_state_worker *w)
+{
+ int error;
+
+ KASSERT(!w->exiting);
+ mutex_enter(&w->lock);
+ w->exiting = true;
+ cv_signal(&w->cv);
+ mutex_exit(&w->lock);
+ error = kthread_join(w->lwp);
+ KASSERT(error == 0);
+ cv_destroy(&w->cv);
+ mutex_destroy(&w->lock);
+ kmem_free(w, sizeof(*w));
+}
+#endif
diff -r 5cb57add1a95 -r 0765acf8fd07 external/cddl/osnet/dist/uts/common/sys/dtrace_impl.h
--- a/external/cddl/osnet/dist/uts/common/sys/dtrace_impl.h Wed Oct 19 10:55:50 2011 +0000
+++ b/external/cddl/osnet/dist/uts/common/sys/dtrace_impl.h Wed Oct 19 11:02:08 2011 +0000
@@ -1135,8 +1135,8 @@
cyclic_id_t dts_cleaner; /* cleaning cyclic */
cyclic_id_t dts_deadman; /* deadman cyclic */
#else
- struct callout dts_cleaner; /* Cleaning callout. */
- struct callout dts_deadman; /* Deadman callout. */
+ struct dtrace_state_worker *dts_cleaner;/* cleaning cyclic */
+ struct dtrace_state_worker *dts_deadman;/* deadman cyclic */
#endif
hrtime_t dts_alive; /* time last alive */
char dts_speculates; /* boolean: has speculations */
Home |
Main Index |
Thread Index |
Old Index